1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
| | /* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright (c) 2022 Red Hat GmbH
* Author: Stefano Brivio <sbrivio@redhat.com>
*/
#ifndef LOG_H
#define LOG_H
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <syslog.h>
/* This would make more sense in util.h, but because we use it in die(), that
* would cause awkward circular reference problems.
*/
void passt_exit(int status) __attribute__((noreturn));
#define LOGFILE_SIZE_DEFAULT (1024 * 1024UL)
#define LOGFILE_CUT_RATIO 30 /* When full, cut ~30% size */
#define LOGFILE_SIZE_MIN (5UL * MAX(BUFSIZ, PAGE_SIZE))
void vlogmsg(bool newline, bool cont, int pri, const char *format, va_list ap);
void logmsg(bool newline, bool cont, int pri, const char *format, ...)
__attribute__((format(printf, 4, 5)));
void logmsg_perror(int pri, const char *format, ...)
__attribute__((format(printf, 2, 3)));
#define err(...) logmsg(true, false, LOG_ERR, __VA_ARGS__)
#define warn(...) logmsg(true, false, LOG_WARNING, __VA_ARGS__)
#define info(...) logmsg(true, false, LOG_INFO, __VA_ARGS__)
#define debug(...) logmsg(true, false, LOG_DEBUG, __VA_ARGS__)
#define err_perror(...) logmsg_perror( LOG_ERR, __VA_ARGS__)
#define warn_perror(...) logmsg_perror( LOG_WARNING, __VA_ARGS__)
#define info_perror(...) logmsg_perror( LOG_INFO, __VA_ARGS__)
#define debug_perror(...) logmsg_perror( LOG_DEBUG, __VA_ARGS__)
#define die(...) \
do { \
err(__VA_ARGS__); \
passt_exit(EXIT_FAILURE); \
} while (0)
#define die_perror(...) \
do { \
err_perror(__VA_ARGS__); \
passt_exit(EXIT_FAILURE); \
} while (0)
#define LOG_RATELIMIT_BURST 5 /* Max messages per window per call site */
#define LOG_RATELIMIT_INTERVAL 1 /* Default rate limit window in seconds */
/**
* logmsg_ratelimit() - Rate-limited log message
* @fn: Logging function
* @now: current timestamp
* @intv: Minimum interval in seconds between allowed messages
*/
#define logmsg_ratelimit(fn, now, intv, ...) \
do { \
static time_t _rl_last; \
static unsigned int _rl_printed; \
static unsigned int _rl_suppressed; \
\
if ((now)->tv_sec - _rl_last > (intv)) { \
if (_rl_suppressed) \
fn("(suppressed %u similar messages)", \
_rl_suppressed); \
_rl_last = (now)->tv_sec; \
_rl_printed = 0; \
_rl_suppressed = 0; \
} \
\
if (_rl_printed < LOG_RATELIMIT_BURST) { \
fn(__VA_ARGS__); \
_rl_printed++; \
} else { \
_rl_suppressed++; \
} \
} while (0)
#define err_ratelimit(now, intv, ...) \
logmsg_ratelimit(err, now, intv, __VA_ARGS__)
#define warn_ratelimit(now, intv, ...) \
logmsg_ratelimit(warn, now, intv, __VA_ARGS__)
#define info_ratelimit(now, intv, ...) \
logmsg_ratelimit(info, now, intv, __VA_ARGS__)
#define debug_ratelimit(now, intv, ...) \
logmsg_ratelimit(debug, now, intv, __VA_ARGS__)
extern int log_file;
extern int log_trace;
extern bool log_conf_parsed;
extern bool log_stderr;
extern struct timespec log_start;
void trace_init(int enable);
#define trace(...) \
do { \
if (log_trace) \
debug(__VA_ARGS__); \
} while (0)
void __openlog(const char *ident, int option, int facility);
void logfile_init(const char *name, const char *path, size_t size);
void __setlogmask(int mask);
#endif /* LOG_H */
|