2 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
27 #include <sys/types.h>
31 #include "async-append.h"
34 #include "dynamic-string.h"
36 #include "ovs-thread.h"
38 #include "socket-util.h"
44 VLOG_DEFINE_THIS_MODULE(vlog
);
46 /* ovs_assert() logs the assertion message, so using ovs_assert() in this
47 * source file could cause recursion. */
49 #define ovs_assert use_assert_instead_of_ovs_assert_in_this_module
51 /* Name for each logging level. */
52 static const char *const level_names
[VLL_N_LEVELS
] = {
53 #define VLOG_LEVEL(NAME, SYSLOG_LEVEL, RFC5424) #NAME,
58 /* Syslog value for each logging level. */
59 static const int syslog_levels
[VLL_N_LEVELS
] = {
60 #define VLOG_LEVEL(NAME, SYSLOG_LEVEL, RFC5424) SYSLOG_LEVEL,
65 /* RFC 5424 defines specific values for each syslog level. Normally LOG_* use
66 * the same values. Verify that in fact they're the same. If we get assertion
67 * failures here then we need to define a separate rfc5424_levels[] array. */
68 #define VLOG_LEVEL(NAME, SYSLOG_LEVEL, RFC5424) \
69 BUILD_ASSERT_DECL(SYSLOG_LEVEL == RFC5424);
73 /* Similarly, RFC 5424 defines the local0 facility with the value ordinarily
74 * used for LOG_LOCAL0. */
75 BUILD_ASSERT_DECL(LOG_LOCAL0
== (16 << 3));
77 /* The log modules. */
78 struct list vlog_modules
= LIST_INITIALIZER(&vlog_modules
);
80 /* Protects the 'pattern' in all "struct facility"s, so that a race between
81 * changing and reading the pattern does not cause an access to freed
83 static struct ovs_rwlock pattern_rwlock
= OVS_RWLOCK_INITIALIZER
;
85 /* Information about each facility. */
87 const char *name
; /* Name. */
88 char *pattern
OVS_GUARDED_BY(pattern_rwlock
); /* Current pattern. */
89 bool default_pattern
; /* Whether current pattern is the default. */
91 static struct facility facilities
[VLF_N_FACILITIES
] = {
92 #define VLOG_FACILITY(NAME, PATTERN) {#NAME, PATTERN, true},
97 /* Sequence number for the message currently being composed. */
98 DEFINE_STATIC_PER_THREAD_DATA(unsigned int, msg_num
, 0);
100 /* VLF_FILE configuration.
102 * All of the following is protected by 'log_file_mutex', which nests inside
104 static struct ovs_mutex log_file_mutex
= OVS_MUTEX_INITIALIZER
;
105 static char *log_file_name
OVS_GUARDED_BY(log_file_mutex
);
106 static int log_fd
OVS_GUARDED_BY(log_file_mutex
) = -1;
107 static struct async_append
*log_writer
OVS_GUARDED_BY(log_file_mutex
);
108 static bool log_async
OVS_GUARDED_BY(log_file_mutex
);
110 /* Syslog export configuration. */
111 static int syslog_fd
OVS_GUARDED_BY(pattern_rwlock
) = -1;
113 static void format_log_message(const struct vlog_module
*, enum vlog_level
,
115 const char *message
, va_list, struct ds
*)
118 /* Searches the 'n_names' in 'names'. Returns the index of a match for
119 * 'target', or 'n_names' if no name matches. */
121 search_name_array(const char *target
, const char *const *names
, size_t n_names
)
125 for (i
= 0; i
< n_names
; i
++) {
127 if (!strcasecmp(names
[i
], target
)) {
134 /* Returns the name for logging level 'level'. */
136 vlog_get_level_name(enum vlog_level level
)
138 assert(level
< VLL_N_LEVELS
);
139 return level_names
[level
];
142 /* Returns the logging level with the given 'name', or VLL_N_LEVELS if 'name'
143 * is not the name of a logging level. */
145 vlog_get_level_val(const char *name
)
147 return search_name_array(name
, level_names
, ARRAY_SIZE(level_names
));
150 /* Returns the name for logging facility 'facility'. */
152 vlog_get_facility_name(enum vlog_facility facility
)
154 assert(facility
< VLF_N_FACILITIES
);
155 return facilities
[facility
].name
;
158 /* Returns the logging facility named 'name', or VLF_N_FACILITIES if 'name' is
159 * not the name of a logging facility. */
161 vlog_get_facility_val(const char *name
)
165 for (i
= 0; i
< VLF_N_FACILITIES
; i
++) {
166 if (!strcasecmp(facilities
[i
].name
, name
)) {
173 /* Returns the name for logging module 'module'. */
175 vlog_get_module_name(const struct vlog_module
*module
)
180 /* Returns the logging module named 'name', or NULL if 'name' is not the name
181 * of a logging module. */
183 vlog_module_from_name(const char *name
)
185 struct vlog_module
*mp
;
187 LIST_FOR_EACH (mp
, list
, &vlog_modules
) {
188 if (!strcasecmp(name
, mp
->name
)) {
196 /* Returns the current logging level for the given 'module' and 'facility'. */
198 vlog_get_level(const struct vlog_module
*module
, enum vlog_facility facility
)
200 assert(facility
< VLF_N_FACILITIES
);
201 return module
->levels
[facility
];
205 update_min_level(struct vlog_module
*module
) OVS_REQUIRES(&log_file_mutex
)
207 enum vlog_facility facility
;
209 module
->min_level
= VLL_OFF
;
210 for (facility
= 0; facility
< VLF_N_FACILITIES
; facility
++) {
211 if (log_fd
>= 0 || facility
!= VLF_FILE
) {
212 enum vlog_level level
= module
->levels
[facility
];
213 if (level
> module
->min_level
) {
214 module
->min_level
= level
;
221 set_facility_level(enum vlog_facility facility
, struct vlog_module
*module
,
222 enum vlog_level level
)
224 assert(facility
>= 0 && facility
< VLF_N_FACILITIES
);
225 assert(level
< VLL_N_LEVELS
);
227 ovs_mutex_lock(&log_file_mutex
);
229 struct vlog_module
*mp
;
230 LIST_FOR_EACH (mp
, list
, &vlog_modules
) {
231 mp
->levels
[facility
] = level
;
232 update_min_level(mp
);
235 module
->levels
[facility
] = level
;
236 update_min_level(module
);
238 ovs_mutex_unlock(&log_file_mutex
);
241 /* Sets the logging level for the given 'module' and 'facility' to 'level'. A
242 * null 'module' or a 'facility' of VLF_ANY_FACILITY is treated as a wildcard
243 * across all modules or facilities, respectively. */
245 vlog_set_levels(struct vlog_module
*module
, enum vlog_facility facility
,
246 enum vlog_level level
)
248 assert(facility
< VLF_N_FACILITIES
|| facility
== VLF_ANY_FACILITY
);
249 if (facility
== VLF_ANY_FACILITY
) {
250 for (facility
= 0; facility
< VLF_N_FACILITIES
; facility
++) {
251 set_facility_level(facility
, module
, level
);
254 set_facility_level(facility
, module
, level
);
259 do_set_pattern(enum vlog_facility facility
, const char *pattern
)
261 struct facility
*f
= &facilities
[facility
];
263 ovs_rwlock_wrlock(&pattern_rwlock
);
264 if (!f
->default_pattern
) {
267 f
->default_pattern
= false;
269 f
->pattern
= xstrdup(pattern
);
270 ovs_rwlock_unlock(&pattern_rwlock
);
273 /* Sets the pattern for the given 'facility' to 'pattern'. */
275 vlog_set_pattern(enum vlog_facility facility
, const char *pattern
)
277 assert(facility
< VLF_N_FACILITIES
|| facility
== VLF_ANY_FACILITY
);
278 if (facility
== VLF_ANY_FACILITY
) {
279 for (facility
= 0; facility
< VLF_N_FACILITIES
; facility
++) {
280 do_set_pattern(facility
, pattern
);
283 do_set_pattern(facility
, pattern
);
287 /* Sets the name of the log file used by VLF_FILE to 'file_name', or to the
288 * default file name if 'file_name' is null. Returns 0 if successful,
289 * otherwise a positive errno value. */
291 vlog_set_log_file(const char *file_name
)
293 char *new_log_file_name
;
294 struct vlog_module
*mp
;
295 struct stat old_stat
;
296 struct stat new_stat
;
301 /* Open new log file. */
302 new_log_file_name
= (file_name
304 : xasprintf("%s/%s.log", ovs_logdir(), program_name
));
305 new_log_fd
= open(new_log_file_name
, O_WRONLY
| O_CREAT
| O_APPEND
, 0666);
306 if (new_log_fd
< 0) {
307 VLOG_WARN("failed to open %s for logging: %s",
308 new_log_file_name
, ovs_strerror(errno
));
309 free(new_log_file_name
);
313 /* If the new log file is the same one we already have open, bail out. */
314 ovs_mutex_lock(&log_file_mutex
);
315 same_file
= (log_fd
>= 0
317 && !fstat(log_fd
, &old_stat
)
318 && !fstat(new_log_fd
, &new_stat
)
319 && old_stat
.st_dev
== new_stat
.st_dev
320 && old_stat
.st_ino
== new_stat
.st_ino
);
321 ovs_mutex_unlock(&log_file_mutex
);
324 free(new_log_file_name
);
328 /* Log closing old log file (we can't log while holding log_file_mutex). */
329 ovs_mutex_lock(&log_file_mutex
);
330 log_close
= log_fd
>= 0;
331 ovs_mutex_unlock(&log_file_mutex
);
333 VLOG_INFO("closing log file");
336 /* Close old log file, if any, and install new one. */
337 ovs_mutex_lock(&log_file_mutex
);
341 async_append_destroy(log_writer
);
344 log_file_name
= xstrdup(new_log_file_name
);
347 log_writer
= async_append_create(new_log_fd
);
350 LIST_FOR_EACH (mp
, list
, &vlog_modules
) {
351 update_min_level(mp
);
353 ovs_mutex_unlock(&log_file_mutex
);
355 /* Log opening new log file (we can't log while holding log_file_mutex). */
356 VLOG_INFO("opened log file %s", new_log_file_name
);
357 free(new_log_file_name
);
362 /* Closes and then attempts to re-open the current log file. (This is useful
363 * just after log rotation, to ensure that the new log file starts being used.)
364 * Returns 0 if successful, otherwise a positive errno value. */
366 vlog_reopen_log_file(void)
370 ovs_mutex_lock(&log_file_mutex
);
371 fn
= log_file_name
? xstrdup(log_file_name
) : NULL
;
372 ovs_mutex_unlock(&log_file_mutex
);
375 int error
= vlog_set_log_file(fn
);
383 /* Set debugging levels. Returns null if successful, otherwise an error
384 * message that the caller must free(). */
386 vlog_set_levels_from_string(const char *s_
)
388 char *s
= xstrdup(s_
);
389 char *save_ptr
= NULL
;
393 word
= strtok_r(s
, " ,:\t", &save_ptr
);
394 if (word
&& !strcasecmp(word
, "PATTERN")) {
395 enum vlog_facility facility
;
397 word
= strtok_r(NULL
, " ,:\t", &save_ptr
);
399 msg
= xstrdup("missing facility");
403 facility
= (!strcasecmp(word
, "ANY")
405 : vlog_get_facility_val(word
));
406 if (facility
== VLF_N_FACILITIES
) {
407 msg
= xasprintf("unknown facility \"%s\"", word
);
410 vlog_set_pattern(facility
, save_ptr
);
412 struct vlog_module
*module
= NULL
;
413 enum vlog_level level
= VLL_N_LEVELS
;
414 enum vlog_facility facility
= VLF_N_FACILITIES
;
416 for (; word
!= NULL
; word
= strtok_r(NULL
, " ,:\t", &save_ptr
)) {
417 if (!strcasecmp(word
, "ANY")) {
419 } else if (vlog_get_facility_val(word
) != VLF_N_FACILITIES
) {
420 if (facility
!= VLF_N_FACILITIES
) {
421 msg
= xstrdup("cannot specify multiple facilities");
424 facility
= vlog_get_facility_val(word
);
425 } else if (vlog_get_level_val(word
) != VLL_N_LEVELS
) {
426 if (level
!= VLL_N_LEVELS
) {
427 msg
= xstrdup("cannot specify multiple levels");
430 level
= vlog_get_level_val(word
);
431 } else if (vlog_module_from_name(word
)) {
433 msg
= xstrdup("cannot specify multiple modules");
436 module
= vlog_module_from_name(word
);
438 msg
= xasprintf("no facility, level, or module \"%s\"", word
);
443 if (facility
== VLF_N_FACILITIES
) {
444 facility
= VLF_ANY_FACILITY
;
446 if (level
== VLL_N_LEVELS
) {
449 vlog_set_levels(module
, facility
, level
);
457 /* Set debugging levels. Abort with an error message if 's' is invalid. */
459 vlog_set_levels_from_string_assert(const char *s
)
461 char *error
= vlog_set_levels_from_string(s
);
463 ovs_fatal(0, "%s", error
);
467 /* If 'arg' is null, configure maximum verbosity. Otherwise, sets
468 * configuration according to 'arg' (see vlog_set_levels_from_string()). */
470 vlog_set_verbosity(const char *arg
)
473 char *msg
= vlog_set_levels_from_string(arg
);
475 ovs_fatal(0, "processing \"%s\": %s", arg
, msg
);
478 vlog_set_levels(NULL
, VLF_ANY_FACILITY
, VLL_DBG
);
482 /* Set the vlog udp syslog target. */
484 vlog_set_syslog_target(const char *target
)
488 inet_open_active(SOCK_DGRAM
, target
, 0, NULL
, &new_fd
, 0);
490 ovs_rwlock_wrlock(&pattern_rwlock
);
491 if (syslog_fd
>= 0) {
495 ovs_rwlock_unlock(&pattern_rwlock
);
499 vlog_unixctl_set(struct unixctl_conn
*conn
, int argc
, const char *argv
[],
500 void *aux OVS_UNUSED
)
504 for (i
= 1; i
< argc
; i
++) {
505 char *msg
= vlog_set_levels_from_string(argv
[i
]);
507 unixctl_command_reply_error(conn
, msg
);
512 unixctl_command_reply(conn
, NULL
);
516 vlog_unixctl_list(struct unixctl_conn
*conn
, int argc OVS_UNUSED
,
517 const char *argv
[] OVS_UNUSED
, void *aux OVS_UNUSED
)
519 char *msg
= vlog_get_levels();
520 unixctl_command_reply(conn
, msg
);
525 vlog_unixctl_reopen(struct unixctl_conn
*conn
, int argc OVS_UNUSED
,
526 const char *argv
[] OVS_UNUSED
, void *aux OVS_UNUSED
)
530 ovs_mutex_lock(&log_file_mutex
);
531 has_log_file
= log_file_name
!= NULL
;
532 ovs_mutex_unlock(&log_file_mutex
);
535 int error
= vlog_reopen_log_file();
537 unixctl_command_reply_error(conn
, ovs_strerror(errno
));
539 unixctl_command_reply(conn
, NULL
);
542 unixctl_command_reply_error(conn
, "Logging to file not configured");
547 set_all_rate_limits(bool enable
)
549 struct vlog_module
*mp
;
551 LIST_FOR_EACH (mp
, list
, &vlog_modules
) {
552 mp
->honor_rate_limits
= enable
;
557 set_rate_limits(struct unixctl_conn
*conn
, int argc
,
558 const char *argv
[], bool enable
)
563 for (i
= 1; i
< argc
; i
++) {
564 if (!strcasecmp(argv
[i
], "ANY")) {
565 set_all_rate_limits(enable
);
567 struct vlog_module
*module
= vlog_module_from_name(argv
[i
]);
569 unixctl_command_reply_error(conn
, "unknown module");
572 module
->honor_rate_limits
= enable
;
576 set_all_rate_limits(enable
);
578 unixctl_command_reply(conn
, NULL
);
582 vlog_enable_rate_limit(struct unixctl_conn
*conn
, int argc
,
583 const char *argv
[], void *aux OVS_UNUSED
)
585 set_rate_limits(conn
, argc
, argv
, true);
589 vlog_disable_rate_limit(struct unixctl_conn
*conn
, int argc
,
590 const char *argv
[], void *aux OVS_UNUSED
)
592 set_rate_limits(conn
, argc
, argv
, false);
595 /* Initializes the logging subsystem and registers its unixctl server
600 static struct ovsthread_once once
= OVSTHREAD_ONCE_INITIALIZER
;
602 if (ovsthread_once_start(&once
)) {
603 static char *program_name_copy
;
606 /* Do initialization work that needs to be done before any logging
607 * occurs. We want to keep this really minimal because any attempt to
608 * log anything before calling ovsthread_once_done() will deadlock. */
610 /* openlog() is allowed to keep the pointer passed in, without making a
611 * copy. The daemonize code sometimes frees and replaces
612 * 'program_name', so make a private copy just for openlog(). (We keep
613 * a pointer to the private copy to suppress memory leak warnings in
614 * case openlog() does make its own copy.) */
615 program_name_copy
= program_name
? xstrdup(program_name
) : NULL
;
616 openlog(program_name_copy
, LOG_NDELAY
, LOG_DAEMON
);
617 ovsthread_once_done(&once
);
619 /* Now do anything that we want to happen only once but doesn't have to
620 * finish before we start logging. */
622 now
= time_wall_msec();
624 char *s
= xastrftime_msec("%a, %d %b %Y %H:%M:%S", now
, true);
625 VLOG_ERR("current time is negative: %s (%lld)", s
, now
);
629 unixctl_command_register(
630 "vlog/set", "{spec | PATTERN:facility:pattern}",
631 1, INT_MAX
, vlog_unixctl_set
, NULL
);
632 unixctl_command_register("vlog/list", "", 0, 0, vlog_unixctl_list
,
634 unixctl_command_register("vlog/enable-rate-limit", "[module]...",
635 0, INT_MAX
, vlog_enable_rate_limit
, NULL
);
636 unixctl_command_register("vlog/disable-rate-limit", "[module]...",
637 0, INT_MAX
, vlog_disable_rate_limit
, NULL
);
638 unixctl_command_register("vlog/reopen", "", 0, 0,
639 vlog_unixctl_reopen
, NULL
);
643 /* Enables VLF_FILE log output to be written asynchronously to disk.
644 * Asynchronous file writes avoid blocking the process in the case of a busy
645 * disk, but on the other hand they are less robust: there is a chance that the
646 * write will not make it to the log file if the process crashes soon after the
649 vlog_enable_async(void)
651 ovs_mutex_lock(&log_file_mutex
);
653 if (log_fd
>= 0 && !log_writer
) {
654 log_writer
= async_append_create(log_fd
);
656 ovs_mutex_unlock(&log_file_mutex
);
659 /* Print the current logging level for each module. */
661 vlog_get_levels(void)
663 struct ds s
= DS_EMPTY_INITIALIZER
;
664 struct vlog_module
*mp
;
665 struct svec lines
= SVEC_EMPTY_INITIALIZER
;
669 ds_put_format(&s
, " console syslog file\n");
670 ds_put_format(&s
, " ------- ------ ------\n");
672 LIST_FOR_EACH (mp
, list
, &vlog_modules
) {
676 ds_put_format(&line
, "%-16s %4s %4s %4s",
677 vlog_get_module_name(mp
),
678 vlog_get_level_name(vlog_get_level(mp
, VLF_CONSOLE
)),
679 vlog_get_level_name(vlog_get_level(mp
, VLF_SYSLOG
)),
680 vlog_get_level_name(vlog_get_level(mp
, VLF_FILE
)));
681 if (!mp
->honor_rate_limits
) {
682 ds_put_cstr(&line
, " (rate limiting disabled)");
684 ds_put_char(&line
, '\n');
686 svec_add_nocopy(&lines
, ds_steal_cstr(&line
));
690 SVEC_FOR_EACH (i
, line
, &lines
) {
691 ds_put_cstr(&s
, line
);
693 svec_destroy(&lines
);
698 /* Returns true if a log message emitted for the given 'module' and 'level'
699 * would cause some log output, false if that module and level are completely
702 vlog_is_enabled(const struct vlog_module
*module
, enum vlog_level level
)
704 return module
->min_level
>= level
;
708 fetch_braces(const char *p
, const char *def
, char *out
, size_t out_size
)
711 size_t n
= strcspn(p
+ 1, "}");
712 size_t n_copy
= MIN(n
, out_size
- 1);
713 memcpy(out
, p
+ 1, n_copy
);
717 ovs_strlcpy(out
, def
, out_size
);
723 format_log_message(const struct vlog_module
*module
, enum vlog_level level
,
724 const char *pattern
, const char *message
,
725 va_list args_
, struct ds
*s
)
732 for (p
= pattern
; *p
!= '\0'; ) {
733 const char *subprogram_name
;
734 enum { LEFT
, RIGHT
} justify
= RIGHT
;
736 size_t length
, field
, used
;
739 ds_put_char(s
, *p
++);
753 while (isdigit((unsigned char)*p
)) {
754 field
= (field
* 10) + (*p
- '0');
761 ds_put_cstr(s
, program_name
);
764 ds_put_format(s
, "%d", LOG_LOCAL0
+ syslog_levels
[level
]);
767 p
= fetch_braces(p
, "", tmp
, sizeof tmp
);
768 ds_put_cstr(s
, vlog_get_module_name(module
));
771 p
= fetch_braces(p
, "%Y-%m-%d %H:%M:%S.###", tmp
, sizeof tmp
);
772 ds_put_strftime_msec(s
, tmp
, time_wall_msec(), false);
775 p
= fetch_braces(p
, "%Y-%m-%d %H:%M:%S.###", tmp
, sizeof tmp
);
776 ds_put_strftime_msec(s
, tmp
, time_wall_msec(), true);
779 gethostname(tmp
, sizeof tmp
);
780 tmp
[sizeof tmp
- 1] = '\0';
784 /* Format user-supplied log message and trim trailing new-lines. */
786 va_copy(args
, args_
);
787 ds_put_format_valist(s
, message
, args
);
789 while (s
->length
> length
&& s
->string
[s
->length
- 1] == '\n') {
794 ds_put_format(s
, "%u", *msg_num_get_unsafe());
797 ds_put_char(s
, '\n');
800 ds_put_cstr(s
, vlog_get_level_name(level
));
803 ds_put_format(s
, "%ld", (long int) getpid());
806 ds_put_format(s
, "%lld", time_msec() - time_boot_msec());
809 subprogram_name
= get_subprogram_name();
810 ds_put_cstr(s
, subprogram_name
[0] ? subprogram_name
: "main");
813 subprogram_name
= get_subprogram_name();
814 if (subprogram_name
[0]) {
815 ds_put_format(s
, "(%s)", subprogram_name
);
819 ds_put_char(s
, p
[-1]);
822 used
= s
->length
- length
;
824 size_t n_pad
= field
- used
;
825 if (justify
== RIGHT
) {
826 ds_put_uninit(s
, n_pad
);
827 memmove(&s
->string
[length
+ n_pad
], &s
->string
[length
], used
);
828 memset(&s
->string
[length
], pad
, n_pad
);
830 ds_put_char_multiple(s
, pad
, n_pad
);
836 /* Exports the given 'syslog_message' to the configured udp syslog sink. */
838 send_to_syslog_fd(const char *s
, size_t length
)
839 OVS_REQ_RDLOCK(pattern_rwlock
)
841 static size_t max_length
= SIZE_MAX
;
842 size_t send_len
= MIN(length
, max_length
);
844 while (write(syslog_fd
, s
, send_len
) < 0 && errno
== EMSGSIZE
) {
845 send_len
-= send_len
/ 20;
846 max_length
= send_len
;
850 /* Writes 'message' to the log at the given 'level' and as coming from the
853 * Guaranteed to preserve errno. */
855 vlog_valist(const struct vlog_module
*module
, enum vlog_level level
,
856 const char *message
, va_list args
)
858 bool log_to_console
= module
->levels
[VLF_CONSOLE
] >= level
;
859 bool log_to_syslog
= module
->levels
[VLF_SYSLOG
] >= level
;
862 ovs_mutex_lock(&log_file_mutex
);
863 log_to_file
= module
->levels
[VLF_FILE
] >= level
&& log_fd
>= 0;
864 ovs_mutex_unlock(&log_file_mutex
);
865 if (log_to_console
|| log_to_syslog
|| log_to_file
) {
866 int save_errno
= errno
;
872 ds_reserve(&s
, 1024);
875 ovs_rwlock_rdlock(&pattern_rwlock
);
876 if (log_to_console
) {
877 format_log_message(module
, level
, facilities
[VLF_CONSOLE
].pattern
,
879 ds_put_char(&s
, '\n');
880 fputs(ds_cstr(&s
), stderr
);
884 int syslog_level
= syslog_levels
[level
];
885 char *save_ptr
= NULL
;
888 format_log_message(module
, level
, facilities
[VLF_SYSLOG
].pattern
,
890 for (line
= strtok_r(s
.string
, "\n", &save_ptr
); line
;
891 line
= strtok_r(NULL
, "\n", &save_ptr
)) {
892 syslog(syslog_level
, "%s", line
);
895 if (syslog_fd
>= 0) {
896 format_log_message(module
, level
,
897 "<%B>1 %D{%Y-%m-%dT%H:%M:%S.###Z} "
898 "%E %A %P %c - \xef\xbb\xbf%m",
900 send_to_syslog_fd(ds_cstr(&s
), s
.length
);
905 format_log_message(module
, level
, facilities
[VLF_FILE
].pattern
,
907 ds_put_char(&s
, '\n');
909 ovs_mutex_lock(&log_file_mutex
);
912 async_append_write(log_writer
, s
.string
, s
.length
);
913 if (level
== VLL_EMER
) {
914 async_append_flush(log_writer
);
917 ignore(write(log_fd
, s
.string
, s
.length
));
920 ovs_mutex_unlock(&log_file_mutex
);
922 ovs_rwlock_unlock(&pattern_rwlock
);
930 vlog(const struct vlog_module
*module
, enum vlog_level level
,
931 const char *message
, ...)
935 va_start(args
, message
);
936 vlog_valist(module
, level
, message
, args
);
940 /* Logs 'message' to 'module' at maximum verbosity, then exits with a failure
941 * exit code. Always writes the message to stderr, even if the console
942 * facility is disabled.
944 * Choose this function instead of vlog_abort_valist() if the daemon monitoring
945 * facility shouldn't automatically restart the current daemon. */
947 vlog_fatal_valist(const struct vlog_module
*module_
,
948 const char *message
, va_list args
)
950 struct vlog_module
*module
= CONST_CAST(struct vlog_module
*, module_
);
952 /* Don't log this message to the console to avoid redundancy with the
953 * message written by the later ovs_fatal_valist(). */
954 module
->levels
[VLF_CONSOLE
] = VLL_OFF
;
956 vlog_valist(module
, VLL_EMER
, message
, args
);
957 ovs_fatal_valist(0, message
, args
);
960 /* Logs 'message' to 'module' at maximum verbosity, then exits with a failure
961 * exit code. Always writes the message to stderr, even if the console
962 * facility is disabled.
964 * Choose this function instead of vlog_abort() if the daemon monitoring
965 * facility shouldn't automatically restart the current daemon. */
967 vlog_fatal(const struct vlog_module
*module
, const char *message
, ...)
971 va_start(args
, message
);
972 vlog_fatal_valist(module
, message
, args
);
976 /* Logs 'message' to 'module' at maximum verbosity, then calls abort(). Always
977 * writes the message to stderr, even if the console facility is disabled.
979 * Choose this function instead of vlog_fatal_valist() if the daemon monitoring
980 * facility should automatically restart the current daemon. */
982 vlog_abort_valist(const struct vlog_module
*module_
,
983 const char *message
, va_list args
)
985 struct vlog_module
*module
= (struct vlog_module
*) module_
;
987 /* Don't log this message to the console to avoid redundancy with the
988 * message written by the later ovs_abort_valist(). */
989 module
->levels
[VLF_CONSOLE
] = VLL_OFF
;
991 vlog_valist(module
, VLL_EMER
, message
, args
);
992 ovs_abort_valist(0, message
, args
);
995 /* Logs 'message' to 'module' at maximum verbosity, then calls abort(). Always
996 * writes the message to stderr, even if the console facility is disabled.
998 * Choose this function instead of vlog_fatal() if the daemon monitoring
999 * facility should automatically restart the current daemon. */
1001 vlog_abort(const struct vlog_module
*module
, const char *message
, ...)
1005 va_start(args
, message
);
1006 vlog_abort_valist(module
, message
, args
);
1011 vlog_should_drop(const struct vlog_module
*module
, enum vlog_level level
,
1012 struct vlog_rate_limit
*rl
)
1014 if (!module
->honor_rate_limits
) {
1018 if (!vlog_is_enabled(module
, level
)) {
1022 ovs_mutex_lock(&rl
->mutex
);
1023 if (!token_bucket_withdraw(&rl
->token_bucket
, VLOG_MSG_TOKENS
)) {
1024 time_t now
= time_now();
1025 if (!rl
->n_dropped
) {
1026 rl
->first_dropped
= now
;
1028 rl
->last_dropped
= now
;
1030 ovs_mutex_unlock(&rl
->mutex
);
1034 if (!rl
->n_dropped
) {
1035 ovs_mutex_unlock(&rl
->mutex
);
1037 time_t now
= time_now();
1038 unsigned int n_dropped
= rl
->n_dropped
;
1039 unsigned int first_dropped_elapsed
= now
- rl
->first_dropped
;
1040 unsigned int last_dropped_elapsed
= now
- rl
->last_dropped
;
1042 ovs_mutex_unlock(&rl
->mutex
);
1045 "Dropped %u log messages in last %u seconds (most recently, "
1046 "%u seconds ago) due to excessive rate",
1047 n_dropped
, first_dropped_elapsed
, last_dropped_elapsed
);
1054 vlog_rate_limit(const struct vlog_module
*module
, enum vlog_level level
,
1055 struct vlog_rate_limit
*rl
, const char *message
, ...)
1057 if (!vlog_should_drop(module
, level
, rl
)) {
1060 va_start(args
, message
);
1061 vlog_valist(module
, level
, message
, args
);
1071 -vSPEC, --verbose=SPEC set logging levels\n\
1072 -v, --verbose set maximum verbosity level\n\
1073 --log-file[=FILE] enable logging to specified FILE\n\
1074 (default: %s/%s.log)\n\
1075 --syslog-target=HOST:PORT also send syslog msgs to HOST:PORT via UDP\n",
1076 ovs_logdir(), program_name
);