Files
libucore/include/ucore/logging.h
T
Nils O. Selåsdal 84153e90db Make UC_LL_NONE work
2013-06-20 19:55:09 +02:00

310 lines
9.8 KiB
C

#ifndef UCORE_LOGGING_H_
#define UCORE_LOGGING_H_
/** Logging functions.
* All logging functions except uc_log_init are thread safe,
* so logging can be performed from any thread after the logging
* system have been initialized.
*
* The logging system has the concept of 'modules'. Modules are defined
* by the application, and would match the logical parts of an application.
* uc_log_init() tells the logging library about these modules, and would normally
* be used like:
*
* enum {
* POLLER,
* DB,
* IO
*};
*
* struct uc_log_module modules[] = {
* {
* .id = POLLER,
* .short_name = "POLLER",
* .long_name = "Poller thread",
* .log_level = UC_LL_DEBUG,
* },
* {
* .id = DB,
* .short_name = "DB",
* .long_name = "Database handler",
* .log_level == UC_LL_DEBUG
* },
* {
* .id = IO,
* .short_name = "IO",
* .long_name = "I/O worker",
* .log_level == UC_LL_DEBUG
* }
* };
* struct uc_log_modules m = {
* .mods = modules,
* .cnt = ARRAY_SIZE(modules)
* };
*
* uc_log_init(&m);
*
* So the application defines 3 modules logging
* will be categorized by.
* Note that the values (the enum in this case)
* defining all the .id memmbers of uc_log_module
* must start at 0 and be concecutive.
*
* Now, the database code in the application can do
* logging as e.g.
*
* UC_LOGF(UC_LL_INFO, DB, "connecting to server %s\n", ip);
*
* And the resulting log line will include the short_name
* modules[DB].short_name
*
* Log levels of the messages logged are checked first
* by the log_level of the uc_log_destination, and then
* by the log_level of the module for that destination.
*
* Thus for a message to actually be logged the level
* must be above the overall log level for the destination and
* the log level of the module.
*/
#ifdef __cplusplus
extern "C" {
#endif
/** The log levels defined by ucore logging
* UC_LL_NONE must not be used in logging statements - but
* can be used to suppress all logging for a destination or module*/
enum UC_LOG_LEVEL {
UC_LL_DEBUG = 1,
UC_LL_INFO = 3,
UC_LL_WARNING = 5,
UC_LL_ERROR = 7,
UC_LL_NONE = 9,
};
/** A destination for the logging messages*/
enum UC_LOG_DESTINATION {
/** Logs using the unix syslog system */
UC_LDEST_SYSLOG,
/** Prints log messages to stderr. */
UC_LDEST_STDERR,
/** Prints log messages to a file */
UC_LDEST_FILE,
};
/** A module of a program, that will perform logging.
* This is used group logging from parts of a larger program,
* and allow the log message to identigy which module the
* log message originates from
*/
struct uc_log_module {
/** The id of the log module.
* This is the id one specifies in the various log
* functions/macros.
* Within the struct uc_log_modules, this id must start
* at 0 and be incremented consecutively, being equal
* to the index within struct uc_log_modules.mods
*/
int id;
/** A short name for the module.
* This will appear in log messages */
const char *short_name;
/** A longer description for the log module*/
const char *long_name;
/** The log level of this module. Only
* log statements with a level >= the log_level
* are actually logged, but the log_level of a destination
* can restrict the logging further*/
int log_level;
};
/* A collection of struct uc_log_module */
struct uc_log_modules {
/* Pointer to the first element of the array */
struct uc_log_module *mods;
/** The number of elements in the mods array. */
int cnt;
};
struct uc_log_destination;
/* Returns a string representation of the log level.
*
* @param ll The log level
* @return String representation of the log level. (This will be a string literal)
*/
const char *uc_ll_2_str(enum UC_LOG_LEVEL l);
/* creates a new uc_log_destination for printing on stderr.
*
* @param log_level log level of this destination. only log messages
* with a log level >= the log level of the destination are actually logged.
* @param log_location whether to log info about the source file and line number
* in a log message.
*
* @return An opaque uc_log_destination that can be added as a destination to
* the ucore logging system
*/
struct uc_log_destination *uc_log_new_stderr(int log_level, int log_location);
/* creates a new uc_log_destination for logging to syslog
*
* @param ident The ident as used in the syslog openlog() funcion
* @param facility The facility as used in the syslog openlog() function()
* @param log_level log level of this destination. only log messages
* with a log level >= the log level of the destination are actually logged.
* @param log_location whether to log info about the source file and line number
* in a log message.
* @return An opaque uc_log_destination that can be added as a destination to
* the ucore logging system
*/
struct uc_log_destination *uc_log_new_syslog(const char *ident, int facility, int log_level, int log_location);
/* creates a new uc_log_destination for printing on stderr.
*
* @param log_level log level of this destination. only log messages
* with a log level >= the log level of the destination are actually logged.
* @param log_location whether to log info about the source file and line number
* in a log message.
* @param return An opaque uc_log_destination that can be added as a destination to
* the ucore logging system
*/
struct uc_log_destination *uc_log_new_file(const char *filename, int log_level, int log_location);
/** Add a uc_log_destination to the logging system.
*
* @param dest The uc_log_destination to add.
*/
void uc_log_add_destination(struct uc_log_destination *dest);
/** Remove a log destination.
* Note that this does not free the destination, it can be readded later.
* For file destination, the log file is NOT closed.
*
* @param dest The uc_log_destination to remove.
*/
void uc_log_remove_destination(struct uc_log_destination *dest);
/** Change the log level of a destination..
*
* @param dest destination for which to set the log level
* @param level The new log level
*/
void uc_log_destination_set_loglevel(struct uc_log_destination *dest, enum UC_LOG_LEVEL level);
/** Change whether to log the location (file/line no.) of logging
* output on a destination,
*
* @param dest log destination to change
* @param log_location 1=log the locaton, 0=don't log the location
*/
void uc_log_destination_set_log_location(struct uc_log_destination *dest, int log_location);
/** Remove and free a destination.
* This frees the memory allocated to the destination. For
* UC_LDEST_FILE the log file is closed.
*
* If the destination is not already removed, it will be removed first,
* there's no need to call uc_log_remove_destination first.
* The destination cannot be used again after this function has been called.
*
* @param dest The destination to delete.
*/
void uc_log_delete_destination(struct uc_log_destination *dest);
/** Set the log level for a particular module on this destination
*
* @param dest destination to chang
* @param moudle the module id to change
* @param log_level new log level to set for the module
*/
void uc_log_destination_set_module_loglevel(
struct uc_log_destination *dest,
int module,
enum UC_LOG_LEVEL log_level
);
/** Set the log mask for the given destination.
* The log_mask is a string specifying the log levels for
* the modules logged by this destination.
* The log_level of the destination itself takes priority
* over the log_level of the modules.
* The format of the log_mask string is.
*
* SHORT_NAME_1=LEVEL:SHORT_NAME_2=LEVEL:SHORT_NAME_N=LEVEL
*
* The SHORT_NAME_N is the .short_name within a struct uc_log_module
* LEVEL is one of DEBUG,INFO, WARNING or ERROR
* Example:
* DB=DEBUG:IO=ERROR:POLLER=INFO
*
* Modules not mentioned in the string retain their default value.
* No whitespaces must be specifed before/after the : or = character
*
* @param dest destination to set the log mask on
* @parama log_mask the log mask as described above to set.
*/
void uc_log_destination_set_mask(
struct uc_log_destination *dest,
const char *log_mask
);
/** Closes and re-opens all the UC_LDEST_FILE log destinations.
* Intended for use when a log file is rotated externally.
*
* @param return 0 on success, non-zero if an error occured when re-opening a file.
*/
int uc_log_reopen_files(void);
/** Init the logging system. This function must be called before performing any other
* logging action.
*
* @param user_struct containing an array of all the modules defined by the application.
*/
void uc_log_init(struct uc_log_modules *user_modules);
void uc_logf(int log_level, int module, int raw,
const char *file, int line, const char *fmt, ...)
__attribute__((format(printf, 6, 7)));
#ifdef DEBUG
# define UC_DEBUGF(mod, fmt, ...)\
uc_logf(UC_LL_DEBUG, mod,0 , __FILE__, __LINE__, fmt, ## __VA_ARGS__)
# define UC_DEBUGFR(mod, fmt, ...)\
uc_logf(UC_LL_DEBUG, mod,1 , __FILE__, __LINE__, fmt, ## __VA_ARGS__)
#else
# define UC_DEBUGF(mod, fmt, ...)
# define UC_DEBUGFR(mod, fmt, ...)
#endif
/** Main macro that should be used for logging.
*
* For log messages with UC_LL_DEBUG, the UC_DEBUGF() macro can be used,
* UC_DEBUGF will only be compiled in if the DEBUG macro is defined
*
* @param lvl log level of this log message
* @param mod module id of this log messagex.
* @param fmt printf style format string
* @param ... printf style arguments
*/
#define UC_LOGF(lvl, mod, fmt, ...) \
uc_logf(lvl, mod, 0, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
/** Raw logging ,Like UC_LOGF, but only prints the supplied
* data, not timestamp, log level etc.
*/
#define UC_LOGFR(lvl, mod, fmt, ...) \
uc_logf(lvl, mod, 1, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif