logger.c

Go to the documentation of this file.
00001 
00002 /* Abstract logging system used to facilitate multiple modes*/
00003 /* of logging*/
00004 
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008 #ifndef _MSC_VER
00009 #include <syslog.h>
00010 #endif
00011 #include <errno.h>
00012 #include <stdarg.h>
00013 #include <ctype.h>
00014 
00015 #include "logger.h"
00016 
00017 #include "MALLOC.h"
00018 
00019 #ifndef _MSC_VER
00020 static int _LOGGER_mode = _LOGGER_SYSLOG;
00021 static int _LOGGER_syslog_mode = LOG_MAIL|LOG_INFO;
00022 #else
00023 static int _LOGGER_mode = _LOGGER_STDERR;
00024 static int _LOGGER_syslog_mode = 0;
00025 #endif
00026 
00027 static FILE *_LOGGER_outf;
00028 
00029 struct LOGGER_globals {
00030         int wrap;
00031         int wraplength;
00032 };
00033 
00034 /* Create and Initialise the global structure for LOGGER,*/
00035 /*              we init it to have NO wrapping.*/
00036 
00037 static struct LOGGER_globals LOGGER_glb={ 0, 0 };
00038 
00039 #ifdef _MSC_VER
00040         #define vsnprintf _vsnprintf
00041 #endif
00042 
00043 /*------------------------------------------------------------------------
00044 Procedure:     LOGGER_get_file ID:1
00045 Purpose:       Returns the pointer to the file being used to output logs to
00046 Input:
00047 Output:
00048 Errors:
00049 ------------------------------------------------------------------------*/
00050 FILE *LOGGER_get_file( void )
00051 {
00052         return _LOGGER_outf;
00053 }
00054 
00055 
00056 /*------------------------------------------------------------------------
00057 Procedure:     LOGGER_set_output_mode ID:1
00058 Purpose:       Sets the message/log output method, ie, stderr, stdout
00059 or syslog
00060 Input:
00061 Output:
00062 Errors:
00063 ------------------------------------------------------------------------*/
00064 int LOGGER_set_output_mode( int modechoice )
00065 {
00066         _LOGGER_mode = modechoice;
00067         return 0;
00068 }
00069 
00070 /*------------------------------------------------------------------------
00071 Procedure:     LOGGER_set_output_file ID:1
00072 Purpose:       Sets the output file for when _LOGGER_mode is set to
00073 _LOGGER_file
00074 Input:
00075 Output:
00076 Errors:
00077 ------------------------------------------------------------------------*/
00078 int LOGGER_set_output_file( FILE *f )
00079 {
00080         _LOGGER_outf = f;
00081         return 0;
00082 }
00083 
00084 /*------------------------------------------------------------------------
00085 Procedure:     LOGGER_set_syslog_mode ID:1
00086 Purpose:       Sets the mode that messaging to the syslog daemon will
00087 be sent as (ie, LOG_MAIL|LOG_INFO)
00088 Input:
00089 Output:
00090 Errors:
00091 ------------------------------------------------------------------------*/
00092 int LOGGER_set_syslog_mode( int syslogmode )
00093 {
00094         _LOGGER_syslog_mode = syslogmode;
00095         return 0;
00096 }
00097 
00098 
00099 
00100 
00101 /*------------------------------------------------------------------------
00102 Procedure:     LOGGER_set_logfile ID:1
00103 Purpose:       Opens and setups the internal Log file file pointer with the
00104 log file as given by lfname
00105 Input:
00106 Output:
00107 Errors:
00108 ------------------------------------------------------------------------*/
00109 int LOGGER_set_logfile( char *lfname )
00110 {
00111         int result = 0;
00112 
00113         _LOGGER_outf = fopen(lfname,"a");
00114         if (!_LOGGER_outf)
00115         {
00116 #ifndef _MSC_VER
00117                 syslog(1,"LOGGER_set_logfile: ERROR - Cannot open logfile '%s' (%s)",lfname,strerror(errno));
00118 #else
00119                 fprintf(stderr, "LOGGER_set_logfile: ERROR - Cannot open logfile '%s' (%s)\n", lfname, strerror(errno));
00120 #endif
00121                 result = -1;
00122         }
00123 
00124         return result;
00125 }
00126 
00127 
00128 
00129 /*------------------------------------------------------------------------
00130 Procedure:     LOGGER_set_wraplength ID:1
00131 Purpose:       Sets the character count at which LOGGER will break a line
00132 Input:         int length: Positive integer indicating number of chracters at which to wrap at
00133 Output:
00134 Errors:
00135 ------------------------------------------------------------------------*/
00136 int LOGGER_set_wraplength( int length )
00137 {
00138         if ( length >= 0 )
00139         {
00140                 LOGGER_glb.wraplength = length;
00141         }
00142 
00143         return LOGGER_glb.wraplength;
00144 }
00145 
00146 /*------------------------------------------------------------------------
00147 Procedure:     LOGGER_set_wrap ID:1
00148 Purpose:       Set log output wrapping to on or off
00149 Input:         int level: 0 = no wrap, > 0 = wrap.
00150 Output:
00151 Errors:
00152 ------------------------------------------------------------------------*/
00153 int LOGGER_set_wrap( int level )
00154 {
00155         if ( level >= 0 )
00156         {
00157                 LOGGER_glb.wrap = level;
00158         }
00159 
00160         return LOGGER_glb.wrap;
00161 }
00162 
00163 
00164 
00165 /*------------------------------------------------------------------------
00166 Procedure:     LOGGER_close_logfile ID:1
00167 Purpose:       Closes the modules log file pointer.
00168 Input:
00169 Output:
00170 Errors:
00171 ------------------------------------------------------------------------*/
00172 int LOGGER_close_logfile( void )
00173 {
00174         int result = 0;
00175 
00176         if (_LOGGER_outf) fclose(_LOGGER_outf);
00177 
00178         return result;
00179 }
00180 
00181 
00182 
00183 /*------------------------------------------------------------------------
00184 Procedure:     LOGGER_clean_output ID:1
00185 Purpose:       Checks through the output string for any characters which could cause
00186 potential 'isssues' with the data writing calls, items such as stray non-escaped
00187 % characters can cause havoc.
00188 Input:         char *string: Raw string
00189 int maxsize: Maximum available buffer size for this string to expand to
00190 Output:
00191 Errors:
00192 ------------------------------------------------------------------------*/
00193 int LOGGER_clean_output( char *string, char **buffer )
00194 {
00195         char *newstr;
00196         char *p, *q;
00197         char *next_space;
00198 
00199         int pc;
00200         int slen = strlen( string );
00201         int line_size;
00202         int maxsize = slen *2;
00203 
00204         /* First up, allocate maxsize bytes for a temporary new string.*/
00205         newstr = MALLOC(slen *2 +1); 
00206         if ( newstr == NULL )
00207         {
00208           /* FIXME - Report an error here ... to -somewhere-*/
00209                 return -1;
00210         }
00211 
00212         p = newstr;
00213         q = string;
00214         pc = 0;
00215         line_size = 0;
00216 
00217         while (slen--)
00218         {
00219 
00220           /* Do we need to apply any wrapping to the output? If so then we*/
00221           /*            shall embark on a journey of strange space and distance*/
00222           /*            evaluations to determine if we should wrap now or later*/
00223 
00224                 if ( LOGGER_glb.wrap > 0 )
00225                 {
00226                         if (isspace((int)*q))
00227                         {
00228                                 next_space = strpbrk( (q+1), "\t\r\n\v " );
00229                                 if (next_space != NULL)
00230                                 {
00231                                         if ((line_size +(next_space -q)) >= LOGGER_glb.wraplength)
00232                                         {
00233                                                 *p = '\n';
00234                                                 p++;
00235                                                 pc++;
00236                                                 line_size = 0;
00237                                         }
00238                                 }
00239                         }
00240 
00241                         if ( line_size >= LOGGER_glb.wraplength )
00242                         {
00243                                 *p = '\n';
00244                                 p++;
00245                                 pc++;
00246                                 line_size = 0;
00247                         }
00248                 }
00249 
00250                 /* If the string has a % in it, then we need to encode it as*/
00251                 /*      a DOUBLE % symbol.*/
00252 
00253                 if (*q == '%') {
00254                   /*                    if (strchr("fdlsxXn",*(q+1)))*/
00255                   /*                    {*/
00256                                 *p = '%';
00257                                 p++;
00258                                 pc++;
00259                                 /*                      }*/
00260                 }
00261 
00262                 /* Copy the character of the string in*/
00263                 *p = *q;
00264 
00265                 /* Move everything along.*/
00266                 q++;
00267                 p++;
00268                 pc++;
00269                 line_size++;
00270 
00271                 if ( pc > (maxsize -1) ) {
00272                         break;
00273                 }
00274         }
00275 
00276         *p = '\0';
00277 
00278         /* This will have to be deallocated later!*/
00279         if (newstr) *buffer = newstr;
00280 
00281         return 0;
00282 }
00283 
00284 /*------------------------------------------------------------------------
00285 Procedure:     LOGGER_log ID:1
00286 Purpose:       Logs the params as supplied to the required
00287 output as defined by LOGGER_set_output
00288 Input:
00289 Output:
00290 Errors:
00291 ------------------------------------------------------------------------*/
00292 int LOGGER_log( char *format, ...)
00293 {
00294         va_list ptr;
00295         char tmpoutput[10240];
00296         char linebreak[]="\n";
00297         char nolinebreak[]="";
00298         char *lineend;
00299         char *output;
00300 
00301 
00302         /* get our variable arguments*/
00303         va_start(ptr,format);
00304 
00305         /* produce output, and spit to the log file*/
00306 #ifdef NO_SNPRINTF
00307         vsprintf(tmpoutput, format, ptr);
00308 #else
00309         vsnprintf(tmpoutput,10240,format,ptr);
00310 #endif
00311 
00312         LOGGER_clean_output( tmpoutput, &output );
00313 
00314         if ( output[strlen(output)-1] == '\n' ) {
00315                 lineend = nolinebreak;
00316         }
00317         else {
00318                 lineend = linebreak;
00319         }
00320 
00321         if ( output[strlen(output)-1] == '\n' ) { lineend = nolinebreak; } else { lineend = linebreak; }
00322 
00323         /* Send the output to the appropriate output destination*/
00324         switch (_LOGGER_mode) {
00325                 case _LOGGER_STDERR:
00326                         fprintf(stderr,"%s%s",output, lineend );
00327                         break;
00328                 case _LOGGER_SYSLOG:
00329                         #ifndef _MSC_VER
00330                         syslog(_LOGGER_syslog_mode,output);
00331                         #endif
00332                         break;
00333                 case _LOGGER_STDOUT:
00334                         fprintf(stdout,"%s%s",output, lineend);
00335                         fflush(stdout);
00336                         break;
00337                 case _LOGGER_FILE:
00338                         fprintf(_LOGGER_outf,"%s%s",output,lineend);
00339                         fflush(_LOGGER_outf);
00340                         break;
00341                 default:
00342                         fprintf(stdout,"LOGGER-Default: %s%s",output,lineend);
00343         }
00344 
00345 
00346         if (output) FREE(output);
00347 
00348         return 0;
00349 }
00350 
00351 
00352 
00353 

Generated on Sun Mar 4 15:03:49 2007 for Scilab [trunk] by  doxygen 1.5.1