Enhance FileChannel purge setting.

This commit is contained in:
aaron0x 2015-09-26 23:31:30 +08:00 committed by Guenter Obiltschnig
parent 13b34666d9
commit 3066e66f32
4 changed files with 110 additions and 51 deletions

View File

@ -23,6 +23,7 @@
#include "Poco/Foundation.h"
#include "Poco/Channel.h"
#include "Poco/Timestamp.h"
#include "Poco/Timespan.h"
#include "Poco/Mutex.h"
@ -243,6 +244,11 @@ protected:
void purge();
private:
bool setNoPurge(const std::string& value);
int extractDigit(const std::string& value, std::string::const_iterator* nextToDigit = NULL) const;
void setPurgeStrategy(PurgeStrategy* strategy);
Timespan::TimeDiff extractFactor(const std::string& value, std::string::const_iterator start) const;
std::string _path;
std::string _times;
std::string _rotation;

View File

@ -24,7 +24,6 @@
#include "Poco/DateTime.h"
#include "Poco/LocalDateTime.h"
#include "Poco/String.h"
#include "Poco/Timespan.h"
#include "Poco/Exception.h"
#include "Poco/Ascii.h"
@ -314,65 +313,22 @@ void FileChannel::setCompress(const std::string& compress)
void FileChannel::setPurgeAge(const std::string& age)
{
delete _pPurgeStrategy;
_pPurgeStrategy = 0;
_purgeAge = "none";
if (setNoPurge(age)) return;
if (age.empty() || 0 == icompare(age, "none"))
return;
std::string::const_iterator nextToDigit;
int num = extractDigit(age, &nextToDigit);
Timespan::TimeDiff factor = extractFactor(age, nextToDigit);
std::string::const_iterator it = age.begin();
std::string::const_iterator end = age.end();
int n = 0;
while (it != end && Ascii::isSpace(*it)) ++it;
while (it != end && Ascii::isDigit(*it)) { n *= 10; n += *it++ - '0'; }
if (0 == n)
throw InvalidArgumentException("Zero is not valid purge age.");
while (it != end && Ascii::isSpace(*it)) ++it;
std::string unit;
while (it != end && Ascii::isAlpha(*it)) unit += *it++;
Timespan::TimeDiff factor = Timespan::SECONDS;
if (unit == "minutes")
factor = Timespan::MINUTES;
else if (unit == "hours")
factor = Timespan::HOURS;
else if (unit == "days")
factor = Timespan::DAYS;
else if (unit == "weeks")
factor = 7*Timespan::DAYS;
else if (unit == "months")
factor = 30*Timespan::DAYS;
else if (unit != "seconds")
throw InvalidArgumentException("purgeAge", age);
_pPurgeStrategy = new PurgeByAgeStrategy(Timespan(factor*n));
setPurgeStrategy(new PurgeByAgeStrategy(Timespan(num * factor)));
_purgeAge = age;
}
void FileChannel::setPurgeCount(const std::string& count)
{
delete _pPurgeStrategy;
_pPurgeStrategy = 0;
_purgeAge = "none";
if (setNoPurge(count)) return;
if (count.empty() || 0 == icompare(count, "none"))
return;
std::string::const_iterator it = count.begin();
std::string::const_iterator end = count.end();
int n = 0;
while (it != end && Ascii::isSpace(*it)) ++it;
while (it != end && Ascii::isDigit(*it)) { n *= 10; n += *it++ - '0'; }
if (0 == n)
throw InvalidArgumentException("Zero is not valid purge count.");
while (it != end && Ascii::isSpace(*it)) ++it;
delete _pPurgeStrategy;
_pPurgeStrategy = new PurgeByCountStrategy(n);
setPurgeStrategy(new PurgeByCountStrategy(extractDigit(count)));
_purgeCount = count;
}
@ -404,4 +360,71 @@ void FileChannel::purge()
}
bool FileChannel::setNoPurge(const std::string& value)
{
if (value.empty() || 0 == icompare(value, "none"))
{
delete _pPurgeStrategy;
_pPurgeStrategy = 0;
_purgeAge = "none";
return true;
}
else return false;
}
int FileChannel::extractDigit(const std::string& value, std::string::const_iterator* nextToDigit) const
{
std::string::const_iterator it = value.begin();
std::string::const_iterator end = value.end();
int digit = 0;
while (it != end && Ascii::isSpace(*it)) ++it;
while (it != end && Ascii::isDigit(*it))
{
digit *= 10;
digit += *it++ - '0';
}
if (digit == 0)
throw InvalidArgumentException("Zero is not valid purge age.");
if (nextToDigit) *nextToDigit = it;
return digit;
}
void FileChannel::setPurgeStrategy(PurgeStrategy* strategy)
{
delete _pPurgeStrategy;
_pPurgeStrategy = strategy;
}
Timespan::TimeDiff FileChannel::extractFactor(const std::string& value, std::string::const_iterator start) const
{
while (start != value.end() && Ascii::isSpace(*start)) ++start;
std::string unit;
while (start != value.end() && Ascii::isAlpha(*start)) unit += *start++;
if (unit == "seconds")
return Timespan::SECONDS;
if (unit == "minutes")
return Timespan::MINUTES;
else if (unit == "hours")
return Timespan::HOURS;
else if (unit == "days")
return Timespan::DAYS;
else if (unit == "weeks")
return 7 * Timespan::DAYS;
else if (unit == "months")
return 30 * Timespan::DAYS;
else throw InvalidArgumentException("purgeAge", value);
return Timespan::TimeDiff();
}
} // namespace Poco

View File

@ -518,6 +518,34 @@ void FileChannelTest::testPurgeCount()
}
void FileChannelTest::testWrongPurgeOption()
{
std::string name = filename();
AutoPtr<FileChannel> pChannel = new FileChannel(name);
pChannel->setProperty(FileChannel::PROP_PURGEAGE, "5 seconds");
try
{
pChannel->setProperty(FileChannel::PROP_PURGEAGE, "peace");
fail("must fail");
} catch (InvalidArgumentException)
{
assert(pChannel->getProperty(FileChannel::PROP_PURGEAGE) == "5 seconds");
}
try
{
pChannel->setProperty(FileChannel::PROP_PURGECOUNT, "peace");
fail("must fail");
} catch (InvalidArgumentException)
{
assert(pChannel->getProperty(FileChannel::PROP_PURGEAGE) == "5 seconds");
}
remove(name);
}
void FileChannelTest::setUp()
{
}
@ -620,6 +648,7 @@ CppUnit::Test* FileChannelTest::suite()
CppUnit_addTest(pSuite, FileChannelTest, testCompress);
CppUnit_addTest(pSuite, FileChannelTest, testPurgeAge);
CppUnit_addTest(pSuite, FileChannelTest, testPurgeCount);
CppUnit_addTest(pSuite, FileChannelTest, testWrongPurgeOption);
return pSuite;
}

View File

@ -45,6 +45,7 @@ public:
void testCompress();
void testPurgeAge();
void testPurgeCount();
void testWrongPurgeOption();
void setUp();
void tearDown();