Add new logging options, add legacy "debug" option
authorHenning Rogge <hrogge@googlemail.com>
Sun, 22 Mar 2009 11:21:21 +0000 (12:21 +0100)
committerHenning Rogge <hrogge@googlemail.com>
Sun, 22 Mar 2009 11:21:21 +0000 (12:21 +0100)
Remove debug_level variable

lib/httpinfo/src/olsrd_httpinfo.c
src/generate_msg.c
src/main.c
src/olsr.c
src/olsr_cfg.c
src/olsr_cfg.h
src/olsr_cfg_gen.c
src/olsr_logging.c

index 2645220..f7541d8 100644 (file)
@@ -855,7 +855,9 @@ static void build_config_body(struct autobuf *abuf)
 
   abuf_appendf(abuf, "<td>Main address: <strong>%s</strong></td>\n", olsr_ip_to_string(&mainaddrbuf, &olsr_cnf->router_id));
   abuf_appendf(abuf, "<td>IP version: %d</td>\n", olsr_cnf->ip_version == AF_INET ? 4 : 6);
-  abuf_appendf(abuf, "<td>Debug level: %d</td>\n", olsr_cnf->debug_level);
+
+  // TODO: add logging information into http info ?
+  abuf_appendf(abuf, "<td></td>\n");
   abuf_appendf(abuf, "<td>FIB Metrics: %s</td>\n", FIBM_FLAT == olsr_cnf->fib_metric ? CFG_FIBM_FLAT : FIBM_CORRECT == olsr_cnf->fib_metric ? CFG_FIBM_CORRECT : CFG_FIBM_APPROX);
 
   abuf_puts(abuf, "</tr>\n<tr>\n");
