00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00037 #include "blocxx/BLOCXX_config.h"
00038 #include "blocxx/FileAppender.hpp"
00039 #include "blocxx/Format.hpp"
00040 #include "blocxx/Logger.hpp"
00041 #include "blocxx/LogMessage.hpp"
00042 #include "blocxx/Mutex.hpp"
00043 #include "blocxx/MutexLock.hpp"
00044 #include "blocxx/FileSystem.hpp"
00045
00046 #include <fstream>
00047
00048 namespace BLOCXX_NAMESPACE
00049 {
00050
00052 FileAppender::FileAppender(const StringArray& components,
00053 const StringArray& categories,
00054 const char* filename,
00055 const String& pattern,
00056 UInt64 maxFileSize,
00057 unsigned int maxBackupIndex,
00058 bool flushLog)
00059 : LogAppender(components, categories, pattern)
00060 , m_filename(filename)
00061 , m_maxFileSize(maxFileSize)
00062 , m_maxBackupIndex(maxBackupIndex)
00063 , m_flushLog(flushLog)
00064 {
00065 m_log.open(m_filename.c_str(), std::ios::out | std::ios::app);
00066 if (!m_log)
00067 {
00068 BLOCXX_THROW(LoggerException, Format("FileAppender: Unable to open file: %1", m_filename).toString().c_str() );
00069 }
00070 }
00071
00073 FileAppender::~FileAppender()
00074 {
00075 }
00076
00078 namespace
00079 {
00080 Mutex fileGuard;
00081 }
00082 void
00083 FileAppender::doProcessLogMessage(const String& formattedMessage, const LogMessage& message) const
00084 {
00085 MutexLock lock(fileGuard);
00086
00087
00088 if (!FileSystem::exists(m_filename.c_str()))
00089 {
00090 m_log.close();
00091 m_log.open(m_filename.c_str(), std::ios::out | std::ios::app);
00092 }
00093
00094 if (!m_log)
00095 {
00096
00097 return;
00098 }
00099
00100 m_log.write(formattedMessage.c_str(), formattedMessage.length());
00101 m_log << '\n';
00102
00103 if (m_flushLog)
00104 {
00105 m_log.flush();
00106 }
00107
00108
00109 if (m_maxFileSize != NO_MAX_LOG_SIZE && m_log.tellp() >= static_cast<std::streampos>(m_maxFileSize * 1024))
00110 {
00111
00112
00113
00114 m_log.close();
00115
00116 if (m_maxBackupIndex > 0)
00117 {
00118
00119 FileSystem::removeFile(m_filename + '.' + String(m_maxBackupIndex));
00120
00121
00122 for (unsigned int i = m_maxBackupIndex - 1; i >= 1; --i)
00123 {
00124 FileSystem::renameFile(m_filename + '.' + String(i), m_filename + '.' + String(i + 1));
00125 }
00126
00127 if (!FileSystem::renameFile(m_filename, m_filename + ".1"))
00128 {
00129
00130 return;
00131 }
00132 }
00133
00134
00135 m_log.open(m_filename.c_str(), std::ios_base::out | std::ios_base::trunc);
00136 }
00137 }
00138
00140 const String FileAppender::STR_DEFAULT_MESSAGE_PATTERN("%d{%a %b %d %H:%M:%S %Y} [%t]: %m");
00141
00142 }
00143
00144
00145
00146