}
/**
- * Set the color for one loglevel.
+ * Set the color for log messages of the given severity level.
*
- * \param arg Must be of the form "ll:[fg [bg]] [attr]".
+ * \param arg Must be of the form "severity:[fg [bg]] [attr]".
*/
void daemon_set_log_color_or_die(const char *arg)
{
+ unsigned ll;
+ const char * const sev[] = {SEVERITIES};
char *p = strchr(arg, ':');
- int ret, ll;
if (!p)
goto err;
- ret = get_loglevel_by_name(arg);
- if (ret < 0)
- goto err;
- ll = ret;
- p++;
- color_parse_or_die(p, me->log_colors[ll]);
- return;
+ for (ll = 0; ll < NUM_LOGLEVELS; ll++) {
+ const char *name = sev[ll];
+ /*
+ * Parse only the first part of the string so that, for
+ * example, the argument "info:something_else" is recognized.
+ * Note that the string comparison is performed
+ * case-insensitively.
+ */
+ if (strncasecmp(arg, name, strlen(name)))
+ continue;
+ return color_parse_or_die(p + 1, me->log_colors[ll]);
+ }
err:
PARA_EMERG_LOG("%s: invalid color argument\n", arg);
exit(EXIT_FAILURE);
}
/**
- * Suppress log messages with severity lower than the given loglevel.
+ * Control the verbosity for logging.
*
- * \param loglevel The smallest level that should be logged.
+ * This instructs the daemon to not log subsequent messages whose severity is
+ * lower than the given value.
+ *
+ * \param loglevel The new log level.
*/
-void daemon_set_loglevel(const char *loglevel)
+void daemon_set_loglevel(int loglevel)
{
- int ret = get_loglevel_by_name(loglevel);
+ assert(loglevel >= 0);
+ assert(loglevel < NUM_LOGLEVELS);
+ me->loglevel = loglevel;
+}
- assert(ret >= 0);
- me->loglevel = ret;
+/**
+ * Get the current log level of the daemon.
+ *
+ * \return Greater or equal than zero and less than NUM_LOGLEVELS. This
+ * function never fails.
+ */
+int daemon_get_loglevel(void)
+{
+ return me->loglevel;
}
+/**
+ * Register functions to be called before and after a message is logged.
+ *
+ * \param pre_log_hook Called before the message is logged.
+ * \param post_log_hook Called after the message is logged.
+ *
+ * The purpose of this function is to provide a primitive for multi-threaded
+ * applications to serialize the access to the log facility, preventing
+ * interleaving log messages. This can be achieved by having the pre-log hook
+ * acquire a lock which blocks the other threads on the attempt to log a
+ * message at the same time. The post-log hook is responsible for releasing
+ * the lock.
+ *
+ * If these hooks are unnecessary, for example because the application is
+ * single-threaded, this function does not need to be called.
+ */
void daemon_set_hooks(void (*pre_log_hook)(void), void (*post_log_hook)(void))
{
me->pre_log_hook = pre_log_hook;
}
/**
- * fopen() the logfile in append mode.
+ * Open the logfile in append mode.
*
- * \return Either succeeds or exits.
+ * This function either succeeds or exits.
*/
void daemon_open_log_or_die(void)
{