00001
00015 #pragma once
00016
00017 #include "TStd.h"
00018 #include "TBoostFilesystem.h"
00019 #include "RegistryKey.h"
00020 #include "IGenericLogManager.h"
00021
00022 #define LOGGING_KEYNAME_PATH_PREFIX _T("PathPrefix")
00023 #define LOGGING_KEYNAME_APPEND_PROCESS_NAME_TO_PATH_PREFIX _T("AppendProcessNameToPathPrefix")
00024 #define LOGGING_KEYNAME_GET_MAX_FILE_COUNT _T("MaxFileCount")
00025 #define LOGGING_KEYNAME_GET_MAX_FILE_SIZE _T("MaxFileSize")
00026 #define LOGGING_FILELOGMANAGER_DEFAULT_PATH_PREFIX _T("%ALLUSERSPROFILE%\\Documents\\NvidiaLogging\\Log.")
00027 #define LOGGING_FILELOGMANAGER_LOG_SUFFIX _T(".log")
00028 #define LOGGING_FILELOGMANAGER_INSTANCE_SUFFIX _T(".inst")
00029 #define LOGGING_MAX_INSTANCES_COUNT 16
00030
00031 namespace Nvidia {
00032 namespace Logging {
00033
00034 namespace Test {
00035 class FileLogManagerTest;
00036 }
00037
00039 class FileLogManager : public IGenericLogManager<std::tstring>
00040 {
00041 friend class Test::FileLogManagerTest;
00042
00043 private:
00045 std::tfstream m_fstream;
00046
00052 std::tstring m_pathPrefix;
00053
00059 unsigned int m_maxFileCount;
00060
00066 unsigned int m_maxFileSize;
00067
00068 public:
00074 FileLogManager();
00075
00082 FileLogManager(const RegistryKey& key);
00083
00085 virtual void ManageMessage(const std::tstring& message);
00086
00087 private:
00089 void RotateIfNecessary();
00090
00098 void InitFstream();
00099 };
00100
00101 inline FileLogManager::FileLogManager()
00102 {
00103 m_pathPrefix = LOGGING_FILELOGMANAGER_DEFAULT_PATH_PREFIX;
00104 m_pathPrefix = Utils::ExpandEnvironmentVariables(m_pathPrefix);
00105 m_pathPrefix += Utils::GetProcessName();
00106
00107 m_maxFileCount = 10;
00108 m_maxFileSize = 1000000;
00109
00110 InitFstream();
00111 }
00112
00113 inline FileLogManager::FileLogManager(const RegistryKey& key)
00114 {
00115 m_pathPrefix = key.GetStringValue(LOGGING_KEYNAME_PATH_PREFIX);
00116 m_pathPrefix = Utils::ExpandEnvironmentVariables(m_pathPrefix);
00117
00118 if ( key.GetDWORDValue(LOGGING_KEYNAME_APPEND_PROCESS_NAME_TO_PATH_PREFIX) )
00119 {
00120 m_pathPrefix += _T(".");
00121 m_pathPrefix += Utils::GetProcessName();
00122 }
00123 m_maxFileCount = key.GetDWORDValue(LOGGING_KEYNAME_GET_MAX_FILE_COUNT);
00124 m_maxFileSize = key.GetDWORDValue(LOGGING_KEYNAME_GET_MAX_FILE_SIZE);
00125
00126 InitFstream();
00127 }
00128
00129 inline void FileLogManager::InitFstream()
00130 {
00131 boost::filesystem::tpath file(m_pathPrefix + LOGGING_FILELOGMANAGER_LOG_SUFFIX, boost::filesystem::native);
00132 boost::filesystem::create_directories(file.parent_path());
00133
00134 m_fstream.open((m_pathPrefix + LOGGING_FILELOGMANAGER_LOG_SUFFIX).c_str(), std::tfstream::app | std::tfstream::out);
00135
00136 if ( !m_fstream.fail() )
00137 {
00138 m_pathPrefix += LOGGING_FILELOGMANAGER_LOG_SUFFIX;
00139 }
00140 else
00141 {
00142 std::tstring instancePathPrefix;
00143 for ( int i = 1 ; i <= LOGGING_MAX_INSTANCES_COUNT ; i++ )
00144 {
00145 instancePathPrefix = m_pathPrefix + LOGGING_FILELOGMANAGER_INSTANCE_SUFFIX + boost::lexical_cast<std::tstring>(i);
00146 m_fstream.open((instancePathPrefix + LOGGING_FILELOGMANAGER_LOG_SUFFIX).c_str(), std::tfstream::app | std::tfstream::out);
00147 if ( !m_fstream.fail() )
00148 {
00149 m_pathPrefix = instancePathPrefix;
00150 return;
00151 }
00152 }
00153
00154 throw std::runtime_error("Failed to create or open the output file for FileLogManager");
00155 }
00156 }
00157
00158 inline void FileLogManager::ManageMessage(const std::tstring& message)
00159 {
00160 m_fstream << message << std::endl;
00161 RotateIfNecessary();
00162 }
00163
00164 inline void FileLogManager::RotateIfNecessary()
00165 {
00166 boost::filesystem::tpath file(m_pathPrefix, boost::filesystem::native);
00167
00168 if ( boost::filesystem::file_size(file) > m_maxFileSize )
00169 {
00170 m_fstream.close();
00171
00172 boost::filesystem::tpath lastFile(m_pathPrefix + boost::lexical_cast<std::tstring>(m_maxFileCount));
00173 boost::filesystem::remove(lastFile);
00174
00175 for ( unsigned int i = m_maxFileCount - 1 ; i >= 1 ; i-- )
00176 {
00177 boost::filesystem::tpath thisFile(m_pathPrefix + boost::lexical_cast<std::tstring>(i));
00178 if ( boost::filesystem::exists(thisFile) )
00179 {
00180 boost::filesystem::tpath nextFile(m_pathPrefix + boost::lexical_cast<std::tstring>(i + 1));
00181 boost::filesystem::rename(thisFile, nextFile);
00182 }
00183 }
00184
00185 boost::filesystem::tpath firstFile(m_pathPrefix + boost::lexical_cast<std::tstring>(1));
00186 boost::filesystem::rename(file, firstFile);
00187
00188 m_fstream.open(m_pathPrefix.c_str(), std::tfstream::app | std::tfstream::out);
00189 }
00190 }
00191
00192 }
00193 }