#include "../../include/logging/FileLog.h" #define WIN32_LEAN_AND_MEAN #include #include #include #include "../../include/toolkit/safe_function.h" #include "../../include/toolkit/XEnv.h" #include "../../include/toolkit/ILock.h" static const char* DEFAULT_LOG_DIR = "Log\\"; static const int LOG_BUFFER_LEN = 2048; static const int LOG_FILENAME_LEN = 512; FileLogHandler* FileLogHandler::_pInstance = NULL; class FileLogHandlerImpl : public FileLogHandler { public: FileLogHandlerImpl(); virtual ~FileLogHandlerImpl(); virtual bool LogStringEx( const char* szLogDir, const char* szAppName, const char* szLog, ... ); virtual bool LogString( const char* szLog, ... ); virtual bool LogStringToFileEx( const char* szLogDir, const char* szAppName, const char* szFileName, const char* szLog, ... ); protected: bool CreateDir( const char * pDir ); bool _LogString( const char* szLogDir, const char* szAppName, const char* szLog, va_list va ); bool _LogStringEx( const char* szLogDir, const char* szAppName, const char* szFileName, const char* szLog, va_list va ); protected: XCriticalSection m_CS; }; bool FileLogHandler::Init() { if( _pInstance ) { return false; } _pInstance = new FileLogHandlerImpl; if( _pInstance == NULL ) { return false; } return true; } bool FileLogHandler::DeInit() { if( _pInstance ) { delete _pInstance; _pInstance = NULL; return true; } return false; } FileLogHandler* FileLogHandler::GetFileLogHandler() { return _pInstance; } FileLogHandler::~FileLogHandler() { } FileLogHandlerImpl::FileLogHandlerImpl() : m_CS( "FileLogHandlerImpl" ) { } FileLogHandlerImpl::~FileLogHandlerImpl() { } bool FileLogHandlerImpl::LogStringToFileEx( const char* szLogDir, const char* szAppName, const char* szFileName, const char* szLog, ... ) { va_list va; va_start( va , szLog ); bool bRet = _LogStringEx( szLogDir, szAppName, szFileName, szLog, va ); va_end( va ); return bRet; } bool FileLogHandlerImpl::LogStringEx( const char* szLogDir, const char* szAppName, const char* szLog, ... ) { va_list va; va_start( va , szLog ); bool bRet = _LogString( szLogDir, szAppName, szLog, va ); va_end( va ); return bRet; } bool FileLogHandlerImpl::CreateDir( const char * pDir ) { DWORD dwRs = GetFileAttributes(pDir); if( dwRs == -1 ) { DWORD dwError = GetLastError(); if( dwError == ERROR_FILE_NOT_FOUND ) { if( !::CreateDirectory(pDir, NULL) ) { return false; } } else if ( dwError == ERROR_PATH_NOT_FOUND ) { char szDirectory[255]; s_strcpy( szDirectory, _countof( szDirectory ), pDir ); int i = static_cast< int >( strlen( pDir ) - 1 ); while( i >= 0 && ( pDir[i] == '\\' || pDir [i] == '/' ) ) i--; if( i < 0 ) return false; while( i > 0 && ( pDir[i] != '\\' && pDir [i] != '/' ) ) i--; if( i < 1 ) return false; szDirectory[i] = 0; if( !CreateDir( szDirectory ) ) { return false; } if( !::CreateDirectory(pDir, NULL) ) { return false; } } else { return false; } } else if( !(dwRs & FILE_ATTRIBUTE_DIRECTORY) ) { return false; } return true; } bool FileLogHandlerImpl::LogString( const char* szLog, ... ) { va_list va; va_start( va , szLog ); bool bRet = _LogString( NULL, ENV().GetString( "app.name", "Logging" ).c_str(), szLog, va ); va_end( va ); return bRet; } bool FileLogHandlerImpl::_LogString( const char* szLogDir, const char* szAppName, const char* szLog, va_list va ) { THREAD_SYNCRONIZE( &m_CS ); char szFileName[LOG_FILENAME_LEN]; char _szLogDir[LOG_FILENAME_LEN]; char buf[LOG_BUFFER_LEN]; char* _szApp; time_t tt = time( NULL ); struct tm lt; localtime_s( <, &tt ); if( szAppName == NULL ) { _szApp = "Unknown"; } else { _szApp = const_cast< char* >( szAppName ); } s_sprintf( szFileName, _countof( szFileName ), "%s_%04d-%02d-%02d.log", _szApp, lt.tm_year+1900, lt.tm_mon+1, lt.tm_mday ); if( szLogDir == NULL ) { s_strcpy( _szLogDir, _countof( _szLogDir ), DEFAULT_LOG_DIR ); } else { s_strcpy( _szLogDir, _countof( _szLogDir ), szLogDir ); int nLen = static_cast< int >( strlen( _szLogDir ) ); if( _szLogDir[nLen - 1] != '/' && _szLogDir[nLen - 1] != '\\' ) { s_strcat( _szLogDir, _countof( _szLogDir ), "/" ); nLen++; } } if( !CreateDir( _szLogDir ) ) { return false; } s_strcat( _szLogDir, _countof( _szLogDir ), szFileName ); FILE *fp = NULL; if( fopen_s( &fp, _szLogDir, "a+" ) != 0 ) return false; if( !fp ) return false; s_sprintf( buf, _countof( buf ), "%04d-%02d-%02d %02d:%02d:%02d ", lt.tm_year+1900, lt.tm_mon+1, lt.tm_mday, lt.tm_hour, lt.tm_min, lt.tm_sec ); s_vsprintf( &buf[20], _countof(buf) - 21, szLog, va ); s_strcat( buf, _countof( buf ), "\r\n" ); int rtn = fputs( buf, fp ); fclose( fp ); if( rtn == EOF ) return false; return true; } bool FileLogHandlerImpl::_LogStringEx( const char* szLogDir, const char* szAppName, const char* szFileName, const char* szLog, va_list va ) { THREAD_SYNCRONIZE( &m_CS ); char _szFileName[LOG_FILENAME_LEN]; char _szLogDir[LOG_FILENAME_LEN]; char buf[LOG_BUFFER_LEN]; char* _szApp; time_t tt = time( NULL ); struct tm lt; localtime_s( <, &tt ); if( szAppName == NULL ) { _szApp = "Unknown"; } else { _szApp = const_cast< char* >( szAppName ); } int nLen = s_sprintf( _szFileName, _countof( _szFileName ), "%s_", _szApp ); if( nLen <= 0 ) return false; strftime( _szFileName + nLen, _countof( _szFileName ) - nLen, szFileName, < ); if( szLogDir == NULL ) { s_strcpy( _szLogDir, _countof( _szLogDir ), DEFAULT_LOG_DIR ); } else { s_strcpy( _szLogDir, _countof( _szLogDir ), szLogDir ); nLen = (int)strlen(_szLogDir); if( _szLogDir[nLen - 1] != '/' && _szLogDir[nLen - 1] != '\\' ) { s_strcat( _szLogDir, _countof( _szLogDir ), "/" ); nLen++; } } if( !CreateDir( _szLogDir ) ) { return false; } s_strcat( _szLogDir, _countof( _szLogDir ), _szFileName ); FILE *fp = NULL; if( fopen_s( &fp, _szLogDir, "a+" ) != 0 ) return false; if( !fp ) return false; s_sprintf( buf, _countof( buf ), "%04d-%02d-%02d %02d:%02d:%02d ", lt.tm_year+1900, lt.tm_mon+1, lt.tm_mday, lt.tm_hour, lt.tm_min, lt.tm_sec ); s_vsprintf( &buf[20], _countof(buf) - 21, szLog, va ); s_strcat( buf, _countof( buf ), "\r\n" ); int rtn = fputs( buf, fp ); fclose( fp ); if( rtn == EOF ) return false; return true; }