]>
Commit | Line | Data |
---|---|---|
e0b4037d DL |
1 | /* |
2 | * lxc: linux Container library | |
3 | * | |
4 | * (C) Copyright IBM Corp. 2007, 2008 | |
5 | * | |
6 | * Authors: | |
7 | * Daniel Lezcano <dlezcano at fr.ibm.com> | |
8 | * Cedric Le Goater <legoater@free.fr> | |
9 | * | |
10 | * This library is free software; you can redistribute it and/or | |
11 | * modify it under the terms of the GNU Lesser General Public | |
12 | * License as published by the Free Software Foundation; either | |
13 | * version 2.1 of the License, or (at your option) any later version. | |
14 | * | |
15 | * This library is distributed in the hope that it will be useful, | |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
18 | * Lesser General Public License for more details. | |
19 | * | |
20 | * You should have received a copy of the GNU Lesser General Public | |
21 | * License along with this library; if not, write to the Free Software | |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 | */ | |
0ad19a3f | 24 | #ifndef _log_h |
25 | #define _log_h | |
26 | ||
cb8c5720 CLG |
27 | #include <stdarg.h> |
28 | #include <stdio.h> | |
29 | #include <sys/time.h> | |
30 | #include <string.h> | |
31 | ||
eabbb2f0 MN |
32 | #ifndef O_CLOEXEC |
33 | #define O_CLOEXEC 02000000 | |
34 | #endif | |
35 | ||
36 | #ifndef F_DUPFD_CLOEXEC | |
37 | #define F_DUPFD_CLOEXEC 1030 | |
38 | #endif | |
39 | ||
40 | #define LXC_LOG_PREFIX_SIZE 32 | |
41 | #define LXC_LOG_BUFFER_SIZE 512 | |
42 | ||
cb8c5720 CLG |
43 | /* predefined priorities. */ |
44 | enum { | |
45 | LXC_LOG_PRIORITY_TRACE, | |
46 | LXC_LOG_PRIORITY_DEBUG, | |
47 | LXC_LOG_PRIORITY_INFO, | |
48 | LXC_LOG_PRIORITY_NOTICE, | |
49 | LXC_LOG_PRIORITY_WARN, | |
50 | LXC_LOG_PRIORITY_ERROR, | |
51 | LXC_LOG_PRIORITY_CRIT, | |
52 | LXC_LOG_PRIORITY_ALERT, | |
53 | LXC_LOG_PRIORITY_FATAL, | |
54 | LXC_LOG_PRIORITY_NOTSET, | |
55 | }; | |
56 | ||
57 | /* location information of the logging event */ | |
58 | struct lxc_log_locinfo { | |
59 | const char *file; | |
60 | const char *func; | |
61 | int line; | |
62 | }; | |
63 | ||
64 | #define LXC_LOG_LOCINFO_INIT \ | |
65 | { .file = __FILE__, .func = __func__, .line = __LINE__ } | |
66 | ||
67 | /* brief logging event object */ | |
68 | struct lxc_log_event { | |
69 | const char* category; | |
70 | int priority; | |
71 | struct timeval timestamp; | |
72 | struct lxc_log_locinfo *locinfo; | |
73 | const char *fmt; | |
5fd8380b | 74 | va_list *vap; |
cb8c5720 CLG |
75 | }; |
76 | ||
77 | /* log appender object */ | |
78 | struct lxc_log_appender { | |
79 | const char* name; | |
5fd8380b | 80 | int (*append)(const struct lxc_log_appender *, struct lxc_log_event *); |
cb8c5720 CLG |
81 | |
82 | /* | |
83 | * appenders can be stacked | |
84 | */ | |
85 | struct lxc_log_appender *next; | |
86 | }; | |
87 | ||
88 | /* log category object */ | |
89 | struct lxc_log_category { | |
90 | const char *name; | |
91 | int priority; | |
92 | struct lxc_log_appender *appender; | |
93 | const struct lxc_log_category *parent; | |
94 | }; | |
95 | ||
96 | /* | |
97 | * Returns true if the chained priority is equal to or higher than | |
98 | * given priority. | |
99 | */ | |
100 | static inline int | |
101 | lxc_log_priority_is_enabled(const struct lxc_log_category* category, | |
102 | int priority) | |
103 | { | |
104 | while (category->priority == LXC_LOG_PRIORITY_NOTSET && | |
105 | category->parent) | |
106 | category = category->parent; | |
107 | ||
108 | return priority >= category->priority; | |
109 | } | |
110 | ||
111 | /* | |
112 | * converts a priority to a literal string | |
113 | */ | |
114 | static inline const char* lxc_log_priority_to_string(int priority) | |
115 | { | |
116 | switch (priority) { | |
117 | case LXC_LOG_PRIORITY_TRACE: return "TRACE"; | |
118 | case LXC_LOG_PRIORITY_DEBUG: return "DEBUG"; | |
119 | case LXC_LOG_PRIORITY_INFO: return "INFO"; | |
120 | case LXC_LOG_PRIORITY_NOTICE: return "NOTICE"; | |
121 | case LXC_LOG_PRIORITY_WARN: return "WARN"; | |
122 | case LXC_LOG_PRIORITY_ERROR: return "ERROR"; | |
123 | case LXC_LOG_PRIORITY_CRIT: return "CRIT"; | |
124 | case LXC_LOG_PRIORITY_ALERT: return "ALERT"; | |
125 | case LXC_LOG_PRIORITY_FATAL: return "FATAL"; | |
126 | default: | |
127 | return "NOTSET"; | |
128 | } | |
129 | } | |
130 | /* | |
131 | * converts a literal priority to an int | |
132 | */ | |
133 | static inline int lxc_log_priority_to_int(const char* name) | |
134 | { | |
135 | if (!strcasecmp("TRACE", name)) return LXC_LOG_PRIORITY_TRACE; | |
136 | if (!strcasecmp("DEBUG", name)) return LXC_LOG_PRIORITY_DEBUG; | |
137 | if (!strcasecmp("INFO", name)) return LXC_LOG_PRIORITY_INFO; | |
138 | if (!strcasecmp("NOTICE", name)) return LXC_LOG_PRIORITY_NOTICE; | |
139 | if (!strcasecmp("WARN", name)) return LXC_LOG_PRIORITY_WARN; | |
140 | if (!strcasecmp("ERROR", name)) return LXC_LOG_PRIORITY_ERROR; | |
141 | if (!strcasecmp("CRIT", name)) return LXC_LOG_PRIORITY_CRIT; | |
142 | if (!strcasecmp("ALERT", name)) return LXC_LOG_PRIORITY_ALERT; | |
143 | if (!strcasecmp("FATAL", name)) return LXC_LOG_PRIORITY_FATAL; | |
144 | ||
145 | return LXC_LOG_PRIORITY_NOTSET; | |
146 | } | |
147 | ||
148 | static inline void | |
149 | __lxc_log_append(const struct lxc_log_appender *appender, | |
5fd8380b | 150 | struct lxc_log_event* event) |
cb8c5720 | 151 | { |
5fd8380b MN |
152 | va_list va, *va_keep; |
153 | va_keep = event->vap; | |
154 | ||
cb8c5720 | 155 | while (appender) { |
5fd8380b MN |
156 | va_copy(va, *va_keep); |
157 | event->vap = &va; | |
cb8c5720 CLG |
158 | appender->append(appender, event); |
159 | appender = appender->next; | |
5fd8380b | 160 | va_end(va); |
cb8c5720 CLG |
161 | } |
162 | } | |
163 | ||
164 | static inline void | |
165 | __lxc_log(const struct lxc_log_category* category, | |
5fd8380b | 166 | struct lxc_log_event* event) |
cb8c5720 CLG |
167 | { |
168 | while (category) { | |
169 | __lxc_log_append(category->appender, event); | |
170 | category = category->parent; | |
171 | } | |
172 | } | |
173 | ||
174 | /* | |
175 | * Helper macro to define log fonctions. | |
176 | */ | |
177 | #define lxc_log_priority_define(acategory, PRIORITY) \ | |
178 | \ | |
179 | static inline void LXC_##PRIORITY(struct lxc_log_locinfo *, \ | |
180 | const char *, ...) __attribute__ ((format (printf, 2, 3))); \ | |
181 | \ | |
182 | static inline void LXC_##PRIORITY(struct lxc_log_locinfo* locinfo, \ | |
183 | const char* format, ...) \ | |
184 | { \ | |
185 | if (lxc_log_priority_is_enabled(acategory, \ | |
186 | LXC_LOG_PRIORITY_##PRIORITY)) { \ | |
187 | struct lxc_log_event evt = { \ | |
188 | .category = (acategory)->name, \ | |
189 | .priority = LXC_LOG_PRIORITY_##PRIORITY, \ | |
190 | .fmt = format, \ | |
191 | .locinfo = locinfo \ | |
192 | }; \ | |
5fd8380b | 193 | va_list va_ref; \ |
cb8c5720 CLG |
194 | \ |
195 | gettimeofday(&evt.timestamp, NULL); \ | |
196 | \ | |
5fd8380b MN |
197 | va_start(va_ref, format); \ |
198 | evt.vap = &va_ref; \ | |
cb8c5720 | 199 | __lxc_log(acategory, &evt); \ |
5fd8380b | 200 | va_end(va_ref); \ |
cb8c5720 CLG |
201 | } \ |
202 | } | |
203 | ||
204 | /* | |
205 | * Helper macro to define and use static categories. | |
206 | */ | |
207 | #define lxc_log_category_define(name, parent) \ | |
208 | extern struct lxc_log_category lxc_log_category_##parent; \ | |
209 | struct lxc_log_category lxc_log_category_##name = { \ | |
210 | #name, \ | |
211 | LXC_LOG_PRIORITY_NOTSET, \ | |
212 | NULL, \ | |
213 | &lxc_log_category_##parent \ | |
214 | }; | |
215 | ||
216 | #define lxc_log_define(name, parent) \ | |
217 | lxc_log_category_define(name, parent) \ | |
218 | \ | |
219 | lxc_log_priority_define(&lxc_log_category_##name, TRACE) \ | |
220 | lxc_log_priority_define(&lxc_log_category_##name, DEBUG) \ | |
221 | lxc_log_priority_define(&lxc_log_category_##name, INFO) \ | |
222 | lxc_log_priority_define(&lxc_log_category_##name, NOTICE) \ | |
223 | lxc_log_priority_define(&lxc_log_category_##name, WARN) \ | |
224 | lxc_log_priority_define(&lxc_log_category_##name, ERROR) \ | |
225 | lxc_log_priority_define(&lxc_log_category_##name, CRIT) \ | |
226 | lxc_log_priority_define(&lxc_log_category_##name, ALERT) \ | |
227 | lxc_log_priority_define(&lxc_log_category_##name, FATAL) | |
228 | ||
229 | #define lxc_log_category_priority(name) \ | |
230 | (lxc_log_priority_to_string(lxc_log_category_##name.priority)) | |
231 | ||
232 | /* | |
233 | * top categories | |
234 | */ | |
235 | extern struct lxc_log_category lxc_log_category_lxc; | |
236 | ||
237 | #define TRACE(format, ...) do { \ | |
238 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
239 | LXC_TRACE(&locinfo, format, ##__VA_ARGS__); \ | |
240 | } while (0) | |
241 | ||
242 | #define DEBUG(format, ...) do { \ | |
243 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
244 | LXC_DEBUG(&locinfo, format, ##__VA_ARGS__); \ | |
245 | } while (0) | |
246 | ||
247 | #define INFO(format, ...) do { \ | |
248 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
249 | LXC_INFO(&locinfo, format, ##__VA_ARGS__); \ | |
250 | } while (0) | |
251 | ||
252 | #define NOTICE(format, ...) do { \ | |
253 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
254 | LXC_NOTICE(&locinfo, format, ##__VA_ARGS__); \ | |
255 | } while (0) | |
256 | ||
257 | #define WARN(format, ...) do { \ | |
258 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
259 | LXC_WARN(&locinfo, format, ##__VA_ARGS__); \ | |
260 | } while (0) | |
261 | ||
262 | #define ERROR(format, ...) do { \ | |
263 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
264 | LXC_ERROR(&locinfo, format, ##__VA_ARGS__); \ | |
265 | } while (0) | |
266 | ||
267 | #define CRIT(format, ...) do { \ | |
268 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
269 | LXC_CRIT(&locinfo, format, ##__VA_ARGS__); \ | |
270 | } while (0) | |
271 | ||
272 | #define ALERT(format, ...) do { \ | |
273 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
274 | LXC_ALERT(&locinfo, format, ##__VA_ARGS__); \ | |
275 | } while (0) | |
276 | ||
277 | #define FATAL(format, ...) do { \ | |
278 | struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \ | |
279 | LXC_FATAL(&locinfo, format, ##__VA_ARGS__); \ | |
280 | } while (0) | |
281 | ||
282 | ||
283 | ||
284 | #define SYSERROR(format, ...) do { \ | |
69c3910d | 285 | ERROR("%s - " format, strerror(errno), ##__VA_ARGS__); \ |
cb8c5720 CLG |
286 | } while (0) |
287 | ||
641c20a6 CLG |
288 | extern int lxc_log_fd; |
289 | ||
51cab631 | 290 | extern int lxc_log_init(const char *file, const char *priority, |
441e4963 | 291 | const char *prefix, int quiet); |
641c20a6 CLG |
292 | |
293 | extern void lxc_log_setprefix(const char *a_prefix); | |
0ad19a3f | 294 | #endif |