X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ucw%2Flog-conf.c;h=7c7f97afe8ce2ed0c15fd393b7cecae75ee43eb4;hb=315d65b74168b23e820b9dde6166ec19bd048228;hp=8989595d9885fd260e93a8a9dddde4cff85f557f;hpb=b6acda64c6f8fdb461fc62a03b4030bfc7f1ae07;p=libucw.git diff --git a/ucw/log-conf.c b/ucw/log-conf.c index 8989595d..7c7f97af 100644 --- a/ucw/log-conf.c +++ b/ucw/log-conf.c @@ -26,6 +26,7 @@ struct stream_config { cnode n; char *name; char *file_name; + int file_desc; char *syslog_facility; u32 levels; clist types; // simple_list of names @@ -35,6 +36,7 @@ struct stream_config { int show_types; int syslog_pids; int errors_fatal; + int stderr_follows; struct log_stream *ls; int mark; // Used temporarily in log_config_commit() }; @@ -52,6 +54,7 @@ stream_init(void *ptr) struct stream_config *c = ptr; c->levels = ~0U; + c->file_desc = -1; return NULL; } @@ -60,12 +63,17 @@ stream_commit(void *ptr) { struct stream_config *c = ptr; - if (c->file_name && c->syslog_facility) - return "Both FileName and SyslogFacility selected"; - if (c->syslog_facility && !log_syslog_facility_exists(c->syslog_facility)) - return cf_printf("SyslogFacility `%s' is not recognized", c->syslog_facility); - if (c->syslog_facility && c->microseconds) - return "Syslog streams do not support microsecond precision"; + if (c->syslog_facility) + { + if (!log_syslog_facility_exists(c->syslog_facility)) + return cf_printf("SyslogFacility `%s' is not recognized", c->syslog_facility); + if (c->file_name) + return "Both FileName and SyslogFacility selected"; + if (c->microseconds) + return "Syslog streams do not support microsecond precision"; + } + if (c->stderr_follows && !c->file_name) + return "StdErrFollows requires a file-based stream"; return NULL; } @@ -96,6 +104,7 @@ static struct cf_section stream_config = { #define P(x) PTR_TO(struct stream_config, x) CF_STRING("Name", P(name)), CF_STRING("FileName", P(file_name)), + CF_INT("FileDesc", P(file_desc)), CF_STRING("SyslogFacility", P(syslog_facility)), CF_BITMAP_LOOKUP("Levels", P(levels), level_names), CF_LIST("Types", P(types), &cf_string_list_config), @@ -105,6 +114,7 @@ static struct cf_section stream_config = { CF_INT("ShowTypes", P(show_types)), CF_INT("SyslogPID", P(syslog_pids)), CF_INT("ErrorsFatal", P(errors_fatal)), + CF_INT("StdErrFollows", P(stderr_follows)), #undef P CF_END } @@ -244,6 +254,10 @@ log_limiter(struct log_stream *ls, struct log_msg *m) static void log_apply_limits(struct log_stream *ls, struct limit_config *lim) { + uns mask = log_type_mask(&lim->types); + if (!mask) + return; + if (!ls->user_data) { ls->user_data = cf_malloc_zero(LS_NUM_TYPES * sizeof(struct token_bucket_filter *)); @@ -255,7 +269,6 @@ log_apply_limits(struct log_stream *ls, struct limit_config *lim) tbf->burst = lim->burst; tbf_init(tbf); - uns mask = log_type_mask(&lim->types); for (uns i=0; i < LS_NUM_TYPES; i++) if (mask & (1 << i)) limits[i] = tbf; @@ -282,7 +295,9 @@ do_new_configured(struct stream_config *c) return c->ls; if (c->file_name) - ls = log_new_file(c->file_name, 0); + ls = log_new_file(c->file_name, (c->stderr_follows ? FF_FD2_FOLLOWS : 0)); + else if (c->file_desc >= 0) + ls = log_new_fd(c->file_desc, (c->stderr_follows ? FF_FD2_FOLLOWS : 0)); else if (c->syslog_facility) ls = log_new_syslog(c->syslog_facility, (c->syslog_pids ? LOG_PID : 0)); else @@ -321,11 +336,7 @@ log_new_configured(const char *name) void log_configured(const char *name) { - struct log_stream *ls = log_new_configured(name); - struct log_stream *def = log_stream_by_flags(0); - log_rm_substream(def, NULL); - log_add_substream(def, ls); - log_close_stream(ls); + log_set_default_stream(log_new_configured(name)); } #ifdef TEST @@ -347,6 +358,7 @@ int main(int argc, char **argv) msg(L_INFO | ls->regnum | type, "Hello, universe!"); usleep(200000); } + fprintf(stderr, "Alas, this was printed to stderr.\n"); log_close_all(); return 0;