]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/log-conf.c
Logging: Adapted the `logger' utility to the new numbering of levels.
[libucw.git] / ucw / log-conf.c
index 9d36d8a94b27450022fb2cc4966c9571919bb1ad..6a92c20e157ecaabe6c00c36ab745b9266ff85ff 100644 (file)
 #include "ucw/simple-lists.h"
 
 #include <string.h>
 #include "ucw/simple-lists.h"
 
 #include <string.h>
-#include <syslog.h>    // FIXME
+#include <syslog.h>
 
 struct stream_config {
   cnode n;
   char *name;
   char *file_name;
   char *syslog_facility;
 
 struct stream_config {
   cnode n;
   char *name;
   char *file_name;
   char *syslog_facility;
+  u32 levels;
   clist substreams;                    // simple_list of names
   clist substreams;                    // simple_list of names
+  int microseconds;                    // Enable logging of precise timestamps
+  int syslog_pids;
   struct log_stream *ls;
   int mark;                            // Used temporarily in log_config_commit()
 };
 
   struct log_stream *ls;
   int mark;                            // Used temporarily in log_config_commit()
 };
 
+static char *
+stream_init(void *ptr)
+{
+  struct stream_config *c = ptr;
+
+  c->levels = ~0U;
+  return NULL;
+}
+
 static char *
 stream_commit(void *ptr)
 {
 static char *
 stream_commit(void *ptr)
 {
@@ -32,18 +44,33 @@ stream_commit(void *ptr)
 
   if (c->file_name && c->syslog_facility)
     return "Both FileName and SyslogFacility selected";
 
   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";
   return NULL;
 }
 
   return NULL;
 }
 
+static const char * const level_names[] = {
+#define P(x) #x,
+  LOG_LEVEL_NAMES
+#undef P
+  NULL
+};
+
 static struct cf_section stream_config = {
   CF_TYPE(struct stream_config),
 static struct cf_section stream_config = {
   CF_TYPE(struct stream_config),
+  CF_INIT(stream_init),
   CF_COMMIT(stream_commit),
   CF_ITEMS {
 #define P(x) PTR_TO(struct stream_config, x)
     CF_STRING("Name", P(name)),
     CF_STRING("FileName", P(file_name)),
     CF_STRING("SyslogFacility", P(syslog_facility)),
   CF_COMMIT(stream_commit),
   CF_ITEMS {
 #define P(x) PTR_TO(struct stream_config, x)
     CF_STRING("Name", P(name)),
     CF_STRING("FileName", P(file_name)),
     CF_STRING("SyslogFacility", P(syslog_facility)),
+    CF_BITMAP_LOOKUP("Levels", P(levels), level_names),
     CF_LIST("Substream", P(substreams), &cf_string_list_config),
     CF_LIST("Substream", P(substreams), &cf_string_list_config),
+    CF_INT("Microseconds", P(microseconds)),
+    CF_INT("SyslogPID", P(syslog_pids)),
 #undef P
     CF_END
   }
 #undef P
     CF_END
   }
@@ -134,13 +161,17 @@ do_new_configured(struct stream_config *c)
   if (c->file_name)
     ls = log_new_file(c->file_name);
   else if (c->syslog_facility)
   if (c->file_name)
     ls = log_new_file(c->file_name);
   else if (c->syslog_facility)
-    ls = log_new_syslog(LOG_USER, NULL);       // FIXME: Facility
+    ls = log_new_syslog(c->syslog_facility, (c->syslog_pids ? LOG_PID : 0));
   else
     ls = log_new_stream(sizeof(*ls));
 
   CLIST_FOR_EACH(simp_node *, s, c->substreams)
     log_add_substream(ls, do_new_configured(stream_find(s->s)));
 
   else
     ls = log_new_stream(sizeof(*ls));
 
   CLIST_FOR_EACH(simp_node *, s, c->substreams)
     log_add_substream(ls, do_new_configured(stream_find(s->s)));
 
+  ls->levels = c->levels;
+  if (c->microseconds)
+    ls->msgfmt |= LSFMT_USEC;
+
   c->ls = ls;
   return ls;
 }
   c->ls = ls;
   return ls;
 }
@@ -156,6 +187,16 @@ log_new_configured(const char *name)
   return do_new_configured(c);
 }
 
   return do_new_configured(c);
 }
 
+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);
+}
+
 #ifdef TEST
 
 #include "ucw/getopt.h"
 #ifdef TEST
 
 #include "ucw/getopt.h"
@@ -170,6 +211,7 @@ int main(int argc, char **argv)
   struct log_stream *ls = log_new_configured("combined");
   msg(L_INFO | ls->regnum, "Hello, universe!");
 
   struct log_stream *ls = log_new_configured("combined");
   msg(L_INFO | ls->regnum, "Hello, universe!");
 
+  log_close_all();
   return 0;
 }
 
   return 0;
 }