Pol  Revision:740
clib/logfile.cpp
Go to the documentation of this file.
00001 /*
00002 History
00003 =======
00004 
00005 2009/08/25 Shinigami: STLport-5.2.1 fix: Log and Log2 changed little bit
00006 2009/10/14 Turley:    added bool LogfileTimestampEveryLine
00007 
00008 
00009 Notes
00010 =======
00011 
00012 */
00013 
00014 #include "stl_inc.h"
00015 
00016 #include <stdio.h>
00017 #include <stdarg.h>
00018 #include <time.h>
00019 
00020 #include "logfile.h"
00021 namespace Pol {
00022   namespace Clib {
00023     FILE *logfile = NULL;
00024 
00025     bool LogfileTimestampEveryLine = false;
00026     std::mutex _logfile_mutex;
00027 
00028     static string namebase;
00029     static string log_filename;
00030     static time_t last_timestamp;
00031     static struct tm open_tm;
00032     static bool rollover;
00033 
00034     int OpenLogFileName( const char* i_namebase, bool i_rollover )
00035     {
00036       namebase = i_namebase;
00037       rollover = i_rollover;
00038       log_filename = namebase + ".log";
00039       logfile = fopen( log_filename.c_str(), "a+t" );
00040       if( logfile )
00041       {
00042         time_t now = time( NULL );
00043         open_tm = *localtime( &now );
00044 
00045         Log( "Logfile opened.\n" );
00046         return 0;
00047       }
00048       else
00049       {
00050         return -1;
00051       }
00052     }
00053     int OpenLogFile( void )
00054     {
00055       return OpenLogFileName( "logfile", false );
00056     }
00057 
00058     void CloseLogFile( void )
00059     {
00060       Log( "Closing logfile.\n" );
00061       if( logfile )
00062       {
00063         fclose( logfile );
00064         logfile = NULL;
00065       }
00066     }
00067 
00068     void Log( const char *fmt, ... )
00069     {
00070       std::lock_guard<std::mutex> lock( _logfile_mutex );
00071       if( logfile )
00072       {
00073         va_list va;
00074         time_t now = time( NULL );
00075         if( ( now != last_timestamp ) || ( LogfileTimestampEveryLine ) )
00076         {
00077           char buffer[30];
00078 
00079           struct tm* tm_now = localtime( &now );
00080           if( rollover && ( tm_now->tm_mday != open_tm.tm_mday ||
00081             tm_now->tm_mon != open_tm.tm_mon ) )
00082           {
00083             // roll the log file over
00084             strftime( buffer, sizeof buffer, "%Y-%m-%d", &open_tm );
00085             string archive_name = namebase + "-" + buffer + ".log";
00086             fclose( logfile );
00087 
00088             // whether the rename succeeds or fails, the action is the same.
00089             rename( log_filename.c_str(), archive_name.c_str() );
00090 
00091             // moved.  open the new file
00092             logfile = fopen( log_filename.c_str(), "a+t" );
00093             if( !logfile )
00094               return;
00095             open_tm = *tm_now;
00096           }
00097 
00098           strftime( buffer, sizeof buffer, "%m/%d %H:%M:%S", tm_now );
00099           fprintf( logfile, "[%s] ", buffer );
00100           last_timestamp = now;
00101         }
00102         va_start( va, fmt );
00103         vfprintf( logfile, fmt, va );
00104         va_end( va );
00105         fflush( logfile );
00106       }
00107     }
00108 
00109     void Log2( const char *fmt, ... )
00110     {
00111       std::lock_guard<std::mutex> lock( _logfile_mutex );
00112       if( logfile )
00113       {
00114         va_list va;
00115         time_t now = time( NULL );
00116         if( ( now != last_timestamp ) || ( LogfileTimestampEveryLine ) )
00117         {
00118           char buffer[30];
00119 
00120           struct tm* tm_now = localtime( &now );
00121           if( rollover && ( tm_now->tm_mday != open_tm.tm_mday ||
00122             tm_now->tm_mon != open_tm.tm_mon ) )
00123           {
00124             // roll the log file over
00125             strftime( buffer, sizeof buffer, "%Y-%m-%d", &open_tm );
00126             string archive_name = namebase + "-" + buffer + ".log";
00127             fclose( logfile );
00128 
00129             // whether the rename succeeds or fails, the action is the same.
00130             rename( log_filename.c_str(), archive_name.c_str() );
00131 
00132             // moved.  open the new file
00133             logfile = fopen( log_filename.c_str(), "a+t" );
00134             if( !logfile )
00135               return;
00136             open_tm = *tm_now;
00137           }
00138 
00139           strftime( buffer, sizeof buffer, "%m/%d %H:%M:%S", tm_now );
00140           fprintf( logfile, "[%s] ", buffer );
00141           last_timestamp = now;
00142         }
00143         va_start( va, fmt );
00144         vfprintf( logfile, fmt, va );
00145         va_end( va );
00146         fflush( logfile );
00147       }
00148       va_list va;
00149       va_start( va, fmt );
00150       vfprintf( stdout, fmt, va );
00151       va_end( va );
00152     }
00153 
00154   }
00155 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines