* derivatives without specific, written prior permission.
*/
+#include <config.h>
#include "vlog.h"
#include <assert.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <syslog.h>
+#include <time.h>
#include "dynamic-string.h"
#include "util.h"
+#define THIS_MODULE VLM_vlog
+
/* Name for each logging level. */
static const char *level_names[VLL_N_LEVELS] = {
[VLL_EMER] = "EMER",
/* Set debugging levels:
*
- * mod:facility:level mod2:facility:level ...
+ * mod[:facility[:level]] mod2[:facility[:level]] ...
*
* Return null if successful, otherwise an error message that the caller must
* free().
facility = strtok_r(NULL, ":", &save_ptr);
level = strtok_r(NULL, ":", &save_ptr);
- if (level == NULL || facility == NULL) {
- free(s);
- return xstrdup("syntax error in level string");
- }
if (!strcmp(module, "ANY")) {
e_module = VLM_ANY_MODULE;
}
}
- if (!strcmp(facility, "ANY")) {
+ if (!facility || !strcmp(facility, "ANY")) {
e_facility = VLF_ANY_FACILITY;
} else {
e_facility = vlog_get_facility_val(facility);
}
}
- e_level = vlog_get_level_val(level);
+ e_level = level ? vlog_get_level_val(level) : VLL_DBG;
if (e_level >= VLL_N_LEVELS) {
char *msg = xasprintf("unknown level \"%s\"", level);
free(s);
}
/* If 'arg' is null, configure maximum verbosity. Otherwise, sets
- * configuration according to 'arg' (see vlog_set_levels_from_string()). If
- * parsing fails, default to maximum verbosity. */
+ * configuration according to 'arg' (see vlog_set_levels_from_string()). */
void
vlog_set_verbosity(const char *arg)
{
- if (arg == NULL || !vlog_set_levels_from_string(arg)) {
- vlog_set_levels(VLM_ANY_MODULE, VLF_CONSOLE, VLL_DBG);
+ if (arg) {
+ char *msg = vlog_set_levels_from_string(arg);
+ if (msg) {
+ fatal(0, "processing \"%s\": %s", arg, msg);
+ }
+ } else {
+ vlog_set_levels(VLM_ANY_MODULE, VLF_ANY_FACILITY, VLL_DBG);
}
}
void
vlog_init(void)
{
+ time_t now;
+
openlog(program_name, LOG_NDELAY, LOG_DAEMON);
- vlog_set_levels(VLM_ANY_MODULE, VLF_CONSOLE, VLL_WARN);
+ vlog_set_levels(VLM_ANY_MODULE, VLF_ANY_FACILITY, VLL_WARN);
+
+ now = time(0);
+ if (now < 0) {
+ struct tm tm;
+ char s[128];
+
+ localtime_r(&now, &tm);
+ strftime(s, sizeof s, "%a, %d %b %Y %H:%M:%S %z", &tm);
+ VLOG_ERR("current time is negative: %s (%ld)", s, (long int) now);
+ }
}
/* Closes the logging subsystem. */
return ds_cstr(&s);
}
+/* Returns true if a log message emitted for the given 'module' and 'level'
+ * would cause some log output, false if that module and level are completely
+ * disabled. */
+bool
+vlog_is_enabled(enum vlog_module module, enum vlog_level level)
+{
+ return (levels[module][VLF_CONSOLE] >= level
+ || levels[module][VLF_SYSLOG] >= level);
+}
+
/* Writes 'message' to the log at the given 'level' and as coming from the
* given 'module'.
*
static int msg_num;
const char *module_name = vlog_get_module_name(module);
const char *level_name = vlog_get_level_name(level);
+ time_t now;
+ struct tm tm;
va_list args;
char s[1024];
- size_t len;
+ size_t len, time_len;
+
+ now = time(0);
+ localtime_r(&now, &tm);
- len = sprintf(s, "%05d|%s|%s:", ++msg_num, module_name, level_name);
+ len = time_len = strftime(s, sizeof s, "%b %d %H:%M:%S|", &tm);
+ len += sprintf(s + len, "%05d|%s|%s:",
+ ++msg_num, module_name, level_name);
va_start(args, message);
len += vsnprintf(s + len, sizeof s - len, message, args);
va_end(args);
[VLL_DBG] = LOG_DEBUG,
};
- syslog(syslog_levels[level], "%s", s);
+ syslog(syslog_levels[level], "%s", s + time_len);
}
errno = save_errno;
}