/* silclog.h Author: Johnny Mnemonic Copyright (C) 1997 - 2002 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ /****h* silcutil/SilcLogAPI * * DESCRIPTION * * The SILC logging APIs provide a powerful and easy-to-use interface to * the logging system and debugging output. * ***/ #ifndef SILCLOG_H #define SILCLOG_H /****d* silcutil/SilcLogAPI/SilcLogType * * NAME * * typedef enum { ... } SilcLogType; * * DESCRIPTION * * This is the main logging channel id. There are currently four known * logging channels (plus the debugging output channel), and they are * ordered by importance. * See the source code for SILC coding conventions about how choosing * the right output channel. * * SOURCE */ typedef enum { /* Generic info channel file */ SILC_LOG_INFO, /* This should be used for warnings and non critical failures */ SILC_LOG_WARNING, /* Generic error and critical failures messages */ SILC_LOG_ERROR, /* Fatal messages (usually situations that will lead to a program crash */ SILC_LOG_FATAL, /* Total logging channels */ SILC_LOG_MAX } SilcLogType; /***/ /****f* silcutil/SilcLogAPI/SilcLogCb * * SYNOPSIS * * typedef bool (*SilcLogCb)(SilcLogType type, char *message, * void *context); * * DESCRIPTION * * The logging custom callback function. The `type' is the channel ID * that triggered the event, which allows you to use the same callback * function for multiple logging channels. * The `message' parameter points to a null-terminated buffer containing * the received message, while `context' is the caller-specified context. * The message must not be modified or freed by the callback function. * * SEE ALSO * silc_log_set_callback * ***/ typedef bool (*SilcLogCb)(SilcLogType type, char *message, void *context); /****f* silcutil/SilcLogAPI/SilcLogDebugCb * * SYNOPSIS * * typedef bool (*SilcLogDebugCb)(char *file, char *function, int line, * char *message, void *context); * * DESCRIPTION * * The debug logging callback function. The default behaviour is to * output messages to stderr. `file', `function', and `line' are the * corresponding offsets in the source files. `message' points to a * null-terminated buffer containing the debugging message, and `context' * is the caller-specified context. * The message must not be modified or freed by the callback function. * If the function returns TRUE, SilcLog will assume the message as handled * and won't run its default handler. * * SEE ALSO * silc_debug, silc_log_set_debug_callbacks * ***/ typedef bool (*SilcLogDebugCb)(char *file, char *function, int line, char *message, void *context); /****f* silcutil/SilcLogAPI/SilcLogHexdumpCb * * SYNOPSIS * * typedef bool (*SilcDebugHexdumpCb)(char *file, char *function, int line, * unsigned char *data, uint32 data_len, * char *message, void *context; * * DESCRIPTION * * The hexdump logging callback function. The default behaviour is to * print a formatted hexdump to stderr, and is commonly what you would it * like to be. `file', `function', and `line' are the corresponding * offsets in the source files. `data' is the begin of the buffer that * should be hexdumped, which is `data_len' bytes long. * The `message' parameter points to a null-terminated buffer containing * the received message, while `context' is the caller-specified context. * The message must not be modified or freed by the callback function. * If the function returns TRUE, SilcLog will assume the message as handled * and won't run its default handler. * * SEE ALSO * silc_debug_hexdump, silc_log_set_debug_callbacks * ***/ typedef bool (*SilcLogHexdumpCb)(char *file, char *function, int line, unsigned char *data, uint32 data_len, char *message, void *context); /* Global Variables */ /****v* silcutil/SilcLogAPI/silc_log_quick * * NAME * * bool silc_log_quick -- enable/disable fast logging output * * DESCRIPTION * * SilcLog makes use of libc stream buffering output, which means that it * saves HD activity by buffering the logging messages and writing them * all together every some minutes (default is 5 minutes). * Setting this variable to TRUE will force SilcLog to write messages to the * filesystem as soon as they are received. This increases the CPU activity * notably on bigger servers, but reduces memory usage. * If you want to change the logging style on-the-fly, make sure to call * silc_log_flush_all() after setting this variable to TRUE. * ***/ extern bool silc_log_quick; /****v* silcutil/SilcLogAPI/silc_debug * * NAME * * bool silc_debug -- enable/disable debugging output * * DESCRIPTION * * If silc_debug is set to FALSE, debugging functions won't procude any * output. This is useful when for example you compile in the debugging * support but at a certain point you want to send the program in the * background. * * SEE ALSO * SILC_LOG_DEBUG * ***/ extern bool silc_debug; /****v* silcutil/SilcLogAPI/silc_debug_hexdump * * NAME * * bool silc_debug_hexdump -- enable/disable debugging output * * DESCRIPTION * * If silc_debug_hexdump is set to FALSE, debugging functions won't produce * any output. This is useful when for example you compile in the debugging * support but at a certain point you want to send the program in the * background. * * SEE ALSO * SILC_LOG_HEXDUMP * ***/ extern bool silc_debug_hexdump; /* Macros */ #ifdef WIN32 #define __FUNCTION__ "" #endif /****d* silcutil/SilcLogAPI/SILC_LOG_INFO * * NAME * * #define SILC_LOG_INFO(...) * * DESCRIPTION * * This macro is a wrapper to the main logging function. * It supports variable argument list formatting, and *automatically* * appends newline at the end of the string. * * NOTES * * This macro requires double parenthesis to ensure that the VA list * formatting would work correctly. * * EXAMPLE * * SILC_LOG_INFO(("Today i feel %s", core->mood)); * * SOURCE */ #define SILC_LOG_INFO(fmt) silc_log_output(SILC_LOG_INFO, silc_format fmt) /***/ /****d* silcutil/SilcLogAPI/SILC_LOG_WARNING * * NAME * * #define SILC_LOG_WARNING(...) * * DESCRIPTION * * Wrapper to the WARNING logging channel. * Please see the SILC_LOG_INFO macro. * * SEE ALSO * SILC_LOG_INFO * * SOURCE */ #define SILC_LOG_WARNING(fmt) silc_log_output(SILC_LOG_WARNING, silc_format fmt) /***/ /****d* silcutil/SilcLogAPI/SILC_LOG_ERROR * * NAME * * #define SILC_LOG_ERROR(...) * * DESCRIPTION * * Wrapper to the ERROR logging channel. * Please see the SILC_LOG_INFO macro. * * SEE ALSO * SILC_LOG_INFO * * SOURCE */ #define SILC_LOG_ERROR(fmt) silc_log_output(SILC_LOG_ERROR, silc_format fmt) /***/ /****d* silcutil/SilcLogAPI/SILC_LOG_FATAL * * NAME * * #define SILC_LOG_FATAL(...) * * DESCRIPTION * * Wrapper to the FATAL logging channel. * Please see the SILC_LOG_INFO macro. * * SEE ALSO * SILC_LOG_INFO * * SOURCE */ #define SILC_LOG_FATAL(fmt) silc_log_output(SILC_LOG_FATAL, silc_format fmt) /***/ /****d* silcutil/SilcLogAPI/SILC_LOG_DEBUG * * NAME * * #define SILC_LOG_DEBUG(...) * * DESCRIPTION * * This is a special wrapper to the debugging output (usually stderr). * The standard behaviour is the same as SILC_LOG_INFO, but this macro * also depends on the global debugging macro SILC_DEBUG. * Undefining the global SILC_DEBUG define causes these functions to be * defined to an empty value, thus removing all logging calls from the * compiled program. * * SEE ALSO * SILC_LOG_INFO * * SOURCE */ #ifdef SILC_DEBUG #define SILC_LOG_DEBUG(fmt) silc_log_output_debug(__FILE__, \ __FUNCTION__, \ __LINE__, \ silc_format fmt) #else #define SILC_LOG_DEBUG(fmt) #endif /* SILC_DEBUG */ /***/ /****d* silcutil/SilcLogAPI/SILC_LOG_HEXDUMP * * NAME * * #define SILC_LOG_HEXDUMP(...) * * DESCRIPTION * * This is a special wrapper to the hexdump output function. This macro * behaves slightly differently from other logging wrappers. * The first parameter, is composed by a group of parameters delimited by * parenthesis. * The second parameter is a (char *) pointer to the beginning of the * memory section that should be hexdumped, and the third parameter is * the length of this memory section. * This macro is also affected by the global variable silc_debug_hexdump. * Undefining the global SILC_DEBUG define causes these functions to be * defined to an empty value, thus removing all logging calls from the * compiled program. * * EXAMPLE * * SILC_LOG_HEXDUMP(("Outgoing packet [%d], len %d", pckt->seq, pckt->len), * pckt->data, pckt->datalen); * * SOURCE */ #ifdef SILC_DEBUG #define SILC_LOG_HEXDUMP(fmt, data, len) silc_log_output_hexdump(__FILE__, \ __FUNCTION__, \ __LINE__, \ (data), (len), \ silc_format fmt) #else #define SILC_LOG_HEXDUMP(fmt, data, len) #endif /* SILC_DEBUG */ /***/ /* Prototypes */ /****f* silcutil/SilcLogAPI/silc_log_output * * SYNOPSIS * * void silc_log_output(SilcLogType type, char *string); * * DESCRIPTION * * This is the main function for logging output. Please note that you * should rather use one of the logging wrapper macros. * If you really want to use this function, its usage is quite simple. * The `type' parameter identifies the channel to use, while the `string' * parameter must be a dynamic allocated (null-terminated) buffer, because * it will be freed at the end of this function, for internal reasons. * If there are registered callbacks for the specified type, this function * will first trigger those callbacks. The callback functions must NOT * free or modify the original buffer. * * SEE ALSO * SILC_LOG_INFO, SILC_LOG_WARNING, SILC_LOG_ERROR, SILC_LOG_FATAL * ***/ void silc_log_output(SilcLogType type, char *string); /****f* silcutil/SilcLogAPI/silc_log_get_file * * SYNOPSIS * * char *silc_log_get_file(SilcLogType type); * * DESCRIPTION * * Returns the current logging file for the channel `type'. * If there has been an error during the opening of this channel, NULL * is returned, even if the file has been previously set with * silc_log_set_file(). * The returned pointer points to internally allocated storage and must * must not be freed, modified or stored. * ***/ char *silc_log_get_file(SilcLogType type); /****f* silcutil/SilcLogAPI/silc_log_set_file * * SYNOPSIS * * bool silc_log_set_file(SilcLogType type, char *filename, uint32 maxsize, * SilcSchedule scheduler); * * DESCRIPTION * * Sets `filename', which can be maximum `maxsize' bytes long, as the new * logging file for the channel `type'. If you specify an illegal filename * a warning message is printed and FALSE is returned. In this case * logging settings are not changed. * You can disable logging for a channel by specifying NULL filename, the * maxsize in this case is not important. * The `scheduler' parameter is needed by the internal logging to allow * buffered output and thus to save HD activity. * ***/ bool silc_log_set_file(SilcLogType type, char *filename, uint32 maxsize, SilcSchedule scheduler); /****f* silcutil/SilcLogAPI/silc_log_set_callback * * SYNOPSIS * * void silc_log_set_callback(SilcLogType type, SilcLogCb cb, * void *context); * * DESCRIPTION * * Set `cb' as the default callback function for the logging channel * `type'. When SilcLog receives a message for this channel, it will * trigger the callback function. If the callback function returns TRUE * SilcLog will assume the input as handled and won't run its default * handler. * You can disable/remove a callback by setting it to NULL or calling the * function silc_log_reset_callbacks. * If set, the callback function must be in the form described by * SilcLogCb. * * SEE ALSO * SilcLogCb, silc_log_reset_callbacks * ***/ void silc_log_set_callback(SilcLogType type, SilcLogCb cb, void *context); /****f* silcutil/SilcLogAPI/silc_log_reset_callbacks * * SYNOPSIS * * void silc_log_reset_callbacks(); * * DESCRIPTION * * Removes all logging callbacks for normal channels. This function does * NOT remove callbacks for debugging channels (debug and hexdump), you * rather need to call silc_log_set_debug_callbacks() with NULL callbacks. * ***/ void silc_log_reset_callbacks(); /****f* silcutil/SilcLogAPI/silc_log_flush_all * * SYNOPSIS * * void silc_log_flush_all(); * * DESCRIPTION * * Forces flushing for all logging channels. This should be called for * example after receiving special signals. * * SEE ALSO * silc_log_quick * ***/ void silc_log_flush_all(); /****f* silcutil/SilcLogAPI/silc_log_reset_all * * SYNOPSIS * * void silc_log_reset_all(); * * DESCRIPTION * * Forces all logging channels to close and reopen their streams. Useful * for example after a SIGHUP signal. * Please note that this function could cause some warning messages if * some logging channel points to an illegal filename. * ***/ void silc_log_reset_all(); /****f* silcutil/SilcLogAPI/silc_log_output_debug * * SYNOPSIS * * void silc_log_output_debug(char *file, char *function, * int line, char *string); * * DESCRIPTION * * This is the main function for debug output. Please note that you should * rather use the wrapper macro SILC_LOG_DEBUG. * If you want to use it anyway, the `file', `function', and `line' are the * corresponding offsets in the source files, while `string' must be a * dynamic allocated (null-terminated) buffer. * ***/ void silc_log_output_debug(char *file, char *function, int line, char *string); /****f* silcutil/SilcLogAPI/silc_log_output_hexdump * * SYNOPSIS * * void silc_log_output_hexdump(char *file, char *function, * int line, void *data_in, * uint32 len, char *string); * * DESCRIPTION * * This is the main function for hexdump output. Please note that you * should rather use the wrapper macro SILC_LOG_HEXDUMP. * If you want to use it anyway, the `file', `function', and `line' are the * corresponding offsets in the source files, `data_in' is the beginning * of the buffer you wish to hexdump, which is `len' bytes long. * `string' must be a dynamic allocated (null-terminated) buffer. * ***/ void silc_log_output_hexdump(char *file, char *function, int line, void *data_in, uint32 len, char *string); /****f* silcutil/SilcLogAPI/silc_log_set_debug_callbacks * * SYNOPSIS * * void silc_log_set_debug_callbacks(SilcLogDebugCb debug_cb, * void *debug_context, * SilcLogHexdumpCb hexdump_cb, * void *hexdump_context); * * DESCRIPTION * * Sets `debug_cb' as the the default callback function for the debug * output, that will be called with the `debug_context' parameter. * When SilcLog receives a debug message, it will trigger the callback * function. If the callback function returns TRUE SilcLog will assume * the input as handled and won't run its default handler. * `hexdump_cb' and `hexdump_context' works the same way, except that they * are referred to SILC_LOG_HEXDUMP requests. * You can disable/remove a callback by setting it to NULL. * If set, each callback function must be either in the form described by * SilcLogDebugCb or SilcLogHexdumpCb. * * SEE ALSO * SilcLogDebugCb, SilcLogHexdumpCb * ***/ void silc_log_set_debug_callbacks(SilcLogDebugCb debug_cb, void *debug_context, SilcLogHexdumpCb hexdump_cb, void *hexdump_context); /****f* silcutil/SilcLogAPI/silc_log_set_debug_string * * SYNOPSIS * * void silc_log_set_debug_string(const char *debug_string); * * DESCRIPTION * * Sets `debug_string' as the regexp string for filtering debugging * output. The string is copied and it can be modified/destroyed after * this function call. * ***/ void silc_log_set_debug_string(const char *debug_string); #endif /* !SILCLOG_H */