diff --git a/completions/zsh/_yambar b/completions/zsh/_yambar index 85790b9..aa8172f 100644 --- a/completions/zsh/_yambar +++ b/completions/zsh/_yambar @@ -7,4 +7,6 @@ _arguments \ '(-b --backend)'{-b,--backend}'[backend to use (default: auto)]:backend:(xcb wayland auto)' \ '(-c --config)'{-c,--config}'[alternative configuration file]:filename:_files' \ '(-C --validate)'{-C,--validate}'[verify configuration then quit]' \ - '(-p --print-pid)'{-p,--print-pid}'[print PID to this file or FD when up and running]:pidfile:_files' + '(-p --print-pid)'{-p,--print-pid}'[print PID to this file or FD when up and running]:pidfile:_files' \ + '(-l --log-colorize)'{-l,--log-colorize}'[enable or disable colorization of log output on stderr]:logcolor:(never always auto)' \ + '(-s --log-no-syslog)'{-s,--log-no-syslog}'[disable syslog logging]' diff --git a/doc/yambar.1.scd b/doc/yambar.1.scd index a4cc095..b750468 100644 --- a/doc/yambar.1.scd +++ b/doc/yambar.1.scd @@ -27,6 +27,12 @@ yambar - modular status panel for X11 and Wayland (or FD) is closed immediately after writing the PID. When a _FILE_ as been specified, the file is unlinked when yambar exits. +*-l*,*--log-colorize*=[{*never*,*always*,*auto*}] + Enables or disables colorization of log output on stderr. + +*-s*,*--log-no-syslog* + Disables syslog logging. Logging is only done on stderr. + *-v*,*--version* Show the version number and quit diff --git a/log.c b/log.c index f9e2c69..344752b 100644 --- a/log.c +++ b/log.c @@ -12,19 +12,25 @@ #include static bool colorize = false; +static bool do_syslog = true; -static void __attribute__((constructor)) -init(void) +void +log_init(enum log_colorize _colorize, bool _do_syslog) { - colorize = isatty(STDERR_FILENO); - openlog(NULL, /*LOG_PID*/0, LOG_USER); - setlogmask(LOG_UPTO(LOG_WARNING)); + colorize = _colorize == LOG_COLORIZE_NEVER ? false : _colorize == LOG_COLORIZE_ALWAYS ? true : isatty(STDERR_FILENO); + do_syslog = _do_syslog; + + if (do_syslog) { + openlog(NULL, /*LOG_PID*/0, LOG_USER); + setlogmask(LOG_UPTO(LOG_WARNING)); + } } -static void __attribute__((destructor)) -fini(void) +void +log_deinit(void) { - closelog(); + if (do_syslog) + closelog(); } static void @@ -66,6 +72,9 @@ static void _sys_log(enum log_class log_class, const char *module, const char *file, int lineno, const char *fmt, int sys_errno, va_list va) { + if (!do_syslog) + return; + /* Map our log level to syslog's level */ int level = -1; switch (log_class) { @@ -85,7 +94,8 @@ _sys_log(enum log_class log_class, const char *module, const char *file, /* Calculate required size of buffer holding the entire log message */ int required_len = 0; required_len += strlen(module) + 2; /* "%s: " */ - required_len += vsnprintf(NULL, 0, fmt, va2); va_end(va2); + required_len += vsnprintf(NULL, 0, fmt, va2); + va_end(va2); if (sys_errno != 0) required_len += strlen(sys_err) + 2; /* ": %s" */ diff --git a/log.h b/log.h index ba32d03..1730ef1 100644 --- a/log.h +++ b/log.h @@ -1,7 +1,13 @@ #pragma once +#include + +enum log_colorize { LOG_COLORIZE_NEVER, LOG_COLORIZE_ALWAYS, LOG_COLORIZE_AUTO }; enum log_class { LOG_CLASS_ERROR, LOG_CLASS_WARNING, LOG_CLASS_INFO, LOG_CLASS_DEBUG }; +void log_init(enum log_colorize colorize, bool do_syslog); +void log_deinit(void); + void log_msg(enum log_class log_class, const char *module, const char *file, int lineno, const char *fmt, ...) __attribute__((format (printf, 5, 6))); diff --git a/main.c b/main.c index 303ddf8..4b595b3 100644 --- a/main.c +++ b/main.c @@ -127,11 +127,13 @@ print_usage(const char *prog_name) printf("Usage: %s [OPTION]...\n", prog_name); printf("\n"); printf("Options:\n"); - printf(" -b,--backend={xcb,wayland,auto} backend to use (default: auto)\n" - " -c,--config=FILE alternative configuration file\n" - " -C,--validate verify configuration then quit\n" - " -p,--print-pid=FILE|FD print PID to file or FD\n" - " -v,--version print f00sel version and quit\n"); + printf(" -b,--backend={xcb,wayland,auto} backend to use (default: auto)\n" + " -c,--config=FILE alternative configuration file\n" + " -C,--validate verify configuration then quit\n" + " -p,--print-pid=FILE|FD print PID to file or FD\n" + " -l,--log-colorize=[never|always|auto] enable/disable colorization of log output on stderr\n" + " -s,--log-no-syslog disable syslog logging\n" + " -v,--version show the version number and quit\n"); } static bool @@ -181,6 +183,8 @@ main(int argc, char *const *argv) {"config", required_argument, 0, 'c'}, {"validate", no_argument, 0, 'C'}, {"print-pid", required_argument, 0, 'p'}, + {"log-colorize", optional_argument, 0, 'l'}, + {"log-no-syslog", no_argument, 0, 's'}, {"version", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, {NULL, no_argument, 0, 0}, @@ -193,8 +197,11 @@ main(int argc, char *const *argv) char *config_path = NULL; enum bar_backend backend = BAR_BACKEND_AUTO; + enum log_colorize log_colorize = LOG_COLORIZE_AUTO; + bool log_syslog = true; + while (true) { - int c = getopt_long(argc, argv, ":b:c:Cp:vh", longopts, NULL); + int c = getopt_long(argc, argv, ":b:c:Cp:l::svh", longopts, NULL); if (c == -1) break; @@ -205,7 +212,7 @@ main(int argc, char *const *argv) else if (strcmp(optarg, "wayland") == 0) backend = BAR_BACKEND_WAYLAND; else { - LOG_ERR("%s: invalid backend", optarg); + fprintf(stderr, "%s: invalid backend\n", optarg); return EXIT_FAILURE; } break; @@ -213,10 +220,10 @@ main(int argc, char *const *argv) case 'c': { struct stat st; if (stat(optarg, &st) == -1) { - LOG_ERRNO("%s: invalid configuration file", optarg); + fprintf(stderr, "%s: invalid configuration file: %s\n", optarg, strerror(errno)); return EXIT_FAILURE; } else if (!S_ISREG(st.st_mode)) { - LOG_ERR("%s: invalid configuration file: not a regular file", + fprintf(stderr, "%s: invalid configuration file: not a regular file\n", optarg); return EXIT_FAILURE; } @@ -233,6 +240,23 @@ main(int argc, char *const *argv) pid_file = optarg; break; + case 'l': + if (optarg == NULL || strcmp(optarg, "auto") == 0) + log_colorize = LOG_COLORIZE_AUTO; + else if (strcmp(optarg, "never") == 0) + log_colorize = LOG_COLORIZE_NEVER; + else if (strcmp(optarg, "always") == 0) + log_colorize = LOG_COLORIZE_ALWAYS; + else { + fprintf(stderr, "%s: argument must be one of 'never', 'always' or 'auto'\n", optarg); + return EXIT_FAILURE; + } + break; + + case 's': + log_syslog = false; + break; + case 'v': printf("yambar version %s\n", YAMBAR_VERSION); return EXIT_SUCCESS; @@ -251,6 +275,8 @@ main(int argc, char *const *argv) } } + log_init(log_colorize, log_syslog); + const struct sigaction sa = {.sa_handler = &signal_handler}; sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); @@ -266,6 +292,7 @@ main(int argc, char *const *argv) int abort_fd = eventfd(0, EFD_CLOEXEC); if (abort_fd == -1) { LOG_ERRNO("failed to create eventfd (for abort signalling)"); + log_deinit(); return 1; } @@ -273,6 +300,7 @@ main(int argc, char *const *argv) config_path = get_config_path(); if (config_path == NULL) { LOG_ERR("could not find a configuration (see man 5 yambar)"); + log_deinit(); return 1; } } @@ -282,12 +310,14 @@ main(int argc, char *const *argv) if (bar == NULL) { close(abort_fd); + log_deinit(); return 1; } if (verify_config) { bar->destroy(bar); close(abort_fd); + log_deinit(); return 0; } @@ -335,5 +365,6 @@ done: if (unlink_pid_file) unlink(pid_file); + log_deinit(); return res; }