1 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 15 */ 16 #ifndef FR_LOG_H 17 #define FR_LOG_H 18 /** 19 * $Id: 2736591779e3c80137b1a753bf75e5d2182595c5 $ 20 * 21 * @file log.h 22 * @brief Macros and function definitions to write log messages, and control the logging system. 23 * 24 * @copyright 2015 Arran Cudbard-Bell <a.cudbardb@freeradius.org> 25 * @copyright 2013 Alan DeKok <aland@freeradius.org> 26 */ 27 RCSIDH(log_h, "$Id: 2736591779e3c80137b1a753bf75e5d2182595c5 $") 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 typedef enum log_type { 34 L_AUTH = 2, //!< Authentication message. 35 L_INFO = 3, //!< Informational message. 36 L_ERR = 4, //!< Error message. 37 L_WARN = 5, //!< Warning. 38 L_PROXY = 6, //!< Proxy messages 39 L_ACCT = 7, //!< Accounting messages 40 41 L_DBG = 16, //!< Only displayed when debugging is enabled. 42 L_DBG_WARN = 17, //!< Warning only displayed when debugging is enabled. 43 L_DBG_ERR = 18, //!< Error only displayed when debugging is enabled. 44 L_DBG_WARN_REQ = 19, //!< Less severe warning only displayed when debugging is enabled. 45 L_DBG_ERR_REQ = 20 //!< Less severe error only displayed when debugging is enabled. 46 } log_type_t; 47 48 typedef enum log_lvl { 49 L_DBG_LVL_DISABLE = -1, //!< Don't print messages. 50 L_DBG_LVL_OFF = 0, //!< No debug messages. 51 L_DBG_LVL_1, //!< Highest priority debug messages (-x). 52 L_DBG_LVL_2, //!< 2nd highest priority debug messages (-xx | -X). 53 L_DBG_LVL_3, //!< 3rd highest priority debug messages (-xxx | -Xx). 54 L_DBG_LVL_MAX //!< Lowest priority debug messages (-xxxx | -Xxx). 55 } log_lvl_t; 56 57 typedef enum log_dst { 58 L_DST_STDOUT = 0, //!< Log to stdout. 59 L_DST_FILES, //!< Log to a file on disk. 60 L_DST_SYSLOG, //!< Log to syslog. 61 L_DST_STDERR, //!< Log to stderr. 62 L_DST_NULL, //!< Discard log messages. 63 L_DST_NUM_DEST 64 } log_dst_t; 65 66 typedef struct fr_log_t { 67 bool colourise; //!< Prefix log messages with VT100 escape codes to change text 68 //!< colour. 69 int fd; //!< File descriptor to write messages to. 70 log_dst_t dst; //!< Log destination. 71 char const *file; //!< Path to log file. 72 char const *debug_file; //!< Path to debug log file. 73 } fr_log_t; 74 75 typedef void (*radlog_func_t)(log_type_t lvl, log_lvl_t priority, REQUEST *, char const *, va_list ap); 76 77 extern FR_NAME_NUMBER const syslog_facility_table[]; 78 extern FR_NAME_NUMBER const syslog_severity_table[]; 79 extern FR_NAME_NUMBER const log_str2dst[]; 80 extern fr_log_t default_log; 81 82 int radlog_init(fr_log_t *log, bool daemonize); 83 84 int vradlog(log_type_t lvl, char const *fmt, va_list ap) 85 CC_HINT(format (printf, 2, 0)) CC_HINT(nonnull); 86 int radlog(log_type_t lvl, char const *fmt, ...) 87 CC_HINT(format (printf, 2, 3)) CC_HINT(nonnull (2)); 88 89 bool debug_enabled(log_type_t type, log_lvl_t lvl); 90 91 bool rate_limit_enabled(void); 92 93 bool radlog_debug_enabled(log_type_t type, log_lvl_t lvl, REQUEST *request) 94 CC_HINT(nonnull); 95 96 void vradlog_request(log_type_t type, log_lvl_t lvl, REQUEST *request, char const *msg, va_list ap) 97 CC_HINT(format (printf, 4, 0)) CC_HINT(nonnull (3, 4)); 98 99 void radlog_request(log_type_t type, log_lvl_t lvl, REQUEST *request, char const *msg, ...) 100 CC_HINT(format (printf, 4, 5)) CC_HINT(nonnull (3, 4)); 101 102 void radlog_request_error(log_type_t type, log_lvl_t lvl, REQUEST *request, char const *msg, ...) 103 CC_HINT(format (printf, 4, 5)) CC_HINT(nonnull (3, 4)); 104 105 void radlog_request_marker(log_type_t type, log_lvl_t lvl, REQUEST *request, 106 char const *fmt, size_t indent, char const *error) 107 CC_HINT(nonnull); 108 109 void fr_canonicalize_error(TALLOC_CTX *ctx, char **spaces, char **text, ssize_t slen, char const *msg); 110 111 /** @name Log global messages 112 * 113 * Write to the global log. 114 * 115 * Messages will always be written irrespective of the debugging level set with ``-x`` or ``-X``. 116 * 117 * @warning If a REQUEST * is **NOT** available, these macros **MUST** be used. 118 * 119 * @note These macros should only be used for important global events. 120 * 121 * **Debug categories** 122 * Name | Syslog severity | Colour/style | When to use 123 * -------- | ----------------------- | ------------ | ----------- 124 * AUTH | LOG_NOTICE | Bold | Never - Deprecated 125 * ACCT | LOG_NOTICE | Bold | Never - Deprecated 126 * PROXY | LOG_NOTICE | Bold | Never - Deprecated 127 * INFO | LOG_INFO | Bold | TBD 128 * WARN | LOG_WARNING | Yellow | Warnings. Impending resource exhaustion, resource exhaustion 129 * ERROR | LOG_ERR | Red | Critical server errors. Malformed queries, failed operations, connection errors, packet processing errors 130 * 131 * @{ 132 */ 133 #define AUTH(fmt, ...) radlog(L_AUTH, fmt, ## __VA_ARGS__) 134 #define ACCT(fmt, ...) radlog(L_ACCT, fmt, ## __VA_ARGS__) 135 #define PROXY(fmt, ...) radlog(L_PROXY, fmt, ## __VA_ARGS__) 136 137 #define INFO(fmt, ...) radlog(L_INFO, fmt, ## __VA_ARGS__) 138 #define WARN(fmt, ...) radlog(L_WARN, fmt, ## __VA_ARGS__) 139 #define ERROR(fmt, ...) radlog(L_ERR, fmt, ## __VA_ARGS__) 140 /** @} */ 141 142 /** @name Log global debug messages (DEBUG*) 143 * 144 * Write debugging messages to the global log. 145 * 146 * Messages will be written if the debug level is high enough. 147 * 148 * **Debug categories** 149 * Name | Syslog severity | Colour/style | When to use 150 * -------- | ----------------------- | -------------| ----------- 151 * DEBUG | LOG_DEBUG | Regular | Normal debug output 152 * 153 * **Debug levels** 154 * Level | Debug arguments | Macro(s) enabled | When to use 155 * -------- | ----------------------- | ----------------------------- | ----------- 156 * 1 | ``-x`` | DEBUG | Never - Deprecated 157 * 2 | ``-xx`` or ``-X`` | DEBUG, DEBUG2 | Interactions with external entities. Connection management, control socket, triggers, etc... 158 * 3 | ``-xxx`` or ``-Xx`` | DEBUG, DEBUG2, DEBUG3 | Lower priority events. Polling for detail files, cleanups, etc... 159 * 4 | ``-xxxx`` or ``-Xxx`` | DEBUG, DEBUG2, DEBUG3, DEBUG4 | Internal server state debugging. 160 * 161 * @{ 162 */ 163 #define DEBUG_ENABLED debug_enabled(L_DBG, L_DBG_LVL_1) //!< True if global debug level 1 messages are enabled 164 #define DEBUG_ENABLED2 debug_enabled(L_DBG, L_DBG_LVL_2) //!< True if global debug level 1-2 messages are enabled 165 #define DEBUG_ENABLED3 debug_enabled(L_DBG, L_DBG_LVL_3) //!< True if global debug level 1-3 messages are enabled 166 #define DEBUG_ENABLED4 debug_enabled(L_DBG, L_DBG_LVL_MAX) //!< True if global debug level 1-4 messages are enabled 167 168 #define _SL(_l, _p, _f, ...) if (rad_debug_lvl >= _p) radlog(_l, _f, ## __VA_ARGS__) 169 #define DEBUG(fmt, ...) _SL(L_DBG, L_DBG_LVL_1, fmt, ## __VA_ARGS__) 170 #define DEBUG2(fmt, ...) _SL(L_DBG, L_DBG_LVL_2, fmt, ## __VA_ARGS__) 171 #define DEBUG3(fmt, ...) _SL(L_DBG, L_DBG_LVL_3, fmt, ## __VA_ARGS__) 172 #define DEBUG4(fmt, ...) _SL(L_DBG, L_DBG_LVL_MAX, fmt, ## __VA_ARGS__) 173 /** @} */ 174 175 /** @name Log request-specific messages (R*) 176 * 177 * Write to the request log, or the global log if a request logging function is not set. 178 * 179 * Messages will always be written irrespective of the debugging level set with ``-x`` or ``-X``. 180 * 181 * @note Automatically prepends date (at lvl >= 3), request number, and module, to the log message. 182 * @note If a REQUEST * is available, these macros should be used. 183 * @note These macros should only be used for important global events. 184 * 185 * **Debug categories** 186 * Name | Syslog severity | Colour/style | When to use 187 * -------- | ----------------------- | -------------| ----------- 188 * RAUTH | LOG_NOTICE | Bold | Never - Deprecated 189 * RACCT | LOG_NOTICE | Bold | Never - Deprecated 190 * RPROXY | LOG_NOTICE | Bold | Never - Deprecated 191 * RINFO | LOG_INFO | Bold | TBD 192 * RWARN | LOG_WARNING | Yellow/Bold | Warnings. Impending resource exhaustion, or resource exhaustion. 193 * RERROR | LOG_ERR | Red/Bold | Critical server errors. Malformed queries, failed operations, connection errors, packet processing errors. 194 * @{ 195 */ 196 #define RAUTH(fmt, ...) radlog_request(L_AUTH, L_DBG_LVL_OFF, request, fmt, ## __VA_ARGS__) 197 #define RACCT(fmt, ...) radlog_request(L_ACCT, L_DBG_LVL_OFF, request, fmt, ## __VA_ARGS__) 198 #define RPROXY(fmt, ...) radlog_request(L_PROXY, L_DBG_LVL_OFF, request, fmt, ## __VA_ARGS__) 199 #define RINFO(fmt, ...) radlog_request(L_INFO, L_DBG_LVL_OFF, request, fmt, ## __VA_ARGS__) 200 #define RWARN(fmt, ...) radlog_request(L_DBG_WARN, L_DBG_LVL_OFF, request, fmt, ## __VA_ARGS__) 201 #define RERROR(fmt, ...) radlog_request_error(L_DBG_ERR, L_DBG_LVL_OFF, request, fmt, ## __VA_ARGS__) 202 /** @} */ 203 204 /** @name Log request-specific debug (R*DEBUG*) 205 * 206 * Write debug messages to the request log. 207 * 208 * Messages will only be written if a request log function is set and the request or global 209 * debug level is high enough. 210 * 211 * @note Automatically prepends date (at lvl >= 3), request number, and module, to the log message. 212 * 213 * **Debug categories** 214 * Name | Syslog severity | Colour and style | When to use 215 * -------- | ----------------------- | -----------------| ----------- 216 * RDEBUG* | LOG_DEBUG | Regular | Normal debugging messages 217 * RIDEBUG* | LOG_DEBUG | Bold | Informational messages. 218 * RWDEBUG* | LOG_DEBUG | Yellow/Bold | Warnings. Invalid configuration, missing or invalid attributes etc... 219 * REDEBUG* | LOG_DEBUG | Red/Bold | Errors. Reject messages, bad values etc... 220 * 221 * **Debug levels** 222 * Level | Debug arguments | Macro(s) enabled | When to use 223 * -------- | ----------------------- | -------------------------------------- | ----------- 224 * 1 | ``-x`` | R*DEBUG | Never - Deprecated 225 * 2 | ``-xx`` or ``-X`` | R*DEBUG, R*DEBUG2 | Normal request flow. Operations, Results of queries, or execs, etc... 226 * 3 | ``-xxx`` or ``-Xx`` | R*DEBUG, R*DEBUG2, R*DEBUG3 | Internal server state or packet input. State machine changes, extra attribute info, etc... 227 * 4 | ``-xxxx`` or ``-Xxx`` | R*DEBUG, R*DEBUG2, R*DEBUG3, R*DEBUG4 | Verbose internal server state messages or packet input. Hex dumps, structure dumps, pointer values. 228 * 229 * @{ 230 */ 231 #define RDEBUG_ENABLED radlog_debug_enabled(L_DBG, L_DBG_LVL_1, request) //!< True if request debug level 1 messages are enabled 232 #define RDEBUG_ENABLED2 radlog_debug_enabled(L_DBG, L_DBG_LVL_2, request) //!< True if request debug level 1-2 messages are enabled 233 #define RDEBUG_ENABLED3 radlog_debug_enabled(L_DBG, L_DBG_LVL_3, request) //!< True if request debug level 1-3 messages are enabled 234 #define RDEBUG_ENABLED4 radlog_debug_enabled(L_DBG, L_DBG_LVL_MAX, request) //!< True if request debug level 1-4 messages are enabled 235 236 #define RDEBUGX(_l, fmt, ...) radlog_request(L_DBG, _l, request, fmt, ## __VA_ARGS__) 237 #define RDEBUG(fmt, ...) if (rad_debug_lvl || request->log.lvl) radlog_request(L_DBG, L_DBG_LVL_1, request, fmt, ## __VA_ARGS__) 238 #define RDEBUG2(fmt, ...) if (rad_debug_lvl || request->log.lvl) radlog_request(L_DBG, L_DBG_LVL_2, request, fmt, ## __VA_ARGS__) 239 #define RDEBUG3(fmt, ...) if (rad_debug_lvl || request->log.lvl) radlog_request(L_DBG, L_DBG_LVL_3, request, fmt, ## __VA_ARGS__) 240 #define RDEBUG4(fmt, ...) if (rad_debug_lvl || request->log.lvl) radlog_request(L_DBG, L_DBG_LVL_MAX, request, fmt, ## __VA_ARGS__) 241 242 #define RIDEBUG(fmt, ...) radlog_request(L_INFO, L_DBG_LVL_1, request, fmt, ## __VA_ARGS__) 243 #define RIDEBUG2(fmt, ...) radlog_request(L_INFO, L_DBG_LVL_2, request, fmt, ## __VA_ARGS__) 244 245 #define RWDEBUG(fmt, ...) if (rad_debug_lvl || request->log.lvl) radlog_request(L_DBG_WARN, L_DBG_LVL_1, request, fmt, ## __VA_ARGS__) 246 #define RWDEBUG2(fmt, ...) if (rad_debug_lvl || request->log.lvl) radlog_request(L_DBG_WARN, L_DBG_LVL_2, request, fmt, ## __VA_ARGS__) 247 248 #define REDEBUG(fmt, ...) radlog_request_error(L_DBG_ERR, L_DBG_LVL_1, request, fmt, ## __VA_ARGS__) 249 #define REDEBUG2(fmt, ...) radlog_request_error(L_DBG_ERR, L_DBG_LVL_2, request, fmt, ## __VA_ARGS__) 250 #define REDEBUG3(fmt, ...) radlog_request_error(L_DBG_ERR, L_DBG_LVL_3, request, fmt, ## __VA_ARGS__) 251 #define REDEBUG4(fmt, ...) radlog_request_error(L_DBG_ERR, L_DBG_LVL_MAX, request, fmt, ## __VA_ARGS__) 252 /** @} */ 253 254 /** Indent R* messages by one level 255 * 256 * @note Has no effect on the indentation of INFO, WARN, ERROR, DEBUG messages, 257 * only RINFO, RWARN, RERROR etc... 258 */ 259 #define RINDENT() (request->log.indent += 2) 260 261 /** Exdent (unindent) R* messages by one level 262 * 263 * @note Has no effect on the indentation of INFO, WARN, ERROR, DEBUG messages, 264 * only RINFO, RWARN, RERROR etc... 265 */ 266 #define REXDENT() (request->log.indent -= 2) 267 268 /** Output string with error marker, showing where format error occurred 269 * 270 @verbatim 271 my pet kitty 272 ^ kitties are not pets, are nature devouring hell beasts 273 @endverbatim 274 * 275 * @warning If a REQUEST * is **NOT** available, or is NULL, this macro must **NOT** be used. 276 * 277 * @param _l log category, a log_type_t value. 278 * @param _p log priority, a log_lvl_t value. 279 * @param _m string to mark e.g. "my pet kitty". 280 * @param _i index e.g. 3 (starts from 0). 281 * @param _e error e.g. "kitties are not pets, are nature devouring hell beasts". 282 */ 283 #define RMARKER(_l, _p, _m, _i, _e) radlog_request_marker(_l, _p, request, _m, _i, _e) 284 285 /** Output string with error marker, showing where format error occurred 286 * 287 * These are logged as RERROR messages. 288 * 289 @verbatim 290 my pet kitty 291 ^ kitties are not pets, are nature devouring hell beasts 292 @endverbatim 293 * 294 * @warning If a REQUEST * is **NOT** available, or is NULL, this macro must **NOT** be used. 295 * 296 * @param _m string to mark e.g. "my pet kitty". 297 * @param _i index e.g. 3 (starts from 0). 298 * @param _e error e.g. "kitties are not pets, are nature devouring hell beasts". 299 */ 300 #define REMARKER(_m, _i, _e) RMARKER(L_DBG_ERR, L_DBG_LVL_1, _m, _i, _e) 301 302 /** Output string with error marker, showing where format error occurred 303 * 304 * These are logged as RDEBUG messages. 305 * 306 @verbatim 307 my pet kitty 308 ^ kitties are not pets, are nature devouring hell beasts 309 @endverbatim 310 * 311 * @warning If a REQUEST * is **NOT** available, or is NULL, this macro must **NOT** be used. 312 * 313 * @param _m string to mark e.g. "my pet kitty". 314 * @param _i index e.g. 3 (starts from 0). 315 * @param _e error e.g. "kitties are not pets, are nature devouring hell beasts". 316 */ 317 #define RDMARKER(_m, _i, _e) RMARKER(L_DBG, L_DBG_LVL_1, _m, _i, _e) 318 319 /** Use different logging functions depending on whether request is NULL or not. 320 * 321 * @note The module must define MOD_PREFIX as its name (do this in the module 322 * header file) e.g. @code{.c}#define MOD_PREFIX "rlm_example"@endcode 323 * 324 * This is useful for areas of code which are run on server startup, and when 325 * processing requests. 326 * 327 * @param _l_request The name of a R* logging macro e.g. RDEBUG3. 328 * @param _l_global The name of a global logging macro e.g. DEBUG3. 329 * @param fmt printf style format string. 330 * @param ... printf arguments. 331 */ 332 #define MOD_ROPTIONAL(_l_request, _l_global, fmt, ...) \ 333 do {\ 334 if (request) {\ 335 _l_request(fmt, ## __VA_ARGS__);\ 336 } else {\ 337 _l_global(MOD_PREFIX " (%s): " fmt, inst->name, ## __VA_ARGS__);\ 338 }\ 339 } while (0) 340 341 /** Use different logging functions depending on whether request is NULL or not. 342 * 343 * This is useful for areas of code which are run on server startup, and when 344 * processing requests. 345 * 346 * @param _l_request The name of a R* logging macro e.g. RDEBUG3. 347 * @param _l_global The name of a global logging macro e.g. DEBUG3. 348 * @param fmt printf style format string. 349 * @param ... printf arguments. 350 */ 351 #define ROPTIONAL(_l_request, _l_global, fmt, ...) \ 352 do {\ 353 if (request) {\ 354 _l_request(fmt, ## __VA_ARGS__);\ 355 } else {\ 356 _l_global(LOG_PREFIX ": " fmt, ## __VA_ARGS__);\ 357 }\ 358 } while (0) 359 360 #define RATE_LIMIT_ENABLED rate_limit_enabled() //!< True if rate limiting is enabled. 361 /** Rate limit messages 362 * 363 * Rate limit log messages so they're written a maximum of once per second. 364 * 365 @code{.c} 366 RATE_LIMIT(RERROR("Home servers alive in pool %s", pool->name)); 367 @endcode 368 * @note Rate limits the macro, not the message. If five different messages are 369 * produced using the same macro in the same second, only the first will 370 * be written to the log. 371 * 372 * @param _x Logging macro to limit. 373 */ 374 #define RATE_LIMIT(_x) \ 375 do {\ 376 if (RATE_LIMIT_ENABLED) {\ 377 static time_t _last_complained = 0;\ 378 time_t _now = time(NULL);\ 379 if (_now != _last_complained) {\ 380 _last_complained = _now;\ 381 _x;\ 382 }\ 383 } else _x;\ 384 } while (0) 385 386 #ifdef __cplusplus 387 } 388 #endif 389 390 #endif /* FR_LOG_H */ 391