summaryrefslogtreecommitdiffstats
path: root/src/libserver/logger.h
blob: 8d4e313a88d8702aeafc3aa4baa8cf9ab0fedd47 (plain)
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
#ifndef RSPAMD_LOGGER_H
#define RSPAMD_LOGGER_H

#include "config.h"
#include "radix.h"
#include "util.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef G_LOG_LEVEL_USER_SHIFT
#define G_LOG_LEVEL_USER_SHIFT 8
#endif

#define RSPAMD_LOG_ID_LEN 6

struct rspamd_config;

enum rspamd_log_flags {
	RSPAMD_LOG_FORCED = (1 << G_LOG_LEVEL_USER_SHIFT),
	RSPAMD_LOG_ENCRYPTED = (1 << (G_LOG_LEVEL_USER_SHIFT + 1)),
	RSPAMD_LOG_LEVEL_MASK = ~(RSPAMD_LOG_FORCED | RSPAMD_LOG_ENCRYPTED)
};

typedef struct rspamd_logger_s rspamd_logger_t;
typedef bool (*rspamd_log_func_t)(const gchar *module, const gchar *id,
								  const gchar *function,
								  gint level_flags,
								  const gchar *message,
								  gsize mlen,
								  rspamd_logger_t *logger,
								  gpointer arg);
typedef void *(*rspamd_log_init_func)(rspamd_logger_t *logger,
									  struct rspamd_config *cfg,
									  uid_t uid, gid_t gid,
									  GError **err);
typedef bool (*rspamd_log_on_fork_func)(rspamd_logger_t *logger,
										struct rspamd_config *cfg,
										gpointer arg,
										GError **err);
typedef void *(*rspamd_log_reload_func)(rspamd_logger_t *logger,
										struct rspamd_config *cfg,
										gpointer arg,
										uid_t uid, gid_t gid,
										GError **err);
typedef void (*rspamd_log_dtor_func)(rspamd_logger_t *logger,
									 gpointer arg);

struct rspamd_logger_funcs {
	rspamd_log_init_func init;
	rspamd_log_reload_func reload;
	rspamd_log_dtor_func dtor;
	rspamd_log_func_t log;
	rspamd_log_on_fork_func on_fork;
	gpointer specific;
};

#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
#define RSPAMD_LOGBUF_SIZE 8192
#else
/* Use a smaller buffer */
#define RSPAMD_LOGBUF_SIZE 2048
#endif

/**
 * Opens a new (initial) logger with console type
 * This logger is also used as an emergency logger
 * @return new rspamd logger object
 */
rspamd_logger_t *rspamd_log_open_emergency(rspamd_mempool_t *pool, gint flags);

/**
 * Open specific (configured logging)
 * @param pool
 * @param config
 * @param uid
 * @param gid
 * @return
 */
rspamd_logger_t *rspamd_log_open_specific(rspamd_mempool_t *pool,
										  struct rspamd_config *config,
										  const gchar *ptype,
										  uid_t uid, gid_t gid);

/**
 * Set log level (from GLogLevelFlags)
 * @param logger
 * @param level
 */
void rspamd_log_set_log_level(rspamd_logger_t *logger, gint level);
gint rspamd_log_get_log_level(rspamd_logger_t *logger);
const gchar *rspamd_get_log_severity_string(gint level_flags);
/**
 * Set log flags (from enum rspamd_log_flags)
 * @param logger
 * @param flags
 */
void rspamd_log_set_log_flags(rspamd_logger_t *logger, gint flags);

/**
 * Close log file or destroy other structures
 */
void rspamd_log_close(rspamd_logger_t *logger);


rspamd_logger_t *rspamd_log_default_logger(void);
rspamd_logger_t *rspamd_log_emergency_logger(void);

/**
 * Close and open log again for privileged processes
 */
bool rspamd_log_reopen(rspamd_logger_t *logger, struct rspamd_config *cfg,
					   uid_t uid, gid_t gid);

/**
 * Set log pid
 */
void rspamd_log_on_fork(GQuark ptype, struct rspamd_config *cfg,
						rspamd_logger_t *logger);

/**
 * Log function that is compatible for glib messages
 */
void rspamd_glib_log_function(const gchar *log_domain,
							  GLogLevelFlags log_level,
							  const gchar *message,
							  gpointer arg);

