diff options
Diffstat (limited to '')
-rw-r--r-- | src/libserver/logger.h | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/src/libserver/logger.h b/src/libserver/logger.h new file mode 100644 index 0000000..8d4e313 --- /dev/null +++ b/src/libserver/logger.h @@ -0,0 +1,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 |