1 /* 2 ** Copyright (C) 2001-2020 by Carnegie Mellon University. 3 ** 4 ** @OPENSOURCE_LICENSE_START@ 5 ** See license information in ../../LICENSE.txt 6 ** @OPENSOURCE_LICENSE_END@ 7 */ 8 9 /* 10 ** sklog.h 11 ** 12 ** Function prototypes for writing messages to log files. 13 ** 14 */ 15 #ifndef _LOG_H 16 #define _LOG_H 17 #ifdef __cplusplus 18 extern "C" { 19 #endif 20 21 #include <silk/silk.h> 22 23 RCSIDENTVAR(rcsID_LOG_H, "$SiLK: sklog.h ef14e54179be 2020-04-14 21:57:45Z mthomas $"); 24 25 #include <syslog.h> 26 27 /** 28 * @file 29 * 30 * Functions to write messages to log files or to the system log 31 * (syslog). 32 * 33 * This file is part of libsilk. 34 */ 35 36 37 /* 38 * These wrapper functions invoke syslog() or fprintf(). The 39 * syslog level is implied by the function's name (see syslog(3)) 40 * and are listed here from most severe to least. This functions 41 * have the same caveats as sklog(). 42 * 43 * These functions always return 0; they return a value to be 44 * consistent with printf and sk_msg_fn_t. 45 */ 46 #ifdef TEST_PRINTF_FORMATS 47 # define EMERGMSG printf 48 # define ALERTMSG printf 49 # define CRITMSG printf 50 # define ERRMSG printf 51 # define WARNINGMSG printf 52 # define NOTICEMSG printf 53 # define INFOMSG printf 54 # define DEBUGMSG printf 55 #else 56 int 57 EMERGMSG( 58 const char *fmt, 59 ...) 60 SK_CHECK_PRINTF(1, 2); 61 int 62 ALERTMSG( 63 const char *fmt, 64 ...) 65 SK_CHECK_PRINTF(1, 2); 66 int 67 CRITMSG( 68 const char *fmt, 69 ...) 70 SK_CHECK_PRINTF(1, 2); 71 int 72 ERRMSG( 73 const char *fmt, 74 ...) 75 SK_CHECK_PRINTF(1, 2); 76 int 77 WARNINGMSG( 78 const char *fmt, 79 ...) 80 SK_CHECK_PRINTF(1, 2); 81 int 82 NOTICEMSG( 83 const char *fmt, 84 ...) 85 SK_CHECK_PRINTF(1, 2); 86 int 87 INFOMSG( 88 const char *fmt, 89 ...) 90 SK_CHECK_PRINTF(1, 2); 91 int 92 DEBUGMSG( 93 const char *fmt, 94 ...) 95 SK_CHECK_PRINTF(1, 2); 96 #endif 97 98 99 /* 100 * Available features; pass to sklogSetup(). 101 */ 102 /** Enable options for use of syslog() */ 103 #define SKLOG_FEATURE_SYSLOG 1 104 /** Enable options that mimic the legacy logging */ 105 #define SKLOG_FEATURE_LEGACY 2 106 107 108 /* 109 * TRACEMSG() messages should use DEBUGMSG. See sktracemsg.h. 110 */ 111 #ifndef TRACEMSG_FUNCTION 112 # define TRACEMSG_FUNCTION DEBUGMSG 113 #endif 114 115 116 /** 117 * Signature of function callbacked that will be invoked to lock 118 * and unlock the log. These functions are set by 119 * sklogSetLocking(). 120 */ 121 typedef int (*sklog_lock_fn_t)( 122 void *caller_data); 123 124 125 /** 126 * Signature of function that will produce a time/machine stamp on 127 * each log message. Function should write the stamp into the 128 * beginning of the buffer and return the strlen() of the text it 129 * added. The text should probably include a trailing ": ". 130 */ 131 typedef size_t (*sklog_stamp_fn_t)( 132 char *buffer, 133 size_t buffer_size); 134 135 136 /** 137 * Writes a message with the specified 'priority' to the log. 138 * Requires that sklogSetup() has created the log, that 139 * sklogSetDestination() has been called, and that sklogOpen() has 140 * opened the log. Writing to an unopend log produces no error and 141 * no message. 142 */ 143 #ifdef TEST_PRINTF_FORMATS 144 #define sklog(priority, ...) printf(__VA_ARGS__) 145 #else 146 void 147 sklog( 148 int priority, 149 const char *fmt, 150 ...) 151 SK_CHECK_PRINTF(2, 3); 152 #endif 153 154 155 /** 156 * Return a non-zero value if the current logging level includes 157 * 'level', where 'level' is one of the syslog macros LOG_EMERG, 158 * LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, 159 * or LOG_DEBUG. 160 * 161 * Return 0 if messages at 'level' are not being written to the log. 162 * 163 * Since SiLK 3.17.0. 164 */ 165 int 166 sklogCheckLevel( 167 int level); 168 169 170 /** 171 * Closes the log. The log can be re-opened by calling 172 * sklogOpen(). 173 */ 174 void 175 sklogClose( 176 void); 177 178 179 /** 180 * Creates an internal buffer holding the command line used to 181 * invoke the application from the specified 'argc' and 'argv' and 182 * writes it to the log. If the log is not yet opened, the buffer 183 * will be written once sklogOpen() is called. 184 */ 185 void 186 sklogCommandLine( 187 int argc, 188 char * const *argv); 189 190 191 /** 192 * Disable log rotation once the log has been opened. Once this 193 * function has been called, there is no way to re-enable log 194 * rotation. 195 * 196 * This function should be called in the child process after a call 197 * to fork() to avoid having multiple processes attempt to rotate 198 * the log file. 199 */ 200 void 201 sklogDisableRotation( 202 void); 203 204 205 /** 206 * This function is only available when using libsilk-thrd. 207 * 208 * Configure the log for use in a multithreaded environemnt. This 209 * function creates a mutex and calls the sklogSetLocking() 210 * function with the necessary function pointers. This function 211 * returns the value returned by sklogSetLocking(); i.e., it 212 * returns 0 unless sklogSetup() has not yet been called. 213 * 214 * If the multithreaded program calls fork(), the child process 215 * should first call sklogSetLocking() using NULL for all 216 * parameters. This ensures that the (single-threaded) child 217 * process ignores the log-file lock that the parent may have held 218 * when fork() was called. Next the child should call 219 * sklogDisableRotation() to ensure it does not attempt to rotate 220 * the log-file. 221 */ 222 int 223 sklogEnableThreadedLogging( 224 void); 225 226 227 /** 228 * Return the file handle to the log file or rotated log file. 229 * Return NULL if syslog or no logging is being used, or if the log 230 * has not yet been opened. 231 */ 232 FILE * 233 sklogGetDestination( 234 void); 235 236 237 /** 238 * Fill the character array 'buf' with the name of the logging 239 * directory as set by sklogSetDirectory() and return a pointer to 240 * 'buf'. Returns NULL if a log-directory has not been specified, 241 * or if the logging directory is longer than 'bufsize' characters. 242 */ 243 char * 244 sklogGetDirectory( 245 char *buf, 246 size_t bufsize); 247 248 249 /** 250 * Return the current level for log messages. Return NULL before 251 * sklogSetup() is called and after sklogTeardown() is called. 252 * 253 * Since SiLK 3.11.0. 254 */ 255 const char * 256 sklogGetLevel( 257 void); 258 259 260 /** 261 * Return the current mask for log messages. Return 0 before 262 * sklogSetup() is called and after sklogTeardown() is called. 263 * 264 * Since SiLK 3.11.0. 265 */ 266 int 267 sklogGetMask( 268 void); 269 270 271 /** 272 * Similar to sklog(), but returns without logging the message if 273 * the log is already locked. 274 */ 275 void 276 sklogNonBlock( 277 int priority, 278 const char *fmt, 279 ...) 280 SK_CHECK_PRINTF(2, 3); 281 282 283 /** 284 * Opens the log. This function requires that sklogSetup() and 285 * sklogSetDestination() be called beforehand. Return 0 on 286 * success, or -1 if the log cannot be opened. 287 */ 288 int 289 sklogOpen( 290 void); 291 292 293 /** 294 * Verifies that all the required options have been specified and 295 * that valid values were given. When an invalid option is found, 296 * an error message will be printed. Returns -1 if there is an 297 * issue with an option; returns 0 on success. 298 */ 299 int 300 sklogOptionsVerify( 301 void); 302 303 304 /** 305 * Print the usage of the options defined by this library to the 306 * specified file handle. 307 */ 308 void 309 sklogOptionsUsage( 310 FILE *fp); 311 312 313 /** 314 * Redirect the standard output and standard error as follows: 315 * 316 * If log messages are going to a local file, redirect stdout and 317 * stderr to write to that file. 318 * 319 * If log messages are going to either stdout or stderr, do not 320 * redirect anything. This also includes the case where messages 321 * are going to both syslog and stderr. 322 * 323 * If logging is disabled or if the messages are going to syslog 324 * exclusively, redirect stdout and stderr to /dev/null. 325 * 326 * This function may only be called after the log has been opened. 327 * 328 * Return 0 on success. On failure, write an error message into 329 * 'buf' (when provided) and return -1. 330 */ 331 int 332 sklogRedirectStandardStreams( 333 char *buf, 334 size_t bufsize); 335 336 337 /** 338 * Set the destination for the log messages. This should be the 339 * full path to the log file, or the strings 'none' for no logging, 340 * 'stdout' to log to the standard output, 'stderr' to log to the 341 * standard error, 'syslog' to log with syslog(3), or 'both' to log 342 * to both syslog and the standard error. Note that 'both' is only 343 * available on systems where LOG_PERROR is defiend. 344 * 345 * This function must be called after sklogSetup() and prior to 346 * sklogOpen()ing the log. 347 * 348 * Returns 0 on success, or -1 on error (not a full path). 349 * 350 * See also sklogSetDirectory(). 351 */ 352 int 353 sklogSetDestination( 354 const char *destination); 355 356 357 /** 358 * This function is provided for backward compatibility. We 359 * recommend the use of syslog(3) instead. 360 * 361 * Set the destination for log messages to multiple files in the 362 * directory 'dir_name', using 'base_name' as part of the basename 363 * for the files, and the current date as the remainder of the 364 * name. The format of the files will be 365 * 366 * <dir_name>/<base_name>-YYYYMMDD.log 367 * 368 * The files will be rotated when they receive the first message 369 * after midnight local time. The previous day's log file will be 370 * compressed. 371 * 372 * If 'base_name' is NULL, the string returned by skAppName() is 373 * used. 374 * 375 * This function must be called after sklogSetup() and prior to 376 * sklogOpen()ing the log. 377 * 378 * Return 0 on success, or -1 if 'dir_name' does not exist, 379 * 'base_name' contains a '/', or the combined path is too long. 380 */ 381 int 382 sklogSetDirectory( 383 const char *dir_name, 384 const char *base_name); 385 386 387 /** 388 * When using syslog(3) for logging, this determines the facility 389 * to use. This can only be called prior to sklogOpen(). The 390 * facility is ignored unless syslog(3) is used. 391 */ 392 int 393 sklogSetFacility( 394 int facility); 395 396 397 /** 398 * Set the facility for syslog(3) by name or by a C-string that is 399 * parsable as a number or a recognized name. Recognized names are 400 * the values 'user', 'daemon', and 'local0'..'local7'. Other 401 * facilities must be set by value. 402 */ 403 int 404 sklogSetFacilityByName( 405 const char *name_or_number); 406 407 408 /** 409 * Sets the log level to all levels up to and including the level 410 * named by 'level'. This may be called at any time after 411 * sklogSetup(). Returns 0 on success, or -1 if 'level' is not a 412 * valid level. 413 * 414 * The valid levels are: "emerg", "alert", "crit", "err", 415 * "warning", "notice", "info", "debug". 416 */ 417 int 418 sklogSetLevel( 419 const char *level); 420 421 422 /** 423 * Set functions that lock and unlock the log when a logging 424 * mechanism other than syslog(3) is used. These functions should 425 * be set in a multi-threaded application so that messages from 426 * different threads are kept distinct. The 'locker' function will 427 * be called to lock the log; the 'unlocker' function to unlock it. 428 * The value in 'data' will be passed to these functions. 429 * 430 * The function in 'try_locker' is used when sklogNonBlock() is 431 * called. The function should lock the log and return 0 if it is 432 * currently unlocked, or immediately return a non-zero value. 433 * 434 * This function must be called after sklogSetup(). The function 435 * returns 0 unless sklogSetup() has not yet been called, in which 436 * case -1 is returned. 437 * 438 * This function can be called multiple times to modify the locking 439 * mechanism, and it can be called with all arguments set to NULL 440 * to disable log file locking. Changing or disabling the locking 441 * in a multi-threaded environment or when the log file is locked 442 * is undefined. 443 * 444 * See also the sklogEnableThreadedLogging() function. 445 */ 446 int 447 sklogSetLocking( 448 sklog_lock_fn_t locker, 449 sklog_lock_fn_t unlocker, 450 sklog_lock_fn_t try_locker, 451 void *data); 452 453 454 /** 455 * Set the mask for log messages. This may be set at any time 456 * after calling setup. Returns the old log mask. Use the syslog 457 * macro LOG_UPTO() to specify the mask for this function. 458 */ 459 int 460 sklogSetMask( 461 int mask); 462 463 464 /** 465 * Specify that 'command' is to run on the newly closed log file 466 * after log roation. If 'command' is the empty string, no action 467 * is taken. If 'command' is NULL, the default action of 468 * compressing the log file is taken. 469 * 470 * Return 0 on success. If log-rotation is not active, print a 471 * message and return 0. On failure, print an error message and 472 * return -1. 473 * 474 * The following %-conversions are supported: %s is the full path 475 * to the closed file, and %% is the character '%'. 476 */ 477 int 478 sklogSetPostRotateCommand( 479 const char *command); 480 481 482 /** 483 * Sets the function that will be used to prefix each log message 484 * when a logging mechanism other than syslog(3) is used. If this 485 * function is not called, a default stamping function is used. 486 * This function must be called after sklogSetup() and before 487 * sklogOpen(). 488 */ 489 int 490 sklogSetStampFunction( 491 sklog_stamp_fn_t makestamp); 492 493 494 /** 495 * Sets up the sklog module by initializing all memory. The module 496 * will register the options appropriate for the 'feature_list' 497 * requested. The available features are macros defined above as 498 * SKLOG_FEATURE_*. Returns 0 unless there was a problem 499 * registering the options. 500 */ 501 int 502 sklogSetup( 503 int feature_list); 504 505 506 /** 507 * Frees and clears all memory associated with the log. If the log 508 * is opened it will be closed. 509 */ 510 void 511 sklogTeardown( 512 void); 513 514 515 /** 516 * Prototypes that match sk_msg_vargs_fn_t 517 */ 518 int 519 EMERGMSG_v( 520 const char *fmt, 521 va_list args) 522 SK_CHECK_PRINTF(1, 0); 523 int 524 ALERTMSG_v( 525 const char *fmt, 526 va_list args) 527 SK_CHECK_PRINTF(1, 0); 528 int 529 CRITMSG_v( 530 const char *fmt, 531 va_list args) 532 SK_CHECK_PRINTF(1, 0); 533 int 534 ERRMSG_v( 535 const char *fmt, 536 va_list args) 537 SK_CHECK_PRINTF(1, 0); 538 int 539 WARNINGMSG_v( 540 const char *fmt, 541 va_list args) 542 SK_CHECK_PRINTF(1, 0); 543 int 544 NOTICEMSG_v( 545 const char *fmt, 546 va_list args) 547 SK_CHECK_PRINTF(1, 0); 548 int 549 INFOMSG_v( 550 const char *fmt, 551 va_list args) 552 SK_CHECK_PRINTF(1, 0); 553 int 554 DEBUGMSG_v( 555 const char *fmt, 556 va_list args) 557 SK_CHECK_PRINTF(1, 0); 558 559 560 /** 561 * Writes a message with the specified 'priority' to the log. 562 * Requires that sklogSetup() has created the log, that 563 * sklogSetDestination() has been called, and that sklogOpen() has 564 * opened the log. 565 */ 566 void 567 sklogv( 568 int priority, 569 const char *fmt, 570 va_list args) 571 SK_CHECK_PRINTF(2, 0); 572 573 #ifdef __cplusplus 574 } 575 #endif 576 #endif /* _LOG_H */ 577 578 /* 579 ** Local Variables: 580 ** mode:c 581 ** indent-tabs-mode:nil 582 ** c-basic-offset:4 583 ** End: 584 */ 585