[1096] | 1 | #pragma once
|
---|
| 2 | #include <plog/Appenders/IAppender.h>
|
---|
| 3 | #include <plog/Converters/UTF8Converter.h>
|
---|
| 4 | #include <plog/Util.h>
|
---|
| 5 | #include <algorithm>
|
---|
| 6 |
|
---|
| 7 | namespace plog
|
---|
| 8 | {
|
---|
| 9 | template<class Formatter, class Converter = UTF8Converter>
|
---|
| 10 | class RollingFileAppender : public IAppender
|
---|
| 11 | {
|
---|
| 12 | public:
|
---|
| 13 | RollingFileAppender(const util::nchar* fileName, size_t maxFileSize = 0, int maxFiles = 0)
|
---|
| 14 | : m_fileSize()
|
---|
| 15 | , m_maxFileSize((std::max)(static_cast<off_t>(maxFileSize), static_cast<off_t>(1000))) // set a lower limit for the maxFileSize
|
---|
| 16 | , m_lastFileNumber((std::max)(maxFiles - 1, 0))
|
---|
| 17 | , m_firstWrite(true)
|
---|
| 18 | {
|
---|
| 19 | util::splitFileName(fileName, m_fileNameNoExt, m_fileExt);
|
---|
| 20 | }
|
---|
| 21 |
|
---|
| 22 | #ifdef _WIN32
|
---|
| 23 | RollingFileAppender(const char* fileName, size_t maxFileSize = 0, int maxFiles = 0)
|
---|
| 24 | : m_fileSize()
|
---|
| 25 | , m_maxFileSize((std::max)(static_cast<off_t>(maxFileSize), static_cast<off_t>(1000))) // set a lower limit for the maxFileSize
|
---|
| 26 | , m_lastFileNumber((std::max)(maxFiles - 1, 0))
|
---|
| 27 | , m_firstWrite(true)
|
---|
| 28 | {
|
---|
| 29 | util::splitFileName(util::toWide(fileName).c_str(), m_fileNameNoExt, m_fileExt);
|
---|
| 30 | }
|
---|
| 31 | #endif
|
---|
| 32 |
|
---|
| 33 | virtual void write(const Record& record)
|
---|
| 34 | {
|
---|
| 35 | util::MutexLock lock(m_mutex);
|
---|
| 36 |
|
---|
| 37 | if (m_firstWrite)
|
---|
| 38 | {
|
---|
| 39 | openLogFile();
|
---|
| 40 | m_firstWrite = false;
|
---|
| 41 | }
|
---|
| 42 | else if (m_lastFileNumber > 0 && m_fileSize > m_maxFileSize && -1 != m_fileSize)
|
---|
| 43 | {
|
---|
| 44 | rollLogFiles();
|
---|
| 45 | }
|
---|
| 46 |
|
---|
| 47 | int bytesWritten = m_file.write(Converter::convert(Formatter::format(record)));
|
---|
| 48 |
|
---|
| 49 | if (bytesWritten > 0)
|
---|
| 50 | {
|
---|
| 51 | m_fileSize += bytesWritten;
|
---|
| 52 | }
|
---|
| 53 | }
|
---|
| 54 |
|
---|
| 55 | private:
|
---|
| 56 | void rollLogFiles()
|
---|
| 57 | {
|
---|
| 58 | m_file.close();
|
---|
| 59 |
|
---|
| 60 | util::nstring lastFileName = buildFileName(m_lastFileNumber);
|
---|
| 61 | util::File::unlink(lastFileName.c_str());
|
---|
| 62 |
|
---|
| 63 | for (int fileNumber = m_lastFileNumber - 1; fileNumber >= 0; --fileNumber)
|
---|
| 64 | {
|
---|
| 65 | util::nstring currentFileName = buildFileName(fileNumber);
|
---|
| 66 | util::nstring nextFileName = buildFileName(fileNumber + 1);
|
---|
| 67 |
|
---|
| 68 | util::File::rename(currentFileName.c_str(), nextFileName.c_str());
|
---|
| 69 | }
|
---|
| 70 |
|
---|
| 71 | openLogFile();
|
---|
| 72 | }
|
---|
| 73 |
|
---|
| 74 | void openLogFile()
|
---|
| 75 | {
|
---|
| 76 | util::nstring fileName = buildFileName();
|
---|
| 77 | m_fileSize = m_file.open(fileName.c_str());
|
---|
| 78 |
|
---|
| 79 | if (0 == m_fileSize)
|
---|
| 80 | {
|
---|
| 81 | int bytesWritten = m_file.write(Converter::header(Formatter::header()));
|
---|
| 82 |
|
---|
| 83 | if (bytesWritten > 0)
|
---|
| 84 | {
|
---|
| 85 | m_fileSize += bytesWritten;
|
---|
| 86 | }
|
---|
| 87 | }
|
---|
| 88 | }
|
---|
| 89 |
|
---|
| 90 | util::nstring buildFileName(int fileNumber = 0)
|
---|
| 91 | {
|
---|
| 92 | util::nstringstream ss;
|
---|
| 93 | ss << m_fileNameNoExt;
|
---|
| 94 |
|
---|
| 95 | if (fileNumber > 0)
|
---|
| 96 | {
|
---|
| 97 | ss << '.' << fileNumber;
|
---|
| 98 | }
|
---|
| 99 |
|
---|
| 100 | if (!m_fileExt.empty())
|
---|
| 101 | {
|
---|
| 102 | ss << '.' << m_fileExt;
|
---|
| 103 | }
|
---|
| 104 |
|
---|
| 105 | return ss.str();
|
---|
| 106 | }
|
---|
| 107 |
|
---|
| 108 | private:
|
---|
| 109 | util::Mutex m_mutex;
|
---|
| 110 | util::File m_file;
|
---|
| 111 | off_t m_fileSize;
|
---|
| 112 | const off_t m_maxFileSize;
|
---|
| 113 | const int m_lastFileNumber;
|
---|
| 114 | util::nstring m_fileExt;
|
---|
| 115 | util::nstring m_fileNameNoExt;
|
---|
| 116 | bool m_firstWrite;
|
---|
| 117 | };
|
---|
| 118 | }
|
---|