mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-27 11:06:50 +01:00
Custom rotate, archive and purge strategies for FileChannel (#3810)
* Adding the ability to set custom rotate, archive and purge strategies. * Force CI
This commit is contained in:
@@ -42,6 +42,9 @@ public:
|
|||||||
ArchiveStrategy();
|
ArchiveStrategy();
|
||||||
virtual ~ArchiveStrategy();
|
virtual ~ArchiveStrategy();
|
||||||
|
|
||||||
|
virtual LogFile* open(LogFile* pFile) = 0;
|
||||||
|
/// Open a new log file and return it.
|
||||||
|
|
||||||
virtual LogFile* archive(LogFile* pFile) = 0;
|
virtual LogFile* archive(LogFile* pFile) = 0;
|
||||||
/// Renames the given log file for archiving
|
/// Renames the given log file for archiving
|
||||||
/// and creates and returns a new log file.
|
/// and creates and returns a new log file.
|
||||||
@@ -71,6 +74,8 @@ class Foundation_API ArchiveByNumberStrategy: public ArchiveStrategy
|
|||||||
public:
|
public:
|
||||||
ArchiveByNumberStrategy();
|
ArchiveByNumberStrategy();
|
||||||
~ArchiveByNumberStrategy();
|
~ArchiveByNumberStrategy();
|
||||||
|
|
||||||
|
LogFile* open(LogFile* pFile);
|
||||||
LogFile* archive(LogFile* pFile);
|
LogFile* archive(LogFile* pFile);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -89,6 +94,11 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogFile* open(LogFile* pFile)
|
||||||
|
{
|
||||||
|
return pFile;
|
||||||
|
}
|
||||||
|
|
||||||
LogFile* archive(LogFile* pFile)
|
LogFile* archive(LogFile* pFile)
|
||||||
/// Archives the file by appending the current timestamp to the
|
/// Archives the file by appending the current timestamp to the
|
||||||
/// file name. If the new file name exists, additionally a monotonic
|
/// file name. If the new file name exists, additionally a monotonic
|
||||||
|
|||||||
@@ -211,6 +211,18 @@ public:
|
|||||||
/// See setProperty() for a description of the supported
|
/// See setProperty() for a description of the supported
|
||||||
/// properties.
|
/// properties.
|
||||||
|
|
||||||
|
void setRotationStrategy(RotateStrategy* strategy);
|
||||||
|
/// Set a rotation strategy.
|
||||||
|
/// FileChannel will take ownership of the pointer
|
||||||
|
|
||||||
|
void setArchiveStrategy(ArchiveStrategy* strategy);
|
||||||
|
/// Set an archive strategy.
|
||||||
|
/// FileChannel will take ownership of the pointer
|
||||||
|
|
||||||
|
void setPurgeStrategy(PurgeStrategy* strategy);
|
||||||
|
/// Set a purge strategy.
|
||||||
|
/// FileChannel will take ownership of the pointer
|
||||||
|
|
||||||
Timestamp creationDate() const;
|
Timestamp creationDate() const;
|
||||||
/// Returns the log file's creation date.
|
/// Returns the log file's creation date.
|
||||||
|
|
||||||
@@ -232,6 +244,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
~FileChannel();
|
~FileChannel();
|
||||||
|
|
||||||
void setRotation(const std::string& rotation);
|
void setRotation(const std::string& rotation);
|
||||||
void setArchive(const std::string& archive);
|
void setArchive(const std::string& archive);
|
||||||
void setCompress(const std::string& compress);
|
void setCompress(const std::string& compress);
|
||||||
@@ -244,9 +257,11 @@ protected:
|
|||||||
private:
|
private:
|
||||||
bool setNoPurge(const std::string& value);
|
bool setNoPurge(const std::string& value);
|
||||||
int extractDigit(const std::string& value, std::string::const_iterator* nextToDigit = NULL) const;
|
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;
|
Timespan::TimeDiff extractFactor(const std::string& value, std::string::const_iterator start) const;
|
||||||
|
|
||||||
|
RotateStrategy* createRotationStrategy(const std::string& rotation, const std::string& times) const;
|
||||||
|
ArchiveStrategy* createArchiveStrategy(const std::string& archive, const std::string& times) const;
|
||||||
|
|
||||||
std::string _path;
|
std::string _path;
|
||||||
std::string _times;
|
std::string _times;
|
||||||
std::string _rotation;
|
std::string _rotation;
|
||||||
|
|||||||
@@ -60,6 +60,16 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Foundation_API NullPurgeStrategy : public PurgeStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NullPurgeStrategy();
|
||||||
|
~NullPurgeStrategy();
|
||||||
|
|
||||||
|
void purge(const std::string& path);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Foundation_API PurgeByAgeStrategy: public PurgeStrategy
|
class Foundation_API PurgeByAgeStrategy: public PurgeStrategy
|
||||||
/// This purge strategy purges all files that have
|
/// This purge strategy purges all files that have
|
||||||
/// exceeded a given age (given in seconds).
|
/// exceeded a given age (given in seconds).
|
||||||
|
|||||||
@@ -49,6 +49,13 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Foundation_API NullRotateStrategy : public RotateStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool mustRotate(LogFile* pFile);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class DT>
|
template <class DT>
|
||||||
class RotateAtTimeStrategy: public RotateStrategy
|
class RotateAtTimeStrategy: public RotateStrategy
|
||||||
/// The file is rotated at specified [day,][hour]:minute
|
/// The file is rotated at specified [day,][hour]:minute
|
||||||
|
|||||||
@@ -161,6 +161,12 @@ ArchiveByNumberStrategy::~ArchiveByNumberStrategy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LogFile* ArchiveByNumberStrategy::open(LogFile* pFile)
|
||||||
|
{
|
||||||
|
return pFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LogFile* ArchiveByNumberStrategy::archive(LogFile* pFile)
|
LogFile* ArchiveByNumberStrategy::archive(LogFile* pFile)
|
||||||
{
|
{
|
||||||
std::string basePath = pFile->path();
|
std::string basePath = pFile->path();
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ FileChannel::FileChannel():
|
|||||||
_flush(true),
|
_flush(true),
|
||||||
_rotateOnOpen(false),
|
_rotateOnOpen(false),
|
||||||
_pFile(0),
|
_pFile(0),
|
||||||
_pRotateStrategy(0),
|
_pRotateStrategy(new NullRotateStrategy()),
|
||||||
_pArchiveStrategy(new ArchiveByNumberStrategy),
|
_pArchiveStrategy(new ArchiveByNumberStrategy),
|
||||||
_pPurgeStrategy(0)
|
_pPurgeStrategy(new NullPurgeStrategy())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,9 +59,9 @@ FileChannel::FileChannel(const std::string& path):
|
|||||||
_flush(true),
|
_flush(true),
|
||||||
_rotateOnOpen(false),
|
_rotateOnOpen(false),
|
||||||
_pFile(0),
|
_pFile(0),
|
||||||
_pRotateStrategy(0),
|
_pRotateStrategy(new NullRotateStrategy()),
|
||||||
_pArchiveStrategy(new ArchiveByNumberStrategy),
|
_pArchiveStrategy(new ArchiveByNumberStrategy),
|
||||||
_pPurgeStrategy(0)
|
_pPurgeStrategy(new NullPurgeStrategy())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,6 +101,8 @@ void FileChannel::open()
|
|||||||
_pFile = new LogFile(_path);
|
_pFile = new LogFile(_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_pFile = _pArchiveStrategy->open(_pFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +122,7 @@ void FileChannel::log(const Message& msg)
|
|||||||
|
|
||||||
FastMutex::ScopedLock lock(_mutex);
|
FastMutex::ScopedLock lock(_mutex);
|
||||||
|
|
||||||
if (_pRotateStrategy && _pArchiveStrategy && _pRotateStrategy->mustRotate(_pFile))
|
if (_pRotateStrategy->mustRotate(_pFile))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -224,7 +226,7 @@ const std::string& FileChannel::path() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FileChannel::setRotation(const std::string& rotation)
|
RotateStrategy* FileChannel::createRotationStrategy(const std::string& rotation, const std::string& times) const
|
||||||
{
|
{
|
||||||
std::string::const_iterator it = rotation.begin();
|
std::string::const_iterator it = rotation.begin();
|
||||||
std::string::const_iterator end = rotation.end();
|
std::string::const_iterator end = rotation.end();
|
||||||
@@ -238,12 +240,12 @@ void FileChannel::setRotation(const std::string& rotation)
|
|||||||
RotateStrategy* pStrategy = 0;
|
RotateStrategy* pStrategy = 0;
|
||||||
if ((rotation.find(',') != std::string::npos) || (rotation.find(':') != std::string::npos))
|
if ((rotation.find(',') != std::string::npos) || (rotation.find(':') != std::string::npos))
|
||||||
{
|
{
|
||||||
if (_times == "utc")
|
if (times == "utc")
|
||||||
pStrategy = new RotateAtTimeStrategy<DateTime>(rotation);
|
pStrategy = new RotateAtTimeStrategy<DateTime>(rotation);
|
||||||
else if (_times == "local")
|
else if (times == "local")
|
||||||
pStrategy = new RotateAtTimeStrategy<LocalDateTime>(rotation);
|
pStrategy = new RotateAtTimeStrategy<LocalDateTime>(rotation);
|
||||||
else
|
else
|
||||||
throw PropertyNotSupportedException("times", _times);
|
throw PropertyNotSupportedException("times", times);
|
||||||
}
|
}
|
||||||
else if (unit == "daily")
|
else if (unit == "daily")
|
||||||
pStrategy = new RotateByIntervalStrategy(Timespan(1*Timespan::DAYS));
|
pStrategy = new RotateByIntervalStrategy(Timespan(1*Timespan::DAYS));
|
||||||
@@ -271,12 +273,57 @@ void FileChannel::setRotation(const std::string& rotation)
|
|||||||
pStrategy = new RotateBySizeStrategy(n);
|
pStrategy = new RotateBySizeStrategy(n);
|
||||||
else if (unit != "never")
|
else if (unit != "never")
|
||||||
throw InvalidArgumentException("rotation", rotation);
|
throw InvalidArgumentException("rotation", rotation);
|
||||||
|
|
||||||
|
return pStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileChannel::setRotationStrategy(RotateStrategy* strategy)
|
||||||
|
{
|
||||||
|
poco_check_ptr(strategy);
|
||||||
|
|
||||||
delete _pRotateStrategy;
|
delete _pRotateStrategy;
|
||||||
_pRotateStrategy = pStrategy;
|
_pRotateStrategy = strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileChannel::setRotation(const std::string& rotation)
|
||||||
|
{
|
||||||
|
setRotationStrategy(createRotationStrategy(rotation, _times));
|
||||||
_rotation = rotation;
|
_rotation = rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ArchiveStrategy* FileChannel::createArchiveStrategy(const std::string& archive, const std::string& times) const
|
||||||
|
{
|
||||||
|
ArchiveStrategy* pStrategy = 0;
|
||||||
|
if (archive == "number")
|
||||||
|
{
|
||||||
|
pStrategy = new ArchiveByNumberStrategy;
|
||||||
|
}
|
||||||
|
else if (archive == "timestamp")
|
||||||
|
{
|
||||||
|
if (times == "utc")
|
||||||
|
pStrategy = new ArchiveByTimestampStrategy<DateTime>;
|
||||||
|
else if (times == "local")
|
||||||
|
pStrategy = new ArchiveByTimestampStrategy<LocalDateTime>;
|
||||||
|
else
|
||||||
|
throw PropertyNotSupportedException("times", times);
|
||||||
|
}
|
||||||
|
else throw InvalidArgumentException("archive", archive);
|
||||||
|
return pStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileChannel::setArchiveStrategy(ArchiveStrategy* strategy)
|
||||||
|
{
|
||||||
|
poco_check_ptr(strategy);
|
||||||
|
|
||||||
|
delete _pArchiveStrategy;
|
||||||
|
_pArchiveStrategy = strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FileChannel::setArchive(const std::string& archive)
|
void FileChannel::setArchive(const std::string& archive)
|
||||||
{
|
{
|
||||||
ArchiveStrategy* pStrategy = 0;
|
ArchiveStrategy* pStrategy = 0;
|
||||||
@@ -304,7 +351,6 @@ void FileChannel::setArchive(const std::string& archive)
|
|||||||
void FileChannel::setCompress(const std::string& compress)
|
void FileChannel::setCompress(const std::string& compress)
|
||||||
{
|
{
|
||||||
_compress = icompare(compress, "true") == 0;
|
_compress = icompare(compress, "true") == 0;
|
||||||
if (_pArchiveStrategy)
|
|
||||||
_pArchiveStrategy->compress(_compress);
|
_pArchiveStrategy->compress(_compress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,8 +391,6 @@ void FileChannel::setRotateOnOpen(const std::string& rotateOnOpen)
|
|||||||
|
|
||||||
void FileChannel::purge()
|
void FileChannel::purge()
|
||||||
{
|
{
|
||||||
if (_pPurgeStrategy)
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_pPurgeStrategy->purge(_path);
|
_pPurgeStrategy->purge(_path);
|
||||||
@@ -354,7 +398,6 @@ void FileChannel::purge()
|
|||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -363,7 +406,7 @@ bool FileChannel::setNoPurge(const std::string& value)
|
|||||||
if (value.empty() || 0 == icompare(value, "none"))
|
if (value.empty() || 0 == icompare(value, "none"))
|
||||||
{
|
{
|
||||||
delete _pPurgeStrategy;
|
delete _pPurgeStrategy;
|
||||||
_pPurgeStrategy = 0;
|
_pPurgeStrategy = new NullPurgeStrategy();
|
||||||
_purgeAge = "none";
|
_purgeAge = "none";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -394,6 +437,8 @@ int FileChannel::extractDigit(const std::string& value, std::string::const_itera
|
|||||||
|
|
||||||
void FileChannel::setPurgeStrategy(PurgeStrategy* strategy)
|
void FileChannel::setPurgeStrategy(PurgeStrategy* strategy)
|
||||||
{
|
{
|
||||||
|
poco_check_ptr(strategy);
|
||||||
|
|
||||||
delete _pPurgeStrategy;
|
delete _pPurgeStrategy;
|
||||||
_pPurgeStrategy = strategy;
|
_pPurgeStrategy = strategy;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,26 @@ void PurgeStrategy::list(const std::string& path, std::vector<File>& files)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// NullPurgeStrategy
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
NullPurgeStrategy::NullPurgeStrategy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NullPurgeStrategy::~NullPurgeStrategy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NullPurgeStrategy::purge(const std::string& path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// PurgeByAgeStrategy
|
// PurgeByAgeStrategy
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -38,6 +38,17 @@ RotateStrategy::~RotateStrategy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// NullRotateStrategy
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
bool NullRotateStrategy::mustRotate(LogFile* pFile)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// RotateByIntervalStrategy
|
// RotateByIntervalStrategy
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -26,6 +26,9 @@
|
|||||||
#include "Poco/NumberFormatter.h"
|
#include "Poco/NumberFormatter.h"
|
||||||
#include "Poco/DirectoryIterator.h"
|
#include "Poco/DirectoryIterator.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
|
#include "Poco/RotateStrategy.h"
|
||||||
|
#include "Poco/ArchiveStrategy.h"
|
||||||
|
#include "Poco/PurgeStrategy.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
@@ -287,6 +290,57 @@ void FileChannelTest::testRotateAtTimeMinLocal()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class RotateByCustomStrategy : public Poco::RotateStrategy
|
||||||
|
/// The file is rotated when the log file
|
||||||
|
/// exceeds a given age.
|
||||||
|
///
|
||||||
|
/// For this to work reliably across all platforms and file systems
|
||||||
|
/// (there are severe issues on most platforms finding out the real
|
||||||
|
/// creation date of a file), the creation date of the file is
|
||||||
|
/// written into the log file as the first entry.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool mustRotate(Poco::LogFile* pFile)
|
||||||
|
{
|
||||||
|
return pFile->size() > 2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void FileChannelTest::testRotateByStrategy()
|
||||||
|
{
|
||||||
|
std::string name = filename();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AutoPtr<FileChannel> pChannel = new FileChannel(name);
|
||||||
|
|
||||||
|
// this test rotates at 2k just like testRotateBySize. Set the prop rotation to 50k to verify that the rotation strategy takes over
|
||||||
|
pChannel->setProperty(FileChannel::PROP_ROTATION, "50 K");
|
||||||
|
pChannel->setRotationStrategy(new RotateByCustomStrategy());
|
||||||
|
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 f(name + ".0");
|
||||||
|
assertTrue(f.exists());
|
||||||
|
f = name + ".1";
|
||||||
|
assertTrue(f.exists());
|
||||||
|
f = name + ".2";
|
||||||
|
assertTrue(!f.exists());
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
remove(name);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FileChannelTest::testArchive()
|
void FileChannelTest::testArchive()
|
||||||
{
|
{
|
||||||
std::string name = filename();
|
std::string name = filename();
|
||||||
@@ -313,6 +367,88 @@ void FileChannelTest::testArchive()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ArchiveByCustomNumberStrategy : public Poco::ArchiveStrategy
|
||||||
|
/// A monotonic increasing number is appended to the
|
||||||
|
/// log file name. The most recent archived file
|
||||||
|
/// always has the number zero.
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Poco::LogFile* open(Poco::LogFile* pFile)
|
||||||
|
{
|
||||||
|
return pFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Poco::LogFile* archive(Poco::LogFile* pFile)
|
||||||
|
{
|
||||||
|
std::string basePath = pFile->path();
|
||||||
|
delete pFile;
|
||||||
|
int n = -1;
|
||||||
|
std::string path;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
path = basePath;
|
||||||
|
path = path.substr(0, path.length() - 4);
|
||||||
|
path.append("_");
|
||||||
|
NumberFormatter::append(path, ++n);
|
||||||
|
path.append(".log");
|
||||||
|
} while (exists(path));
|
||||||
|
|
||||||
|
while (n >= 0)
|
||||||
|
{
|
||||||
|
std::string oldPath = basePath;
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
oldPath = oldPath.substr(0, oldPath.length() - 4);
|
||||||
|
oldPath.append("_");
|
||||||
|
NumberFormatter::append(oldPath, n - 1);
|
||||||
|
oldPath.append(".log");
|
||||||
|
}
|
||||||
|
std::string newPath = basePath;
|
||||||
|
newPath = newPath.substr(0, newPath.length() - 4);
|
||||||
|
newPath.append("_");
|
||||||
|
NumberFormatter::append(newPath, n);
|
||||||
|
newPath.append(".log");
|
||||||
|
moveFile(oldPath, newPath);
|
||||||
|
--n;
|
||||||
|
}
|
||||||
|
return new Poco::LogFile(basePath);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void FileChannelTest::testArchiveByStrategy()
|
||||||
|
{
|
||||||
|
std::string name = filename();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AutoPtr<FileChannel> pChannel = new FileChannel(name);
|
||||||
|
pChannel->setProperty(FileChannel::PROP_ROTATION, "2 K");
|
||||||
|
pChannel->setProperty(FileChannel::PROP_ARCHIVE, "number");
|
||||||
|
|
||||||
|
pChannel->setArchiveStrategy(new ArchiveByCustomNumberStrategy());
|
||||||
|
|
||||||
|
pChannel->open();
|
||||||
|
Message msg("source", "This is a log file entry", Message::PRIO_INFORMATION);
|
||||||
|
for (int i = 0; i < 200; ++i)
|
||||||
|
{
|
||||||
|
pChannel->log(msg);
|
||||||
|
}
|
||||||
|
name = name.substr(0, name.length() - 4);
|
||||||
|
name.append("_0.log");
|
||||||
|
|
||||||
|
File f(name);
|
||||||
|
assertTrue(f.exists());
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
remove(name);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FileChannelTest::testCompress()
|
void FileChannelTest::testCompress()
|
||||||
{
|
{
|
||||||
std::string name = filename();
|
std::string name = filename();
|
||||||
@@ -544,6 +680,40 @@ void FileChannelTest::testWrongPurgeOption()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileChannelTest::testPurgeByStrategy()
|
||||||
|
{
|
||||||
|
std::string name = filename();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AutoPtr<FileChannel> pChannel = new FileChannel(name);
|
||||||
|
pChannel->setProperty(FileChannel::PROP_ROTATION, "1 K");
|
||||||
|
pChannel->setProperty(FileChannel::PROP_ARCHIVE, "number");
|
||||||
|
pChannel->setProperty(FileChannel::PROP_PURGECOUNT, "");
|
||||||
|
// simpler to test the type that already exists. A true "custom" purge strategy might be time based or total size based
|
||||||
|
pChannel->setPurgeStrategy(new Poco::PurgeByCountStrategy(2));
|
||||||
|
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");
|
||||||
|
assertTrue(f0.exists());
|
||||||
|
File f1(name + ".1");
|
||||||
|
assertTrue(f1.exists());
|
||||||
|
File f2(name + ".2");
|
||||||
|
assertTrue(!f2.exists());
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
remove(name);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FileChannelTest::setUp()
|
void FileChannelTest::setUp()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -642,11 +812,14 @@ CppUnit::Test* FileChannelTest::suite()
|
|||||||
CppUnit_addLongTest(pSuite, FileChannelTest, testRotateAtTimeHourLocal);
|
CppUnit_addLongTest(pSuite, FileChannelTest, testRotateAtTimeHourLocal);
|
||||||
CppUnit_addLongTest(pSuite, FileChannelTest, testRotateAtTimeMinUTC);
|
CppUnit_addLongTest(pSuite, FileChannelTest, testRotateAtTimeMinUTC);
|
||||||
CppUnit_addLongTest(pSuite, FileChannelTest, testRotateAtTimeMinLocal);
|
CppUnit_addLongTest(pSuite, FileChannelTest, testRotateAtTimeMinLocal);
|
||||||
|
CppUnit_addTest(pSuite, FileChannelTest, testRotateByStrategy);
|
||||||
CppUnit_addTest(pSuite, FileChannelTest, testArchive);
|
CppUnit_addTest(pSuite, FileChannelTest, testArchive);
|
||||||
|
CppUnit_addTest(pSuite, FileChannelTest, testArchiveByStrategy);
|
||||||
CppUnit_addTest(pSuite, FileChannelTest, testCompress);
|
CppUnit_addTest(pSuite, FileChannelTest, testCompress);
|
||||||
CppUnit_addLongTest(pSuite, FileChannelTest, testPurgeAge);
|
CppUnit_addLongTest(pSuite, FileChannelTest, testPurgeAge);
|
||||||
CppUnit_addTest(pSuite, FileChannelTest, testPurgeCount);
|
CppUnit_addTest(pSuite, FileChannelTest, testPurgeCount);
|
||||||
CppUnit_addTest(pSuite, FileChannelTest, testWrongPurgeOption);
|
CppUnit_addTest(pSuite, FileChannelTest, testWrongPurgeOption);
|
||||||
|
CppUnit_addTest(pSuite, FileChannelTest, testPurgeByStrategy);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,11 +39,14 @@ public:
|
|||||||
void testRotateAtTimeHourLocal();
|
void testRotateAtTimeHourLocal();
|
||||||
void testRotateAtTimeMinUTC();
|
void testRotateAtTimeMinUTC();
|
||||||
void testRotateAtTimeMinLocal();
|
void testRotateAtTimeMinLocal();
|
||||||
|
void testRotateByStrategy();
|
||||||
void testArchive();
|
void testArchive();
|
||||||
|
void testArchiveByStrategy();
|
||||||
void testCompress();
|
void testCompress();
|
||||||
void testPurgeAge();
|
void testPurgeAge();
|
||||||
void testPurgeCount();
|
void testPurgeCount();
|
||||||
void testWrongPurgeOption();
|
void testWrongPurgeOption();
|
||||||
|
void testPurgeByStrategy();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
|||||||
Reference in New Issue
Block a user