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

# logger.cpp

Go to the documentation of this file.

    00001 //---------------------------------------------------------------------------
    00002 #include "logger.h"
    00003 #include <ios>      // ios_base
    00004 #include <time.h>   // _tzset()
    00005 #include <string.h>   // strcpy(), strcat()
    00006 #include <string>
    00007 #include <stdarg.h>   // va_list, et.al.
    00008 #include <stdio.h>    // error reporting
    00009 #include <globalutils.h>
    00010 #include <worm_environ.h>
    00011
    00012 //---------------------------------------------------------------------------
    00013 #pragma package(smart_init)
    00014
    00015 TMutex * TLogger::AccessLock = NULL;
    00016 std::fstream TLogger::OutStream;
    00017 char TLogger::PreviousDate[WORM_TIMESTR_LENGTH+1] = { "" };
    00018 bool TLogger::TruncOnOpen = false;
    00019 int TLogger::MaxTooLongLength = 0;
    00020
    00021 //---------------------------------------------------------------------------
    00022 WORM_STATUS_CODE TLogger::OpenFile()
    00023 {
    00024    WORM_STATUS_CODE r_status = WORM_STAT_SUCCESS;
    00025
    00026    char _timbuf[WORM_TIMESTR_LENGTH];
    00027
    00028    // request time in format YYYYMMDD
    00029    TTimeFuncs::DateString(_timbuf, WORM_TIMEFMT_8, WORM_LOCAL_TIME );
    00030
    00031    if (   strncmp(_timbuf, PreviousDate, strlen(PreviousDate)) != 0
    00032        || (! OutStream.is_open())
    00033       )
    00034    {
    00035       // date has changed, open a new file
    00036       strcpy( PreviousDate, _timbuf );
    00037
    00038       if ( OutStream.is_open() )
    00039       {
    00040          OutStream.close();
    00041       }
    00042
    00043       char _logname[256];
    00044
    00045       bool _nodirectory = false;
    00046
    00047       if ( TGlobalUtils::GetEnvironmentValue(WORM_LOG_DIR) == NULL )
    00048       {
    00049          if ( TGlobalUtils::GetEnvironmentValue(EW_LOG_DIR) == NULL )
    00050          {
    00051             _nodirectory = true;
    00052             strcpy( _logname, "" );
    00053          }
    00054          else
    00055          {
    00056             strcpy( _logname, TGlobalUtils::GetEnvironmentValue(EW_LOG_DIR) );
    00057          }
    00058       }
    00059       else
    00060       {
    00061          strcpy( _logname, TGlobalUtils::GetEnvironmentValue(WORM_LOG_DIR) );
    00062       }
    00063       strcat( _logname, TGlobalUtils::GetProgramName() );
    00064       strcat( _logname, "_" );
    00065       strcat( _logname, _timbuf );
    00066       strcat( _logname, ".log" );
    00067
    00068       try
    00069       {
    00070          if ( TruncOnOpen )
    00071          {
    00072             OutStream.open( _logname, std::ios_base::out|std::ios_base::trunc );
    00073          }
    00074          else
    00075          {
    00076             OutStream.open( _logname, std::ios_base::out|std::ios_base::app );
    00077          }
    00078
    00079          if ( OutStream.fail() )
    00080          {
    00081             throw std::ios_base::failure( "Failed opening Log file" );
    00082          }
    00083          else if ( ! OutStream.is_open() )
    00084          {
    00085             throw std::ios_base::failure( "OutStream Log file" );
    00086          }
    00087
    00088 #if defined(_WINNT) || defined(_Windows)
    00089          if ( TGlobalUtils::GetEnvironmentValue(WORM_TIME_ZONE) == NULL )
    00090          {
    00091             OutStream << "==================================================" << std::endl;
    00092             OutStream << "WARNING: The environment variable " WORM_TIME_ZONE << std::endl;
    00093             OutStream << "         (time zone) is not set." << std::endl;
    00094             OutStream << "         UTC times in log messages may be bogus." << std::endl;
    00095             OutStream << "==================================================" << std::endl;
    00096          }
    00097          else
    00098          {
    00099             OutStream << "Notice: Using environment variable " WORM_TIME_ZONE;
    00100             OutStream << "=" << TGlobalUtils::GetEnvironmentValue(WORM_TIME_ZONE);
    00101             OutStream << " for time zone." << std::endl;
    00102             _tzset();
    00103          }
    00104 #endif
    00105
    00106          if ( _nodirectory )
    00107          {
    00108             Logit( WORM_LOG_TOFILE|WORM_LOG_TOSTDERR|WORM_LOG_TIMESTAMP
    00109                  , "Neither environment variable <%s> nor <%s> defined, writing logs to execution directory\n"
    00110                  , WORM_LOG_DIR
    00111                  , EW_LOG_DIR
    00112                  );
    00113          }
    00114       }
    00115       catch( std::ios_base::failure ex )
    00116       {
    00117          OutStream.close();
    00118          fprintf( stderr
    00119                 , "TLogger::OpenFile() File: %s\nError: %s"
    00120                 , _logname
    00121                 , ex.what()
    00122                 );
    00123          r_status = WORM_STAT_FAILURE;
    00124       }
    00125
    00126    }
    00127    return r_status;
    00128 }
    00129 //---------------------------------------------------------------------------
    00130 void TLogger::Close()
    00131 {
    00132    if ( OutStream.is_open() )
    00133    {
    00134       OutStream.close();
    00135    }
    00136    if ( AccessLock != NULL )
    00137    {
    00138       delete( AccessLock );
    00139       AccessLock = NULL;
    00140    }
    00141 }
    00142 //---------------------------------------------------------------------------
    00143 int TLogger::Logit( WORM_LOG_FLAGS p_flags, const char* p_format, ... )
    00144 {
    00145    int r_count = 0;
    00146
    00147    if ( AccessLock == NULL )
    00148    {
    00149       if ( (AccessLock = new TMutex("logmutex")) == NULL )
    00150       {
    00151          fprintf( stderr, "TLogger::Logit(): Failed creating log file mutex\n" );
    00152          return -1;
    00153       }
    00154    }
    00155
    00156    AccessLock->RequestLock();
    00157
    00158    // The vast majority of the time, this space will not be used, but
    00159    // at least the startstop status message's max size is apx 15K.
    00160    // (actually, there are rumors of one message that is apx 65K).
    00161    static char _buff[16384];
    00162    static char _args[16384];
    00163
    00164    strcpy( _buff, "" );
    00165
    00166    if ( p_flags & WORM_LOG_TIMESTAMP )
    00167    {
    00168       TTimeFuncs::DateString(_buff, WORM_TIMEFMT_UTC21);
    00169       strcat( _buff, " " );
    00170    }
    00171
    00172    /* TODO : Doesn't really make sense to add program filename to error file */
    00173
    00174    if ( p_flags & WORM_LOG_NAMESTAMP )
    00175    {
    00176       strcat( _buff, TGlobalUtils::GetProgramName() );
    00177       strcat( _buff, " " );
    00178    }
    00179
    00180    if ( p_flags & WORM_LOG_PIDSTAMP )
    00181    {
    00182       char _pids[10];
    00183       sprintf( _pids, " %d", TGlobalUtils::GetPID() );
    00184       strcat( _buff, _pids );
    00185       strcat( _buff, " " );
    00186    }
    00187
    00188    strcpy( _args, "" );
    00189    va_list _argptr;
    00190    va_start(_argptr, p_format);
    00191    r_count = vsprintf(_args, p_format, _argptr);
    00192    va_end(_argptr);
    00193
    00194
    00195    if ( 0 < r_count )
    00196    {
    00197       strcat( _buff, _args );
    00198    }
    00199
    00200    if ( p_flags & WORM_LOG_TOSTDOUT )
    00201    {
    00202       fprintf( stdout, "%s", _buff );
    00203    }
    00204
    00205    if ( p_flags & WORM_LOG_TOSTDERR )
    00206    {
    00207       fprintf( stderr, "%s", _buff );
    00208    }
    00209
    00210
    00211    if ( p_flags & WORM_LOG_TOFILE && TGlobalUtils::WriteLogFile() )
    00212    {
    00213 //fprintf( stdout, "DEBUG Logit() V\n" );
    00214
    00215       if ( OpenFile() == WORM_STAT_SUCCESS )
    00216       {
    00217 //fprintf( stdout, "DEBUG Logit() W -1\n" );
    00218 //fprintf( stdout, "DEBUG Logit() W:  >%s<\n", _buff );
    00219 //fprintf( stdout, "DEBUG Logit() W  1\n" );
    00220
    00221          if ( ! OutStream.is_open() )
    00222          {
    00223             fprintf( stderr
    00224                    , "TLogger::Logit() OutStream is not open\n"
    00225                    );
    00226          }
    00227          else
    00228          {
    00229 //fprintf( stdout, "DEBUG Logit() X -1\n" );
    00230             try
    00231             {
    00232                 OutStream << _buff;
    00233             }
    00234             catch( ... ) //            catch( ios_base::failure _ioex )
    00235             {
    00236 //fprintf( stdout, "TLogger::Logit() OutStream << resulted in exception\n" );
    00237             }
    00238 //fprintf( stdout, "DEBUG Logit() X\n" );
    00239             OutStream.flush();
    00240          }
    00241 //fprintf( stdout, "DEBUG Logit() Y\n" );
    00242       }
    00243       else
    00244       {
    00245          fprintf( stderr
    00246                 , "TLogger::Logit() FAILED OPENING LOG FILE FOR MESSAGE\n%s\n"
    00247                 , _buff
    00248                 );
    00249       }
    00250    }
    00251
    00252    AccessLock->ReleaseLock();
    00253
    00254 //fprintf( stdout, "DEBUG Logit() Z\n" );
    00255
    00256    return r_count;
    00257 }
    00258 //---------------------------------------------------------------------------