Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

loghandler.cc

Go to the documentation of this file.
00001 /**************************************************************************
00002 
00003     loghandler - generic logfile interface.
00004 
00005     Copyright (C) 2000,2001 Stein Vråle <stein@terminator.net>
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 
00021 **************************************************************************/
00022 /*
00023   INTRO
00024 
00025   This is a generic log application providing basic log routines, 
00026   for use in any application that need a simple way to produce logfiles.
00027 
00028   USAGE
00029 
00030   To use loghandler in a new application, make sure the header file 
00031   is included in all source files where log messages will be generated.
00032 
00033   Then init the needed loghandles during application startup, by providing 
00034   the filename to be written into and any additional configuration 
00035   parameters.
00036 
00037   Finally add one of the message recorders wherever a logmessage is needed,
00038   and specify the targeted loglevel/class, a printf formatted message 
00039   template, and any arguments needed for the current logmessage.
00040 
00041   The logf method is meant for permanent logmessages, while the debugf 
00042   method is meant for development logging - to be easy to turn of  when the 
00043   applictions runs in production.
00044 
00045   Examples:
00046   
00047   loghandler_init(0,"/tmp/app.log");
00048 
00049   logf(MSG_NORMAL,"User %s connected",username);
00050 
00051   debugf(MSG_VERBOSE || LOG_NET,
00052       "Connection params: ip=%s user=%s pw=%s",hostname,username,password);
00053 
00054   loghandler(MSG_ERROR,LOG_MAIN,"Missing config file %s",filename);
00055 
00056 
00057   LOG CLASSIFICATON
00058 
00059   logclass: Used to seperate between different parts of program etc.
00060   loglevel: Importance of this log message. Higher number is less important.
00061   logcode: Combined level and class
00062 
00063   RECORDER METHODS
00064 
00065   logf: Record msg by code
00066   loghandler: Same as logf, but specify by level and class
00067   debugf: Record msg by code, and add debugflag automatically
00068 
00069   CONTROL METHODS
00070   
00071   loghandler_init:
00072 
00073   loghandler_setlevel:
00074   loghandler_getlevel:
00075 
00076   loghandler_setclass:
00077   loghandler_getclass:
00078 
00079   INTERNAL FUNCTIONS
00080 
00081   logfilter: Process the logmsg recived from recorder and use filter to 
00082   find the target loghandle
00083 
00084 ****************************************************************************/
00085 #include <stdio.h>
00086 #include <stdarg.h>
00087 #include <string.h>
00088 #include <time.h>
00089 #include "loghandler.h"
00090 
00091 typedef struct {
00092     const char *logdevice;
00093     int logclass;
00094     int loglevel;
00095     int logformat;
00096 } loghandle_struct;
00097 
00098 loghandle_struct loghandle[LOGHANDLE_MAX];
00099 
00100 static const char *event_code[] = {
00101     "mark",
00102     "fatal",
00103     "error",
00104     "warning",
00105     "normal",
00106     "notice",
00107     "info",
00108     "verbose",
00109     "check",
00110     "logic",
00111     "argh",
00112     "hmm",
00113     "func",
00114     "var",
00115     "io",
00116     "trace"
00117 };
00118 
00119 int logfilter(int logcode, const char *logmsg)
00120 {   
00121     char time_str[LOGMSG_MAX];
00122     char date_str[LOGMSG_MAX];
00123     char year_str[LOGMSG_MAX];
00124 
00125     time_t log_time;
00126     struct tm *time_tm;
00127 
00128     int logclass;
00129     int loglevel;
00130     char *str_ptr;
00131 
00132     /* Decode log code */
00133     loglevel = logcode & 15;
00134     logclass = logcode & 240;
00135 
00136     /* Format timestamp */
00137     log_time = time(NULL);
00138     time_tm = localtime(&log_time);
00139     strftime(year_str,LOGMSG_MAX,"%G",time_tm);
00140     strftime(date_str,LOGMSG_MAX,"%m%d",time_tm);
00141     strftime(time_str,LOGMSG_MAX,"%H:%M:%S",time_tm);
00142 
00143     /* Replace eventual line feeds */
00144     while ((str_ptr=strchr(logmsg,'\n'))){
00145         *str_ptr = ' ';
00146     }
00147 
00148     /* Loop all loghandles and see if they handle this message */
00149     for (int id=0; id <= LOGHANDLE_MAX; id++){
00150         if ((loghandle[id].logdevice != NULL) &&        // Current loghandle is configured
00151             (loghandle[id].logclass & logclass) &&      // loghandle handles this class 
00152             (loghandle[id].loglevel >= loglevel))       // loghandle handles this level
00153             {               
00154                 /* Format message for output */
00155                 char outmsg[LOGMSG_MAX];
00156                 char buf[LOGMSG_MAX];
00157 
00158                 // Prefix format
00159                 if (loghandle[id].logformat & SHOW_YEAR){
00160                     sprintf(buf,"%s ",year_str);
00161                     strcat(outmsg,buf);
00162                 }
00163                 if (loghandle[id].logformat & SHOW_DATE){
00164                     sprintf(buf,"%s ",date_str);
00165                     strcat(outmsg,buf);
00166                 }
00167                 if (loghandle[id].logformat & SHOW_TIME){
00168                     sprintf(buf,"%s ",time_str);
00169                     strcat(outmsg,buf);
00170                 }
00171 
00172                 strcat(outmsg,"[");
00173 
00174                 if (loghandle[id].logformat & SHOW_ID){
00175                     sprintf(buf,"%i.",id);
00176                     strcat(outmsg,buf);
00177                 }
00178                 if (loghandle[id].logformat & SHOW_CLASS){
00179                     sprintf(buf,"%i.",logclass);
00180                     strcat(outmsg,buf);
00181                 }
00182                 if (loghandle[id].logformat & SHOW_LEVEL){
00183                     sprintf(buf,"%s",event_code[loglevel]);
00184                     strcat(outmsg,buf);
00185                 }
00186                 // Message
00187                 snprintf(buf,sizeof(buf)-1,"] %s",logmsg);
00188                 strncat(outmsg,buf,sizeof(outmsg)-strlen(outmsg)-1);
00189                 
00190                 /* Write message to logdevice */
00191                 FILE *fout = fopen (loghandle[id].logdevice,"a");
00192                 if (fout != NULL){
00193                     fprintf(fout,"%s\n",outmsg);
00194                     fclose(fout);
00195                 }
00196                 else
00197                     printf("loghandler FATAL: Could not write to logfile %s",loghandle[id].logdevice);
00198             }
00199     }
00200     return (0);
00201 }
00202 
00203 int loghandler_init(int id,
00204                     const char *logdevice,
00205                     int logclass, 
00206                     int loglevel,
00207                     int logformat)
00208 {
00209     char msg[LOGMSG_MAX];
00210     
00211     // Check parameters
00212     if (id > LOGHANDLE_MAX) return(-1);
00213     if (logdevice == NULL) return(-1);
00214     FILE *fout = fopen (logdevice,"a");
00215     if (fout==NULL)
00216         return (-1);
00217     else
00218         fclose (fout);
00219 
00220     if (logformat < 0) logformat = DEFAULT_LOGFORMAT;
00221     if (logclass < 0) logclass = DEFAULT_LOGCLASS;
00222     if (loglevel < 0) loglevel = DEFAULT_LOGLEVEL;
00223     
00224     // Set config
00225     loghandle[id].logdevice = logdevice;
00226     loghandle[id].logformat = logformat;
00227     loghandle[id].logclass = logclass;
00228     loghandle[id].loglevel = loglevel;
00229 
00230     // Notify
00231     snprintf(msg,
00232              LOGMSG_MAX,
00233              "INIT::loghandle[%i] device[%s] format[%i] classfilter[%i] level[%i]",
00234              id,
00235              logdevice,
00236              logformat,
00237              logclass,
00238              loglevel);
00239     loghandler(logclass,D_CHECK,msg);
00240     return(0);
00241 }
00242 
00243 int loghandler_init(int id,const char *logdevice)
00244 {
00245     return (loghandler_init(id,logdevice,-1,-1,-1));
00246 }
00247 
00248 int loghandler_setlevel(int id, int loglevel)
00249 {
00250     loghandler(loghandle[id].logclass,
00251                D_CHECK,
00252                "loghandle[%i].setlevel %i",
00253                id,
00254                loglevel);
00255     
00256     loghandle[id].loglevel = loglevel;
00257     
00258     return(0);
00259 }
00260 
00261 int loghandler_getlevel(int id)
00262 {
00263     return (loghandle[id].loglevel);
00264 }
00265 
00266 int loghandler_setclass(int id, int logclass)
00267 {
00268     loghandle[id].logclass = logclass;
00269 
00270     return(0);
00271 }
00272 
00273 int loghandler_getclass(int id)
00274 {
00275     return (loghandle[id].logclass);
00276 }
00277 
00278 void loghandler(int loglevel, int logclass, const char *msg, ...)
00279 {   
00280     char logmsg[LOGMSG_MAX];
00281     int logcode;
00282 
00283     /* Combine class and level to logcode */
00284     logcode = loglevel | logclass;
00285 
00286     // Format message
00287     va_list list;
00288     va_start (list,msg);
00289     vsprintf (logmsg,msg,list);
00290     va_end (list);
00291     
00292     logfilter(logcode, logmsg);     
00293 }
00294 
00295 void logf(int logcode, const char *msg, ...)
00296 {   
00297     char logmsg[LOGMSG_MAX];
00298 
00299     logcode |= MAIN_LOG;
00300 
00301     // Format message
00302     va_list list;
00303     va_start (list,msg);
00304     vsprintf (logmsg,msg,list);
00305     va_end (list);
00306 
00307     logfilter(logcode, logmsg);
00308 }
00309 
00310 void debugf(int logcode, const char *msg, ...)
00311 {   
00312     char logmsg[LOGMSG_MAX];
00313 
00314     logcode |= DEBUG_LOG; // Add debug flag
00315     logcode |= MAIN_LOG;  // Temporary hack
00316  
00317     // Format message
00318     va_list list;
00319     va_start (list,msg);
00320     vsprintf (logmsg,msg,list);
00321     va_end (list);
00322 
00323     logfilter(logcode, logmsg);
00324 }
00325 
00326 
00327 

Generated at Mon Jan 22 08:35:12 2001 for ldapconf by doxygen1.2.1 written by Dimitri van Heesch, © 1997-2000