#include "timeval.h"
#include "unixctl.h"
#include "util.h"
-#include "worker.h"
VLOG_DEFINE_THIS_MODULE(vlog);
enum vlog_facility, unsigned int msg_num,
const char *message, va_list, struct ds *)
PRINTF_FORMAT(5, 0);
-static void vlog_write_file(struct ds *);
-static void vlog_update_async_log_fd(void);
/* Searches the 'n_names' in 'names'. Returns the index of a match for
* 'target', or 'n_names' if no name matches. */
}
}
-/* Returns the name of the log file used by VLF_FILE, or a null pointer if no
- * log file has been set. (A non-null return value does not assert that the
- * named log file is in use: if vlog_set_log_file() or vlog_reopen_log_file()
- * fails, it still sets the log file name.) */
-const char *
-vlog_get_log_file(void)
-{
- return log_file_name;
-}
-
/* Sets the name of the log file used by VLF_FILE to 'file_name', or to the
* default file name if 'file_name' is null. Returns 0 if successful,
* otherwise a positive errno value. */
/* Open new log file and update min_levels[] to reflect whether we actually
* have a log_file. */
log_fd = open(log_file_name, O_WRONLY | O_CREAT | O_APPEND, 0666);
- if (log_fd >= 0) {
- vlog_update_async_log_fd();
- }
for (mp = vlog_modules; mp < &vlog_modules[n_vlog_modules]; mp++) {
update_min_level(*mp);
}
/* Log success or failure. */
if (log_fd < 0) {
VLOG_WARN("failed to open %s for logging: %s",
- log_file_name, strerror(errno));
+ log_file_name, ovs_strerror(errno));
error = errno;
} else {
VLOG_INFO("opened log file %s", log_file_name);
if (log_file_name) {
int error = vlog_reopen_log_file();
if (error) {
- unixctl_command_reply_error(conn, strerror(errno));
+ unixctl_command_reply_error(conn, ovs_strerror(errno));
} else {
unixctl_command_reply(conn, NULL);
}
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(
ds_clear(s);
for (p = facilities[facility].pattern; *p != '\0'; ) {
+ const char *subprogram_name;
enum { LEFT, RIGHT } justify = RIGHT;
int pad = '0';
size_t length, field, used;
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. */
ds_put_format(s, "%lld", time_msec() - time_boot_msec());
break;
case 't':
+ subprogram_name = get_subprogram_name();
ds_put_cstr(s, subprogram_name[0] ? subprogram_name : "main");
break;
case 'T':
+ subprogram_name = get_subprogram_name();
if (subprogram_name[0]) {
ds_put_format(s, "(%s)", subprogram_name);
}
format_log_message(module, level, VLF_FILE, msg_num,
message, args, &s);
ds_put_char(&s, '\n');
- vlog_write_file(&s);
+ ignore(write(log_fd, s.string, s.length));
}
ds_destroy(&s);
return true;
}
+ xpthread_mutex_lock(&rl->mutex);
if (!token_bucket_withdraw(&rl->token_bucket, VLOG_MSG_TOKENS)) {
time_t now = time_now();
if (!rl->n_dropped) {
}
rl->last_dropped = now;
rl->n_dropped++;
+ xpthread_mutex_unlock(&rl->mutex);
return true;
}
- if (rl->n_dropped) {
+ if (!rl->n_dropped) {
+ xpthread_mutex_unlock(&rl->mutex);
+ } else {
time_t now = time_now();
+ unsigned int n_dropped = rl->n_dropped;
unsigned int first_dropped_elapsed = now - rl->first_dropped;
unsigned int last_dropped_elapsed = now - rl->last_dropped;
+ rl->n_dropped = 0;
+ xpthread_mutex_unlock(&rl->mutex);
vlog(module, level,
"Dropped %u log messages in last %u seconds (most recently, "
"%u seconds ago) due to excessive rate",
- rl->n_dropped, first_dropped_elapsed, last_dropped_elapsed);
-
- rl->n_dropped = 0;
+ n_dropped, first_dropped_elapsed, last_dropped_elapsed);
}
+
return false;
}
" (default: %s/%s.log)\n",
ovs_logdir(), program_name);
}
-\f
-static bool vlog_async_inited = false;
-
-static worker_request_func vlog_async_write_request_cb;
-
-static void
-vlog_write_file(struct ds *s)
-{
- if (worker_is_running()) {
- 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
-vlog_update_async_log_fd(void)
-{
- if (worker_is_running()) {
- worker_request(NULL, 0, &log_fd, 1, vlog_async_write_request_cb,
- NULL, NULL);
- vlog_async_inited = true;
- }
-}
-
-static void
-vlog_async_write_request_cb(struct ofpbuf *request,
- const int *fd, size_t n_fds)
-{
- if (n_fds > 0) {
- if (log_fd >= 0) {
- close(log_fd);
- }
- log_fd = *fd;
- }
-
- if (request->size > 0) {
- ignore(write(log_fd, request->data, request->size));
- }
-}