/**
 * Log function for printing glib assertions
 */
void rspamd_glib_printerr_function(const gchar *message);

/**
 * Function with variable number of arguments support
 */
bool rspamd_common_log_function(rspamd_logger_t *logger,
								gint level_flags,
								const gchar *module, const gchar *id,
								const gchar *function, const gchar *fmt, ...);

bool rspamd_common_logv(rspamd_logger_t *logger, gint level_flags,
						const gchar *module, const gchar *id, const gchar *function,
						const gchar *fmt, va_list args);

/**
 * Add new logging module, returns module ID
 * @param mod
 * @return
 */
gint rspamd_logger_add_debug_module(const gchar *mod);

/*
 * Macro to use for faster debug modules
 */
#define INIT_LOG_MODULE(mname)                                            \
	static gint rspamd_##mname##_log_id = -1;                             \
	RSPAMD_CONSTRUCTOR(rspamd_##mname##_log_init)                         \
	{                                                                     \
		rspamd_##mname##_log_id = rspamd_logger_add_debug_module(#mname); \
	}


#define INIT_LOG_MODULE_PUBLIC(mname)                                     \
	gint rspamd_##mname##_log_id = -1;                                    \
	RSPAMD_CONSTRUCTOR(rspamd_##mname##_log_init)                         \
	{                                                                     \
		rspamd_##mname##_log_id = rspamd_logger_add_debug_module(#mname); \
	}

#define EXTERN_LOG_MODULE_DEF(mname) \
	extern gint rspamd_##mname##_log_id

void rspamd_logger_configure_modules(GHashTable *mods_enabled);

/**
 * Conditional debug function
 */
bool rspamd_conditional_debug(rspamd_logger_t *logger,
							  rspamd_inet_addr_t *addr, const gchar *module, const gchar *id,
							  const gchar *function, const gchar *fmt, ...);

bool rspamd_conditional_debug_fast(rspamd_logger_t *logger,
								   rspamd_inet_addr_t *addr,
								   gint mod_id,
								   const gchar *module, const gchar *id,
								   const gchar *function, const gchar *fmt, ...);
bool rspamd_conditional_debug_fast_num_id(rspamd_logger_t *logger,
										  rspamd_inet_addr_t *addr,
										  gint mod_id,
										  const gchar *module, guint64 id,
										  const gchar *function, const gchar *fmt, ...);
gboolean rspamd_logger_need_log(rspamd_logger_t *rspamd_log,
								GLogLevelFlags log_level,
								gint module_id);

/**
 * Function with variable number of arguments support that uses static default logger
 */
bool rspamd_default_log_function(gint level_flags,
								 const gchar *module, const gchar *id,
								 const gchar *function,
								 const gchar *fmt,
								 ...);

/**
 * Varargs version of default log function
 * @param log_level
 * @param function
 * @param fmt
 * @param args
 */
bool rspamd_default_logv(gint level_flags,
						 const gchar *module, const gchar *id,
						 const gchar *function,
						 const gchar *fmt,
						 va_list args);

/**
 * Temporary turn on debug
 */
void rspamd_log_debug(rspamd_logger_t *logger);

/**
 * Turn off debug
 */
void rspamd_log_nodebug(rspamd_logger_t *logger);

/**
 * Return array of counters (4 numbers):
 * 0 - errors
 * 1 - warnings
 * 2 - info messages
 * 3 - debug messages
 */
const guint64 *rspamd_log_counters(rspamd_logger_t *logger);

/**
 * Returns errors ring buffer as ucl array
 * @param logger
 * @return
 */
ucl_object_t *rspamd_log_errorbuf_export(const rspamd_logger_t *logger);

/**
 * Sets new logger functions and initialise logging if needed
 * @param logger
 * @param nfuncs
 * @return static pointer to the old functions (so this function is not reentrant)
 */
struct rspamd_logger_funcs *rspamd_logger_set_log_function(rspamd_logger_t *logger,
														   struct rspamd_logger_funcs *nfuncs);

/* Typical functions */

extern guint rspamd_task_log_id;
#ifdef __cplusplus
#define RSPAMD_LOG_FUNC __func__
#else
#define RSPAMD_LOG_FUNC G_STRFUNC
#endif

/* Logging in postfix style */
#define msg_err(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL, \
												 NULL, NULL,           \
												 RSPAMD_LOG_FUNC,      \
												 __VA_ARGS__)
#define msg_warn(...) rspamd_default_log_function(G_LOG_LEVEL_WARNING, \
												  NULL, NULL,          \
												  RSPAMD_LOG_FUNC,     \
												  __VA_ARGS__)
