Coverage Report

Created: 2024-01-20 12:42

/src/systemd/src/basic/log.h
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
#pragma once
3
4
#include <stdarg.h>
5
#include <stdbool.h>
6
#include <stdlib.h>
7
#include <string.h>
8
#include <syslog.h>
9
10
#include "macro.h"
11
#include "ratelimit.h"
12
13
/* Some structures we reference but don't want to pull in headers for */
14
struct iovec;
15
struct signalfd_siginfo;
16
17
typedef enum LogTarget{
18
        LOG_TARGET_CONSOLE,
19
        LOG_TARGET_CONSOLE_PREFIXED,
20
        LOG_TARGET_KMSG,
21
        LOG_TARGET_JOURNAL,
22
        LOG_TARGET_JOURNAL_OR_KMSG,
23
        LOG_TARGET_SYSLOG,
24
        LOG_TARGET_SYSLOG_OR_KMSG,
25
        LOG_TARGET_AUTO, /* console if stderr is not journal, JOURNAL_OR_KMSG otherwise */
26
        LOG_TARGET_NULL,
27
        _LOG_TARGET_MAX,
28
        _LOG_TARGET_INVALID = -EINVAL,
29
} LogTarget;
30
31
/* This log level disables logging completely. It can only be passed to log_set_max_level() and cannot be
32
 * used a regular log level. */
33
#define LOG_NULL (LOG_EMERG - 1)
34
35
/* Note to readers: << and >> have lower precedence (are evaluated earlier) than & and | */
36
#define SYNTHETIC_ERRNO(num)                (1 << 30 | (num))
37
#define IS_SYNTHETIC_ERRNO(val)             ((val) >> 30 & 1)
38
462k
#define ERRNO_VALUE(val)                    (abs(val) & ~(1 << 30))
39
40
/* The callback function to be invoked when syntax warnings are seen
41
 * in the unit files. */
42
typedef void (*log_syntax_callback_t)(const char *unit, int level, void *userdata);
43
void set_log_syntax_callback(log_syntax_callback_t cb, void *userdata);
44
45
0
static inline void clear_log_syntax_callback(dummy_t *dummy) {
46
0
          set_log_syntax_callback(/* cb= */ NULL, /* userdata= */ NULL);
47
0
}
Unexecuted instantiation: fuzz-link-parser.c:clear_log_syntax_callback
Unexecuted instantiation: link-config.c:clear_log_syntax_callback
Unexecuted instantiation: link-config-gperf.c:clear_log_syntax_callback
48
49
const char *log_target_to_string(LogTarget target) _const_;
50
LogTarget log_target_from_string(const char *s) _pure_;
51
void log_set_target(LogTarget target);
52
int log_set_target_from_string(const char *e);
53
LogTarget log_get_target(void) _pure_;
54
55
void log_set_max_level(int level);
56
int log_set_max_level_from_string(const char *e);
57
int log_get_max_level(void) _pure_;
58
59
void log_set_facility(int facility);
60
61
void log_show_color(bool b);
62
bool log_get_show_color(void) _pure_;
63
void log_show_location(bool b);
64
bool log_get_show_location(void) _pure_;
65
void log_show_time(bool b);
66
bool log_get_show_time(void) _pure_;
67
void log_show_tid(bool b);
68
bool log_get_show_tid(void) _pure_;
69
70
int log_show_color_from_string(const char *e);
71
int log_show_location_from_string(const char *e);
72
int log_show_time_from_string(const char *e);
73
int log_show_tid_from_string(const char *e);
74
75
/* Functions below that open and close logs or configure logging based on the
76
 * environment should not be called from library code — this is always a job
77
 * for the application itself. */
78
79
assert_cc(STRLEN(__FILE__) > STRLEN(RELATIVE_SOURCE_PATH) + 1);
80
0
#define PROJECT_FILE (&__FILE__[STRLEN(RELATIVE_SOURCE_PATH) + 1])
81
82
int log_open(void);
83
void log_close(void);
84
void log_forget_fds(void);
85
86
void log_parse_environment_variables(void);
87
void log_parse_environment(void);
88
89
int log_dispatch_internal(
90
                int level,
91
                int error,
92
                const char *file,
93
                int line,
94
                const char *func,
95
                const char *object_field,
96
                const char *object,
97
                const char *extra,
98
                const char *extra_field,
99
                char *buffer);
