master
h 258 lines 7.65 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #ifndef NETDATA_ND_LOG_INTERNALS_H
4 #define NETDATA_ND_LOG_INTERNALS_H
5
6 #include "../libnetdata.h"
7
8 #ifdef __FreeBSD__
9 #include <sys/endian.h>
10 #endif
11
12 #ifdef __APPLE__
13 #include <machine/endian.h>
14 #endif
15
16 #if !defined(ENABLE_SENTRY) && defined(HAVE_BACKTRACE)
17 #include <execinfo.h>
18 #endif
19
20 #ifdef HAVE_SYSTEMD
21 #include <systemd/sd-journal.h>
22 #endif
23
24 const char *errno2str(int errnum, char *buf, size_t size);
25
26 // --------------------------------------------------------------------------------------------------------------------
27 // ND_LOG_METHOD
28
29 typedef enum __attribute__((__packed__)) {
30 NDLM_DISABLED = 0,
31 NDLM_DEVNULL,
32 NDLM_DEFAULT,
33 NDLM_JOURNAL,
34 NDLM_SYSLOG,
35 NDLM_STDOUT,
36 NDLM_STDERR,
37 NDLM_FILE,
38 #if defined(OS_WINDOWS)
39 #if defined(HAVE_ETW)
40 NDLM_ETW,
41 #endif
42 #if defined(HAVE_WEL)
43 NDLM_WEL,
44 #endif
45 #endif
46 } ND_LOG_METHOD;
47
48 // all the log methods are finally mapped to these
49 #if defined(HAVE_ETW)
50 #define ETW_CONDITION(ndlo) ((ndlo) == NDLM_ETW)
51 #else
52 #define ETW_CONDITION(ndlo) (false)
53 #endif
54
55 #if defined(HAVE_WEL)
56 #define WEL_CONDITION(ndlo) ((ndlo) == NDLM_WEL)
57 #else
58 #define WEL_CONDITION(ndlo) (false)
59 #endif
60
61 #define IS_VALID_LOG_METHOD_FOR_EXTERNAL_PLUGINS(ndlo) ((ndlo) == NDLM_JOURNAL || (ndlo) == NDLM_SYSLOG || (ndlo) == NDLM_STDERR || ETW_CONDITION(ndlo) || WEL_CONDITION(ndlo))
62 #define IS_FINAL_LOG_METHOD(ndlo) ((ndlo) == NDLM_FILE || (ndlo) == NDLM_JOURNAL || (ndlo) == NDLM_SYSLOG || ETW_CONDITION(ndlo) || WEL_CONDITION(ndlo))
63
64 ND_LOG_METHOD nd_log_method2id(const char *method);
65 const char *nd_log_id2method(ND_LOG_METHOD method);
66
67 // --------------------------------------------------------------------------------------------------------------------
68 // ND_LOG_FORMAT
69
70 typedef enum __attribute__((__packed__)) {
71 NDLF_JOURNAL,
72 NDLF_LOGFMT,
73 NDLF_JSON,
74 #if defined(OS_WINDOWS)
75 #if defined(HAVE_ETW)
76 NDLF_ETW, // Event Tracing for Windows
77 #endif
78 #if defined(HAVE_WEL)
79 NDLF_WEL, // Windows Event Log
80 #endif
81 #endif
82 } ND_LOG_FORMAT;
83
84 #define ETW_NAME "etw"
85 #define WEL_NAME "wel"
86
87 const char *nd_log_id2format(ND_LOG_FORMAT format);
88 ND_LOG_FORMAT nd_log_format2id(const char *format);
89
90 size_t nd_log_source2id(const char *source, ND_LOG_SOURCES def);
91 const char *nd_log_id2source(ND_LOG_SOURCES source);
92
93 const char *nd_log_id2priority(ND_LOG_FIELD_PRIORITY priority);
94 int nd_log_priority2id(const char *priority);
95
96 const char *nd_log_id2facility(int facility);
97 int nd_log_facility2id(const char *facility);
98
99 #include "nd_log_limit.h"
100
101 struct nd_log_source {
102 netdata_mutex_t mutex; // protects write() serialization for FILE* output
103 ND_LOG_METHOD method;
104 ND_LOG_FORMAT format;
105 const char *filename;
106 int fd;
107 FILE *fp;
108
109 ND_LOG_FIELD_PRIORITY min_priority;
110 const nd_uuid_t *pending_msgid;
111 const char *pending_msg;
112 struct nd_log_limit limits;
113
114 #if defined(OS_WINDOWS)
115 ND_LOG_SOURCES source;
116 HANDLE hEventLog;
117 USHORT channelID;
118 UCHAR Opcode;
119 USHORT Task;
120 ULONGLONG Keyword;
121 #endif
122 };
123
124 struct nd_log {
125 nd_uuid_t invocation_id;
126
127 ND_LOG_SOURCES overwrite_process_source;
128 bool mutexes_initialized;
129 // Only set in post-fork nofork spawn-server children, which stay single-threaded in-tree.
130 bool single_threaded_child;
131 log_event_t fatal_hook_cb;
132 fatal_event_t fatal_final_cb;
133
134 struct nd_log_source sources[_NDLS_MAX];
135
136 struct {
137 bool initialized;
138 bool first_msg;
139 int fd; // we don't control this, we just detect it to keep it open
140 } journal;
141
142 struct {
143 bool initialized;
144 int fd;
145 char filename[FILENAME_MAX];
146 } journal_direct;
147
148 struct {
149 bool initialized;
150 int facility;
151 } syslog;
152
153 struct {
154 bool etw; // when set use etw, otherwise wel
155 bool initialized;
156 bool provider_enabled; // track etw provider state
157 SPINLOCK provider_lock; // Protect etw provider state access
158 } eventlog;
159
160 struct {
161 netdata_mutex_t mutex; // protects write() serialization for stdout
162 bool initialized;
163 } std_output;
164
165 struct {
166 netdata_mutex_t mutex; // protects write() serialization for stderr
167 bool initialized;
168 } std_error;
169
170 };
171
172 // --------------------------------------------------------------------------------------------------------------------
173
174 struct log_field;
175 typedef const char *(*annotator_t)(struct log_field *lf);
176
177 struct log_field {
178 const char *journal;
179 const char *logfmt;
180 const char *eventlog;
181 annotator_t logfmt_annotator;
182 struct log_stack_entry entry;
183 };
184
185 #define THREAD_LOG_STACK_MAX 50
186 #define THREAD_FIELDS_MAX (sizeof(thread_log_fields) / sizeof(thread_log_fields[0]))
187
188 extern __thread struct log_stack_entry *thread_log_stack_base[THREAD_LOG_STACK_MAX];
189 extern __thread size_t thread_log_stack_next;
190 extern __thread struct log_field thread_log_fields[_NDF_MAX];
191
192 // --------------------------------------------------------------------------------------------------------------------
193
194 extern struct nd_log nd_log;
195 bool nd_log_replace_existing_fd(struct nd_log_source *e, int new_fd);
196 void nd_log_open(struct nd_log_source *e, ND_LOG_SOURCES source);
197 void nd_log_stdin_init(int fd, const char *filename);
198
199 // --------------------------------------------------------------------------------------------------------------------
200 // annotators
201
202 struct log_field;
203 const char *errno_annotator(struct log_field *lf);
204 const char *priority_annotator(struct log_field *lf);
205 const char *timestamp_usec_annotator(struct log_field *lf);
206
207 #if defined(OS_WINDOWS)
208 const char *winerror_annotator(struct log_field *lf);
209 #endif
210
211 // --------------------------------------------------------------------------------------------------------------------
212 // field formatters
213
214 uint64_t log_field_to_uint64(struct log_field *lf);
215 int64_t log_field_to_int64(struct log_field *lf);
216 const char *log_field_strdupz(struct log_field *lf);
217
218 // --------------------------------------------------------------------------------------------------------------------
219 // common text formatters
220
221 void nd_logger_logfmt(BUFFER *wb, struct log_field *fields, size_t fields_max);
222 void nd_logger_json(BUFFER *wb, struct log_field *fields, size_t fields_max);
223
224 // --------------------------------------------------------------------------------------------------------------------
225 // output to syslog
226
227 void nd_log_init_syslog(void);
228 void nd_log_reset_syslog(void);
229 bool nd_logger_syslog(int priority, ND_LOG_FORMAT format, struct log_field *fields, size_t fields_max);
230
231 // --------------------------------------------------------------------------------------------------------------------
232 // output to systemd-journal
233
234 bool nd_log_journal_systemd_init(void);
235 bool nd_log_journal_direct_init(const char *path);
236 bool nd_logger_journal_direct(struct log_field *fields, size_t fields_max);
237 bool nd_logger_journal_libsystemd(struct log_field *fields, size_t fields_max);
238
239 // --------------------------------------------------------------------------------------------------------------------
240 // output to file
241
242 bool nd_logger_file(int fd, FILE *fp, netdata_mutex_t *mutex, ND_LOG_FORMAT format, struct log_field *fields, size_t fields_max);
243
244 // --------------------------------------------------------------------------------------------------------------------
245 // output to windows events log
246
247 #if defined(OS_WINDOWS)
248 #if defined(HAVE_ETW)
249 bool nd_log_init_etw(void);
250 bool nd_logger_etw(struct nd_log_source *source, struct log_field *fields, size_t fields_max);
251 #endif
252 #if defined(HAVE_WEL)
253 bool nd_log_init_wel(void);
254 bool nd_logger_wel(struct nd_log_source *source, struct log_field *fields, size_t fields_max);
255 #endif
256 #endif
257
258 #endif //NETDATA_ND_LOG_INTERNALS_H