]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/log.h
2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Daniel Lezcano <daniel.lezcano at free.fr>
8 * Cedric Le Goater <legoater@free.fr>
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
40 #define O_CLOEXEC 02000000
43 #ifndef F_DUPFD_CLOEXEC
44 #define F_DUPFD_CLOEXEC 1030
47 #define LXC_LOG_PREFIX_SIZE 32
48 #define LXC_LOG_BUFFER_SIZE 4096
50 /* This attribute is required to silence clang warnings */
52 #define ATTR_UNUSED __attribute__ ((unused))
57 /* predefined lxc log priorities. */
71 /* location information of the logging event */
72 struct lxc_log_locinfo
{
78 #define LXC_LOG_LOCINFO_INIT \
79 { .file = __FILE__, .func = __func__, .line = __LINE__ }
81 /* brief logging event object */
82 struct lxc_log_event
{
85 struct timespec timestamp
;
86 struct lxc_log_locinfo
*locinfo
;
91 /* log appender object */
92 struct lxc_log_appender
{
94 int (*append
)(const struct lxc_log_appender
*, struct lxc_log_event
*);
97 * appenders can be stacked
99 struct lxc_log_appender
*next
;
102 /* log category object */
103 struct lxc_log_category
{
106 struct lxc_log_appender
*appender
;
107 const struct lxc_log_category
*parent
;
111 extern int lxc_log_use_global_fd
;
115 * Returns true if the chained priority is equal to or higher than
118 static inline int lxc_log_priority_is_enabled(const struct lxc_log_category
*category
,
121 while (category
->priority
== LXC_LOG_LEVEL_NOTSET
&& category
->parent
)
122 category
= category
->parent
;
124 int cmp_prio
= category
->priority
;
126 if (!lxc_log_use_global_fd
&& current_config
&&
127 current_config
->loglevel
!= LXC_LOG_LEVEL_NOTSET
)
128 cmp_prio
= current_config
->loglevel
;
131 return priority
>= cmp_prio
;
135 * converts a priority to a literal string
137 static inline const char *lxc_log_priority_to_string(int priority
)
140 case LXC_LOG_LEVEL_TRACE
:
142 case LXC_LOG_LEVEL_DEBUG
:
144 case LXC_LOG_LEVEL_INFO
:
146 case LXC_LOG_LEVEL_NOTICE
:
148 case LXC_LOG_LEVEL_WARN
:
150 case LXC_LOG_LEVEL_ERROR
:
152 case LXC_LOG_LEVEL_CRIT
:
154 case LXC_LOG_LEVEL_ALERT
:
156 case LXC_LOG_LEVEL_FATAL
:
163 static inline const char *lxc_syslog_priority_to_string(int priority
)
190 * converts a literal priority to an int
192 static inline int lxc_log_priority_to_int(const char *name
)
194 if (strcasecmp("TRACE", name
) == 0)
195 return LXC_LOG_LEVEL_TRACE
;
196 if (strcasecmp("DEBUG", name
) == 0)
197 return LXC_LOG_LEVEL_DEBUG
;
198 if (strcasecmp("INFO", name
) == 0)
199 return LXC_LOG_LEVEL_INFO
;
200 if (strcasecmp("NOTICE", name
) == 0)
201 return LXC_LOG_LEVEL_NOTICE
;
202 if (strcasecmp("WARN", name
) == 0)
203 return LXC_LOG_LEVEL_WARN
;
204 if (strcasecmp("ERROR", name
) == 0)
205 return LXC_LOG_LEVEL_ERROR
;
206 if (strcasecmp("CRIT", name
) == 0)
207 return LXC_LOG_LEVEL_CRIT
;
208 if (strcasecmp("ALERT", name
) == 0)
209 return LXC_LOG_LEVEL_ALERT
;
210 if (strcasecmp("FATAL", name
) == 0)
211 return LXC_LOG_LEVEL_FATAL
;
213 return LXC_LOG_LEVEL_NOTSET
;
216 static inline int lxc_syslog_priority_to_int(const char *name
)
218 if (strcasecmp("daemon", name
) == 0)
220 if (strcasecmp("local0", name
) == 0)
222 if (strcasecmp("local1", name
) == 0)
224 if (strcasecmp("local2", name
) == 0)
226 if (strcasecmp("local3", name
) == 0)
228 if (strcasecmp("local4", name
) == 0)
230 if (strcasecmp("local5", name
) == 0)
232 if (strcasecmp("local6", name
) == 0)
234 if (strcasecmp("local7", name
) == 0)
240 static inline void __lxc_log_append(const struct lxc_log_appender
*appender
,
241 struct lxc_log_event
*event
)
244 va_list *va_keep
= event
->vap
;
247 va_copy(va
, *va_keep
);
249 appender
->append(appender
, event
);
250 appender
= appender
->next
;
255 static inline void __lxc_log(const struct lxc_log_category
*category
,
256 struct lxc_log_event
*event
)
259 __lxc_log_append(category
->appender
, event
);
260 category
= category
->parent
;
265 * Helper macro to define log functions.
267 #define lxc_log_priority_define(acategory, LEVEL) \
269 ATTR_UNUSED __attribute__ ((format (printf, 2, 3))) \
270 static inline void LXC_##LEVEL(struct lxc_log_locinfo *, const char *, ...); \
272 ATTR_UNUSED static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
273 const char* format, ...) \
275 if (lxc_log_priority_is_enabled(acategory, LXC_LOG_LEVEL_##LEVEL)) { \
278 struct lxc_log_event evt = { \
279 .category = (acategory)->name, \
280 .priority = LXC_LOG_LEVEL_##LEVEL, \
285 /* clock_gettime() is explicitly marked as MT-Safe \
286 * without restrictions. So let's use it for our \
289 saved_errno = errno; \
290 (void)clock_gettime(CLOCK_REALTIME, &evt.timestamp); \
292 va_start(va_ref, format); \
294 __lxc_log(acategory, &evt); \
296 errno = saved_errno; \
301 * Helper macro to define and use static categories.
303 #define lxc_log_category_define(name, parent) \
304 extern struct lxc_log_category lxc_log_category_##parent; \
305 struct lxc_log_category lxc_log_category_##name = { \
307 LXC_LOG_LEVEL_NOTSET, \
309 &lxc_log_category_##parent \
312 #define lxc_log_define(name, parent) \
313 lxc_log_category_define(name, parent) \
315 lxc_log_priority_define(&lxc_log_category_##name, TRACE) \
316 lxc_log_priority_define(&lxc_log_category_##name, DEBUG) \
317 lxc_log_priority_define(&lxc_log_category_##name, INFO) \
318 lxc_log_priority_define(&lxc_log_category_##name, NOTICE) \
319 lxc_log_priority_define(&lxc_log_category_##name, WARN) \
320 lxc_log_priority_define(&lxc_log_category_##name, ERROR) \
321 lxc_log_priority_define(&lxc_log_category_##name, CRIT) \
322 lxc_log_priority_define(&lxc_log_category_##name, ALERT) \
323 lxc_log_priority_define(&lxc_log_category_##name, FATAL)
325 #define lxc_log_category_priority(name) \
326 (lxc_log_priority_to_string(lxc_log_category_##name.priority))
329 * Helper macro to define errno string.
332 #ifndef HAVE_DECL_STRERROR_R
333 #ifdef STRERROR_R_CHAR_P
334 char *strerror_r(int errnum
, char *buf
, size_t buflen
);
336 int strerror_r(int errnum
, char *buf
, size_t buflen
);
340 #ifdef STRERROR_R_CHAR_P
341 #define lxc_log_strerror_r \
342 char errno_buf[PATH_MAX / 2] = {"Failed to get errno string"}; \
345 int saved_errno = errno; \
346 ptr = strerror_r(errno, errno_buf, sizeof(errno_buf)); \
347 errno = saved_errno; \
352 #define lxc_log_strerror_r \
353 char errno_buf[PATH_MAX / 2] = {"Failed to get errno string"}; \
354 char *ptr = errno_buf; \
356 int saved_errno = errno; \
357 (void)strerror_r(errno, errno_buf, sizeof(errno_buf)); \
358 errno = saved_errno; \
361 #elif ENFORCE_THREAD_SAFETY
362 #error ENFORCE_THREAD_SAFETY was set but cannot be guaranteed
364 #define lxc_log_strerror_r \
367 ptr = strerror(errno); \
374 #define TRACE(format, ...) do { \
375 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
376 LXC_TRACE(&locinfo, format, ##__VA_ARGS__); \
379 #define DEBUG(format, ...) do { \
380 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
381 LXC_DEBUG(&locinfo, format, ##__VA_ARGS__); \
384 #define INFO(format, ...) do { \
385 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
386 LXC_INFO(&locinfo, format, ##__VA_ARGS__); \
389 #define NOTICE(format, ...) do { \
390 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
391 LXC_NOTICE(&locinfo, format, ##__VA_ARGS__); \
394 #define WARN(format, ...) do { \
395 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
396 LXC_WARN(&locinfo, format, ##__VA_ARGS__); \
399 #define ERROR(format, ...) do { \
400 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
401 LXC_ERROR(&locinfo, format, ##__VA_ARGS__); \
404 #define CRIT(format, ...) do { \
405 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
406 LXC_CRIT(&locinfo, format, ##__VA_ARGS__); \
409 #define ALERT(format, ...) do { \
410 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
411 LXC_ALERT(&locinfo, format, ##__VA_ARGS__); \
414 #define FATAL(format, ...) do { \
415 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
416 LXC_FATAL(&locinfo, format, ##__VA_ARGS__); \
419 #define SYSTRACE(format, ...) \
421 lxc_log_strerror_r; \
422 TRACE("%s - " format, ptr, ##__VA_ARGS__); \
425 #define SYSDEBUG(format, ...) \
427 lxc_log_strerror_r; \
428 DEBUG("%s - " format, ptr, ##__VA_ARGS__); \
431 #define SYSINFO(format, ...) \
433 lxc_log_strerror_r; \
434 INFO("%s - " format, ptr, ##__VA_ARGS__); \
437 #define SYSNOTICE(format, ...) \
439 lxc_log_strerror_r; \
440 NOTICE("%s - " format, ptr, ##__VA_ARGS__); \
443 #define SYSWARN(format, ...) \
445 lxc_log_strerror_r; \
446 WARN("%s - " format, ptr, ##__VA_ARGS__); \
449 #define SYSERROR(format, ...) \
451 lxc_log_strerror_r; \
452 ERROR("%s - " format, ptr, ##__VA_ARGS__); \
455 #define CMD_SYSERROR(format, ...) \
457 lxc_log_strerror_r; \
458 fprintf(stderr, "%s - " format, ptr, ##__VA_ARGS__); \
461 #define CMD_SYSINFO(format, ...) \
463 lxc_log_strerror_r; \
464 printf("%s - " format, ptr, ##__VA_ARGS__); \
467 extern int lxc_log_fd
;
469 extern int lxc_log_syslog(int facility
);
470 extern void lxc_log_enable_syslog(void);
471 extern int lxc_log_set_level(int *dest
, int level
);
472 extern int lxc_log_get_level(void);
473 extern bool lxc_log_has_valid_level(void);
474 extern int lxc_log_set_file(int *fd
, const char *fname
);
475 extern const char *lxc_log_get_file(void);
476 extern void lxc_log_set_prefix(const char *prefix
);
477 extern const char *lxc_log_get_prefix(void);
478 extern void lxc_log_options_no_override(void);