#define msg_info(...) rspamd_default_log_function(G_LOG_LEVEL_INFO, \
												  NULL, NULL,       \
												  RSPAMD_LOG_FUNC,  \
												  __VA_ARGS__)
#define msg_notice(...) rspamd_default_log_function(G_LOG_LEVEL_MESSAGE, \
													NULL, NULL,          \
													RSPAMD_LOG_FUNC,     \
													__VA_ARGS__)
#define msg_debug(...) rspamd_default_log_function(G_LOG_LEVEL_DEBUG, \
												   NULL, NULL,        \
												   RSPAMD_LOG_FUNC,   \
												   __VA_ARGS__)

#define debug_task(...) rspamd_conditional_debug_fast(NULL,                                                 \
													  task->from_addr,                                      \
													  rspamd_task_log_id, "task", task->task_pool->tag.uid, \
													  RSPAMD_LOG_FUNC,                                      \
													  __VA_ARGS__)

/* Use the following macros if you have `task` in the function */
#define msg_err_task(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL,                                   \
													  task->task_pool->tag.tagname, task->task_pool->tag.uid, \
													  RSPAMD_LOG_FUNC,                                        \
													  __VA_ARGS__)
#define msg_err_task_lambda(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL,                                   \
															 task->task_pool->tag.tagname, task->task_pool->tag.uid, \
															 log_func,                                               \
															 __VA_ARGS__)
#define msg_warn_task(...) rspamd_default_log_function(G_LOG_LEVEL_WARNING,                                    \
													   task->task_pool->tag.tagname, task->task_pool->tag.uid, \
													   RSPAMD_LOG_FUNC,                                        \
													   __VA_ARGS__)
#define msg_notice_task(...) rspamd_default_log_function(G_LOG_LEVEL_MESSAGE,                                    \
														 task->task_pool->tag.tagname, task->task_pool->tag.uid, \
														 RSPAMD_LOG_FUNC,                                        \
														 __VA_ARGS__)
#define msg_info_task(...) rspamd_default_log_function(G_LOG_LEVEL_INFO,                                       \
													   task->task_pool->tag.tagname, task->task_pool->tag.uid, \
													   RSPAMD_LOG_FUNC,                                        \
													   __VA_ARGS__)
#define msg_info_task_lambda(...) rspamd_default_log_function(G_LOG_LEVEL_INFO,                                       \
															  task->task_pool->tag.tagname, task->task_pool->tag.uid, \
															  log_func,                                               \
															  __VA_ARGS__)
#define msg_debug_task(...) rspamd_conditional_debug_fast(NULL, task->from_addr,                                \
														  rspamd_task_log_id, "task", task->task_pool->tag.uid, \
														  RSPAMD_LOG_FUNC,                                      \
														  __VA_ARGS__)
#define msg_debug_task_lambda(...) rspamd_conditional_debug_fast(NULL, task->from_addr,                                \
																 rspamd_task_log_id, "task", task->task_pool->tag.uid, \
																 log_func,                                             \
																 __VA_ARGS__)
#define msg_err_task_encrypted(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL | RSPAMD_LOG_ENCRYPTED,            \
																task->task_pool->tag.tagname, task->task_pool->tag.uid, \
																RSPAMD_LOG_FUNC,                                        \
																__VA_ARGS__)
#define msg_warn_task_encrypted(...) rspamd_default_log_function(G_LOG_LEVEL_WARNING | RSPAMD_LOG_ENCRYPTED,             \
																 task->task_pool->tag.tagname, task->task_pool->tag.uid, \
																 RSPAMD_LOG_FUNC,                                        \
																 __VA_ARGS__)
#define msg_notice_task_encrypted(...) rspamd_default_log_function(G_LOG_LEVEL_MESSAGE | RSPAMD_LOG_ENCRYPTED,             \
																   task->task_pool->tag.tagname, task->task_pool->tag.uid, \
																   RSPAMD_LOG_FUNC,                                        \
																   __VA_ARGS__)