100
101
int log_internal(
102
                int level,
103
                int error,
104
                const char *file,
105
                int line,
106
                const char *func,
107
                const char *format, ...) _printf_(6,7);
108
109
int log_internalv(
110
                int level,
111
                int error,
112
                const char *file,
113
                int line,
114
                const char *func,
115
                const char *format,
116
                va_list ap) _printf_(6,0);
117
118
int log_object_internalv(
119
                int level,
120
                int error,
121
                const char *file,
122
                int line,
123
                const char *func,
124
                const char *object_field,
125
                const char *object,
126
                const char *extra_field,
127
                const char *extra,
128
                const char *format,
129
                va_list ap) _printf_(10,0);
130
131
int log_object_internal(
132
                int level,
133
                int error,
134
                const char *file,
135
                int line,
136
                const char *func,
137
                const char *object_field,
138
                const char *object,
139
                const char *extra_field,
140
                const char *extra,
141
                const char *format, ...) _printf_(10,11);
142
143
int log_struct_internal(
144
                int level,
145
                int error,
146
                const char *file,
147
                int line,
148
                const char *func,
149
                const char *format, ...) _printf_(6,0) _sentinel_;
150
151
int log_oom_internal(
152
                int level,
153
                const char *file,
154
                int line,
155
                const char *func);
156
157
int log_format_iovec(
158
                struct iovec *iovec,
159
                size_t iovec_len,
160
                size_t *n,
161
                bool newline_separator,
162
                int error,
163
                const char *format,
164
                va_list ap) _printf_(6, 0);
165
166
int log_struct_iovec_internal(
167
                int level,
168
                int error,
169
                const char *file,
170
                int line,
171
                const char *func,
172
                const struct iovec *input_iovec,
173
                size_t n_input_iovec);
174
175
/* This modifies the buffer passed! */
176
int log_dump_internal(
177
                int level,
178
                int error,
179
                const char *file,
180
                int line,
181
                const char *func,
182
                char *buffer);
183
184
/* Logging for various assertions */
185
_noreturn_ void log_assert_failed(
186
                const char *text,
187
                const char *file,
188
                int line,
189
                const char *func);
190
191
_noreturn_ void log_assert_failed_unreachable(
192
                const char *file,
193
                int line,
194
                const char *func);
195
196
void log_assert_failed_return(
197
                const char *text,
198
                const char *file,
199
                int line,
200
                const char *func);
201
202
#define log_dispatch(level, error, buffer)                              \
203
        log_dispatch_internal(level, error, PROJECT_FILE, __LINE__, __func__, NULL, NULL, NULL, NULL, buffer)
