mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-26 18:42:41 +01:00
- Poco::FileChannel now supports a new rotateOnOpen property (true/false) which can be used
to force rotation of the log file when it's opened.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// FileChannel.h
|
// FileChannel.h
|
||||||
//
|
//
|
||||||
// $Id: //poco/1.4/Foundation/include/Poco/FileChannel.h#2 $
|
// $Id: //poco/1.4/Foundation/include/Poco/FileChannel.h#5 $
|
||||||
//
|
//
|
||||||
// Library: Foundation
|
// Library: Foundation
|
||||||
// Package: Logging
|
// Package: Logging
|
||||||
@@ -140,7 +140,7 @@ class Foundation_API FileChannel: public Channel
|
|||||||
/// * local: Rotation strategy is based on local time.
|
/// * local: Rotation strategy is based on local time.
|
||||||
///
|
///
|
||||||
/// Archived log files can be compressed using the gzip compression
|
/// Archived log files can be compressed using the gzip compression
|
||||||
/// method. Compressing can be controlled with the "compression"
|
/// method. Compressing can be controlled with the "compress"
|
||||||
/// property. The following values for the "compress" property
|
/// property. The following values for the "compress" property
|
||||||
/// are supported:
|
/// are supported:
|
||||||
///
|
///
|
||||||
@@ -154,7 +154,6 @@ class Foundation_API FileChannel: public Channel
|
|||||||
///
|
///
|
||||||
/// The purgeAge property can have the following values:
|
/// The purgeAge property can have the following values:
|
||||||
///
|
///
|
||||||
/// * "none" or "" no purging
|
|
||||||
/// * <n> [seconds]: the maximum age is <n> seconds.
|
/// * <n> [seconds]: the maximum age is <n> seconds.
|
||||||
/// * <n> minutes: the maximum age is <n> minutes.
|
/// * <n> minutes: the maximum age is <n> minutes.
|
||||||
/// * <n> hours: the maximum age is <n> hours.
|
/// * <n> hours: the maximum age is <n> hours.
|
||||||
@@ -162,10 +161,10 @@ class Foundation_API FileChannel: public Channel
|
|||||||
/// * <n> weeks: the maximum age is <n> weeks.
|
/// * <n> weeks: the maximum age is <n> weeks.
|
||||||
/// * <n> months: the maximum age is <n> months, where a month has 30 days.
|
/// * <n> months: the maximum age is <n> months, where a month has 30 days.
|
||||||
///
|
///
|
||||||
/// The purgeCount property has an integer value that specifies the maximum number
|
/// The purgeCount property has an integer value that
|
||||||
/// of archived log files. If the number is exceeded, archived log files are
|
/// specifies the maximum number of archived log files.
|
||||||
/// deleted, starting with the oldest. When "none" or empty string are
|
/// If the number is exceeded, archived log files are
|
||||||
/// supplied, they reset purgeCount to none (no purging).
|
/// deleted, starting with the oldest.
|
||||||
///
|
///
|
||||||
/// The flush property specifies whether each log message is flushed
|
/// The flush property specifies whether each log message is flushed
|
||||||
/// immediately to the log file (which may hurt application performance,
|
/// immediately to the log file (which may hurt application performance,
|
||||||
@@ -176,6 +175,14 @@ class Foundation_API FileChannel: public Channel
|
|||||||
/// * true: Every essages is immediately flushed to the log file (default).
|
/// * true: Every essages is immediately flushed to the log file (default).
|
||||||
/// * false: Messages are not immediately flushed to the log file.
|
/// * false: Messages are not immediately flushed to the log file.
|
||||||
///
|
///
|
||||||
|
/// The rotateOnOpen property specifies whether an existing log file should be
|
||||||
|
/// rotated (and archived) when the channel is opened. Valid values are:
|
||||||
|
///
|
||||||
|
/// * true: The log file is rotated (and archived) when the channel is opened.
|
||||||
|
/// * false: Log messages will be appended to an existing log file,
|
||||||
|
/// if it exists (unless other conditions for a rotation are met).
|
||||||
|
/// This is the default.
|
||||||
|
///
|
||||||
/// For a more lightweight file channel class, see SimpleFileChannel.
|
/// For a more lightweight file channel class, see SimpleFileChannel.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -217,6 +224,8 @@ public:
|
|||||||
/// * flush: Specifies whether messages are immediately
|
/// * flush: Specifies whether messages are immediately
|
||||||
/// flushed to the log file. See the FileChannel class
|
/// flushed to the log file. See the FileChannel class
|
||||||
/// for details.
|
/// for details.
|
||||||
|
/// * rotateOnOpen: Specifies whether an existing log file should be
|
||||||
|
/// rotated and archived when the channel is opened.
|
||||||
|
|
||||||
std::string getProperty(const std::string& name) const;
|
std::string getProperty(const std::string& name) const;
|
||||||
/// Returns the value of the property with the given name.
|
/// Returns the value of the property with the given name.
|
||||||
@@ -240,6 +249,7 @@ public:
|
|||||||
static const std::string PROP_PURGEAGE;
|
static const std::string PROP_PURGEAGE;
|
||||||
static const std::string PROP_PURGECOUNT;
|
static const std::string PROP_PURGECOUNT;
|
||||||
static const std::string PROP_FLUSH;
|
static const std::string PROP_FLUSH;
|
||||||
|
static const std::string PROP_ROTATEONOPEN;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~FileChannel();
|
~FileChannel();
|
||||||
@@ -249,6 +259,7 @@ protected:
|
|||||||
void setPurgeAge(const std::string& age);
|
void setPurgeAge(const std::string& age);
|
||||||
void setPurgeCount(const std::string& count);
|
void setPurgeCount(const std::string& count);
|
||||||
void setFlush(const std::string& flush);
|
void setFlush(const std::string& flush);
|
||||||
|
void setRotateOnOpen(const std::string& rotateOnOpen);
|
||||||
void purge();
|
void purge();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -260,6 +271,7 @@ private:
|
|||||||
std::string _purgeAge;
|
std::string _purgeAge;
|
||||||
std::string _purgeCount;
|
std::string _purgeCount;
|
||||||
bool _flush;
|
bool _flush;
|
||||||
|
bool _rotateOnOpen;
|
||||||
LogFile* _pFile;
|
LogFile* _pFile;
|
||||||
RotateStrategy* _pRotateStrategy;
|
RotateStrategy* _pRotateStrategy;
|
||||||
ArchiveStrategy* _pArchiveStrategy;
|
ArchiveStrategy* _pArchiveStrategy;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// FileChannel.cpp
|
// FileChannel.cpp
|
||||||
//
|
//
|
||||||
// $Id: //poco/1.4/Foundation/src/FileChannel.cpp#1 $
|
// $Id: //poco/1.4/Foundation/src/FileChannel.cpp#3 $
|
||||||
//
|
//
|
||||||
// Library: Foundation
|
// Library: Foundation
|
||||||
// Package: Logging
|
// Package: Logging
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
#include "Poco/RotateStrategy.h"
|
#include "Poco/RotateStrategy.h"
|
||||||
#include "Poco/PurgeStrategy.h"
|
#include "Poco/PurgeStrategy.h"
|
||||||
#include "Poco/Message.h"
|
#include "Poco/Message.h"
|
||||||
|
#include "Poco/NumberParser.h"
|
||||||
#include "Poco/DateTimeFormatter.h"
|
#include "Poco/DateTimeFormatter.h"
|
||||||
#include "Poco/DateTime.h"
|
#include "Poco/DateTime.h"
|
||||||
#include "Poco/LocalDateTime.h"
|
#include "Poco/LocalDateTime.h"
|
||||||
@@ -47,6 +48,7 @@
|
|||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include "Poco/Ascii.h"
|
#include "Poco/Ascii.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
|
|
||||||
|
|
||||||
@@ -58,12 +60,13 @@ const std::string FileChannel::PROP_COMPRESS = "compress";
|
|||||||
const std::string FileChannel::PROP_PURGEAGE = "purgeAge";
|
const std::string FileChannel::PROP_PURGEAGE = "purgeAge";
|
||||||
const std::string FileChannel::PROP_PURGECOUNT = "purgeCount";
|
const std::string FileChannel::PROP_PURGECOUNT = "purgeCount";
|
||||||
const std::string FileChannel::PROP_FLUSH = "flush ";
|
const std::string FileChannel::PROP_FLUSH = "flush ";
|
||||||
|
const std::string FileChannel::PROP_ROTATEONOPEN = "rotateOnOpen";
|
||||||
|
|
||||||
FileChannel::FileChannel():
|
FileChannel::FileChannel():
|
||||||
_times("utc"),
|
_times("utc"),
|
||||||
_compress(false),
|
_compress(false),
|
||||||
_flush(true),
|
_flush(true),
|
||||||
|
_rotateOnOpen(false),
|
||||||
_pFile(0),
|
_pFile(0),
|
||||||
_pRotateStrategy(0),
|
_pRotateStrategy(0),
|
||||||
_pArchiveStrategy(new ArchiveByNumberStrategy),
|
_pArchiveStrategy(new ArchiveByNumberStrategy),
|
||||||
@@ -77,6 +80,7 @@ FileChannel::FileChannel(const std::string& path):
|
|||||||
_times("utc"),
|
_times("utc"),
|
||||||
_compress(false),
|
_compress(false),
|
||||||
_flush(true),
|
_flush(true),
|
||||||
|
_rotateOnOpen(false),
|
||||||
_pFile(0),
|
_pFile(0),
|
||||||
_pRotateStrategy(0),
|
_pRotateStrategy(0),
|
||||||
_pArchiveStrategy(new ArchiveByNumberStrategy),
|
_pArchiveStrategy(new ArchiveByNumberStrategy),
|
||||||
@@ -101,6 +105,18 @@ void FileChannel::open()
|
|||||||
if (!_pFile)
|
if (!_pFile)
|
||||||
{
|
{
|
||||||
_pFile = new LogFile(_path);
|
_pFile = new LogFile(_path);
|
||||||
|
if (_rotateOnOpen && _pFile->size() > 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_pFile = _pArchiveStrategy->archive(_pFile);
|
||||||
|
purge();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
_pFile = new LogFile(_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +184,8 @@ void FileChannel::setProperty(const std::string& name, const std::string& value)
|
|||||||
setPurgeCount(value);
|
setPurgeCount(value);
|
||||||
else if (name == PROP_FLUSH)
|
else if (name == PROP_FLUSH)
|
||||||
setFlush(value);
|
setFlush(value);
|
||||||
|
else if (name == PROP_ROTATEONOPEN)
|
||||||
|
setRotateOnOpen(value);
|
||||||
else
|
else
|
||||||
Channel::setProperty(name, value);
|
Channel::setProperty(name, value);
|
||||||
}
|
}
|
||||||
@@ -191,6 +209,8 @@ std::string FileChannel::getProperty(const std::string& name) const
|
|||||||
return _purgeCount;
|
return _purgeCount;
|
||||||
else if (name == PROP_FLUSH)
|
else if (name == PROP_FLUSH)
|
||||||
return std::string(_flush ? "true" : "false");
|
return std::string(_flush ? "true" : "false");
|
||||||
|
else if (name == PROP_ROTATEONOPEN)
|
||||||
|
return std::string(_rotateOnOpen ? "true" : "false");
|
||||||
else
|
else
|
||||||
return Channel::getProperty(name);
|
return Channel::getProperty(name);
|
||||||
}
|
}
|
||||||
@@ -230,6 +250,7 @@ void FileChannel::setRotation(const std::string& rotation)
|
|||||||
while (it != end && Ascii::isSpace(*it)) ++it;
|
while (it != end && Ascii::isSpace(*it)) ++it;
|
||||||
std::string unit;
|
std::string unit;
|
||||||
while (it != end && Ascii::isAlpha(*it)) unit += *it++;
|
while (it != end && Ascii::isAlpha(*it)) unit += *it++;
|
||||||
|
|
||||||
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))
|
||||||
{
|
{
|
||||||
@@ -306,28 +327,14 @@ void FileChannel::setCompress(const std::string& compress)
|
|||||||
|
|
||||||
void FileChannel::setPurgeAge(const std::string& age)
|
void FileChannel::setPurgeAge(const std::string& age)
|
||||||
{
|
{
|
||||||
delete _pPurgeStrategy;
|
|
||||||
_pPurgeStrategy = 0;
|
|
||||||
_purgeAge = "none";
|
|
||||||
if (age.empty() || 0 == icompare(age, "none"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string::const_iterator it = age.begin();
|
std::string::const_iterator it = age.begin();
|
||||||
std::string::const_iterator end = age.end();
|
std::string::const_iterator end = age.end();
|
||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
while (it != end && Ascii::isSpace(*it))
|
while (it != end && Ascii::isSpace(*it)) ++it;
|
||||||
++it;
|
while (it != end && Ascii::isDigit(*it)) { n *= 10; n += *it++ - '0'; }
|
||||||
while (it != end && Ascii::isDigit(*it))
|
while (it != end && Ascii::isSpace(*it)) ++it;
|
||||||
{
|
|
||||||
n *= 10;
|
|
||||||
n += *it++ - '0';
|
|
||||||
}
|
|
||||||
while (it != end && Ascii::isSpace(*it))
|
|
||||||
++it;
|
|
||||||
std::string unit;
|
std::string unit;
|
||||||
while (it != end && Ascii::isAlpha(*it))
|
while (it != end && Ascii::isAlpha(*it)) unit += *it++;
|
||||||
unit += *it++;
|
|
||||||
|
|
||||||
Timespan::TimeDiff factor = Timespan::SECONDS;
|
Timespan::TimeDiff factor = Timespan::SECONDS;
|
||||||
if (unit == "minutes")
|
if (unit == "minutes")
|
||||||
@@ -343,47 +350,36 @@ void FileChannel::setPurgeAge(const std::string& age)
|
|||||||
else if (unit != "seconds")
|
else if (unit != "seconds")
|
||||||
throw InvalidArgumentException("purgeAge", age);
|
throw InvalidArgumentException("purgeAge", age);
|
||||||
|
|
||||||
if (0 == n)
|
delete _pPurgeStrategy;
|
||||||
throw InvalidArgumentException("Zero is not valid purge age.");
|
|
||||||
|
|
||||||
_pPurgeStrategy = new PurgeByAgeStrategy(Timespan(factor*n));
|
_pPurgeStrategy = new PurgeByAgeStrategy(Timespan(factor*n));
|
||||||
_purgeAge = age;
|
_purgeAge = age;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileChannel::setPurgeCount(const std::string& count)
|
||||||
|
{
|
||||||
|
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'; }
|
||||||
|
while (it != end && Ascii::isSpace(*it)) ++it;
|
||||||
|
|
||||||
|
delete _pPurgeStrategy;
|
||||||
|
_pPurgeStrategy = new PurgeByCountStrategy(n);
|
||||||
|
_purgeCount = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FileChannel::setFlush(const std::string& flush)
|
void FileChannel::setFlush(const std::string& flush)
|
||||||
{
|
{
|
||||||
_flush = icompare(flush, "true") == 0;
|
_flush = icompare(flush, "true") == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FileChannel::setPurgeCount(const std::string& count)
|
void FileChannel::setRotateOnOpen(const std::string& rotateOnOpen)
|
||||||
{
|
{
|
||||||
delete _pPurgeStrategy;
|
_rotateOnOpen = icompare(rotateOnOpen, "true") == 0;
|
||||||
_pPurgeStrategy = 0;
|
|
||||||
_purgeAge = "none";
|
|
||||||
if (count.empty() || 0 == icompare(count, "none"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
int n = 0;
|
|
||||||
std::string::const_iterator it = count.begin();
|
|
||||||
std::string::const_iterator end = count.end();
|
|
||||||
|
|
||||||
while (it != end && Ascii::isSpace(*it))
|
|
||||||
++it;
|
|
||||||
while (it != end && Ascii::isDigit(*it))
|
|
||||||
{
|
|
||||||
n *= 10;
|
|
||||||
n += *it++ - '0';
|
|
||||||
}
|
|
||||||
while (it != end && Ascii::isSpace(*it))
|
|
||||||
++it;
|
|
||||||
|
|
||||||
if (0 == n)
|
|
||||||
throw InvalidArgumentException("Zero is not valid purge count.");
|
|
||||||
|
|
||||||
_pPurgeStrategy = new PurgeByCountStrategy(n);
|
|
||||||
_purgeCount = count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user