#define msg_info_task_encrypted(...) rspamd_default_log_function(G_LOG_LEVEL_INFO | RSPAMD_LOG_ENCRYPTED,                \
																 task->task_pool->tag.tagname, task->task_pool->tag.uid, \
																 RSPAMD_LOG_FUNC,                                        \
																 __VA_ARGS__)
/* Check for NULL pointer first */
#define msg_err_task_check(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL,                                                               \
															task ? task->task_pool->tag.tagname : NULL, task ? task->task_pool->tag.uid : NULL, \
															RSPAMD_LOG_FUNC,                                                                    \
															__VA_ARGS__)
#define msg_warn_task_check(...) rspamd_default_log_function(G_LOG_LEVEL_WARNING,                                                                \
															 task ? task->task_pool->tag.tagname : NULL, task ? task->task_pool->tag.uid : NULL, \
															 RSPAMD_LOG_FUNC,                                                                    \
															 __VA_ARGS__)
#define msg_info_task_check(...) rspamd_default_log_function(G_LOG_LEVEL_MESSAGE,                                                                \
															 task ? task->task_pool->tag.tagname : NULL, task ? task->task_pool->tag.uid : NULL, \
															 RSPAMD_LOG_FUNC,                                                                    \
															 __VA_ARGS__)
#define msg_notice_task_check(...) rspamd_default_log_function(G_LOG_LEVEL_INFO,                                                                   \
															   task ? task->task_pool->tag.tagname : NULL, task ? task->task_pool->tag.uid : NULL, \
															   RSPAMD_LOG_FUNC,                                                                    \
															   __VA_ARGS__)
#define msg_debug_task_check(...) rspamd_conditional_debug_fast(NULL,                                                               \
																task ? task->from_addr : NULL,                                      \
																rspamd_task_log_id, "task", task ? task->task_pool->tag.uid : NULL, \
																RSPAMD_LOG_FUNC,                                                    \
																__VA_ARGS__)

/* Use the following macros if you have `pool` in the function */
#define msg_err_pool(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL,             \
													  pool->tag.tagname, pool->tag.uid, \
													  RSPAMD_LOG_FUNC,                  \
													  __VA_ARGS__)
#define msg_warn_pool(...) rspamd_default_log_function(G_LOG_LEVEL_WARNING,              \
													   pool->tag.tagname, pool->tag.uid, \
													   RSPAMD_LOG_FUNC,                  \
													   __VA_ARGS__)
#define msg_info_pool(...) rspamd_default_log_function(G_LOG_LEVEL_INFO,                 \
													   pool->tag.tagname, pool->tag.uid, \
													   RSPAMD_LOG_FUNC,                  \
													   __VA_ARGS__)
#define msg_debug_pool(...) rspamd_conditional_debug(NULL, NULL,                       \
													 pool->tag.tagname, pool->tag.uid, \
													 RSPAMD_LOG_FUNC,                  \
													 __VA_ARGS__)
/* Check for NULL pointer first */
#define msg_err_pool_check(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL,                                         \
															pool ? pool->tag.tagname : NULL, pool ? pool->tag.uid : NULL, \
															RSPAMD_LOG_FUNC,                                              \
															__VA_ARGS__)
#define msg_warn_pool_check(...) rspamd_default_log_function(G_LOG_LEVEL_WARNING,                                          \
															 pool ? pool->tag.tagname : NULL, pool ? pool->tag.uid : NULL, \
															 RSPAMD_LOG_FUNC,                                              \
															 __VA_ARGS__)
#define msg_info_pool_check(...) rspamd_default_log_function(G_LOG_LEVEL_INFO,                                             \
															 pool ? pool->tag.tagname : NULL, pool ? pool->tag.uid : NULL, \
															 RSPAMD_LOG_FUNC,                                              \
															 __VA_ARGS__)
#define msg_debug_pool_check(...) rspamd_conditional_debug(NULL, NULL,                                                   \
														   pool ? pool->tag.tagname : NULL, pool ? pool->tag.uid : NULL, \
														   RSPAMD_LOG_FUNC,                                              \
														   __VA_ARGS__)

#ifdef __cplusplus
}
#endif

#endif