diff --git a/Foundation/include/Poco/FileChannel.h b/Foundation/include/Poco/FileChannel.h index cd33674e8..aa31d9095 100644 --- a/Foundation/include/Poco/FileChannel.h +++ b/Foundation/include/Poco/FileChannel.h @@ -151,10 +151,14 @@ class Foundation_API FileChannel: public Channel /// * weeks: the maximum age is weeks. /// * months: the maximum age is months, where a month has 30 days. /// + /// Both empty string ("") and n == 0 indicate no purging. + /// /// The purgeCount property has an integer value that /// specifies the maximum number of archived log files. /// If the number is exceeded, archived log files are /// deleted, starting with the oldest. + /// + /// Both empty string ("") and "0" for indicate no purging. /// /// For a more lightweight file channel class, see SimpleFileChannel. { diff --git a/Foundation/src/FileChannel.cpp b/Foundation/src/FileChannel.cpp index a02079da1..03a2d2842 100644 --- a/Foundation/src/FileChannel.cpp +++ b/Foundation/src/FileChannel.cpp @@ -296,6 +296,14 @@ void FileChannel::setCompress(const std::string& compress) void FileChannel::setPurgeAge(const std::string& age) { + if (age.empty()) + { + delete _pPurgeStrategy; + _pPurgeStrategy = 0; + _purgeAge.clear(); + return; + } + std::string::const_iterator it = age.begin(); std::string::const_iterator end = age.end(); int n = 0; @@ -320,7 +328,12 @@ void FileChannel::setPurgeAge(const std::string& age) throw InvalidArgumentException("purgeAge", age); delete _pPurgeStrategy; - _pPurgeStrategy = new PurgeByAgeStrategy(Timespan(factor*n)); + + if (0 == n || age.empty()) + _pPurgeStrategy = 0; + else + _pPurgeStrategy = new PurgeByAgeStrategy(Timespan(factor*n)); + _purgeAge = age; } @@ -335,7 +348,12 @@ void FileChannel::setPurgeCount(const std::string& count) while (it != end && std::isspace(*it)) ++it; delete _pPurgeStrategy; - _pPurgeStrategy = new PurgeByCountStrategy(n); + + if (0 == n || count.empty()) + _pPurgeStrategy = 0; + else + _pPurgeStrategy = new PurgeByCountStrategy(n); + _purgeCount = count; } diff --git a/Foundation/testsuite/src/FileChannelTest.cpp b/Foundation/testsuite/src/FileChannelTest.cpp index ccb78127c..5597e9a0e 100644 --- a/Foundation/testsuite/src/FileChannelTest.cpp +++ b/Foundation/testsuite/src/FileChannelTest.cpp @@ -363,7 +363,7 @@ void FileChannelTest::testCompress() } -void FileChannelTest::testPurgeAge() +void FileChannelTest::purgeAge(const std::string& pa) { std::string name = filename(); try @@ -371,7 +371,7 @@ void FileChannelTest::testPurgeAge() AutoPtr pChannel = new FileChannel(name); pChannel->setProperty(FileChannel::PROP_ROTATION, "1 K"); pChannel->setProperty(FileChannel::PROP_ARCHIVE, "number"); - pChannel->setProperty(FileChannel::PROP_PURGEAGE, "5 seconds"); + pChannel->setProperty(FileChannel::PROP_PURGEAGE, pa); pChannel->open(); Message msg("source", "This is a log file entry", Message::PRIO_INFORMATION); for (int i = 0; i < 200; ++i) @@ -402,7 +402,7 @@ void FileChannelTest::testPurgeAge() } -void FileChannelTest::testPurgeCount() +void FileChannelTest::noPurgeAge(const std::string& npa) { std::string name = filename(); try @@ -410,7 +410,54 @@ void FileChannelTest::testPurgeCount() AutoPtr pChannel = new FileChannel(name); pChannel->setProperty(FileChannel::PROP_ROTATION, "1 K"); pChannel->setProperty(FileChannel::PROP_ARCHIVE, "number"); - pChannel->setProperty(FileChannel::PROP_PURGECOUNT, "2"); + pChannel->setProperty(FileChannel::PROP_PURGEAGE, npa); + pChannel->open(); + Message msg("source", "This is a log file entry", Message::PRIO_INFORMATION); + for (int i = 0; i < 200; ++i) + { + pChannel->log(msg); + } + File f0(name + ".0"); + assert (f0.exists()); + File f1(name + ".1"); + assert (f1.exists()); + File f2(name + ".2"); + assert (f2.exists()); + + Thread::sleep(5000); + for (int i = 0; i < 50; ++i) + { + pChannel->log(msg); + } + + assert (f2.exists()); + } + catch (...) + { + remove(name); + throw; + } + remove(name); +} + + +void FileChannelTest::testPurgeAge() +{ + purgeAge("5 seconds"); + noPurgeAge("0 seconds"); + noPurgeAge(""); +} + + +void FileChannelTest::purgeCount(const std::string& pc) +{ + std::string name = filename(); + try + { + AutoPtr pChannel = new FileChannel(name); + pChannel->setProperty(FileChannel::PROP_ROTATION, "1 K"); + pChannel->setProperty(FileChannel::PROP_ARCHIVE, "number"); + pChannel->setProperty(FileChannel::PROP_PURGECOUNT, pc); pChannel->open(); Message msg("source", "This is a log file entry", Message::PRIO_INFORMATION); for (int i = 0; i < 200; ++i) @@ -434,6 +481,46 @@ void FileChannelTest::testPurgeCount() } +void FileChannelTest::noPurgeCount(const std::string& npc) +{ + std::string name = filename(); + try + { + AutoPtr pChannel = new FileChannel(name); + pChannel->setProperty(FileChannel::PROP_ROTATION, "1 K"); + pChannel->setProperty(FileChannel::PROP_ARCHIVE, "number"); + pChannel->setProperty(FileChannel::PROP_PURGECOUNT, npc); + pChannel->open(); + Message msg("source", "This is a log file entry", Message::PRIO_INFORMATION); + for (int i = 0; i < 200; ++i) + { + pChannel->log(msg); + Thread::sleep(50); + } + File f0(name + ".0"); + assert (f0.exists()); + File f1(name + ".1"); + assert (f1.exists()); + File f2(name + ".2"); + assert (f2.exists()); + } + catch (...) + { + remove(name); + throw; + } + remove(name); +} + + +void FileChannelTest::testPurgeCount() +{ + purgeCount("2"); + noPurgeCount(""); + noPurgeCount("0"); +} + + void FileChannelTest::setUp() { } diff --git a/Foundation/testsuite/src/FileChannelTest.h b/Foundation/testsuite/src/FileChannelTest.h index 8b106467b..cc7eee181 100644 --- a/Foundation/testsuite/src/FileChannelTest.h +++ b/Foundation/testsuite/src/FileChannelTest.h @@ -75,6 +75,11 @@ private: template std::string rotation(TimeRotation rtype) const; void remove(const std::string& baseName); std::string filename() const; + + void purgeAge(const std::string& purgeAge); + void noPurgeAge(const std::string& purgeAge); + void purgeCount(const std::string& pc); + void noPurgeCount(const std::string& pc); };