vlog: Remove support for worker process.
[sliver-openvswitch.git] / lib / vlog.c
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18 #include "vlog.h"
19 #include <assert.h>
20 #include <ctype.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <syslog.h>
29 #include <time.h>
30 #include <unistd.h>
31 #include "coverage.h"
32 #include "dirs.h"
33 #include "dynamic-string.h"
34 #include "ofpbuf.h"
35 #include "sat-math.h"
36 #include "svec.h"
37 #include "timeval.h"
38 #include "unixctl.h"
39 #include "util.h"
40
41 VLOG_DEFINE_THIS_MODULE(vlog);
42
43 COVERAGE_DEFINE(vlog_recursive);
44
45 /* ovs_assert() logs the assertion message, so using ovs_assert() in this
46  * source file could cause recursion. */
47 #undef ovs_assert
48 #define ovs_assert use_assert_instead_of_ovs_assert_in_this_module
49
50 /* Name for each logging level. */
51 static const char *const level_names[VLL_N_LEVELS] = {
52 #define VLOG_LEVEL(NAME, SYSLOG_LEVEL) #NAME,
53     VLOG_LEVELS
54 #undef VLOG_LEVEL
55 };
56
57 /* Syslog value for each logging level. */
58 static const int syslog_levels[VLL_N_LEVELS] = {
59 #define VLOG_LEVEL(NAME, SYSLOG_LEVEL) SYSLOG_LEVEL,
60     VLOG_LEVELS
61 #undef VLOG_LEVEL
62 };
63
64 /* The log modules. */
65 #if USE_LINKER_SECTIONS
66 extern struct vlog_module *__start_vlog_modules[];
67 extern struct vlog_module *__stop_vlog_modules[];
68 #define vlog_modules __start_vlog_modules
69 #define n_vlog_modules (__stop_vlog_modules - __start_vlog_modules)
70 #else
71 #define VLOG_MODULE VLOG_DEFINE_MODULE__
72 #include "vlog-modules.def"
73 #undef VLOG_MODULE
74
75 struct vlog_module *vlog_modules[] = {
76 #define VLOG_MODULE(NAME) &VLM_##NAME,
77 #include "vlog-modules.def"
78 #undef VLOG_MODULE
79 };
80 #define n_vlog_modules ARRAY_SIZE(vlog_modules)
81 #endif
82
83 /* Information about each facility. */
84 struct facility {
85     const char *name;           /* Name. */
86     char *pattern;              /* Current pattern. */
87     bool default_pattern;       /* Whether current pattern is the default. */
88 };
89 static struct facility facilities[VLF_N_FACILITIES] = {
90 #define VLOG_FACILITY(NAME, PATTERN) {#NAME, PATTERN, true},
91     VLOG_FACILITIES
92 #undef VLOG_FACILITY
93 };
94
95 /* VLF_FILE configuration. */
96 static char *log_file_name;
97 static int log_fd = -1;
98
99 /* vlog initialized? */
100 static bool vlog_inited;
101
102 static void format_log_message(const struct vlog_module *, enum vlog_level,
103                                enum vlog_facility, unsigned int msg_num,
104                                const char *message, va_list, struct ds *)
105     PRINTF_FORMAT(5, 0);
106
107 /* Searches the 'n_names' in 'names'.  Returns the index of a match for
108  * 'target', or 'n_names' if no name matches. */
109 static size_t
110 search_name_array(const char *target, const char *const *names, size_t n_names)
111 {
112     size_t i;
113
114     for (i = 0; i < n_names; i++) {
115         assert(names[i]);
116         if (!strcasecmp(names[i], target)) {
117             break;
118         }
119     }
120     return i;
121 }
122
123 /* Returns the name for logging level 'level'. */
124 const char *
125 vlog_get_level_name(enum vlog_level level)
126 {
127     assert(level < VLL_N_LEVELS);
128     return level_names[level];
129 }
130
131 /* Returns the logging level with the given 'name', or VLL_N_LEVELS if 'name'
132  * is not the name of a logging level. */
133 enum vlog_level
134 vlog_get_level_val(const char *name)
135 {
136     return search_name_array(name, level_names, ARRAY_SIZE(level_names));
137 }
138
139 /* Returns the name for logging facility 'facility'. */
140 const char *
141 vlog_get_facility_name(enum vlog_facility facility)
142 {
143     assert(facility < VLF_N_FACILITIES);
144     return facilities[facility].name;
145 }
146
147 /* Returns the logging facility named 'name', or VLF_N_FACILITIES if 'name' is
148  * not the name of a logging facility. */
149 enum vlog_facility
150 vlog_get_facility_val(const char *name)
151 {
152     size_t i;
153
154     for (i = 0; i < VLF_N_FACILITIES; i++) {
155         if (!strcasecmp(facilities[i].name, name)) {
156             break;
157         }
158     }
159     return i;
160 }
161
162 /* Returns the name for logging module 'module'. */
163 const char *
164 vlog_get_module_name(const struct vlog_module *module)
165 {
166     return module->name;
167 }
168
169 /* Returns the logging module named 'name', or NULL if 'name' is not the name
170  * of a logging module. */
171 struct vlog_module *
172 vlog_module_from_name(const char *name)
173 {
174     struct vlog_module **mp;
175
176     for (mp = vlog_modules; mp < &vlog_modules[n_vlog_modules]; mp++) {
177         if (!strcasecmp(name, (*mp)->name)) {
178             return *mp;
179         }
180     }
181     return NULL;
182 }
183
184 /* Returns the current logging level for the given 'module' and 'facility'. */
185 enum vlog_level
186 vlog_get_level(const struct vlog_module *module, enum vlog_facility facility)
187 {
188     assert(facility < VLF_N_FACILITIES);
189     return module->levels[facility];
190 }
191
192 static void
193 update_min_level(struct vlog_module *module)
194 {
195     enum vlog_facility facility;
196
197     module->min_level = VLL_OFF;
198     for (facility = 0; facility < VLF_N_FACILITIES; facility++) {
199         if (log_fd >= 0 || facility != VLF_FILE) {
200             enum vlog_level level = module->levels[facility];
201             if (level > module->min_level) {
202                 module->min_level = level;
203             }
204         }
205     }
206 }
207
208 static void
209 set_facility_level(enum vlog_facility facility, struct vlog_module *module,
210                    enum vlog_level level)
211 {
212     assert(facility >= 0 && facility < VLF_N_FACILITIES);
213     assert(level < VLL_N_LEVELS);
214
215     if (!module) {
216         struct vlog_module **mp;
217
218         for (mp = vlog_modules; mp < &vlog_modules[n_vlog_modules]; mp++) {
219             (*mp)->levels[facility] = level;
220             update_min_level(*mp);
221         }
222     } else {
223         module->levels[facility] = level;
224         update_min_level(module);
225     }
226 }
227
228 /* Sets the logging level for the given 'module' and 'facility' to 'level'.  A
229  * null 'module' or a 'facility' of VLF_ANY_FACILITY is treated as a wildcard
230  * across all modules or facilities, respectively. */
231 void
232 vlog_set_levels(struct vlog_module *module, enum vlog_facility facility,
233                 enum vlog_level level)
234 {
235     assert(facility < VLF_N_FACILITIES || facility == VLF_ANY_FACILITY);
236     if (facility == VLF_ANY_FACILITY) {
237         for (facility = 0; facility < VLF_N_FACILITIES; facility++) {
238             set_facility_level(facility, module, level);
239         }
240     } else {
241         set_facility_level(facility, module, level);
242     }
243 }
244
245 static void
246 do_set_pattern(enum vlog_facility facility, const char *pattern)
247 {
248     struct facility *f = &facilities[facility];
249     if (!f->default_pattern) {
250         free(f->pattern);
251     } else {
252         f->default_pattern = false;
253     }
254     f->pattern = xstrdup(pattern);
255 }
256
257 /* Sets the pattern for the given 'facility' to 'pattern'. */
258 void
259 vlog_set_pattern(enum vlog_facility facility, const char *pattern)
260 {
261     assert(facility < VLF_N_FACILITIES || facility == VLF_ANY_FACILITY);
262     if (facility == VLF_ANY_FACILITY) {
263         for (facility = 0; facility < VLF_N_FACILITIES; facility++) {
264             do_set_pattern(facility, pattern);
265         }
266     } else {
267         do_set_pattern(facility, pattern);
268     }
269 }
270
271 /* Returns the name of the log file used by VLF_FILE, or a null pointer if no
272  * log file has been set.  (A non-null return value does not assert that the
273  * named log file is in use: if vlog_set_log_file() or vlog_reopen_log_file()
274  * fails, it still sets the log file name.) */
275 const char *
276 vlog_get_log_file(void)
277 {
278     return log_file_name;
279 }
280
281 /* Sets the name of the log file used by VLF_FILE to 'file_name', or to the
282  * default file name if 'file_name' is null.  Returns 0 if successful,
283  * otherwise a positive errno value. */
284 int
285 vlog_set_log_file(const char *file_name)
286 {
287     char *old_log_file_name;
288     struct vlog_module **mp;
289     int error;
290
291     /* Close old log file. */
292     if (log_fd >= 0) {
293         VLOG_INFO("closing log file");
294         close(log_fd);
295         log_fd = -1;
296     }
297
298     /* Update log file name and free old name.  The ordering is important
299      * because 'file_name' might be 'log_file_name' or some suffix of it. */
300     old_log_file_name = log_file_name;
301     log_file_name = (file_name
302                      ? xstrdup(file_name)
303                      : xasprintf("%s/%s.log", ovs_logdir(), program_name));
304     free(old_log_file_name);
305     file_name = NULL;           /* Might have been freed. */
306
307     /* Open new log file and update min_levels[] to reflect whether we actually
308      * have a log_file. */
309     log_fd = open(log_file_name, O_WRONLY | O_CREAT | O_APPEND, 0666);
310     for (mp = vlog_modules; mp < &vlog_modules[n_vlog_modules]; mp++) {
311         update_min_level(*mp);
312     }
313
314     /* Log success or failure. */
315     if (log_fd < 0) {
316         VLOG_WARN("failed to open %s for logging: %s",
317                   log_file_name, ovs_strerror(errno));
318         error = errno;
319     } else {
320         VLOG_INFO("opened log file %s", log_file_name);
321         error = 0;
322     }
323
324     return error;
325 }
326
327 /* Closes and then attempts to re-open the current log file.  (This is useful
328  * just after log rotation, to ensure that the new log file starts being used.)
329  * Returns 0 if successful, otherwise a positive errno value. */
330 int
331 vlog_reopen_log_file(void)
332 {
333     struct stat old, new;
334
335     /* Skip re-opening if there's nothing to reopen. */
336     if (!log_file_name) {
337         return 0;
338     }
339
340     /* Skip re-opening if it would be a no-op because the old and new files are
341      * the same.  (This avoids writing "closing log file" followed immediately
342      * by "opened log file".) */
343     if (log_fd >= 0
344         && !fstat(log_fd, &old)
345         && !stat(log_file_name, &new)
346         && old.st_dev == new.st_dev
347         && old.st_ino == new.st_ino) {
348         return 0;
349     }
350
351     return vlog_set_log_file(log_file_name);
352 }
353
354 /* Set debugging levels.  Returns null if successful, otherwise an error
355  * message that the caller must free(). */
356 char *
357 vlog_set_levels_from_string(const char *s_)
358 {
359     char *s = xstrdup(s_);
360     char *save_ptr = NULL;
361     char *msg = NULL;
362     char *word;
363
364     word = strtok_r(s, " ,:\t", &save_ptr);
365     if (word && !strcasecmp(word, "PATTERN")) {
366         enum vlog_facility facility;
367
368         word = strtok_r(NULL, " ,:\t", &save_ptr);
369         if (!word) {
370             msg = xstrdup("missing facility");
371             goto exit;
372         }
373
374         facility = (!strcasecmp(word, "ANY")
375                     ? VLF_ANY_FACILITY
376                     : vlog_get_facility_val(word));
377         if (facility == VLF_N_FACILITIES) {
378             msg = xasprintf("unknown facility \"%s\"", word);
379             goto exit;
380         }
381         vlog_set_pattern(facility, save_ptr);
382     } else {
383         struct vlog_module *module = NULL;
384         enum vlog_level level = VLL_N_LEVELS;
385         enum vlog_facility facility = VLF_N_FACILITIES;
386
387         for (; word != NULL; word = strtok_r(NULL, " ,:\t", &save_ptr)) {
388             if (!strcasecmp(word, "ANY")) {
389                 continue;
390             } else if (vlog_get_facility_val(word) != VLF_N_FACILITIES) {
391                 if (facility != VLF_N_FACILITIES) {
392                     msg = xstrdup("cannot specify multiple facilities");
393                     goto exit;
394                 }
395                 facility = vlog_get_facility_val(word);
396             } else if (vlog_get_level_val(word) != VLL_N_LEVELS) {
397                 if (level != VLL_N_LEVELS) {
398                     msg = xstrdup("cannot specify multiple levels");
399                     goto exit;
400                 }
401                 level = vlog_get_level_val(word);
402             } else if (vlog_module_from_name(word)) {
403                 if (module) {
404                     msg = xstrdup("cannot specify multiple modules");
405                     goto exit;
406                 }
407                 module = vlog_module_from_name(word);
408             } else {
409                 msg = xasprintf("no facility, level, or module \"%s\"", word);
410                 goto exit;
411             }
412         }
413
414         if (facility == VLF_N_FACILITIES) {
415             facility = VLF_ANY_FACILITY;
416         }
417         if (level == VLL_N_LEVELS) {
418             level = VLL_DBG;
419         }
420         vlog_set_levels(module, facility, level);
421     }
422
423 exit:
424     free(s);
425     return msg;
426 }
427
428 /* Set debugging levels.  Abort with an error message if 's' is invalid. */
429 void
430 vlog_set_levels_from_string_assert(const char *s)
431 {
432     char *error = vlog_set_levels_from_string(s);
433     if (error) {
434         ovs_fatal(0, "%s", error);
435     }
436 }
437
438 /* If 'arg' is null, configure maximum verbosity.  Otherwise, sets
439  * configuration according to 'arg' (see vlog_set_levels_from_string()). */
440 void
441 vlog_set_verbosity(const char *arg)
442 {
443     if (arg) {
444         char *msg = vlog_set_levels_from_string(arg);
445         if (msg) {
446             ovs_fatal(0, "processing \"%s\": %s", arg, msg);
447         }
448     } else {
449         vlog_set_levels(NULL, VLF_ANY_FACILITY, VLL_DBG);
450     }
451 }
452
453 static void
454 vlog_unixctl_set(struct unixctl_conn *conn, int argc, const char *argv[],
455                  void *aux OVS_UNUSED)
456 {
457     int i;
458
459     for (i = 1; i < argc; i++) {
460         char *msg = vlog_set_levels_from_string(argv[i]);
461         if (msg) {
462             unixctl_command_reply_error(conn, msg);
463             free(msg);
464             return;
465         }
466     }
467     unixctl_command_reply(conn, NULL);
468 }
469
470 static void
471 vlog_unixctl_list(struct unixctl_conn *conn, int argc OVS_UNUSED,
472                   const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
473 {
474     char *msg = vlog_get_levels();
475     unixctl_command_reply(conn, msg);
476     free(msg);
477 }
478
479 static void
480 vlog_unixctl_reopen(struct unixctl_conn *conn, int argc OVS_UNUSED,
481                     const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
482 {
483     if (log_file_name) {
484         int error = vlog_reopen_log_file();
485         if (error) {
486             unixctl_command_reply_error(conn, ovs_strerror(errno));
487         } else {
488             unixctl_command_reply(conn, NULL);
489         }
490     } else {
491         unixctl_command_reply_error(conn, "Logging to file not configured");
492     }
493 }
494
495 static void
496 set_all_rate_limits(bool enable)
497 {
498     struct vlog_module **mp;
499
500     for (mp = vlog_modules; mp < &vlog_modules[n_vlog_modules]; mp++) {
501         (*mp)->honor_rate_limits = enable;
502     }
503 }
504
505 static void
506 set_rate_limits(struct unixctl_conn *conn, int argc,
507                 const char *argv[], bool enable)
508 {
509     if (argc > 1) {
510         int i;
511
512         for (i = 1; i < argc; i++) {
513             if (!strcasecmp(argv[i], "ANY")) {
514                 set_all_rate_limits(enable);
515             } else {
516                 struct vlog_module *module = vlog_module_from_name(argv[i]);
517                 if (!module) {
518                     unixctl_command_reply_error(conn, "unknown module");
519                     return;
520                 }
521                 module->honor_rate_limits = enable;
522             }
523         }
524     } else {
525         set_all_rate_limits(enable);
526     }
527     unixctl_command_reply(conn, NULL);
528 }
529
530 static void
531 vlog_enable_rate_limit(struct unixctl_conn *conn, int argc,
532                        const char *argv[], void *aux OVS_UNUSED)
533 {
534     set_rate_limits(conn, argc, argv, true);
535 }
536
537 static void
538 vlog_disable_rate_limit(struct unixctl_conn *conn, int argc,
539                        const char *argv[], void *aux OVS_UNUSED)
540 {
541     set_rate_limits(conn, argc, argv, false);
542 }
543
544 /* Initializes the logging subsystem and registers its unixctl server
545  * commands. */
546 void
547 vlog_init(void)
548 {
549     static char *program_name_copy;
550     time_t now;
551
552     if (vlog_inited) {
553         return;
554     }
555     vlog_inited = true;
556
557     /* openlog() is allowed to keep the pointer passed in, without making a
558      * copy.  The daemonize code sometimes frees and replaces 'program_name',
559      * so make a private copy just for openlog().  (We keep a pointer to the
560      * private copy to suppress memory leak warnings in case openlog() does
561      * make its own copy.) */
562     program_name_copy = program_name ? xstrdup(program_name) : NULL;
563     openlog(program_name_copy, LOG_NDELAY, LOG_DAEMON);
564
565     now = time_wall();
566     if (now < 0) {
567         char *s = xastrftime("%a, %d %b %Y %H:%M:%S", now, true);
568         VLOG_ERR("current time is negative: %s (%ld)", s, (long int) now);
569         free(s);
570     }
571
572     unixctl_command_register(
573         "vlog/set", "{spec | PATTERN:facility:pattern}",
574         1, INT_MAX, vlog_unixctl_set, NULL);
575     unixctl_command_register("vlog/list", "", 0, 0, vlog_unixctl_list, NULL);
576     unixctl_command_register("vlog/enable-rate-limit", "[module]...",
577                              0, INT_MAX, vlog_enable_rate_limit, NULL);
578     unixctl_command_register("vlog/disable-rate-limit", "[module]...",
579                              0, INT_MAX, vlog_disable_rate_limit, NULL);
580     unixctl_command_register("vlog/reopen", "", 0, 0,
581                              vlog_unixctl_reopen, NULL);
582 }
583
584 /* Closes the logging subsystem. */
585 void
586 vlog_exit(void)
587 {
588     if (vlog_inited) {
589         closelog();
590         vlog_inited = false;
591     }
592 }
593
594 /* Print the current logging level for each module. */
595 char *
596 vlog_get_levels(void)
597 {
598     struct ds s = DS_EMPTY_INITIALIZER;
599     struct vlog_module **mp;
600     struct svec lines = SVEC_EMPTY_INITIALIZER;
601     char *line;
602     size_t i;
603
604     ds_put_format(&s, "                 console    syslog    file\n");
605     ds_put_format(&s, "                 -------    ------    ------\n");
606
607     for (mp = vlog_modules; mp < &vlog_modules[n_vlog_modules]; mp++) {
608         struct ds line;
609
610         ds_init(&line);
611         ds_put_format(&line, "%-16s  %4s       %4s       %4s",
612                       vlog_get_module_name(*mp),
613                       vlog_get_level_name(vlog_get_level(*mp, VLF_CONSOLE)),
614                       vlog_get_level_name(vlog_get_level(*mp, VLF_SYSLOG)),
615                       vlog_get_level_name(vlog_get_level(*mp, VLF_FILE)));
616         if (!(*mp)->honor_rate_limits) {
617             ds_put_cstr(&line, "    (rate limiting disabled)");
618         }
619         ds_put_char(&line, '\n');
620
621         svec_add_nocopy(&lines, ds_steal_cstr(&line));
622     }
623
624     svec_sort(&lines);
625     SVEC_FOR_EACH (i, line, &lines) {
626         ds_put_cstr(&s, line);
627     }
628     svec_destroy(&lines);
629
630     return ds_cstr(&s);
631 }
632
633 /* Returns true if a log message emitted for the given 'module' and 'level'
634  * would cause some log output, false if that module and level are completely
635  * disabled. */
636 bool
637 vlog_is_enabled(const struct vlog_module *module, enum vlog_level level)
638 {
639     return module->min_level >= level;
640 }
641
642 static const char *
643 fetch_braces(const char *p, const char *def, char *out, size_t out_size)
644 {
645     if (*p == '{') {
646         size_t n = strcspn(p + 1, "}");
647         size_t n_copy = MIN(n, out_size - 1);
648         memcpy(out, p + 1, n_copy);
649         out[n_copy] = '\0';
650         p += n + 2;
651     } else {
652         ovs_strlcpy(out, def, out_size);
653     }
654     return p;
655 }
656
657 static void
658 format_log_message(const struct vlog_module *module, enum vlog_level level,
659                    enum vlog_facility facility, unsigned int msg_num,
660                    const char *message, va_list args_, struct ds *s)
661 {
662     char tmp[128];
663     va_list args;
664     const char *p;
665
666     ds_clear(s);
667     for (p = facilities[facility].pattern; *p != '\0'; ) {
668         enum { LEFT, RIGHT } justify = RIGHT;
669         int pad = '0';
670         size_t length, field, used;
671
672         if (*p != '%') {
673             ds_put_char(s, *p++);
674             continue;
675         }
676
677         p++;
678         if (*p == '-') {
679             justify = LEFT;
680             p++;
681         }
682         if (*p == '0') {
683             pad = '0';
684             p++;
685         }
686         field = 0;
687         while (isdigit((unsigned char)*p)) {
688             field = (field * 10) + (*p - '0');
689             p++;
690         }
691
692         length = s->length;
693         switch (*p++) {
694         case 'A':
695             ds_put_cstr(s, program_name);
696             break;
697         case 'c':
698             p = fetch_braces(p, "", tmp, sizeof tmp);
699             ds_put_cstr(s, vlog_get_module_name(module));
700             break;
701         case 'd':
702             p = fetch_braces(p, "%Y-%m-%d %H:%M:%S", tmp, sizeof tmp);
703             ds_put_strftime(s, tmp, time_wall(), false);
704             break;
705         case 'D':
706             p = fetch_braces(p, "%Y-%m-%d %H:%M:%S", tmp, sizeof tmp);
707             ds_put_strftime(s, tmp, time_wall(), true);
708             break;
709         case 'm':
710             /* Format user-supplied log message and trim trailing new-lines. */
711             length = s->length;
712             va_copy(args, args_);
713             ds_put_format_valist(s, message, args);
714             va_end(args);
715             while (s->length > length && s->string[s->length - 1] == '\n') {
716                 s->length--;
717             }
718             break;
719         case 'N':
720             ds_put_format(s, "%u", msg_num);
721             break;
722         case 'n':
723             ds_put_char(s, '\n');
724             break;
725         case 'p':
726             ds_put_cstr(s, vlog_get_level_name(level));
727             break;
728         case 'P':
729             ds_put_format(s, "%ld", (long int) getpid());
730             break;
731         case 'r':
732             ds_put_format(s, "%lld", time_msec() - time_boot_msec());
733             break;
734         case 't':
735             ds_put_cstr(s, subprogram_name[0] ? subprogram_name : "main");
736             break;
737         case 'T':
738             if (subprogram_name[0]) {
739                 ds_put_format(s, "(%s)", subprogram_name);
740             }
741             break;
742         default:
743             ds_put_char(s, p[-1]);
744             break;
745         }
746         used = s->length - length;
747         if (used < field) {
748             size_t n_pad = field - used;
749             if (justify == RIGHT) {
750                 ds_put_uninit(s, n_pad);
751                 memmove(&s->string[length + n_pad], &s->string[length], used);
752                 memset(&s->string[length], pad, n_pad);
753             } else {
754                 ds_put_char_multiple(s, pad, n_pad);
755             }
756         }
757     }
758 }
759
760 /* Writes 'message' to the log at the given 'level' and as coming from the
761  * given 'module'.
762  *
763  * Guaranteed to preserve errno. */
764 void
765 vlog_valist(const struct vlog_module *module, enum vlog_level level,
766             const char *message, va_list args)
767 {
768     bool log_to_console = module->levels[VLF_CONSOLE] >= level;
769     bool log_to_syslog = module->levels[VLF_SYSLOG] >= level;
770     bool log_to_file = module->levels[VLF_FILE] >= level && log_fd >= 0;
771     if (log_to_console || log_to_syslog || log_to_file) {
772         int save_errno = errno;
773         static unsigned int msg_num;
774         struct ds s;
775
776         vlog_init();
777
778         ds_init(&s);
779         ds_reserve(&s, 1024);
780         msg_num++;
781
782         if (log_to_console) {
783             format_log_message(module, level, VLF_CONSOLE, msg_num,
784                                message, args, &s);
785             ds_put_char(&s, '\n');
786             fputs(ds_cstr(&s), stderr);
787         }
788
789         if (log_to_syslog) {
790             int syslog_level = syslog_levels[level];
791             char *save_ptr = NULL;
792             char *line;
793
794             format_log_message(module, level, VLF_SYSLOG, msg_num,
795                                message, args, &s);
796             for (line = strtok_r(s.string, "\n", &save_ptr); line;
797                  line = strtok_r(NULL, "\n", &save_ptr)) {
798                 syslog(syslog_level, "%s", line);
799             }
800         }
801
802         if (log_to_file) {
803             format_log_message(module, level, VLF_FILE, msg_num,
804                                message, args, &s);
805             ds_put_char(&s, '\n');
806             ignore(write(log_fd, s.string, s.length));
807         }
808
809         ds_destroy(&s);
810         errno = save_errno;
811     }
812 }
813
814 void
815 vlog(const struct vlog_module *module, enum vlog_level level,
816      const char *message, ...)
817 {
818     va_list args;
819
820     va_start(args, message);
821     vlog_valist(module, level, message, args);
822     va_end(args);
823 }
824
825 /* Logs 'message' to 'module' at maximum verbosity, then exits with a failure
826  * exit code.  Always writes the message to stderr, even if the console
827  * facility is disabled.
828  *
829  * Choose this function instead of vlog_abort_valist() if the daemon monitoring
830  * facility shouldn't automatically restart the current daemon.  */
831 void
832 vlog_fatal_valist(const struct vlog_module *module_,
833                   const char *message, va_list args)
834 {
835     struct vlog_module *module = CONST_CAST(struct vlog_module *, module_);
836
837     /* Don't log this message to the console to avoid redundancy with the
838      * message written by the later ovs_fatal_valist(). */
839     module->levels[VLF_CONSOLE] = VLL_OFF;
840
841     vlog_valist(module, VLL_EMER, message, args);
842     ovs_fatal_valist(0, message, args);
843 }
844
845 /* Logs 'message' to 'module' at maximum verbosity, then exits with a failure
846  * exit code.  Always writes the message to stderr, even if the console
847  * facility is disabled.
848  *
849  * Choose this function instead of vlog_abort() if the daemon monitoring
850  * facility shouldn't automatically restart the current daemon.  */
851 void
852 vlog_fatal(const struct vlog_module *module, const char *message, ...)
853 {
854     va_list args;
855
856     va_start(args, message);
857     vlog_fatal_valist(module, message, args);
858     va_end(args);
859 }
860
861 /* Logs 'message' to 'module' at maximum verbosity, then calls abort().  Always
862  * writes the message to stderr, even if the console facility is disabled.
863  *
864  * Choose this function instead of vlog_fatal_valist() if the daemon monitoring
865  * facility should automatically restart the current daemon.  */
866 void
867 vlog_abort_valist(const struct vlog_module *module_,
868                   const char *message, va_list args)
869 {
870     struct vlog_module *module = (struct vlog_module *) module_;
871
872     /* Don't log this message to the console to avoid redundancy with the
873      * message written by the later ovs_abort_valist(). */
874     module->levels[VLF_CONSOLE] = VLL_OFF;
875
876     vlog_valist(module, VLL_EMER, message, args);
877     ovs_abort_valist(0, message, args);
878 }
879
880 /* Logs 'message' to 'module' at maximum verbosity, then calls abort().  Always
881  * writes the message to stderr, even if the console facility is disabled.
882  *
883  * Choose this function instead of vlog_fatal() if the daemon monitoring
884  * facility should automatically restart the current daemon.  */
885 void
886 vlog_abort(const struct vlog_module *module, const char *message, ...)
887 {
888     va_list args;
889
890     va_start(args, message);
891     vlog_abort_valist(module, message, args);
892     va_end(args);
893 }
894
895 bool
896 vlog_should_drop(const struct vlog_module *module, enum vlog_level level,
897                  struct vlog_rate_limit *rl)
898 {
899     if (!module->honor_rate_limits) {
900         return false;
901     }
902
903     if (!vlog_is_enabled(module, level)) {
904         return true;
905     }
906
907     if (!token_bucket_withdraw(&rl->token_bucket, VLOG_MSG_TOKENS)) {
908         time_t now = time_now();
909         if (!rl->n_dropped) {
910             rl->first_dropped = now;
911         }
912         rl->last_dropped = now;
913         rl->n_dropped++;
914         return true;
915     }
916
917     if (rl->n_dropped) {
918         time_t now = time_now();
919         unsigned int first_dropped_elapsed = now - rl->first_dropped;
920         unsigned int last_dropped_elapsed = now - rl->last_dropped;
921
922         vlog(module, level,
923              "Dropped %u log messages in last %u seconds (most recently, "
924              "%u seconds ago) due to excessive rate",
925              rl->n_dropped, first_dropped_elapsed, last_dropped_elapsed);
926
927         rl->n_dropped = 0;
928     }
929     return false;
930 }
931
932 void
933 vlog_rate_limit(const struct vlog_module *module, enum vlog_level level,
934                 struct vlog_rate_limit *rl, const char *message, ...)
935 {
936     if (!vlog_should_drop(module, level, rl)) {
937         va_list args;
938
939         va_start(args, message);
940         vlog_valist(module, level, message, args);
941         va_end(args);
942     }
943 }
944
945 void
946 vlog_usage(void)
947 {
948     printf("\nLogging options:\n"
949            "  -v, --verbose=[SPEC]    set logging levels\n"
950            "  -v, --verbose           set maximum verbosity level\n"
951            "  --log-file[=FILE]       enable logging to specified FILE\n"
952            "                          (default: %s/%s.log)\n",
953            ovs_logdir(), program_name);
954 }