]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/log.h
4cb0b5795f8ff58bb9bb293bb701461e2c1a7769
1 /* SPDX-License-Identifier: LGPL-2.1+ */
23 #define O_CLOEXEC 02000000
26 #ifndef F_DUPFD_CLOEXEC
27 #define F_DUPFD_CLOEXEC 1030
30 #define LXC_LOG_PREFIX_SIZE 32
31 #define LXC_LOG_BUFFER_SIZE 4096
33 /* predefined lxc log priorities. */
47 /* location information of the logging event */
48 struct lxc_log_locinfo
{
54 #define LXC_LOG_LOCINFO_INIT \
55 { .file = __FILE__, .func = __func__, .line = __LINE__ }
57 /* brief logging event object */
58 struct lxc_log_event
{
61 struct timespec timestamp
;
62 struct lxc_log_locinfo
*locinfo
;
67 /* log appender object */
68 struct lxc_log_appender
{
70 int (*append
)(const struct lxc_log_appender
*, struct lxc_log_event
*);
73 * appenders can be stacked
75 struct lxc_log_appender
*next
;
78 /* log category object */
79 struct lxc_log_category
{
82 struct lxc_log_appender
*appender
;
83 const struct lxc_log_category
*parent
;
87 extern int lxc_log_use_global_fd
;
91 * Returns true if the chained priority is equal to or higher than
94 static inline int lxc_log_priority_is_enabled(const struct lxc_log_category
*category
,
97 while (category
->priority
== LXC_LOG_LEVEL_NOTSET
&& category
->parent
)
98 category
= category
->parent
;
100 int cmp_prio
= category
->priority
;
102 if (!lxc_log_use_global_fd
&& current_config
&&
103 current_config
->loglevel
!= LXC_LOG_LEVEL_NOTSET
)
104 cmp_prio
= current_config
->loglevel
;
107 return priority
>= cmp_prio
;
111 * converts a priority to a literal string
113 static inline const char *lxc_log_priority_to_string(int priority
)
116 case LXC_LOG_LEVEL_TRACE
:
118 case LXC_LOG_LEVEL_DEBUG
:
120 case LXC_LOG_LEVEL_INFO
:
122 case LXC_LOG_LEVEL_NOTICE
:
124 case LXC_LOG_LEVEL_WARN
:
126 case LXC_LOG_LEVEL_ERROR
:
128 case LXC_LOG_LEVEL_CRIT
:
130 case LXC_LOG_LEVEL_ALERT
:
132 case LXC_LOG_LEVEL_FATAL
:
139 static inline const char *lxc_syslog_priority_to_string(int priority
)
166 * converts a literal priority to an int
168 static inline int lxc_log_priority_to_int(const char *name
)
170 if (strcasecmp("TRACE", name
) == 0)
171 return LXC_LOG_LEVEL_TRACE
;
172 if (strcasecmp("DEBUG", name
) == 0)
173 return LXC_LOG_LEVEL_DEBUG
;
174 if (strcasecmp("INFO", name
) == 0)
175 return LXC_LOG_LEVEL_INFO
;
176 if (strcasecmp("NOTICE", name
) == 0)
177 return LXC_LOG_LEVEL_NOTICE
;
178 if (strcasecmp("WARN", name
) == 0)
179 return LXC_LOG_LEVEL_WARN
;
180 if (strcasecmp("ERROR", name
) == 0)
181 return LXC_LOG_LEVEL_ERROR
;
182 if (strcasecmp("CRIT", name
) == 0)
183 return LXC_LOG_LEVEL_CRIT
;
184 if (strcasecmp("ALERT", name
) == 0)
185 return LXC_LOG_LEVEL_ALERT
;
186 if (strcasecmp("FATAL", name
) == 0)
187 return LXC_LOG_LEVEL_FATAL
;
189 return LXC_LOG_LEVEL_NOTSET
;
192 static inline int lxc_syslog_priority_to_int(const char *name
)
194 if (strcasecmp("daemon", name
) == 0)
196 if (strcasecmp("local0", name
) == 0)
198 if (strcasecmp("local1", name
) == 0)
200 if (strcasecmp("local2", name
) == 0)
202 if (strcasecmp("local3", name
) == 0)
204 if (strcasecmp("local4", name
) == 0)
206 if (strcasecmp("local5", name
) == 0)
208 if (strcasecmp("local6", name
) == 0)
210 if (strcasecmp("local7", name
) == 0)
216 static inline void __lxc_log_append(const struct lxc_log_appender
*appender
,
217 struct lxc_log_event
*event
)
220 va_list *va_keep
= event
->vap
;
223 va_copy(va
, *va_keep
);
225 appender
->append(appender
, event
);
226 appender
= appender
->next
;
231 static inline void __lxc_log(const struct lxc_log_category
*category
,
232 struct lxc_log_event
*event
)
235 __lxc_log_append(category
->appender
, event
);
236 category
= category
->parent
;
241 * Helper macro to define log functions.
243 #define lxc_log_priority_define(acategory, LEVEL) \
245 __lxc_unused __attribute__ ((format (printf, 2, 3))) \
246 static inline void LXC_##LEVEL(struct lxc_log_locinfo *, const char *, ...); \
248 __lxc_unused static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
249 const char* format, ...) \
251 if (lxc_log_priority_is_enabled(acategory, LXC_LOG_LEVEL_##LEVEL)) { \
254 struct lxc_log_event evt = { \
255 .category = (acategory)->name, \
256 .priority = LXC_LOG_LEVEL_##LEVEL, \
261 /* clock_gettime() is explicitly marked as MT-Safe \
262 * without restrictions. So let's use it for our \
265 saved_errno = errno; \
266 (void)clock_gettime(CLOCK_REALTIME, &evt.timestamp); \
268 va_start(va_ref, format); \
270 __lxc_log(acategory, &evt); \
272 errno = saved_errno; \
277 * Helper macro to define and use static categories.
279 #define lxc_log_category_define(name, parent) \
280 extern struct lxc_log_category lxc_log_category_##parent; \
281 struct lxc_log_category lxc_log_category_##name = { \
283 LXC_LOG_LEVEL_NOTSET, \
285 &lxc_log_category_##parent \
288 #define lxc_log_define(name, parent) \
289 lxc_log_category_define(name, parent) \
291 lxc_log_priority_define(&lxc_log_category_##name, TRACE) \
292 lxc_log_priority_define(&lxc_log_category_##name, DEBUG) \
293 lxc_log_priority_define(&lxc_log_category_##name, INFO) \
294 lxc_log_priority_define(&lxc_log_category_##name, NOTICE) \
295 lxc_log_priority_define(&lxc_log_category_##name, WARN) \
296 lxc_log_priority_define(&lxc_log_category_##name, ERROR) \
297 lxc_log_priority_define(&lxc_log_category_##name, CRIT) \
298 lxc_log_priority_define(&lxc_log_category_##name, ALERT) \
299 lxc_log_priority_define(&lxc_log_category_##name, FATAL)
301 #define lxc_log_category_priority(name) \
302 (lxc_log_priority_to_string(lxc_log_category_##name.priority))
305 * Helper macro to define errno string.
308 #ifndef HAVE_DECL_STRERROR_R
309 #ifdef STRERROR_R_CHAR_P
310 char *strerror_r(int errnum
, char *buf
, size_t buflen
);
312 int strerror_r(int errnum
, char *buf
, size_t buflen
);
316 #ifdef STRERROR_R_CHAR_P
317 #define lxc_log_strerror_r \
318 char errno_buf[PATH_MAX / 2] = {"Failed to get errno string"}; \
321 int __saved_errno = errno; \
322 ptr = strerror_r(errno, errno_buf, sizeof(errno_buf)); \
323 errno = __saved_errno; \
328 #define lxc_log_strerror_r \
329 char errno_buf[PATH_MAX / 2] = {"Failed to get errno string"}; \
330 char *ptr = errno_buf; \
332 int __saved_errno = errno; \
333 (void)strerror_r(errno, errno_buf, sizeof(errno_buf)); \
334 errno = __saved_errno; \
337 #elif ENFORCE_THREAD_SAFETY
338 #error ENFORCE_THREAD_SAFETY was set but cannot be guaranteed
340 #define lxc_log_strerror_r \
343 ptr = strerror(errno); \
350 #define TRACE(format, ...) do { \
351 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
352 LXC_TRACE(&locinfo, format, ##__VA_ARGS__); \
355 #define DEBUG(format, ...) do { \
356 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
357 LXC_DEBUG(&locinfo, format, ##__VA_ARGS__); \
360 #define INFO(format, ...) do { \
361 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
362 LXC_INFO(&locinfo, format, ##__VA_ARGS__); \
365 #define NOTICE(format, ...) do { \
366 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
367 LXC_NOTICE(&locinfo, format, ##__VA_ARGS__); \
370 #define WARN(format, ...) do { \
371 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
372 LXC_WARN(&locinfo, format, ##__VA_ARGS__); \
375 #define ERROR(format, ...) do { \
376 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
377 LXC_ERROR(&locinfo, format, ##__VA_ARGS__); \
380 #define CRIT(format, ...) do { \
381 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
382 LXC_CRIT(&locinfo, format, ##__VA_ARGS__); \
385 #define ALERT(format, ...) do { \
386 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
387 LXC_ALERT(&locinfo, format, ##__VA_ARGS__); \
390 #define FATAL(format, ...) do { \
391 struct lxc_log_locinfo locinfo = LXC_LOG_LOCINFO_INIT; \
392 LXC_FATAL(&locinfo, format, ##__VA_ARGS__); \
395 #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD
396 #define SYSTRACE(format, ...) \
397 TRACE("%m - " format, ##__VA_ARGS__)
399 #define SYSTRACE(format, ...) \
401 lxc_log_strerror_r; \
402 TRACE("%s - " format, ptr, ##__VA_ARGS__); \
406 #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD
407 #define SYSDEBUG(format, ...) \
408 DEBUG("%m - " format, ##__VA_ARGS__)
410 #define SYSDEBUG(format, ...) \
412 lxc_log_strerror_r; \
413 DEBUG("%s - " format, ptr, ##__VA_ARGS__); \
418 #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD
419 #define SYSINFO(format, ...) \
420 INFO("%m - " format, ##__VA_ARGS__)
422 #define SYSINFO(format, ...) \
424 lxc_log_strerror_r; \
425 INFO("%s - " format, ptr, ##__VA_ARGS__); \
429 #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD
430 #define SYSNOTICE(format, ...) \
431 NOTICE("%m - " format, ##__VA_ARGS__)
433 #define SYSNOTICE(format, ...) \
435 lxc_log_strerror_r; \
436 NOTICE("%s - " format, ptr, ##__VA_ARGS__); \
440 #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD
441 #define SYSWARN(format, ...) \
442 WARN("%m - " format, ##__VA_ARGS__)
444 #define SYSWARN(format, ...) \
446 lxc_log_strerror_r; \
447 WARN("%s - " format, ptr, ##__VA_ARGS__); \
451 #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD
452 #define SYSERROR(format, ...) \
453 ERROR("%m - " format, ##__VA_ARGS__)
455 #define SYSERROR(format, ...) \
457 lxc_log_strerror_r; \
458 ERROR("%s - " format, ptr, ##__VA_ARGS__); \
462 #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD
463 #define CMD_SYSERROR(format, ...) \
464 fprintf(stderr, "%s: %d: %s - %m - " format "\n", __FILE__, __LINE__, \
465 __func__, ##__VA_ARGS__);
467 #define CMD_SYSERROR(format, ...) \
469 lxc_log_strerror_r; \
470 fprintf(stderr, "%s: %d: %s - %s - " format "\n", __FILE__, \
471 __LINE__, __func__, ptr, ##__VA_ARGS__); \
475 #if HAVE_M_FORMAT && !ENABLE_COVERITY_BUILD
476 #define CMD_SYSINFO(format, ...) \
477 printf("%s: %d: %s - %m - " format "\n", __FILE__, __LINE__, __func__, \
480 #define CMD_SYSINFO(format, ...) \
482 lxc_log_strerror_r; \
483 printf("%s: %d: %s - %s - " format "\n", __FILE__, __LINE__, \
484 __func__, ptr, ##__VA_ARGS__); \
488 #define log_error_errno(__ret__, __errno__, format, ...) \
490 typeof(__ret__) __internal_ret__ = (__ret__); \
491 errno = (__errno__); \
492 SYSERROR(format, ##__VA_ARGS__); \
496 #define log_error(__ret__, format, ...) \
498 typeof(__ret__) __internal_ret__ = (__ret__); \
499 ERROR(format, ##__VA_ARGS__); \
503 #define log_trace_errno(__ret__, __errno__, format, ...) \
505 typeof(__ret__) __internal_ret__ = (__ret__); \
507 SYSTRACE(format, ##__VA_ARGS__); \
511 #define log_trace(__ret__, format, ...) \
513 typeof(__ret__) __internal_ret__ = (__ret__); \
514 TRACE(format, ##__VA_ARGS__); \
518 #define log_warn_errno(__ret__, __errno__, format, ...) \
520 typeof(__ret__) __internal_ret__ = (__ret__); \
522 SYSWARN(format, ##__VA_ARGS__); \
526 #define log_warn(__ret__, format, ...) \
528 typeof(__ret__) __internal_ret__ = (__ret__); \
529 WARN(format, ##__VA_ARGS__); \
533 #define log_debug_errno(__ret__, __errno__, format, ...) \
535 typeof(__ret__) __internal_ret__ = (__ret__); \
537 SYSDEBUG(format, ##__VA_ARGS__); \
541 #define log_debug(__ret__, format, ...) \
543 typeof(__ret__) __internal_ret__ = (__ret__); \
544 DEBUG(format, ##__VA_ARGS__); \
548 #define log_info_errno(__ret__, __errno__, format, ...) \
550 typeof(__ret__) __internal_ret__ = (__ret__); \
552 SYSINFO(format, ##__VA_ARGS__); \
556 #define log_info(__ret__, format, ...) \
558 typeof(__ret__) __internal_ret__ = (__ret__); \
559 INFO(format, ##__VA_ARGS__); \
563 extern int lxc_log_fd
;
565 extern int lxc_log_syslog(int facility
);
566 extern void lxc_log_enable_syslog(void);
567 extern int lxc_log_set_level(int *dest
, int level
);
568 extern int lxc_log_get_level(void);
569 extern bool lxc_log_has_valid_level(void);
570 extern int lxc_log_set_file(int *fd
, const char *fname
);
571 extern const char *lxc_log_get_file(void);
572 extern void lxc_log_set_prefix(const char *prefix
);
573 extern const char *lxc_log_get_prefix(void);
574 extern void lxc_log_options_no_override(void);