From e08c2750da728fa248836cf53f0f95cd9c64f8aa Mon Sep 17 00:00:00 2001 From: scottmk Date: Sat, 10 Oct 2009 02:28:49 +0000 Subject: [PATCH] Performance tweak to the logging routines. _osrfLogToFile() is no longer a variadic function. We always sent it the same format string, and there was no point in sending a variable-length parameter list that never actually varied in length. Now we send it a fixed-length parameter list -- and thereby avoid two calls to vsnprintf() that had been hidden in the VA_LIST_TO_STRING macro. Also: added doxygen-style comments to several of the functions. M src/libopensrf/log.c git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1810 9efc2488-bf62-4759-914b-345cdb29e865 --- src/libopensrf/log.c | 115 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 103 insertions(+), 12 deletions(-) diff --git a/src/libopensrf/log.c b/src/libopensrf/log.c index 7cb9232..514b9f0 100644 --- a/src/libopensrf/log.c +++ b/src/libopensrf/log.c @@ -17,7 +17,8 @@ static char* _osrfLogXidPfx = NULL; /* xid prefix string */ static void osrfLogSetType( int logtype ); static void _osrfLogDetail( int level, const char* filename, int line, char* msg ); -static void _osrfLogToFile( const char* msg, ... ); +static void _osrfLogToFile( const char* label, long pid, const char* filename, int line, + const char* xid, const char* msg ); static void _osrfLogSetXid( const char* xid ); void osrfLogCleanup( void ) { @@ -29,6 +30,45 @@ void osrfLogCleanup( void ) { } +/** + @brief Record some options for later reference by the logging routines. + @param type Type of logging; i.e. where the log messages go. + @param appname Pointer to the application name (may be NULL). + @param maxlevel Which levels of message to issue or suppress. + + Typically the values for these parameters come from a configuration file. + + There are three valid values for @a type: + + - OSRF_LOG_TYPE_FILE -- write messages to a log file + - OSRF_LOG_TYPE_SYSLOG -- write messages to the syslog facility + - OSRF_LOG_TYPE_STDERR -- write messages to standard error + + If @a type has any other value, log messages will be written to standard error. + + The logging type may be set separately by calling osrfLogSetType(). See also + osrfLogToStderr() and osrfRestoreLogType(). + + The @a appname string prefaces every log message written to a log file or to standard + error. It also identifies the application to the Syslog facility, if the application + uses Syslog. The default application name, if not overridden by this function or by + osrfLogSetAppname(), is "osrf". + + Here are the valid values for @a maxlevel, with the corresponding macros: + + - 1 OSRF_LOG_ERROR + - 2 OSRF_LOG_WARNING + - 3 OSRF_LOG_INFO (the default) + - 4 OSRF_LOG_DEBUG + - 5 OSRF_LOG_INTERNAL + + With the special exception of activity messages (see osrfLogActivity()), the logging + routines will suppress any messages at a level greater than that specified by + @a maxlevel. Setting @a maxlevel to zero or less suppresses all levels of message. + Setting it to 5 or more enables all levels of message. + + The message level may be set separately by calling osrfLogSetLevel(). +*/ void osrfLogInit( int type, const char* appname, int maxlevel ) { osrfLogSetType(type); if(appname) osrfLogSetAppname(appname); @@ -75,7 +115,24 @@ void osrfLogSetIsClient(int is) { _osrfLogXidPfx = buff; } -/** Sets the type of logging to perform. See log types */ +/** + @brief Specify what kind of logging to perform. + @param logtype A code indicating the type of logging. + + There are three valid values for @a logtype: + + - OSRF_LOG_TYPE_FILE -- write messages to a log file + - OSRF_LOG_TYPE_SYSLOG -- write messages to the syslog facility + - OSRF_LOG_TYPE_STDERR -- write messages to standard error + + If @a logtype has any other value, log messages will be written to standard error. + + This function merely records the log type for future reference. It does not open + or close any files. + + See also osrfLogInit(), osrfLogToStderr() and osrfRestoreLogType(). + +*/ static void osrfLogSetType( int logtype ) { switch( logtype ) @@ -199,7 +256,24 @@ void osrfLogActivity( const char* file, int line, const char* msg, ... ) { } } -/** Actually does the logging */ +/** + @brief Issue a log message. + @param level The message level. + @param filename The name of the source file from whence the message is issued. + @param line The line number from whence the message is issued. + @param msg The text of the message. + + This function is the final common pathway for all messages. + + The @a level parameter determines the tag to be incorporated into the message: "ERR", + "WARN", "INFO", "DEBG", "INT " or "ACT". + + The @a filename and @a name identify the location in the application code from whence the + message is being issued. + + Here we format the message and route it to the appropriate output destination, depending + on the current setting of _osrfLogType: Syslog, a log file, or standard error. +*/ static void _osrfLogDetail( int level, const char* filename, int line, char* msg ) { if(!filename) filename = ""; @@ -263,20 +337,36 @@ static void _osrfLogDetail( int level, const char* filename, int line, char* msg } else if( logtype == OSRF_LOG_TYPE_FILE ) - _osrfLogToFile( "[%s:%ld:%s:%d:%s] %s", label, (long) getpid(), filename, line, xid, msg ); + _osrfLogToFile( label, (long) getpid(), filename, line, xid, msg ); else if( logtype == OSRF_LOG_TYPE_STDERR ) fprintf( stderr, "[%s:%ld:%s:%d:%s] %s\n", label, (long) getpid(), filename, line, xid, msg ); } -static void _osrfLogToFile( const char* msg, ... ) { +/** + @brief Write a message to a log file. + @param label The message type: "ERR", "WARN", etc.. + @param pid The process id. + @param filename Name of the source file from whence the message was issued. + @param line Line number from whence the message was issued. + @param xid Transaction id (or an empty string if there is no transaction). + @param msg Message text. + + Open the log file named by _osrfLogFile, in append mode; write the message; close the + file. If unable to open the log file, write the message to standard error. +*/ +static void _osrfLogToFile( const char* label, long pid, const char* filename, int line, + const char* xid, const char* msg ) { - if(!msg) return; - if(!_osrfLogFile) return; - VA_LIST_TO_STRING(msg); + if( !label || !filename || !xid || !msg ) + return; // missing parameter(s) - if(!_osrfLogAppname) _osrfLogAppname = strdup("osrf"); + if(!_osrfLogFile) + return; // No log file defined + + if(!_osrfLogAppname) + _osrfLogAppname = strdup("osrf"); // apply default application name char datebuf[36]; time_t t = time(NULL); @@ -287,18 +377,19 @@ static void _osrfLogToFile( const char* msg, ... ) { if(!file) { fprintf(stderr, "Unable to fopen log file %s for writing; logging to standard error\n", _osrfLogFile); - fprintf(stderr, "%s %s %s\n", _osrfLogAppname, datebuf, VA_BUF ); + fprintf(stderr, "%s %s [%s:%ld:%s:%d:%s] %s\n", + _osrfLogAppname, datebuf, label, (long) getpid(), filename, line, xid, msg ); return; } - fprintf(file, "%s %s %s\n", _osrfLogAppname, datebuf, VA_BUF ); + fprintf(file, "%s %s [%s:%ld:%s:%d:%s] %s\n", + _osrfLogAppname, datebuf, label, (long) getpid(), filename, line, xid, msg ); if( fclose(file) != 0 ) fprintf( stderr, "Error closing log file: %s", strerror(errno)); } - int osrfLogFacilityToInt( const char* facility ) { if(!facility) return LOG_LOCAL0; if(strlen(facility) < 6) return LOG_LOCAL0; -- 2.11.0