diff --git a/compton.sample.conf b/compton.sample.conf index ceada88..52975f5 100644 --- a/compton.sample.conf +++ b/compton.sample.conf @@ -3,6 +3,8 @@ shadow = true; shadow-radius = 7; shadow-offset-x = -7; shadow-offset-y = -7; +log-level = "warn"; +# log-file = "/path/to/your/log/file"; # shadow-opacity = 0.7; # shadow-red = 0.0; # shadow-green = 0.0; diff --git a/man/compton.1.asciidoc b/man/compton.1.asciidoc index 028a67d..6c18ae9 100644 --- a/man/compton.1.asciidoc +++ b/man/compton.1.asciidoc @@ -73,6 +73,9 @@ OPTIONS *--log-level*:: Set the log level. Possible values are "TRACE", "DEBUG", "INFO", "WARN", "ERROR", in increasing level of importance. Case doesn't matter. +*--log-file*:: + Set the log file. If *--log-file* is never specified, logs will be written to stderr. Otherwise, logs will to writeen to the give file, though some of the early logs might still be written to the stderr. When setting this option from the config file, it is recommended to use an absolute path. + *--show-all-xerrors*:: Show all X errors (for debugging). diff --git a/src/compton.c b/src/compton.c index a32ca60..8c4ef72 100644 --- a/src/compton.c +++ b/src/compton.c @@ -2062,26 +2062,6 @@ register_cm(session_t *ps) { return true; } -/** - * Reopen streams for logging. - */ -static bool -stdout_reopen(session_t *ps, const char *path) { - if (!path) - path = ps->o.logpath; - if (!path) - path = "/dev/null"; - - bool success = freopen(path, "a", stdout); - success = freopen(path, "a", stderr) && success; - if (!success) { - log_fatal("(%s): freopen() failed.", path); - exit(1); - } - - return success; -} - /** * Fork program to background and disable all I/O streams. */ @@ -2719,7 +2699,12 @@ session_init(session_t *ps_old, int argc, char **argv) { }; log_init_tls(); - log_add_target_tls(stderr_logger_new()); + struct log_target *log_target = stderr_logger_new(); + if (!log_target) { + fprintf(stderr, "Cannot create any logger, giving up.\n"); + abort(); + } + log_add_target_tls(log_target); // Allocate a session and copy default values into it session_t *ps = cmalloc(session_t); @@ -2845,6 +2830,20 @@ session_init(session_t *ps_old, int argc, char **argv) { // Parse all of the rest command line options get_cfg(&ps->o, argc, argv, shadow_enabled, fading_enable, hasneg, winopt_mask); + if (ps->o.logpath) { + log_target = file_logger_new(ps->o.logpath); + if (log_target) { + auto level = log_get_level_tls(); + log_info("Switching to log file: %s", ps->o.logpath); + log_deinit_tls(); + log_init_tls(); + log_set_level_tls(level); + log_add_target_tls(log_target); + } else { + log_error("Failed to setup log file %s, I will keep using stderr", ps->o.logpath); + } + } + // Get needed atoms for c2 condition lists if (!(c2_list_postprocess(ps, ps->o.unredir_if_possible_blacklist) && c2_list_postprocess(ps, ps->o.paint_blacklist) && @@ -3051,8 +3050,12 @@ session_init(session_t *ps_old, int argc, char **argv) { } // Redirect output stream - if (ps->o.fork_after_register || ps->o.logpath) - stdout_reopen(ps, NULL); + if (ps->o.fork_after_register) { + if (!freopen("/dev/null", "w", stdout) || !freopen("/dev/null", "w", stderr)) { + log_fatal("Failed to redirect stdout/stderr to /dev/null"); + exit(1); + } + } write_pid(ps); diff --git a/src/config_libconfig.c b/src/config_libconfig.c index 959182c..3a6df4d 100644 --- a/src/config_libconfig.c +++ b/src/config_libconfig.c @@ -300,6 +300,13 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad log_set_level_tls(level); } } + // --log-file + if (config_lookup_string(&cfg, "log-file", &sval)) { + if (*sval != '/') { + log_warn("The log-file in your configuration file is not an absolute path"); + } + opt->logpath = strdup(sval); + } // --sw-opti lcfg_lookup_bool(&cfg, "sw-opti", &opt->sw_opti); // --use-ewmh-active-win diff --git a/src/options.c b/src/options.c index ffba306..93b6415 100644 --- a/src/options.c +++ b/src/options.c @@ -452,6 +452,7 @@ static const struct option longopts[] = { {"no-x-selection", no_argument, NULL, 319}, {"no-name-pixmap", no_argument, NULL, 320}, {"log-level", required_argument, NULL, 321}, + {"log-file", required_argument, NULL, 322}, {"reredir-on-root-change", no_argument, NULL, 731}, {"glx-reinit-on-root-change", no_argument, NULL, 732}, {"monitor-repaint", no_argument, NULL, 800}, @@ -471,10 +472,11 @@ bool get_early_config(int argc, char *const *argv, char **config_file, bool *all // Must reset optind to 0 here in case we reread the commandline // arguments optind = 1; + *config_file = NULL; while (-1 != (o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) { - if (o == 256) + if (o == 256) { *config_file = strdup(optarg); - else if (o == 'd') { + } else if (o == 'd') { log_warn("-d will be ignored, please use the DISPLAY " "environment variable"); } else if (o == 314) { @@ -505,8 +507,7 @@ bool get_early_config(int argc, char *const *argv, char **config_file, bool *all * Process arguments and configuration files. */ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, - bool fading_enable, bool conv_kern_hasneg, - win_option_mask_t *winopt_mask) { + bool fading_enable, bool conv_kern_hasneg, win_option_mask_t *winopt_mask) { int o = 0, longopt_idx = -1; @@ -655,7 +656,10 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, P_CASEBOOL(285, blur_background_fixed); P_CASEBOOL(286, dbus); case 287: - // --logpath + log_warn("Please use --log-file instead of --logpath"); + case 322: + // --logpath, --log-file + free(opt->logpath); opt->logpath = strdup(optarg); break; case 288: diff --git a/src/options.h b/src/options.h index 3813085..732837a 100644 --- a/src/options.h +++ b/src/options.h @@ -29,7 +29,6 @@ bool get_early_config(int argc, char *const *argv, char **config_file, bool *all * winopt_mask */ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable, - bool fading_enable, bool conv_kern_hasneg, - win_option_mask_t *winopt_mask); + bool fading_enable, bool conv_kern_hasneg, win_option_mask_t *winopt_mask); // vim: set noet sw=8 ts=8: