/*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <syslog.h>
#include <time.h>
#include <unistd.h>
+#include "coverage.h"
#include "dirs.h"
#include "dynamic-string.h"
#include "ofpbuf.h"
VLOG_DEFINE_THIS_MODULE(vlog);
+COVERAGE_DEFINE(vlog_recursive);
+
+/* ovs_assert() logs the assertion message, so using ovs_assert() in this
+ * source file could cause recursion. */
+#undef ovs_assert
+#define ovs_assert use_assert_instead_of_ovs_assert_in_this_module
+
/* Name for each logging level. */
-static const char *level_names[VLL_N_LEVELS] = {
+static const char *const level_names[VLL_N_LEVELS] = {
#define VLOG_LEVEL(NAME, SYSLOG_LEVEL) #NAME,
VLOG_LEVELS
#undef VLOG_LEVEL
};
/* Syslog value for each logging level. */
-static int syslog_levels[VLL_N_LEVELS] = {
+static const int syslog_levels[VLL_N_LEVELS] = {
#define VLOG_LEVEL(NAME, SYSLOG_LEVEL) SYSLOG_LEVEL,
VLOG_LEVELS
#undef VLOG_LEVEL
/* Searches the 'n_names' in 'names'. Returns the index of a match for
* 'target', or 'n_names' if no name matches. */
static size_t
-search_name_array(const char *target, const char **names, size_t n_names)
+search_name_array(const char *target, const char *const *names, size_t n_names)
{
size_t i;
return msg;
}
+/* Set debugging levels. Abort with an error message if 's' is invalid. */
+void
+vlog_set_levels_from_string_assert(const char *s)
+{
+ char *error = vlog_set_levels_from_string(s);
+ if (error) {
+ ovs_fatal(0, "%s", error);
+ }
+}
+
/* If 'arg' is null, configure maximum verbosity. Otherwise, sets
* configuration according to 'arg' (see vlog_set_levels_from_string()). */
void
now = time_wall();
if (now < 0) {
- struct tm tm;
- char s[128];
-
- gmtime_r(&now, &tm);
- strftime(s, sizeof s, "%a, %d %b %Y %H:%M:%S", &tm);
+ char *s = xastrftime("%a, %d %b %Y %H:%M:%S", now, true);
VLOG_ERR("current time is negative: %s (%ld)", s, (long int) now);
+ free(s);
}
unixctl_command_register(
break;
case 'd':
p = fetch_braces(p, "%Y-%m-%d %H:%M:%S", tmp, sizeof tmp);
- ds_put_strftime(s, tmp, false);
+ ds_put_strftime(s, tmp, time_wall(), false);
break;
case 'D':
p = fetch_braces(p, "%Y-%m-%d %H:%M:%S", tmp, sizeof tmp);
- ds_put_strftime(s, tmp, true);
+ ds_put_strftime(s, tmp, time_wall(), true);
break;
case 'm':
/* Format user-supplied log message and trim trailing new-lines. */
vlog_write_file(struct ds *s)
{
if (worker_is_running()) {
- worker_request(s->string, s->length,
- &log_fd, vlog_async_inited ? 0 : 1,
- vlog_async_write_request_cb, NULL, NULL);
- vlog_async_inited = true;
- } else {
- ignore(write(log_fd, s->string, s->length));
+ static bool in_worker_request = false;
+ if (!in_worker_request) {
+ in_worker_request = true;
+
+ worker_request(s->string, s->length,
+ &log_fd, vlog_async_inited ? 0 : 1,
+ vlog_async_write_request_cb, NULL, NULL);
+ vlog_async_inited = true;
+
+ in_worker_request = false;
+ return;
+ } else {
+ /* We've been entered recursively. This can happen if
+ * worker_request(), or a function that it calls, tries to log
+ * something. We can't call worker_request() recursively, so fall
+ * back to writing the log file directly. */
+ COVERAGE_INC(vlog_recursive);
+ }
}
+ ignore(write(log_fd, s->string, s->length));
}
static void