Log to /var/log/apk.log
This adds a log file at /var/log/apk.log. On each run, apk's version information and the current date & time are written to this file, followed by any normal apk output.cute-signatures
parent
4fe5ac8328
commit
646c834492
|
@ -15,6 +15,8 @@ to install is called the _world_ (see *apk-world*(5)). *apk* supports various
|
|||
sub-commands to query and manipulate _world_ and local & remote package
|
||||
repositories.
|
||||
|
||||
All apk commands which modify the database are logged to /var/log/apk.log.
|
||||
|
||||
# COMMANDS
|
||||
|
||||
Each command is documented in detail on its manual page.
|
||||
|
|
13
src/apk.c
13
src/apk.c
|
@ -46,11 +46,11 @@ time_t time(time_t *tloc)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void version(struct apk_out *out)
|
||||
static void version(struct apk_out *out, const char *prefix)
|
||||
{
|
||||
apk_out(out, "apk-tools " APK_VERSION ", compiled for " APK_DEFAULT_ARCH ".");
|
||||
apk_out_fmt(out, prefix, "apk-tools " APK_VERSION ", compiled for " APK_DEFAULT_ARCH ".");
|
||||
#ifdef TEST_MODE
|
||||
apk_out(out, "TEST MODE BUILD. NOT FOR PRODUCTION USE.");
|
||||
apk_out_fmt(out, prefix, "TEST MODE BUILD. NOT FOR PRODUCTION USE.");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ static int option_parse_global(void *ctx, struct apk_ctx *ac, int opt, const cha
|
|||
ac->out.verbosity++;
|
||||
break;
|
||||
case OPT_GLOBAL_version:
|
||||
version(out);
|
||||
version(out, NULL);
|
||||
return -ESHUTDOWN;
|
||||
case OPT_GLOBAL_force:
|
||||
ac->force |= APK_FORCE_OVERWRITE | APK_FORCE_OLD_APK
|
||||
|
@ -260,7 +260,7 @@ const struct apk_option_group optgroup_commit = {
|
|||
|
||||
static int usage(struct apk_out *out, struct apk_applet *applet)
|
||||
{
|
||||
version(out);
|
||||
version(out, NULL);
|
||||
apk_applet_help(applet, out);
|
||||
return 1;
|
||||
}
|
||||
|
@ -460,6 +460,9 @@ int main(int argc, char **argv)
|
|||
r = apk_ctx_prepare(&ctx);
|
||||
if (r != 0) goto err;
|
||||
|
||||
apk_out_log_argv(&ctx.out, apk_argv);
|
||||
version(&ctx.out, APK_OUT_LOG_ONLY);
|
||||
|
||||
if (ctx.open_flags) {
|
||||
r = apk_db_open(&db, &ctx);
|
||||
if (r != 0) {
|
||||
|
|
|
@ -30,11 +30,15 @@ void apk_url_parse(struct apk_url_print *, const char *);
|
|||
struct apk_out {
|
||||
int verbosity;
|
||||
unsigned int width, last_change;
|
||||
FILE *out, *err;
|
||||
FILE *out, *err, *log;
|
||||
};
|
||||
|
||||
static inline int apk_out_verbosity(struct apk_out *out) { return out->verbosity; }
|
||||
|
||||
// Pass this as the prefix to skip logging to the console (but still write to
|
||||
// the log file).
|
||||
#define APK_OUT_LOG_ONLY ((const char*)-1)
|
||||
|
||||
#define apk_err(out, args...) do { apk_out_fmt(out, "ERROR: ", args); } while (0)
|
||||
#define apk_out(out, args...) do { apk_out_fmt(out, NULL, args); } while (0)
|
||||
#define apk_warn(out, args...) do { if (apk_out_verbosity(out) >= 0) { apk_out_fmt(out, "WARNING: ", args); } } while (0)
|
||||
|
@ -44,6 +48,7 @@ static inline int apk_out_verbosity(struct apk_out *out) { return out->verbosity
|
|||
|
||||
void apk_out_reset(struct apk_out *);
|
||||
void apk_out_fmt(struct apk_out *, const char *prefix, const char *format, ...);
|
||||
void apk_out_log_argv(struct apk_out *, char **argv);
|
||||
|
||||
struct apk_progress {
|
||||
struct apk_out *out;
|
||||
|
|
|
@ -29,6 +29,7 @@ void apk_ctx_free(struct apk_ctx *ac)
|
|||
apk_trust_free(&ac->trust);
|
||||
apk_string_array_free(&ac->repository_list);
|
||||
apk_string_array_free(&ac->private_keys);
|
||||
if (ac->out.log) fclose(ac->out.log);
|
||||
}
|
||||
|
||||
int apk_ctx_prepare(struct apk_ctx *ac)
|
||||
|
@ -53,6 +54,21 @@ int apk_ctx_prepare(struct apk_ctx *ac)
|
|||
apk_err(&ac->out, "Unable to open root: %s", apk_error_str(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (ac->open_flags & APK_OPENF_WRITE) {
|
||||
const char *log_path = "var/log/apk.log", *log_dir = "var/log";
|
||||
const int lflags = O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC;
|
||||
int fd = openat(ac->root_fd, log_path, lflags, 0644);
|
||||
if (fd < 0 && (ac->open_flags & APK_OPENF_CREATE)) {
|
||||
mkdirat(ac->root_fd, log_dir, 0755);
|
||||
fd = openat(ac->root_fd, log_path, lflags, 0644);
|
||||
}
|
||||
if (fd < 0) {
|
||||
apk_err(&ac->out, "Unable to open log: %s", apk_error_str(errno));
|
||||
return -errno;
|
||||
}
|
||||
ac->out.log = fdopen(fd, "a");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
25
src/print.c
25
src/print.c
|
@ -136,10 +136,35 @@ static void log_internal(FILE *dest, const char *prefix, const char *format, va_
|
|||
void apk_out_fmt(struct apk_out *out, const char *prefix, const char *format, ...)
|
||||
{
|
||||
va_list va;
|
||||
if (prefix != APK_OUT_LOG_ONLY) {
|
||||
va_start(va, format);
|
||||
log_internal(prefix ? out->err : out->out, prefix, format, va);
|
||||
out->last_change++;
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
if (out->log) {
|
||||
va_start(va, format);
|
||||
log_internal(out->log, prefix, format, va);
|
||||
va_end(va);
|
||||
}
|
||||
}
|
||||
|
||||
void apk_out_log_argv(struct apk_out *out, char **argv)
|
||||
{
|
||||
char when[32];
|
||||
struct tm tm;
|
||||
time_t now = time(NULL);
|
||||
|
||||
if (!out->log) return;
|
||||
fprintf(out->log, "\nRunning `");
|
||||
for (int i = 0; argv[i]; ++i) {
|
||||
fprintf(out->log, "%s%s", argv[i], argv[i+1] ? " " : "");
|
||||
}
|
||||
|
||||
gmtime_r(&now, &tm);
|
||||
strftime(when, sizeof(when), "%Y-%m-%d %H:%M:%S", &tm);
|
||||
fprintf(out->log, "` at %s\n", when);
|
||||
}
|
||||
|
||||
void apk_print_progress(struct apk_progress *p, size_t done, size_t total)
|
||||
|
|
Loading…
Reference in New Issue