index 822bcd8..46212e6 100644 (file)
@@ -79,12 +79,10 @@ generate_hna(void *p)
 void
 generate_stdout_pulse(void *foo __attribute__((unused)))
 {
-  if (olsr_cnf->debug_level > 0) {
-    if (pulsedata[++pulse_state] == '\0') {
-      pulse_state = 0;
-    }
-    printf("%c\r", pulsedata[pulse_state]);
+  if (pulsedata[++pulse_state] == '\0') {
+    pulse_state = 0;
   }
+  fprintf(stderr, "%c\r", pulsedata[pulse_state]);
 }
 
 /*
index bceda91..98e324b 100644 (file)
@@ -303,7 +303,7 @@ main(int argc, char *argv[])
   /* Print heartbeat to stdout */
 
 #if !defined WINCE
-  if (olsr_cnf->debug_level > 0 && isatty(STDOUT_FILENO)) {
+  if (olsr_cnf->log_target_stderr > 0 && isatty(STDOUT_FILENO)) {
     pulse_timer_cookie = olsr_alloc_cookie("Pulse", OLSR_COOKIE_TYPE_TIMER);
     olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC, &generate_stdout_pulse, NULL, pulse_timer_cookie->ci_id);
   }
@@ -319,7 +319,7 @@ main(int argc, char *argv[])
 
   /* daemon mode */
 #ifndef WIN32
-  if (olsr_cnf->debug_level == 0 && !olsr_cnf->no_fork) {
+  if (!olsr_cnf->no_fork) {
     OLSR_INFO(LOG_MAIN, "%s detaching from the current process...\n", olsrd_version);
     if (daemon(0, 0) < 0) {
       OLSR_ERROR(LOG_MAIN, "daemon(3) failed: %s\n", strerror(errno));
index afc13c2..ccd166e 100644 (file)
@@ -155,7 +155,7 @@ olsr_process_changes(void)
      !changes_hna)
     return;
 
-  if (olsr_cnf->debug_level > 0 && olsr_cnf->clear_screen && isatty(1))
+  if (olsr_cnf->log_target_stderr && olsr_cnf->clear_screen && isatty(STDOUT_FILENO))
   {
       clear_console();
       printf("       *** %s (%s on %s) ***\n", olsrd_version, build_date, build_host);
index ae00fdf..82f4aa0 100644 (file)
 #define PARSER_DEBUG_PRINTF(x, ...)   do { } while (0)
 #endif
 
+/* options that have no short command line variant */
+#define CFG_LOG_DEBUG       256
+#define CFG_LOG_INFO        257
+#define CFG_LOG_WARN        258
+#define CFG_LOG_ERROR       269
+#define CFG_LOG_STDERR      270
+#define CFG_LOG_SYSLOG      271
+#define CFG_LOG_FILE        272
+
+/* remember which log severities have been explicitly set */
+static bool cfg_has_log[LOG_SEVERITY_COUNT];
+
 /*
  * Special strcat for reading the config file and
  * joining a longer section { ... } to one string
@@ -707,31 +719,77 @@ parse_cfg_loadplugin(char *argstr, struct olsr_config *rcfg, char *rmsg)
 }
 
 /*
- * Parses a the parameter string of --log
+ * Parses a the parameter string of --log(debug|info|warn|error)
  * @argstr:     arguments string
  * @rcfg:       config struct to write/change values into
  * @rmsg:   a buf[FILENAME_MAX + 256] to sprint err msgs
  * @returns configuration status as defined in olsr_parse_cfg_result
  */
 static olsr_parse_cfg_result
-parse_cfg_log(char *argstr, struct olsr_config *rcfg, char *rmsg)
+parse_cfg_debug(char *argstr, struct olsr_config *rcfg, char *rmsg)
 {
-  char *p = (char *)argstr, *nextEquals, *nextColon, *nextSlash;
-  bool hasErrorOption = false;
-  int i, j;
+  int dlevel, i;
+  dlevel = atoi(argstr);
 
-  while (p != NULL && *p != 0) {
-    /* split at ',' */
-    nextColon = strchr(p, ',');
-    if (nextColon) {
-      *nextColon++ = 0;
-    }
+  if (dlevel < -2 || dlevel > 2) {
+    sprintf(rmsg, "Error, debug level must be between -2 and 4\n");
+    return CFG_EXIT;
+  }
 
-    nextEquals = strchr(p, '=');
-    if (nextEquals) {
-      *nextEquals++ = 0;
-    }
+  switch(dlevel) {
+    case 3:
+      /* all logging */
+      for (i=0; i<LOG_SOURCE_COUNT; i++) {
+        rcfg->log_event[SEVERITY_DEBUG][i] = true;
+      }
+    case 2:
+      /* all info, warnings and errors */
+      for (i=0; i<LOG_SOURCE_COUNT; i++) {
+        rcfg->log_event[SEVERITY_INFO][i] = true;
+      }
+    case 1:
+      /* some INFO level output, plus all warnings and errors */
+      rcfg->log_event[SEVERITY_INFO][LOG_2NEIGH] = true;
+      rcfg->log_event[SEVERITY_INFO][LOG_LINKS] = true;
+      rcfg->log_event[SEVERITY_INFO][LOG_MAIN] = true;
+      rcfg->log_event[SEVERITY_INFO][LOG_NEIGHTABLE] = true;
+      rcfg->log_event[SEVERITY_INFO][LOG_PLUGINS] = true;
+      rcfg->log_event[SEVERITY_INFO][LOG_ROUTING] = true;
+      rcfg->log_event[SEVERITY_INFO][LOG_TC] = true;
+    case 0:
+      /* errors and warnings */
+      for (i=0; i<LOG_SOURCE_COUNT; i++) {
+        rcfg->log_event[SEVERITY_WARN][i] = true;
+      }
+    case -1:
+      /* only error messages */
+      for (i=0; i<LOG_SOURCE_COUNT; i++) {
+        rcfg->log_event[SEVERITY_ERR][i] = true;
+      }
+    default:      /* no logging at all ! */
+      break;
+  }
+
+  PARSER_DEBUG_PRINTF("Debug level: %d\n", dlevel);
+
+  /* prevent fallback to default 0 */
+  cfg_has_log[SEVERITY_ERR] = true;
+  return CFG_OK;
+}
+/*
+ * Parses a the parameter string of --log(debug|info|warn|error)
+ * @argstr:     arguments string
+ * @rcfg:       config struct to write/change values into
+ * @rmsg:   a buf[FILENAME_MAX + 256] to sprint err msgs
+ * @returns configuration status as defined in olsr_parse_cfg_result
+ */
+static olsr_parse_cfg_result
+parse_cfg_log(char *argstr, struct olsr_config *rcfg, char *rmsg, enum log_severity sev)
+{
+  char *p = (char *)argstr, *next;
+  int i;
 
+#if 0
     if (strcasecmp(p, "list") == 0) {
       printf("Available logging sources: ");
       for (i = 0; i < LOG_SOURCE_COUNT; i++) {
@@ -740,74 +798,37 @@ parse_cfg_log(char *argstr, struct olsr_config *rcfg, char *rmsg)
       printf("\n");
       return CFG_EXIT;
     }
-    for (j = 0; j < LOG_SEVERITY_COUNT; j++) {
-      if (strcasecmp(p, LOG_SEVERITY_NAMES[j]) == 0) {
+#endif
+  while (p != NULL) {
+    /* split at ',' */
+    next = strchr(p, ',');
+    if (next) {
+      *next++ = 0;
+    }
+
+    for (i = 0; i < LOG_SOURCE_COUNT; i++) {
+      if (strcasecmp(p, LOG_SOURCE_NAMES[i]) == 0) {
         break;
       }
     }
 
-    if (j < LOG_SEVERITY_COUNT) {
-      p = nextEquals;
-      while (p != NULL && *p != 0) {
-        /* split at '/' */
-        nextSlash = strchr(p, '/');
-        if (nextSlash) {
-          *nextSlash++ = 0;
-        }
-
-        for (i = 0; i < LOG_SOURCE_COUNT; i++) {
-          if (strcasecmp(p, LOG_SOURCE_NAMES[i]) == 0) {
-            break;
-          }
-        }
-
-        if (i < LOG_SOURCE_COUNT) {
-          rcfg->log_event[j][i] = true;
-        }
-        p = nextSlash;
-      }
-    } else if (strcasecmp(p, "stderr") == 0) {
-      rcfg->log_target_stderr = true;
-    } else if (strcasecmp(p, "syslog") == 0) {
-      rcfg->log_target_syslog = true;
-    } else if (strcasecmp(p, "file") == 0) {
-      rcfg->log_target_file = olsr_strdup(nextEquals);
+    if (i < LOG_SOURCE_COUNT) {
+      rcfg->log_event[sev][i] = true;
     }
     else {
-      sprintf(rmsg, "Unknown keyword %s for log parameter\n", p);
-      return CFG_ERROR;
-    }
-    p = nextColon;
-  }
-
-  /* process results to clean them up */
-
-  /* first handle "all" keyword */
-  for (i = 0; i < LOG_SEVERITY_COUNT; i++) {
-    if (rcfg->log_event[i][LOG_ALL]) {
-      for (j = 1; j < LOG_SOURCE_COUNT; j++) {
-        rcfg->log_event[i][j] = true;
-      }
+      sprintf(rmsg, "Error, unknown logging source: %s\n", p);
+      return CFG_EXIT;
     }
+    p = next;
   }
 
-  /* then copy from info to warn and from warn to error */
-  for (i = 0; i < LOG_SOURCE_COUNT; i++) {
-    if (rcfg->log_event[SEVERITY_INFO][i]) {
-      rcfg->log_event[SEVERITY_WARN][i] = true;
+  /* handle "all" keyword */
+  if (rcfg->log_event[sev][LOG_ALL]) {
+    for (i = 0; i < LOG_SOURCE_COUNT; i++) {
+      rcfg->log_event[sev][i] = true;
     }
-    if (rcfg->log_event[SEVERITY_WARN][i]) {
-      rcfg->log_event[SEVERITY_ERR][i] = true;
-    }
-    if (!hasErrorOption) {
-      rcfg->log_event[SEVERITY_ERR][i] = true;
-    }
-  }
-
-  /* choose stderr as target if none activated */
-  if (rcfg->log_target_file == NULL && !rcfg->log_target_stderr && !rcfg->log_target_syslog) {
-    rcfg->log_target_stderr = true;
   }
+  cfg_has_log[sev] = true;
   return CFG_OK;
 }
 
@@ -856,13 +877,7 @@ parse_cfg_option(const int optint, char *argstr, const int line, struct olsr_con
     PARSER_DEBUG_PRINTF("Clear screen %s\n", rcfg->clear_screen ? "enabled" : "disabled");
     break;
   case 'd':                    /* DebugLevel (i) */
-    {
-      int arg = -1;
-      sscanf(argstr, "%d", &arg);
-      if (0 <= arg && arg < 128)
-        rcfg->debug_level = arg;
-      PARSER_DEBUG_PRINTF("Debug level: %d\n", rcfg->debug_level);
-    }
+    return parse_cfg_debug(argstr, rcfg, rmsg);
     break;
   case 'F':                    /* FIBMetric (str) */
     {
@@ -1017,9 +1032,28 @@ parse_cfg_option(const int optint, char *argstr, const int line, struct olsr_con
       PARSER_DEBUG_PRINTF("Willingness: %d (no auto)\n", rcfg->willingness);
     }
     break;
-  case 'L':                    /* Log (string) */
-    return parse_cfg_log(argstr, rcfg, rmsg);
+  case CFG_LOG_DEBUG:                    /* Log (string) */
+    return parse_cfg_log(argstr, rcfg, rmsg, SEVERITY_DEBUG);
     break;
+  case CFG_LOG_INFO:                    /* Log (string) */
+    return parse_cfg_log(argstr, rcfg, rmsg, SEVERITY_INFO);
+    break;
+  case CFG_LOG_WARN:                    /* Log (string) */
+    return parse_cfg_log(argstr, rcfg, rmsg, SEVERITY_WARN);
+    break;
+  case CFG_LOG_ERROR:                   /* Log (string) */
+    return parse_cfg_log(argstr, rcfg, rmsg, SEVERITY_ERR);
+    break;
+  case CFG_LOG_STDERR:
+    rcfg->log_target_stderr = true;
+    break;
+  case CFG_LOG_SYSLOG:
+    rcfg->log_target_syslog = true;
+    break;
+  case CFG_LOG_FILE:
+    rcfg->log_target_file = strdup(argstr);
+    break;
+
   case 's':                    /* SourceIpMode (string) */
     rcfg->source_ip_mode = (0 == strcmp("yes", argstr)) ? 1 : 0;
     PARSER_DEBUG_PRINTF("Source IP mode %s\n", rcfg->source_ip_mode ? "enabled" : "disabled");
@@ -1116,7 +1150,13 @@ olsr_parse_cfg(int argc, char *argv[], const char *file, char *rmsg, struct olsr
     {"int",                      no_argument,       0, 'l'},
 #endif
     {"ipc",                      no_argument,       0, 'P'},
-    {"log",                      required_argument, 0, 'L'}, /* info=src1/...,warn=src3/... */
+    {"log_debug",                required_argument, 0, CFG_LOG_DEBUG}, /* src1,src2,... */
+    {"log_info",                 required_argument, 0, CFG_LOG_INFO}, /* src1,src2,... */
+    {"log_warn",                 required_argument, 0, CFG_LOG_WARN}, /* src1,src2,... */
+    {"log_error",                required_argument, 0, CFG_LOG_ERROR}, /* src1,src2,... */
+    {"log_stderr",               no_argument,       0, CFG_LOG_STDERR},
+    {"log_syslog",               no_argument,       0, CFG_LOG_SYSLOG},
+    {"log_file",                 required_argument, 0, CFG_LOG_FILE}, /* (filename) */
     {"nofork",                   no_argument,       0, 'n'},
     {"version",                  no_argument,       0, 'v'},
     {"AllowNoInt",               required_argument, 0, 'A'}, /* (yes/no) */
@@ -1163,6 +1203,12 @@ olsr_parse_cfg(int argc, char *argv[], const char *file, char *rmsg, struct olsr
    * memset(opt_line, 0, argc * sizeof(opt_line[0]));
    */
 
+  /* cleanup static logsource flags */
+  cfg_has_log[SEVERITY_DEBUG] = false;
+  cfg_has_log[SEVERITY_INFO] = false;
+  cfg_has_log[SEVERITY_WARN] = false;
+  cfg_has_log[SEVERITY_ERR] = false;
+
   /* Copy argv array for safe free'ing later on */
   while (opt_argc < argc) {
     const char *p = argv[opt_argc];
@@ -1279,6 +1325,26 @@ olsr_parse_cfg(int argc, char *argv[], const char *file, char *rmsg, struct olsr
   free(opt_line);
   free(opt_str);
 
+  /* logging option post processing */
+  if (!((*rcfg)->log_target_syslog || (*rcfg)->log_target_syslog || (*rcfg)->log_target_file != NULL)) {
+    (*rcfg)->log_target_stderr = true;
+  }
+  for (opt = SEVERITY_INFO; opt < LOG_SEVERITY_COUNT; opt++) {
+    if (!cfg_has_log[opt] && cfg_has_log[opt-1]) {
+      int i;
+
+      /* copy debug to info, info to warning, warning to error (if neccessary) */
+      for (i=0; i < LOG_SOURCE_COUNT; i++) {
+        (*rcfg)->log_event[opt][i] = (*rcfg)->log_event[opt-1][i];
+      }
+      cfg_has_log[opt] = true;
+    }
+  }
+  if (!cfg_has_log[SEVERITY_ERR]) {
+    /* no logging at all defined ? fall back to default */
+    char def[2] = "0";
+    parse_cfg_debug(def, *rcfg, rmsg);
+  }
   return rslt;
 }
 
@@ -1291,12 +1357,6 @@ olsr_sanity_check_cfg(struct olsr_config *cfg)
   struct olsr_if_config *in = cfg->if_configs;
   struct olsr_if_options *io;
 
-  /* Debug level */
-  if (cfg->debug_level < MIN_DEBUGLVL || cfg->debug_level > MAX_DEBUGLVL) {
-    fprintf(stderr, "Debuglevel %d is not allowed\n", cfg->debug_level);
-    return -1;
-  }
-
   /* IP version */
   if (cfg->ip_version != AF_INET && cfg->ip_version != AF_INET6) {
     fprintf(stderr, "Ipversion %d not allowed!\n", cfg->ip_version);
@@ -1525,12 +1585,11 @@ olsr_get_default_cfg(void)
   cfg->ipc_connections = DEF_IPC_CONNECTIONS;
   cfg->fib_metric = DEF_FIB_METRIC;
 
-  cfg->debug_level = DEF_DEBUGLVL;
   for (i = 0; i < LOG_SOURCE_COUNT; i++) {
     assert(cfg->log_event[SEVERITY_DEBUG][i] == false);
     assert(cfg->log_event[SEVERITY_INFO][i] == false);
     assert(cfg->log_event[SEVERITY_WARN][i] == false);
-    cfg->log_event[SEVERITY_ERR][i] = true;
+    assert(cfg->log_event[SEVERITY_ERR][i] == false);
   }
   cfg->log_target_stderr = true;
   assert(cfg->log_target_file == NULL);
index 7526501..2a73648 100644 (file)
@@ -192,7 +192,6 @@ struct olsr_config {
   uint8_t ipc_connections;             /* Number of allowed IPC connections */
 
   /* logging information */
-  int8_t debug_level;                  /* Old style */
   bool log_event[LOG_SEVERITY_COUNT][LOG_SOURCE_COUNT]; /* New style */
   bool log_target_stderr;              /* Log output to stderr? */
   char *log_target_file;               /* Filename for log output file, NULL if unused */
index c8441f2..d8dbf92 100644 (file)
@@ -65,10 +65,6 @@ olsr_write_cnf_buf(struct autobuf *abuf, struct olsr_config *cnf, bool write_mor
   abuf_appendf(abuf, "#\n"
                "# Generated config file for %s\n" "#\n\n", olsrd_version);
 
-  /* Debug level */
-  abuf_appendf(abuf, "# Debug level(0-9)\n"
-               "# If set to 0 the daemon runs in the background\n" "DebugLevel\t%d\n\n", cnf->debug_level);
-
   /* IP version */
   abuf_appendf(abuf, "# IP version to use (4 or 6)\n" "IpVersion\t%d\n\n", cnf->ip_version == AF_INET ? 4 : 6);
 
index 15f19cb..1821247 100644 (file)
@@ -234,6 +234,12 @@ void olsr_log (enum log_severity severity, enum log_source source, bool no_heade
 
   assert (p1+p2 < LOGBUFFER_SIZE);
 
+  /* remove \n at the end of the line if necessary */
+  if (logbuffer[p1+p2-1] == '\n') {
+    logbuffer[p1+p2-1] = 0;
+    p2--;
+  }
+
   /* output all events to stderr if logsystem has not been initialized */
   if (!log_initialized) {
 #if DEBUG