Skip to content

Commit

Permalink
Custom rotate, archive and purge strategies for FileChannel (#3810)
Browse files Browse the repository at this point in the history
* Adding the ability to set custom rotate, archive and purge strategies.

* Force CI
  • Loading branch information
andrewauclair authored Mar 18, 2023
1 parent e0e628a commit 66e93f9
Show file tree
Hide file tree
Showing 10 changed files with 322 additions and 22 deletions.
10 changes: 10 additions & 0 deletions Foundation/include/Poco/ArchiveStrategy.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class Foundation_API ArchiveStrategy
ArchiveStrategy();
virtual ~ArchiveStrategy();

virtual LogFile* open(LogFile* pFile) = 0;
/// Open a new log file and return it.

virtual LogFile* archive(LogFile* pFile) = 0;
/// Renames the given log file for archiving
/// and creates and returns a new log file.
Expand Down Expand Up @@ -71,6 +74,8 @@ class Foundation_API ArchiveByNumberStrategy: public ArchiveStrategy
public:
ArchiveByNumberStrategy();
~ArchiveByNumberStrategy();

LogFile* open(LogFile* pFile);
LogFile* archive(LogFile* pFile);
};

Expand All @@ -89,6 +94,11 @@ class ArchiveByTimestampStrategy: public ArchiveStrategy
{
}

LogFile* open(LogFile* pFile)
{
return pFile;
}

LogFile* archive(LogFile* pFile)
/// Archives the file by appending the current timestamp to the
/// file name. If the new file name exists, additionally a monotonic
Expand Down
17 changes: 16 additions & 1 deletion Foundation/include/Poco/FileChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,18 @@ class Foundation_API FileChannel: public Channel
/// See setProperty() for a description of the supported
/// 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;
/// Returns the log file's creation date.

Expand All @@ -232,6 +244,7 @@ class Foundation_API FileChannel: public Channel

protected:
~FileChannel();

void setRotation(const std::string& rotation);
void setArchive(const std::string& archive);
void setCompress(const std::string& compress);
Expand All @@ -244,9 +257,11 @@ class Foundation_API FileChannel: public Channel
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;

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 _times;
std::string _rotation;
Expand Down
10 changes: 10 additions & 0 deletions Foundation/include/Poco/PurgeStrategy.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ class Foundation_API PurgeStrategy
};


class Foundation_API NullPurgeStrategy : public PurgeStrategy
{
public:
NullPurgeStrategy();
~NullPurgeStrategy();

void purge(const std::string& path);
};


class Foundation_API PurgeByAgeStrategy: public PurgeStrategy
/// This purge strategy purges all files that have
/// exceeded a given age (given in seconds).
Expand Down
7 changes: 7 additions & 0 deletions Foundation/include/Poco/RotateStrategy.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ class Foundation_API RotateStrategy
};


class Foundation_API NullRotateStrategy : public RotateStrategy
{
public:
bool mustRotate(LogFile* pFile);
};


template <class DT>
class RotateAtTimeStrategy: public RotateStrategy
/// The file is rotated at specified [day,][hour]:minute
Expand Down
6 changes: 6 additions & 0 deletions Foundation/src/ArchiveStrategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,12 @@ ArchiveByNumberStrategy::~ArchiveByNumberStrategy()
}


LogFile* ArchiveByNumberStrategy::open(LogFile* pFile)
{
return pFile;
}


LogFile* ArchiveByNumberStrategy::archive(LogFile* pFile)
{
std::string basePath = pFile->path();
Expand Down
87 changes: 66 additions & 21 deletions Foundation/src/FileChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ FileChannel::FileChannel():
_flush(true),
_rotateOnOpen(false),
_pFile(0),
_pRotateStrategy(0),
_pRotateStrategy(new NullRotateStrategy()),
_pArchiveStrategy(new ArchiveByNumberStrategy),
_pPurgeStrategy(0)
_pPurgeStrategy(new NullPurgeStrategy())
{
}

Expand All @@ -59,9 +59,9 @@ FileChannel::FileChannel(const std::string& path):
_flush(true),
_rotateOnOpen(false),
_pFile(0),
_pRotateStrategy(0),
_pRotateStrategy(new NullRotateStrategy()),
_pArchiveStrategy(new ArchiveByNumberStrategy),
_pPurgeStrategy(0)
_pPurgeStrategy(new NullPurgeStrategy())
{
}

Expand Down Expand Up @@ -101,6 +101,8 @@ void FileChannel::open()
_pFile = new LogFile(_path);
}
}