204
205
/* Logging with level */
206
#define log_full_errno_zerook(level, error, ...)                        \
207
17.0k
        ({                                                              \
208
17.0k
                int _level = (level), _e = (error);                     \
209
17.0k
                _e = (log_get_max_level() >= LOG_PRI(_level))           \
210
17.0k
                        ? log_internal(_level, _e, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \
211
17.0k
                        : -ERRNO_VALUE(_e);                             \
212
17.0k
                _e < 0 ? _e : -ESTRPIPE;                                \
213
17.0k
        })
214
215
#if BUILD_MODE_DEVELOPER && !defined(TEST_CODE)
216
129
#  define ASSERT_NON_ZERO(x) assert((x) != 0)
217
#else
218
#  define ASSERT_NON_ZERO(x)
219
#endif
220
221
#define log_full_errno(level, error, ...)                               \
222
129
        ({                                                              \
223
129
                int _error = (error);                                   \
224
129
                ASSERT_NON_ZERO(_error);                                \
225
129
                log_full_errno_zerook(level, _error, __VA_ARGS__);      \
226
129
        })
227
228
#define log_full(level, fmt, ...)                                      \
229
16.9k
        ({                                                             \
230
16.9k
                if (BUILD_MODE_DEVELOPER)                              \
231
16.9k
                        assert(!strstr(fmt, "%m"));                    \
232
16.9k
                (void) log_full_errno_zerook(level, 0, fmt, ##__VA_ARGS__); \
233
16.9k
        })
234
235
int log_emergency_level(void);
236
237
/* Normal logging */
238
8.80k
#define log_debug(...)     log_full(LOG_DEBUG,   __VA_ARGS__)
239
0
#define log_info(...)      log_full(LOG_INFO,    __VA_ARGS__)
240
#define log_notice(...)    log_full(LOG_NOTICE,  __VA_ARGS__)
241
8.13k
#define log_warning(...)   log_full(LOG_WARNING, __VA_ARGS__)
242
#define log_error(...)     log_full(LOG_ERR,     __VA_ARGS__)
243
#define log_emergency(...) log_full(log_emergency_level(), __VA_ARGS__)
244
245
/* Logging triggered by an errno-like error */
246
#define log_debug_errno(error, ...)     log_full_errno(LOG_DEBUG,   error, __VA_ARGS__)
247
#define log_info_errno(error, ...)      log_full_errno(LOG_INFO,    error, __VA_ARGS__)
248
#define log_notice_errno(error, ...)    log_full_errno(LOG_NOTICE,  error, __VA_ARGS__)
249
129
#define log_warning_errno(error, ...)   log_full_errno(LOG_WARNING, error, __VA_ARGS__)
250
0
#define log_error_errno(error, ...)     log_full_errno(LOG_ERR,     error, __VA_ARGS__)
251
#define log_emergency_errno(error, ...) log_full_errno(log_emergency_level(), error, __VA_ARGS__)
252
253
/* This logs at the specified level the first time it is called, and then
254
 * logs at debug. If the specified level is debug, this logs only the first
255
 * time it is called. */
256
#define log_once(level, ...)                                             \
257
        ({                                                               \
258
                if (ONCE)                                                \
259
                        log_full(level, __VA_ARGS__);                    \
260
                else if (LOG_PRI(level) != LOG_DEBUG)                    \
261
                        log_debug(__VA_ARGS__);                          \
262
        })
263
264
#define log_once_errno(level, error, ...)                                \
265
        ({                                                               \
266
                int _err = (error);                                      \
267
                if (ONCE)                                                \
268
                        _err = log_full_errno(level, _err, __VA_ARGS__); \
269
                else if (LOG_PRI(level) != LOG_DEBUG)                    \
270
                        _err = log_debug_errno(_err, __VA_ARGS__);       \
271
                else                                                     \
272
                        _err = -ERRNO_VALUE(_err);                       \
273
                _err;                                                    \
274
        })
275
276
#if LOG_TRACE
277
#  define log_trace(...)          log_debug(__VA_ARGS__)
278
#  define log_trace_errno(...)    log_debug_errno(__VA_ARGS__)
279
#else
280
#  define log_trace(...)          do {} while (0)
281
#  define log_trace_errno(e, ...) (-ERRNO_VALUE(e))
282
#endif
283
284
/* Structured logging */
285
#define log_struct_errno(level, error, ...)                             \
286
        log_struct_internal(level, error, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__, NULL)
287
#define log_struct(level, ...) log_struct_errno(level, 0, __VA_ARGS__)
288
289
#define log_struct_iovec_errno(level, error, iovec, n_iovec)            \
290
        log_struct_iovec_internal(level, error, PROJECT_FILE, __LINE__, __func__, iovec, n_iovec)
291
#define log_struct_iovec(level, iovec, n_iovec) log_struct_iovec_errno(level, 0, iovec, n_iovec)
292
293
/* This modifies the buffer passed! */
294
#define log_dump(level, buffer)                                         \
295
        log_dump_internal(level, 0, PROJECT_FILE, __LINE__, __func__, buffer)
296
297
0
#define log_oom() log_oom_internal(LOG_ERR, PROJECT_FILE, __LINE__, __func__)
298
#define log_oom_debug() log_oom_internal(LOG_DEBUG, PROJECT_FILE, __LINE__, __func__)
299
300
bool log_on_console(void) _pure_;
301
302
/* Helper to wrap the main message in structured logging. The macro doesn't do much,
303
 * except to provide visual grouping of the format string and its arguments. */
304
#if LOG_MESSAGE_VERIFICATION || defined(__COVERITY__)
305
/* Do a fake formatting of the message string to let the scanner verify the arguments against the format
306
 * message. The variable will never be set to true, but we don't tell the compiler that :) */
307
extern bool _log_message_dummy;
308
#  define LOG_MESSAGE(fmt, ...) "MESSAGE=%.0d" fmt, (_log_message_dummy && printf(fmt, ##__VA_ARGS__)), ##__VA_ARGS__
309
#else
310
#  define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__
311
#endif
312
313
void log_received_signal(int level, const struct signalfd_siginfo *si);
314
315
/* If turned on, any requests for a log target involving "syslog" will be implicitly upgraded to the equivalent journal target */
316
void log_set_upgrade_syslog_to_journal(bool b);
317
318
/* If turned on, and log_open() is called, we'll not use STDERR_FILENO for logging ever, but rather open /dev/console */
319
void log_set_always_reopen_console(bool b);
320
321
/* If turned on, we'll open the log stream implicitly if needed on each individual log call. This is normally not
322
 * desired as we want to reuse our logging streams. It is useful however  */
323
void log_set_open_when_needed(bool b);
324
325
/* If turned on, then we'll never use IPC-based logging, i.e. never log to syslog or the journal. We'll only log to
326
 * stderr, the console or kmsg */
327
void log_set_prohibit_ipc(bool b);
328
329
int log_dup_console(void);
330
331
int log_syntax_internal(
332
                const char *unit,
333
                int level,
334
                const char *config_file,
335
                unsigned config_line,
336
                int error,
337
                const char *file,
338
                int line,
339
                const char *func,
340
                const char *format, ...) _printf_(9, 10);
341
342
int log_syntax_invalid_utf8_internal(
343
                const char *unit,
344
                int level,
345
                const char *config_file,
346
                unsigned config_line,
347
                const char *file,
348
                int line,
349
                const char *func,
350
                const char *rvalue);
351
352
#define log_syntax(unit, level, config_file, config_line, error, ...)   \
353
428k
        ({                                                              \
354
428k
                int _level = (level), _e = (error);                     \
355
428k
                (log_get_max_level() >= LOG_PRI(_level))                \
356
428k
                        ? log_syntax_internal(unit, _level, config_file, config_line, _e, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \
357
428k
                        : -ERRNO_VALUE(_e);                             \
358
428k
        })
359
360
#define log_syntax_invalid_utf8(unit, level, config_file, config_line, rvalue) \
361
        ({                                                              \
362
                int _level = (level);                                   \
363
                (log_get_max_level() >= LOG_PRI(_level))                \
364
                        ? log_syntax_invalid_utf8_internal(unit, _level, config_file, config_line, PROJECT_FILE, __LINE__, __func__, rvalue) \
365
                        : -EINVAL;                                      \
366
        })
367
368
#define DEBUG_LOGGING _unlikely_(log_get_max_level() >= LOG_DEBUG)
369
370
void log_setup(void);
371
372
typedef struct LogRateLimit {
373
        int error;
374
        int level;
375
        RateLimit ratelimit;
376
} LogRateLimit;
377
378
#define log_ratelimit_internal(_level, _error, _format, _file, _line, _func, ...)        \
379
({                                                                              \
380
        int _log_ratelimit_error = (_error);                                    \
381
        int _log_ratelimit_level = (_level);                                    \
382
        static LogRateLimit _log_ratelimit = {                                  \
383
                .ratelimit = {                                                  \
384
                        .interval = 1 * USEC_PER_SEC,                           \
385
                        .burst = 1,                                             \
386
                },                                                              \
387
        };                                                                      \
388
        unsigned _num_dropped_errors = ratelimit_num_dropped(&_log_ratelimit.ratelimit); \
389
        if (_log_ratelimit_error != _log_ratelimit.error || _log_ratelimit_level != _log_ratelimit.level) { \
390
                ratelimit_reset(&_log_ratelimit.ratelimit);                     \
391
                _log_ratelimit.error = _log_ratelimit_error;                    \
392
                _log_ratelimit.level = _log_ratelimit_level;                    \
393
        }                                                                       \
394
        if (ratelimit_below(&_log_ratelimit.ratelimit))                         \
395
                _log_ratelimit_error = _num_dropped_errors > 0                  \
396
                ? log_internal(_log_ratelimit_level, _log_ratelimit_error, _file, _line, _func, _format " (Dropped %u similar message(s))", __VA_ARGS__, _num_dropped_errors) \
397
                : log_internal(_log_ratelimit_level, _log_ratelimit_error, _file, _line, _func, _format, __VA_ARGS__); \
398
        _log_ratelimit_error;                                                   \
399
})
400
401
#define log_ratelimit_full_errno(level, error, format, ...)             \
402
        ({                                                              \
403
                int _level = (level), _e = (error);                     \
404
                _e = (log_get_max_level() >= LOG_PRI(_level))           \
405
                        ? log_ratelimit_internal(_level, _e, format, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \
406
                        : -ERRNO_VALUE(_e);                             \
407
                _e < 0 ? _e : -ESTRPIPE;                                \
408
        })