1 /* 2 * Copyright (c) 2007-2009 Marko Kreen, Skype Technologies OÜ 3 * 4 * Permission to use, copy, modify, and/or 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 /** 18 * @file 19 * 20 * Logging framework for unix services. 21 * 22 * 23 * Supported outputs: 24 * - syslog 25 * - log file 26 * - stderr 27 * 28 * @section logging_prefix Logging context 29 * 30 * It is possible to pass context info to all logging calls 31 * and later add details to log lines or to filter based on it. 32 * 33 * Each call references 2 macros: 34 * - LOG_CONTEXT_DEF - which can define/call any variables 35 * - LOG_CONTEXT - which should return a pointer variable. 36 * 37 * Later, global callback function \ref logging_prefix_cb 38 * will get this pointer with destination buffer and can either 39 * add more info for log line or tell to skip logging this message. 40 */ 41 #ifndef _USUAL_LOGGING_H_ 42 #define _USUAL_LOGGING_H_ 43 44 #include <usual/base.h> 45 46 /* internal log levels */ 47 enum LogLevel { 48 LG_FATAL = 0, 49 LG_ERROR = 1, 50 LG_WARNING = 2, 51 LG_STATS = 3, 52 LG_INFO = 4, 53 LG_DEBUG = 5, 54 LG_NOISE = 6, 55 }; 56 #ifndef LOG_CONTEXT_DEF 57 /** Example: Prepare dummy context pointer */ 58 #define LOG_CONTEXT_DEF void *_log_ctx = NULL 59 #endif 60 #ifndef LOG_CONTEXT 61 /** Example: Reference dummy context pointer */ 62 #define LOG_CONTEXT _log_ctx 63 #endif 64 65 /** 66 * Signature for logging_prefix_cb. Return value is either added string length in dst 67 * or negative value to skip logging. 68 */ 69 typedef int (*logging_prefix_fn_t)(enum LogLevel lev, void *ctx, char *dst, unsigned int dstlen); 70 71 /** 72 * Optional global callback for each log line. 73 * 74 * It can either add info to log message or skip logging it. 75 */ 76 extern logging_prefix_fn_t logging_prefix_cb; 77 78 /** 79 * Global verbosity level. 80 * 81 * 0 - show only info level msgs (default) 82 * 1 - show debug msgs (log_debug) 83 * 2 - show noise msgs (log_noise) 84 */ 85 extern int cf_verbose; 86 87 /** 88 * Toggle logging to stderr. Default: 1. 89 * daemon.c turns this off if goes to background 90 */ 91 extern int cf_quiet; 92 93 /** 94 * Logfile location, default NULL 95 */ 96 extern const char *cf_logfile; 97 98 /** Syslog on/off */ 99 extern int cf_syslog; 100 /** ident for syslog, if NULL syslog is disabled (default) */ 101 extern const char *cf_syslog_ident; 102 /** Facility name */ 103 extern const char *cf_syslog_facility; 104 105 /** Max log level for syslog writer */ 106 extern enum LogLevel cf_syslog_level; 107 /** Max log level for logfile writer */ 108 extern enum LogLevel cf_logfile_level; 109 /** Max log level for stderr writer */ 110 extern enum LogLevel cf_stderr_level; 111 112 /* 113 * Internal API. 114 */ 115 116 /* non-fatal logging */ 117 void log_generic(enum LogLevel level, void *ctx, const char *s, ...) _PRINTF(3, 4); 118 119 /* this is also defined in base.h for Assert() */ 120 void log_fatal(const char *file, int line, const char *func, bool show_perror, 121 void *ctx, const char *s, ...) _PRINTF(6, 7); 122 123 /* 124 * Public API 125 */ 126 127 /** Log error message */ 128 #define log_error(...) do { LOG_CONTEXT_DEF; \ 129 log_generic(LG_ERROR, LOG_CONTEXT, __VA_ARGS__); \ 130 } while (0) 131 132 /** Log warning message */ 133 #define log_warning(...) do { LOG_CONTEXT_DEF; \ 134 log_generic(LG_WARNING, LOG_CONTEXT, __VA_ARGS__); \ 135 } while (0) 136 137 /** Log stats (liveness) message */ 138 #define log_stats(...) do { LOG_CONTEXT_DEF; \ 139 log_generic(LG_STATS, LOG_CONTEXT, __VA_ARGS__); \ 140 } while (0) 141 142 /** Log info message */ 143 #define log_info(...) do { LOG_CONTEXT_DEF; \ 144 log_generic(LG_INFO, LOG_CONTEXT, __VA_ARGS__); \ 145 } while (0) 146 147 /** Log debug message */ 148 #define log_debug(...) do { LOG_CONTEXT_DEF; \ 149 if (unlikely(cf_verbose > 0)) \ 150 log_generic(LG_DEBUG, LOG_CONTEXT, __VA_ARGS__); \ 151 } while (0) 152 153 /** Log debug noise */ 154 #define log_noise(...) do { LOG_CONTEXT_DEF; \ 155 if (unlikely(cf_verbose > 1)) \ 156 log_generic(LG_NOISE, LOG_CONTEXT, __VA_ARGS__); \ 157 } while (0) 158 159 /** Log and die. It also logs source location */ 160 #define fatal(...) do { LOG_CONTEXT_DEF; \ 161 log_fatal(__FILE__, __LINE__, __func__, false, LOG_CONTEXT, __VA_ARGS__); \ 162 exit(1); } while (0) 163 164 /** Log strerror and die. Error message also includes strerror(errno) */ 165 #define fatal_perror(...) do { LOG_CONTEXT_DEF; \ 166 log_fatal(__FILE__, __LINE__, __func__, true, LOG_CONTEXT, __VA_ARGS__); \ 167 exit(1); } while (0) 168 169 /** Less verbose fatal() */ 170 #define die(...) do { LOG_CONTEXT_DEF; \ 171 log_generic(LG_FATAL, LOG_CONTEXT, __VA_ARGS__); \ 172 exit(1); } while (0) 173 174 /** 175 * Close open logfiles and syslog. 176 * 177 * Useful when rotating log files. 178 */ 179 void reset_logging(void); 180 181 #endif 182