]>
Commit | Line | Data |
---|---|---|
0bdeb5e5 DL |
1 | /* |
2 | * Copyright (c) 2015-19 David Lamparter, for NetDEF, Inc. | |
3 | * | |
4 | * Permission to use, copy, modify, and distribute this software for any | |
5 | * purpose with or without fee is hereby granted, provided that the above | |
6 | * copyright notice and this permission notice appear in all copies. | |
7 | * | |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | */ | |
16 | ||
17 | #ifndef _FRR_ZLOG_H | |
18 | #define _FRR_ZLOG_H | |
19 | ||
20 | #include <stdarg.h> | |
21 | #include <stdbool.h> | |
22 | #include <stdint.h> | |
23 | #include <string.h> | |
24 | #include <syslog.h> | |
25 | #include <unistd.h> | |
26 | #include <sys/uio.h> | |
27 | ||
28 | #include "atomlist.h" | |
29 | #include "frrcu.h" | |
30 | #include "memory.h" | |
31 | #include "hook.h" | |
32 | ||
17e38209 RW |
33 | #ifdef __cplusplus |
34 | extern "C" { | |
35 | #endif | |
36 | ||
0bdeb5e5 DL |
37 | extern char zlog_prefix[]; |
38 | extern size_t zlog_prefixsz; | |
39 | extern int zlog_tmpdirfd; | |
40 | ||
41 | /* These functions are set up to write to stdout/stderr without explicit | |
42 | * initialization and/or before config load. There is no need to call e.g. | |
43 | * fprintf(stderr, ...) just because it's "too early" at startup. Depending | |
44 | * on context, it may still be the right thing to use fprintf though -- try to | |
45 | * determine wether something is a log message or something else. | |
46 | */ | |
47 | ||
48 | extern void vzlog(int prio, const char *fmt, va_list ap); | |
49 | ||
50 | __attribute__ ((format (printf, 2, 3))) | |
51 | static inline void zlog(int prio, const char *fmt, ...) | |
52 | { | |
53 | va_list ap; | |
54 | ||
55 | va_start(ap, fmt); | |
56 | vzlog(prio, fmt, ap); | |
57 | va_end(ap); | |
58 | } | |
59 | ||
60 | #define zlog_err(...) zlog(LOG_ERR, __VA_ARGS__) | |
61 | #define zlog_warn(...) zlog(LOG_WARNING, __VA_ARGS__) | |
62 | #define zlog_info(...) zlog(LOG_INFO, __VA_ARGS__) | |
63 | #define zlog_notice(...) zlog(LOG_NOTICE, __VA_ARGS__) | |
64 | #define zlog_debug(...) zlog(LOG_DEBUG, __VA_ARGS__) | |
65 | ||
66 | extern void zlog_sigsafe(const char *text, size_t len); | |
67 | ||
68 | /* extra priority value to disable a target without deleting it */ | |
69 | #define ZLOG_DISABLED (LOG_EMERG-1) | |
70 | ||
71 | /* zlog_msg encapsulates a particular logging call from somewhere in the code. | |
72 | * The same struct is passed around to all zlog_targets. | |
73 | * | |
74 | * This is used to defer formatting the log message until it is actually | |
75 | * requested by one of the targets. If none of the targets needs the message | |
76 | * formatted, the formatting call is avoided entirely. | |
77 | * | |
78 | * This struct is opaque / private to the core zlog code. Logging targets | |
79 | * should use zlog_msg_* functions to get text / timestamps / ... for a | |
80 | * message. | |
81 | */ | |
82 | ||
83 | struct zlog_msg; | |
84 | ||
85 | extern int zlog_msg_prio(struct zlog_msg *msg); | |
86 | ||
87 | /* pass NULL as textlen if you don't need it. */ | |
88 | extern const char *zlog_msg_text(struct zlog_msg *msg, size_t *textlen); | |
89 | ||
90 | /* timestamp formatting control flags */ | |
91 | ||
92 | /* sub-second digit count */ | |
93 | #define ZLOG_TS_PREC 0xfU | |
94 | ||
95 | /* 8601: 0000-00-00T00:00:00Z (if used with ZLOG_TS_UTC) | |
96 | * 0000-00-00T00:00:00+00:00 (otherwise) | |
97 | * Legacy: 0000/00/00 00:00:00 (no TZ indicated!) | |
98 | */ | |
99 | #define ZLOG_TS_ISO8601 (1 << 8) | |
100 | #define ZLOG_TS_LEGACY (1 << 9) | |
101 | ||
102 | /* default is local time zone */ | |
103 | #define ZLOG_TS_UTC (1 << 10) | |
104 | ||
105 | extern size_t zlog_msg_ts(struct zlog_msg *msg, char *out, size_t outsz, | |
106 | uint32_t flags); | |
107 | ||
108 | /* This list & struct implements the actual logging targets. It is accessed | |
109 | * lock-free from all threads, and thus MUST only be changed atomically, i.e. | |
110 | * RCU. | |
111 | * | |
112 | * Since there's no atomic replace, the replacement action is an add followed | |
113 | * by a delete. This means that during logging config changes, log messages | |
114 | * may be duplicated in the log target that is being changed. The old entry | |
115 | * being changed MUST also at the very least not crash or do other stupid | |
116 | * things. | |
117 | * | |
118 | * This list and struct are NOT related to config. Logging config is kept | |
119 | * separately, and results in creating appropriate zlog_target(s) to realize | |
120 | * the config. Log targets may also be created from varying sources, e.g. | |
121 | * command line options, or VTY commands ("log monitor"). | |
122 | * | |
123 | * struct zlog_target is intended to be embedded into a larger structure that | |
124 | * contains additional field for the specific logging target, e.g. an fd or | |
125 | * additional options. It MUST be the first field in that larger struct. | |
126 | */ | |
127 | ||
128 | PREDECL_ATOMLIST(zlog_targets) | |
129 | struct zlog_target { | |
130 | struct zlog_targets_item head; | |
131 | ||
132 | int prio_min; | |
133 | ||
134 | void (*logfn)(struct zlog_target *zt, struct zlog_msg *msg[], | |
135 | size_t nmsgs); | |
136 | ||
137 | /* for crash handlers, set to NULL if log target can't write crash logs | |
138 | * without possibly deadlocking (AS-Safe) | |
139 | * | |
140 | * text is not \0 terminated & split up into lines (e.g. no \n) | |
141 | */ | |
142 | void (*logfn_sigsafe)(struct zlog_target *zt, const char *text, | |
143 | size_t len); | |
144 | ||
145 | struct rcu_head rcu_head; | |
146 | }; | |
147 | ||
148 | /* make a copy for RCUpdating. oldzt may be NULL to allocate a fresh one. */ | |
149 | extern struct zlog_target *zlog_target_clone(struct memtype *mt, | |
150 | struct zlog_target *oldzt, | |
151 | size_t size); | |
152 | ||
153 | /* update the zlog_targets list; both oldzt and newzt may be NULL. You | |
154 | * still need to zlog_target_free() the old target afterwards if it wasn't | |
155 | * NULL. | |
156 | * | |
157 | * Returns oldzt so you can zlog_target_free(zlog_target_replace(old, new)); | |
158 | * (Some log targets may need extra cleanup inbetween, but remember the old | |
159 | * target MUST remain functional until the end of the current RCU cycle.) | |
160 | */ | |
161 | extern struct zlog_target *zlog_target_replace(struct zlog_target *oldzt, | |
162 | struct zlog_target *newzt); | |
163 | ||
164 | /* Mostly for symmetry for zlog_target_clone(), just rcu_free() internally. */ | |
165 | #define zlog_target_free(mt, zt) \ | |
166 | rcu_free(mt, zt, rcu_head) | |
167 | ||
168 | extern void zlog_init(const char *progname, const char *protoname, | |
169 | unsigned short instance, uid_t uid, gid_t gid); | |
170 | DECLARE_HOOK(zlog_init, (const char *progname, const char *protoname, | |
171 | unsigned short instance, uid_t uid, gid_t gid), | |
172 | (progname, protoname, instance, uid, gid)) | |
173 | ||
174 | extern void zlog_fini(void); | |
175 | DECLARE_KOOH(zlog_fini, (), ()) | |
176 | ||
177 | /* for tools & test programs, i.e. anything not a daemon. | |
178 | * (no cleanup needed at exit) | |
179 | */ | |
180 | extern void zlog_aux_init(const char *prefix, int prio_min); | |
181 | DECLARE_HOOK(zlog_aux_init, (const char *prefix, int prio_min), | |
182 | (prefix, prio_min)) | |
183 | ||
184 | extern void zlog_startup_end(void); | |
185 | ||
186 | extern void zlog_tls_buffer_init(void); | |
187 | extern void zlog_tls_buffer_flush(void); | |
188 | extern void zlog_tls_buffer_fini(void); | |
189 | ||
17e38209 RW |
190 | #ifdef __cplusplus |
191 | } | |
192 | #endif | |
193 | ||
0bdeb5e5 | 194 | #endif /* _FRR_ZLOG_H */ |