]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/log.h
Merge pull request #6918 from ssahani/issue-5625
[thirdparty/systemd.git] / src / basic / log.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 #pragma once
3
4 /***
5 This file is part of systemd.
6
7 Copyright 2010 Lennart Poettering
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 ***/
22
23 #include <errno.h>
24 #include <stdarg.h>
25 #include <stdbool.h>
26 #include <stdlib.h>
27 #include <sys/signalfd.h>
28 #include <sys/socket.h>
29 #include <syslog.h>
30
31 #include "sd-id128.h"
32
33 #include "macro.h"
34 #include "process-util.h"
35
36 typedef enum LogRealm {
37 LOG_REALM_SYSTEMD,
38 LOG_REALM_UDEV,
39 _LOG_REALM_MAX,
40 } LogRealm;
41
42 #ifndef LOG_REALM
43 # define LOG_REALM LOG_REALM_SYSTEMD
44 #endif
45
46 typedef enum LogTarget{
47 LOG_TARGET_CONSOLE,
48 LOG_TARGET_CONSOLE_PREFIXED,
49 LOG_TARGET_KMSG,
50 LOG_TARGET_JOURNAL,
51 LOG_TARGET_JOURNAL_OR_KMSG,
52 LOG_TARGET_SYSLOG,
53 LOG_TARGET_SYSLOG_OR_KMSG,
54 LOG_TARGET_AUTO, /* console if stderr is tty, JOURNAL_OR_KMSG otherwise */
55 LOG_TARGET_SAFE, /* console if stderr is tty, KMSG otherwise */
56 LOG_TARGET_NULL,
57 _LOG_TARGET_MAX,
58 _LOG_TARGET_INVALID = -1
59 } LogTarget;
60
61 #define LOG_REALM_PLUS_LEVEL(realm, level) \
62 ((realm) << 10 | (level))
63 #define LOG_REALM_REMOVE_LEVEL(realm_level) \
64 ((realm_level >> 10))
65
66 void log_set_target(LogTarget target);
67 void log_set_max_level_realm(LogRealm realm, int level);
68 #define log_set_max_level(level) \
69 log_set_max_level_realm(LOG_REALM, (level))
70
71 void log_set_facility(int facility);
72
73 int log_set_target_from_string(const char *e);
74 int log_set_max_level_from_string_realm(LogRealm realm, const char *e);
75 #define log_set_max_level_from_string(e) \
76 log_set_max_level_from_string_realm(LOG_REALM, (e))
77
78 void log_show_color(bool b);
79 bool log_get_show_color(void) _pure_;
80 void log_show_location(bool b);
81 bool log_get_show_location(void) _pure_;
82
83 int log_show_color_from_string(const char *e);
84 int log_show_location_from_string(const char *e);
85
86 LogTarget log_get_target(void) _pure_;
87 int log_get_max_level_realm(LogRealm realm) _pure_;
88 #define log_get_max_level() \
89 log_get_max_level_realm(LOG_REALM)
90
91 /* Functions below that open and close logs or configure logging based on the
92 * environment should not be called from library code — this is always a job
93 * for the application itself.
94 */
95
96 int log_open(void);
97 void log_close(void);
98 void log_forget_fds(void);
99
100 void log_close_syslog(void);
101 void log_close_journal(void);
102 void log_close_kmsg(void);
103 void log_close_console(void);
104
105 void log_parse_environment_realm(LogRealm realm);
106 #define log_parse_environment() \
107 log_parse_environment_realm(LOG_REALM)
108
109 int log_dispatch_internal(
110 int level,
111 int error,
112 const char *file,
113 int line,
114 const char *func,
115 const char *object_field,
116 const char *object,
117 const char *extra,
118 const char *extra_field,
119 char *buffer);
120
121 int log_internal_realm(
122 int level,
123 int error,
124 const char *file,
125 int line,
126 const char *func,
127 const char *format, ...) _printf_(6,7);
128 #define log_internal(level, ...) \
129 log_internal_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
130
131 int log_internalv_realm(
132 int level,
133 int error,
134 const char *file,
135 int line,
136 const char *func,
137 const char *format,
138 va_list ap) _printf_(6,0);
139 #define log_internalv(level, ...) \
140 log_internalv_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
141
142 /* Realm is fixed to LOG_REALM_SYSTEMD for those */
143 int log_object_internal(
144 int level,
145 int error,
146 const char *file,
147 int line,
148 const char *func,
149 const char *object_field,
150 const char *object,
151 const char *extra_field,
152 const char *extra,
153 const char *format, ...) _printf_(10,11);
154
155 int log_object_internalv(
156 int level,
157 int error,
158 const char *file,
159 int line,
160 const char *func,
161 const char *object_field,
162 const char *object,
163 const char *extra_field,
164 const char *extra,
165 const char *format,
166 va_list ap) _printf_(10,0);
167
168 int log_struct_internal(
169 int level,
170 int error,
171 const char *file,
172 int line,
173 const char *func,
174 const char *format, ...) _printf_(6,0) _sentinel_;
175
176 int log_oom_internal(
177 LogRealm realm,
178 const char *file,
179 int line,
180 const char *func);
181
182 int log_format_iovec(
183 struct iovec *iovec,
184 size_t iovec_len,
185 size_t *n,
186 bool newline_separator,
187 int error,
188 const char *format,
189 va_list ap) _printf_(6, 0);
190
191 int log_struct_iovec_internal(
192 int level,
193 int error,
194 const char *file,
195 int line,
196 const char *func,
197 const struct iovec input_iovec[],
198 size_t n_input_iovec);
199
200 /* This modifies the buffer passed! */
201 int log_dump_internal(
202 int level,
203 int error,
204 const char *file,
205 int line,
206 const char *func,
207 char *buffer);
208
209 /* Logging for various assertions */
210 noreturn void log_assert_failed_realm(
211 LogRealm realm,
212 const char *text,
213 const char *file,
214 int line,
215 const char *func);
216 #define log_assert_failed(text, ...) \
217 log_assert_failed_realm(LOG_REALM, (text), __VA_ARGS__)
218
219 noreturn void log_assert_failed_unreachable_realm(
220 LogRealm realm,
221 const char *text,
222 const char *file,
223 int line,
224 const char *func);
225 #define log_assert_failed_unreachable(text, ...) \
226 log_assert_failed_unreachable_realm(LOG_REALM, (text), __VA_ARGS__)
227
228 void log_assert_failed_return_realm(
229 LogRealm realm,
230 const char *text,
231 const char *file,
232 int line,
233 const char *func);
234 #define log_assert_failed_return(text, ...) \
235 log_assert_failed_return_realm(LOG_REALM, (text), __VA_ARGS__)
236
237 #define log_dispatch(level, error, buffer) \
238 log_dispatch_internal(level, error, __FILE__, __LINE__, __func__, NULL, NULL, NULL, NULL, buffer)
239
240 /* Logging with level */
241 #define log_full_errno_realm(realm, level, error, ...) \
242 ({ \
243 int _level = (level), _e = (error); \
244 (log_get_max_level_realm((realm)) >= LOG_PRI(_level)) \
245 ? log_internal_realm(LOG_REALM_PLUS_LEVEL((realm), _level), _e, \
246 __FILE__, __LINE__, __func__, __VA_ARGS__) \
247 : -abs(_e); \
248 })
249
250 #define log_full_errno(level, error, ...) \
251 log_full_errno_realm(LOG_REALM, (level), (error), __VA_ARGS__)
252
253 #define log_full(level, ...) log_full_errno((level), 0, __VA_ARGS__)
254
255 /* Normal logging */
256 #define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__)
257 #define log_info(...) log_full(LOG_INFO, __VA_ARGS__)
258 #define log_notice(...) log_full(LOG_NOTICE, __VA_ARGS__)
259 #define log_warning(...) log_full(LOG_WARNING, __VA_ARGS__)
260 #define log_error(...) log_full(LOG_ERR, __VA_ARGS__)
261 #define log_emergency(...) log_full(getpid_cached() == 1 ? LOG_EMERG : LOG_ERR, __VA_ARGS__)
262
263 /* Logging triggered by an errno-like error */
264 #define log_debug_errno(error, ...) log_full_errno(LOG_DEBUG, error, __VA_ARGS__)
265 #define log_info_errno(error, ...) log_full_errno(LOG_INFO, error, __VA_ARGS__)
266 #define log_notice_errno(error, ...) log_full_errno(LOG_NOTICE, error, __VA_ARGS__)
267 #define log_warning_errno(error, ...) log_full_errno(LOG_WARNING, error, __VA_ARGS__)
268 #define log_error_errno(error, ...) log_full_errno(LOG_ERR, error, __VA_ARGS__)
269 #define log_emergency_errno(error, ...) log_full_errno(getpid_cached() == 1 ? LOG_EMERG : LOG_ERR, error, __VA_ARGS__)
270
271 #ifdef LOG_TRACE
272 # define log_trace(...) log_debug(__VA_ARGS__)
273 #else
274 # define log_trace(...) do {} while (0)
275 #endif
276
277 /* Structured logging */
278 #define log_struct_errno(level, error, ...) \
279 log_struct_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
280 error, __FILE__, __LINE__, __func__, __VA_ARGS__)
281 #define log_struct(level, ...) log_struct_errno(level, 0, __VA_ARGS__)
282
283 #define log_struct_iovec_errno(level, error, iovec, n_iovec) \
284 log_struct_iovec_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
285 error, __FILE__, __LINE__, __func__, iovec, n_iovec)
286 #define log_struct_iovec(level, iovec, n_iovec) log_struct_iovec_errno(level, 0, iovec, n_iovec)
287
288 /* This modifies the buffer passed! */
289 #define log_dump(level, buffer) \
290 log_dump_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
291 0, __FILE__, __LINE__, __func__, buffer)
292
293 #define log_oom() log_oom_internal(LOG_REALM, __FILE__, __LINE__, __func__)
294
295 bool log_on_console(void) _pure_;
296
297 const char *log_target_to_string(LogTarget target) _const_;
298 LogTarget log_target_from_string(const char *s) _pure_;
299
300 /* Helper to prepare various field for structured logging */
301 #define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__
302
303 void log_received_signal(int level, const struct signalfd_siginfo *si);
304
305 void log_set_upgrade_syslog_to_journal(bool b);
306 void log_set_always_reopen_console(bool b);
307 void log_set_open_when_needed(bool b);
308
309 int log_syntax_internal(
310 const char *unit,
311 int level,
312 const char *config_file,
313 unsigned config_line,
314 int error,
315 const char *file,
316 int line,
317 const char *func,
318 const char *format, ...) _printf_(9, 10);
319
320 #define log_syntax(unit, level, config_file, config_line, error, ...) \
321 ({ \
322 int _level = (level), _e = (error); \
323 (log_get_max_level() >= LOG_PRI(_level)) \
324 ? log_syntax_internal(unit, _level, config_file, config_line, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \
325 : -abs(_e); \
326 })
327
328 #define log_syntax_invalid_utf8(unit, level, config_file, config_line, rvalue) \
329 ({ \
330 int _level = (level); \
331 if (log_get_max_level() >= LOG_PRI(_level)) { \
332 _cleanup_free_ char *_p = NULL; \
333 _p = utf8_escape_invalid(rvalue); \
334 log_syntax_internal(unit, _level, config_file, config_line, 0, __FILE__, __LINE__, __func__, \
335 "String is not UTF-8 clean, ignoring assignment: %s", strna(_p)); \
336 } \
337 })