_pFile = _pArchiveStrategy->open(_pFile);
}
}

Expand All @@ -120,7 +122,7 @@ void FileChannel::log(const Message& msg)

FastMutex::ScopedLock lock(_mutex);

if (_pRotateStrategy && _pArchiveStrategy && _pRotateStrategy->mustRotate(_pFile))
if (_pRotateStrategy->mustRotate(_pFile))
{
try
{
Expand Down Expand Up @@ -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 end = rotation.end();
Expand All @@ -238,12 +240,12 @@ void FileChannel::setRotation(const std::string& rotation)
RotateStrategy* pStrategy = 0;
if ((rotation.find(',') != std::string::npos) || (rotation.find(':') != std::string::npos))
{
if (_times == "utc")
if (times == "utc")
pStrategy = new RotateAtTimeStrategy<DateTime>(rotation);
else if (_times == "local")
else if (times == "local")
pStrategy = new RotateAtTimeStrategy<LocalDateTime>(rotation);
else
throw PropertyNotSupportedException("times", _times);
throw PropertyNotSupportedException("times", times);
}
else if (unit == "daily")
pStrategy = new RotateByIntervalStrategy(Timespan(1*Timespan::DAYS));
Expand Down Expand Up @@ -271,12 +273,57 @@ void FileChannel::setRotation(const std::string& rotation)
pStrategy = new RotateBySizeStrategy(n);
else if (unit != "never")
throw InvalidArgumentException("rotation", rotation);

return pStrategy;
}


void FileChannel::setRotationStrategy(RotateStrategy* strategy)
{
poco_check_ptr(strategy);

delete _pRotateStrategy;
_pRotateStrategy = pStrategy;
_pRotateStrategy = strategy;
}


void FileChannel::setRotation(const std::string& rotation)
{
setRotationStrategy(createRotationStrategy(rotation, _times));
_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)
{
ArchiveStrategy* pStrategy = 0;
Expand Down Expand Up @@ -304,8 +351,7 @@ void FileChannel::setArchive(const std::string& archive)
void FileChannel::setCompress(const std::string& compress)
{
_compress = icompare(compress, "true") == 0;
if (_pArchiveStrategy)
_pArchiveStrategy->compress(_compress);
_pArchiveStrategy->compress(_compress);
}


Expand Down Expand Up @@ -345,15 +391,12 @@ void FileChannel::setRotateOnOpen(const std::string& rotateOnOpen)

void FileChannel::purge()
{
if (_pPurgeStrategy)
try
{
_pPurgeStrategy->purge(_path);
}
catch (...)
{
try
{
_pPurgeStrategy->purge(_path);
}
catch (...)
{
}
}
}

Expand All @@ -363,7 +406,7 @@ bool FileChannel::setNoPurge(const std::string& value)
if (value.empty() || 0 == icompare(value, "none"))
{
delete _pPurgeStrategy;
_pPurgeStrategy = 0;
_pPurgeStrategy = new NullPurgeStrategy();
_purgeAge = "none";
return true;
}
Expand Down Expand Up @@ -394,6 +437,8 @@ int FileChannel::extractDigit(const std::string& value, std::string::const_itera

void FileChannel::setPurgeStrategy(PurgeStrategy* strategy)
{
poco_check_ptr(strategy);

delete _pPurgeStrategy;
_pPurgeStrategy = strategy;
}
Expand Down
20 changes: 20 additions & 0 deletions Foundation/src/PurgeStrategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
//
Expand Down
11 changes: 11 additions & 0 deletions Foundation/src/RotateStrategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ RotateStrategy::~RotateStrategy()
}


//
// NullRotateStrategy
//


bool NullRotateStrategy::mustRotate(LogFile* pFile)
{
return false;
}


//
// RotateByIntervalStrategy
//
Expand Down
Loading

0 comments on commit 66e93f9

Please sign in to comment.