]>
Commit | Line | Data |
---|---|---|
064af421 | 1 | /* |
5136ce49 | 2 | * Copyright (c) 2008, 2009, 2010 Nicira Networks. |
064af421 | 3 | * |
a14bc59f BP |
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: | |
064af421 | 7 | * |
a14bc59f BP |
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. | |
064af421 BP |
15 | */ |
16 | ||
17 | #ifndef VLOG_H | |
18 | #define VLOG_H 1 | |
19 | ||
20 | #include <limits.h> | |
21 | #include <stdarg.h> | |
22 | #include <stdbool.h> | |
23 | #include <time.h> | |
24 | #include "util.h" | |
d295e8e9 | 25 | |
f4ade105 JG |
26 | #ifdef __cplusplus |
27 | extern "C" { | |
28 | #endif | |
064af421 BP |
29 | |
30 | /* Logging importance levels. */ | |
31 | #define VLOG_LEVELS \ | |
32 | VLOG_LEVEL(EMER, LOG_ALERT) \ | |
33 | VLOG_LEVEL(ERR, LOG_ERR) \ | |
34 | VLOG_LEVEL(WARN, LOG_WARNING) \ | |
35 | VLOG_LEVEL(INFO, LOG_NOTICE) \ | |
36 | VLOG_LEVEL(DBG, LOG_DEBUG) | |
37 | enum vlog_level { | |
38 | #define VLOG_LEVEL(NAME, SYSLOG_LEVEL) VLL_##NAME, | |
39 | VLOG_LEVELS | |
40 | #undef VLOG_LEVEL | |
41 | VLL_N_LEVELS | |
42 | }; | |
43 | ||
44 | const char *vlog_get_level_name(enum vlog_level); | |
45 | enum vlog_level vlog_get_level_val(const char *name); | |
46 | ||
47 | /* Facilities that we can log to. */ | |
48 | #define VLOG_FACILITIES \ | |
49 | VLOG_FACILITY(SYSLOG, "%05N|%c|%p|%m") \ | |
50 | VLOG_FACILITY(CONSOLE, "%d{%b %d %H:%M:%S}|%05N|%c|%p|%m") \ | |
51 | VLOG_FACILITY(FILE, "%d{%b %d %H:%M:%S}|%05N|%c|%p|%m") | |
52 | enum vlog_facility { | |
53 | #define VLOG_FACILITY(NAME, PATTERN) VLF_##NAME, | |
54 | VLOG_FACILITIES | |
55 | #undef VLOG_FACILITY | |
56 | VLF_N_FACILITIES, | |
57 | VLF_ANY_FACILITY = -1 | |
58 | }; | |
59 | ||
60 | const char *vlog_get_facility_name(enum vlog_facility); | |
61 | enum vlog_facility vlog_get_facility_val(const char *name); | |
62 | ||
480ce8ab BP |
63 | /* A log module. */ |
64 | struct vlog_module { | |
65 | const char *name; /* User-visible name. */ | |
66 | int levels[VLF_N_FACILITIES]; /* Minimum log level for each facility. */ | |
67 | int min_level; /* Minimum log level for any facility. */ | |
064af421 BP |
68 | }; |
69 | ||
480ce8ab BP |
70 | /* Creates and initializes a global instance of a module named MODULE. */ |
71 | #if USE_LINKER_SECTIONS | |
72 | #define VLOG_DEFINE_MODULE(MODULE) \ | |
73 | VLOG_DEFINE_MODULE__(MODULE) \ | |
74 | struct vlog_module *vlog_module_ptr_##MODULE \ | |
d98e6007 | 75 | __attribute__((section("vlog_modules"))) = &VLM_##MODULE |
480ce8ab | 76 | #else |
d98e6007 | 77 | #define VLOG_DEFINE_MODULE(MODULE) extern struct vlog_module VLM_##MODULE |
480ce8ab BP |
78 | #endif |
79 | ||
80 | const char *vlog_get_module_name(const struct vlog_module *); | |
81 | struct vlog_module *vlog_module_from_name(const char *name); | |
064af421 BP |
82 | |
83 | /* Rate-limiter for log messages. */ | |
84 | struct vlog_rate_limit { | |
85 | /* Configuration settings. */ | |
86 | unsigned int rate; /* Tokens per second. */ | |
87 | unsigned int burst; /* Max cumulative tokens credit. */ | |
88 | ||
89 | /* Current status. */ | |
90 | unsigned int tokens; /* Current number of tokens. */ | |
91 | time_t last_fill; /* Last time tokens added. */ | |
92 | time_t first_dropped; /* Time first message was dropped. */ | |
93 | unsigned int n_dropped; /* Number of messages dropped. */ | |
94 | }; | |
95 | ||
96 | /* Number of tokens to emit a message. We add 'rate' tokens per second, which | |
97 | * is 60 times the unit used for 'rate', thus 60 tokens are required to emit | |
98 | * one message. */ | |
99 | #define VLOG_MSG_TOKENS 60 | |
100 | ||
101 | /* Initializer for a struct vlog_rate_limit, to set up a maximum rate of RATE | |
102 | * messages per minute and a maximum burst size of BURST messages. */ | |
103 | #define VLOG_RATE_LIMIT_INIT(RATE, BURST) \ | |
104 | { \ | |
105 | RATE, /* rate */ \ | |
106 | (MIN(BURST, UINT_MAX / VLOG_MSG_TOKENS) \ | |
107 | * VLOG_MSG_TOKENS), /* burst */ \ | |
108 | 0, /* tokens */ \ | |
109 | 0, /* last_fill */ \ | |
110 | 0, /* first_dropped */ \ | |
111 | 0, /* n_dropped */ \ | |
112 | } | |
113 | ||
114 | /* Configuring how each module logs messages. */ | |
480ce8ab BP |
115 | enum vlog_level vlog_get_level(const struct vlog_module *, enum vlog_facility); |
116 | void vlog_set_levels(struct vlog_module *, | |
117 | enum vlog_facility, enum vlog_level); | |
064af421 BP |
118 | char *vlog_set_levels_from_string(const char *); |
119 | char *vlog_get_levels(void); | |
480ce8ab BP |
120 | bool vlog_is_enabled(const struct vlog_module *, enum vlog_level); |
121 | bool vlog_should_drop(const struct vlog_module *, enum vlog_level, | |
064af421 BP |
122 | struct vlog_rate_limit *); |
123 | void vlog_set_verbosity(const char *arg); | |
124 | ||
125 | /* Configuring log facilities. */ | |
126 | void vlog_set_pattern(enum vlog_facility, const char *pattern); | |
127 | const char *vlog_get_log_file(void); | |
128 | int vlog_set_log_file(const char *file_name); | |
129 | int vlog_reopen_log_file(void); | |
130 | ||
131 | /* Function for actual logging. */ | |
132 | void vlog_init(void); | |
133 | void vlog_exit(void); | |
480ce8ab | 134 | void vlog(const struct vlog_module *, enum vlog_level, const char *format, ...) |
064af421 | 135 | __attribute__((format(printf, 3, 4))); |
480ce8ab BP |
136 | void vlog_valist(const struct vlog_module *, enum vlog_level, |
137 | const char *, va_list) | |
064af421 | 138 | __attribute__((format(printf, 3, 0))); |
480ce8ab | 139 | void vlog_rate_limit(const struct vlog_module *, enum vlog_level, |
064af421 BP |
140 | struct vlog_rate_limit *, const char *, ...) |
141 | __attribute__((format(printf, 4, 5))); | |
142 | ||
480ce8ab BP |
143 | /* Creates and initializes a global instance of a module named MODULE, and |
144 | * defines a static variable named THIS_MODULE that points to it, for use with | |
145 | * the convenience macros below. */ | |
146 | #define VLOG_DEFINE_THIS_MODULE(MODULE) \ | |
d98e6007 BP |
147 | VLOG_DEFINE_MODULE(MODULE); \ |
148 | static struct vlog_module *const THIS_MODULE = &VLM_##MODULE | |
5136ce49 | 149 | |
480ce8ab BP |
150 | /* Convenience macros. These assume that THIS_MODULE points to a "struct |
151 | * vlog_module" for the current module, as set up by e.g. the | |
152 | * VLOG_DEFINE_MODULE macro above. | |
5136ce49 | 153 | * |
064af421 BP |
154 | * Guaranteed to preserve errno. |
155 | */ | |
156 | #define VLOG_EMER(...) VLOG(VLL_EMER, __VA_ARGS__) | |
157 | #define VLOG_ERR(...) VLOG(VLL_ERR, __VA_ARGS__) | |
158 | #define VLOG_WARN(...) VLOG(VLL_WARN, __VA_ARGS__) | |
159 | #define VLOG_INFO(...) VLOG(VLL_INFO, __VA_ARGS__) | |
160 | #define VLOG_DBG(...) VLOG(VLL_DBG, __VA_ARGS__) | |
161 | ||
162 | /* More convenience macros, for testing whether a given level is enabled in | |
163 | * THIS_MODULE. When constructing a log message is expensive, this enables it | |
164 | * to be skipped. */ | |
165 | #define VLOG_IS_EMER_ENABLED() true | |
166 | #define VLOG_IS_ERR_ENABLED() vlog_is_enabled(THIS_MODULE, VLL_EMER) | |
167 | #define VLOG_IS_WARN_ENABLED() vlog_is_enabled(THIS_MODULE, VLL_WARN) | |
168 | #define VLOG_IS_INFO_ENABLED() vlog_is_enabled(THIS_MODULE, VLL_INFO) | |
169 | #define VLOG_IS_DBG_ENABLED() vlog_is_enabled(THIS_MODULE, VLL_DBG) | |
170 | ||
171 | /* Convenience macros for rate-limiting. | |
172 | * Guaranteed to preserve errno. | |
173 | */ | |
174 | #define VLOG_ERR_RL(RL, ...) VLOG_RL(RL, VLL_ERR, __VA_ARGS__) | |
175 | #define VLOG_WARN_RL(RL, ...) VLOG_RL(RL, VLL_WARN, __VA_ARGS__) | |
176 | #define VLOG_INFO_RL(RL, ...) VLOG_RL(RL, VLL_INFO, __VA_ARGS__) | |
177 | #define VLOG_DBG_RL(RL, ...) VLOG_RL(RL, VLL_DBG, __VA_ARGS__) | |
178 | ||
179 | #define VLOG_DROP_ERR(RL) vlog_should_drop(THIS_MODULE, VLL_ERR, RL) | |
180 | #define VLOG_DROP_WARN(RL) vlog_should_drop(THIS_MODULE, VLL_WARN, RL) | |
181 | #define VLOG_DROP_INFO(RL) vlog_should_drop(THIS_MODULE, VLL_INFO, RL) | |
182 | #define VLOG_DROP_DBG(RL) vlog_should_drop(THIS_MODULE, VLL_DBG, RL) | |
183 | ||
5136364f BP |
184 | /* Macros for logging at most once per execution. */ |
185 | #define VLOG_ERR_ONCE(...) VLOG_ONCE(VLL_ERR, __VA_ARGS__) | |
186 | #define VLOG_WARN_ONCE(...) VLOG_ONCE(VLL_WARN, __VA_ARGS__) | |
187 | #define VLOG_INFO_ONCE(...) VLOG_ONCE(VLL_INFO, __VA_ARGS__) | |
188 | #define VLOG_DBG_ONCE(...) VLOG_ONCE(VLL_DBG, __VA_ARGS__) | |
189 | ||
064af421 BP |
190 | /* Command line processing. */ |
191 | #define VLOG_OPTION_ENUMS OPT_LOG_FILE | |
192 | #define VLOG_LONG_OPTIONS \ | |
193 | {"verbose", optional_argument, 0, 'v'}, \ | |
194 | {"log-file", optional_argument, 0, OPT_LOG_FILE} | |
195 | #define VLOG_OPTION_HANDLERS \ | |
196 | case 'v': \ | |
197 | vlog_set_verbosity(optarg); \ | |
198 | break; \ | |
199 | case OPT_LOG_FILE: \ | |
200 | vlog_set_log_file(optarg); \ | |
201 | break; | |
202 | void vlog_usage(void); | |
203 | ||
204 | /* Implementation details. */ | |
480ce8ab BP |
205 | #define VLOG(LEVEL, ...) \ |
206 | do { \ | |
207 | if (THIS_MODULE->min_level >= LEVEL) { \ | |
208 | vlog(THIS_MODULE, LEVEL, __VA_ARGS__); \ | |
209 | } \ | |
064af421 BP |
210 | } while (0) |
211 | #define VLOG_RL(RL, LEVEL, ...) \ | |
212 | do { \ | |
480ce8ab | 213 | if (THIS_MODULE->min_level >= LEVEL) { \ |
064af421 BP |
214 | vlog_rate_limit(THIS_MODULE, LEVEL, RL, __VA_ARGS__); \ |
215 | } \ | |
216 | } while (0) | |
5136364f BP |
217 | #define VLOG_ONCE(LEVEL, ...) \ |
218 | do { \ | |
219 | static bool already_logged; \ | |
220 | if (!already_logged) { \ | |
221 | already_logged = true; \ | |
222 | vlog(THIS_MODULE, LEVEL, __VA_ARGS__); \ | |
223 | } \ | |
224 | } while (0) | |
225 | ||
480ce8ab BP |
226 | #define VLOG_DEFINE_MODULE__(MODULE) \ |
227 | struct vlog_module VLM_##MODULE = \ | |
228 | { \ | |
229 | #MODULE, /* name */ \ | |
230 | { [ 0 ... VLF_N_FACILITIES - 1] = VLL_INFO }, /* levels */ \ | |
231 | VLL_INFO, /* min_level */ \ | |
232 | }; | |
233 | ||
f4ade105 JG |
234 | #ifdef __cplusplus |
235 | } | |
236 | #endif | |
064af421 BP |
237 | |
238 | ||
239 | #endif /* vlog.h */ |