4
// $Id: //poco/1.2/Foundation/src/FileChannel.cpp#2 $
10
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
13
// Permission is hereby granted, free of charge, to any person or organization
14
// obtaining a copy of the software and accompanying documentation covered by
15
// this license (the "Software") to use, reproduce, display, distribute,
16
// execute, and transmit the Software, and to prepare derivative works of the
17
// Software, and to permit third-parties to whom the Software is furnished to
18
// do so, all subject to the following:
20
// The copyright notices in the Software and this entire statement, including
21
// the above license grant, this restriction and the following disclaimer,
22
// must be included in all copies of the Software, in whole or in part, and
23
// all derivative works of the Software, unless such copies or derivative
24
// works are solely in the form of machine-executable object code generated by
25
// a source language processor.
27
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
30
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
31
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
32
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33
// DEALINGS IN THE SOFTWARE.
37
#include "Poco/FileChannel.h"
38
#include "Poco/ArchiveStrategy.h"
39
#include "Poco/RotateStrategy.h"
40
#include "Poco/PurgeStrategy.h"
41
#include "Poco/Message.h"
42
#include "Poco/NumberParser.h"
43
#include "Poco/DateTimeFormatter.h"
44
#include "Poco/DateTime.h"
45
#include "Poco/LocalDateTime.h"
46
#include "Poco/String.h"
47
#include "Poco/Timespan.h"
48
#include "Poco/Exception.h"
55
const std::string FileChannel::PROP_PATH = "path";
56
const std::string FileChannel::PROP_ROTATION = "rotation";
57
const std::string FileChannel::PROP_ARCHIVE = "archive";
58
const std::string FileChannel::PROP_TIMES = "times";
59
const std::string FileChannel::PROP_COMPRESS = "compress";
60
const std::string FileChannel::PROP_PURGEAGE = "purgeAge";
61
const std::string FileChannel::PROP_PURGECOUNT = "purgeCount";
64
FileChannel::FileChannel():
69
_pArchiveStrategy(new ArchiveByNumberStrategy),
75
FileChannel::FileChannel(const std::string& path):
81
_pArchiveStrategy(new ArchiveByNumberStrategy),
87
FileChannel::~FileChannel()
90
delete _pRotateStrategy;
91
delete _pArchiveStrategy;
92
delete _pPurgeStrategy;
96
void FileChannel::open()
98
FastMutex::ScopedLock lock(_mutex);
102
_pFile = new LogFile(_path);
107
void FileChannel::close()
109
FastMutex::ScopedLock lock(_mutex);
116
void FileChannel::log(const Message& msg)
120
FastMutex::ScopedLock lock(_mutex);
122
if (_pRotateStrategy && _pArchiveStrategy && _pRotateStrategy->mustRotate(_pFile))
126
_pFile = _pArchiveStrategy->archive(_pFile);
131
_pFile = new LogFile(_path);
134
_pFile->write(msg.getText());
138
void FileChannel::setProperty(const std::string& name, const std::string& value)
140
FastMutex::ScopedLock lock(_mutex);
142
if (name == PROP_TIMES)
146
if (!_rotation.empty())
147
setRotation(_rotation);
149
if (!_archive.empty())
150
setArchive(_archive);
152
else if (name == PROP_PATH)
154
else if (name == PROP_ROTATION)
156
else if (name == PROP_ARCHIVE)
158
else if (name == PROP_COMPRESS)
160
else if (name == PROP_PURGEAGE)
162
else if (name == PROP_PURGECOUNT)
163
setPurgeCount(value);
165
Channel::setProperty(name, value);
169
std::string FileChannel::getProperty(const std::string& name) const
171
if (name == PROP_TIMES)
173
else if (name == PROP_PATH)
175
else if (name == PROP_ROTATION)
177
else if (name == PROP_ARCHIVE)
179
else if (name == PROP_COMPRESS)
180
return std::string(_compress ? "true" : "false");
181
else if (name == PROP_PURGEAGE)
183
else if (name == PROP_PURGECOUNT)
186
return Channel::getProperty(name);
190
Timestamp FileChannel::creationDate() const
193
return _pFile->creationDate();
199
UInt64 FileChannel::size() const
202
return _pFile->size();
208
const std::string& FileChannel::path() const
214
void FileChannel::setRotation(const std::string& rotation)
216
std::string::const_iterator it = rotation.begin();
217
std::string::const_iterator end = rotation.end();
219
while (it != end && isspace(*it)) ++it;
220
while (it != end && isdigit(*it)) { n *= 10; n += *it++ - '0'; }
221
while (it != end && isspace(*it)) ++it;
223
while (it != end && isalpha(*it)) unit += *it++;
225
RotateStrategy* pStrategy = 0;
226
if ((rotation.find(',') != std::string::npos) || (rotation.find(':') != std::string::npos))
229
pStrategy = new RotateAtTimeStrategy<DateTime>(rotation);
230
else if (_times == "local")
231
pStrategy = new RotateAtTimeStrategy<LocalDateTime>(rotation);
233
throw PropertyNotSupportedException("times", _times);
235
else if (unit == "daily")
236
pStrategy = new RotateByIntervalStrategy(Timespan(1*Timespan::DAYS));
237
else if (unit == "weekly")
238
pStrategy = new RotateByIntervalStrategy(Timespan(7*Timespan::DAYS));
239
else if (unit == "monthly")
240
pStrategy = new RotateByIntervalStrategy(Timespan(30*Timespan::DAYS));
241
else if (unit == "seconds") // for testing only
242
pStrategy = new RotateByIntervalStrategy(Timespan(n*Timespan::SECONDS));
243
else if (unit == "hours")
244
pStrategy = new RotateByIntervalStrategy(Timespan(n*Timespan::HOURS));
245
else if (unit == "days")
246
pStrategy = new RotateByIntervalStrategy(Timespan(n*Timespan::DAYS));
247
else if (unit == "weeks")
248
pStrategy = new RotateByIntervalStrategy(Timespan(n*7*Timespan::DAYS));
249
else if (unit == "months")
250
pStrategy = new RotateByIntervalStrategy(Timespan(n*30*Timespan::DAYS));
251
else if (unit == "K")
252
pStrategy = new RotateBySizeStrategy(n*1024);
253
else if (unit == "M")
254
pStrategy = new RotateBySizeStrategy(n*1024*1024);
255
else if (unit.empty())
256
pStrategy = new RotateBySizeStrategy(n);
257
else if (unit != "never")
258
throw InvalidArgumentException("rotation", rotation);
259
delete _pRotateStrategy;
260
_pRotateStrategy = pStrategy;
261
_rotation = rotation;
265
void FileChannel::setArchive(const std::string& archive)
267
ArchiveStrategy* pStrategy = 0;
268
if (archive == "number")
270
pStrategy = new ArchiveByNumberStrategy;
272
else if (archive == "timestamp")
275
pStrategy = new ArchiveByTimestampStrategy<DateTime>;
276
else if (_times == "local")
277
pStrategy = new ArchiveByTimestampStrategy<LocalDateTime>;
279
throw PropertyNotSupportedException("times", _times);
281
else throw InvalidArgumentException("archive", archive);
282
delete _pArchiveStrategy;
283
pStrategy->compress(_compress);
284
_pArchiveStrategy = pStrategy;
289
void FileChannel::setCompress(const std::string& compress)
291
_compress = icompare(compress, "true") == 0;
292
if (_pArchiveStrategy)
293
_pArchiveStrategy->compress(_compress);
297
void FileChannel::setPurgeAge(const std::string& age)
299
std::string::const_iterator it = age.begin();
300
std::string::const_iterator end = age.end();
302
while (it != end && isspace(*it)) ++it;
303
while (it != end && isdigit(*it)) { n *= 10; n += *it++ - '0'; }
304
while (it != end && isspace(*it)) ++it;
306
while (it != end && isalpha(*it)) unit += *it++;
308
Timespan::TimeDiff factor = Timespan::SECONDS;
309
if (unit == "minutes")
310
factor = Timespan::MINUTES;
311
else if (unit == "hours")
312
factor = Timespan::HOURS;
313
else if (unit == "days")
314
factor = Timespan::DAYS;
315
else if (unit == "weeks")
316
factor = 7*Timespan::DAYS;
317
else if (unit == "months")
318
factor = 30*Timespan::DAYS;
319
else if (unit != "seconds")
320
throw InvalidArgumentException("purgeAge", age);
322
delete _pPurgeStrategy;
323
_pPurgeStrategy = new PurgeByAgeStrategy(Timespan(factor*n));
328
void FileChannel::setPurgeCount(const std::string& count)
330
std::string::const_iterator it = count.begin();
331
std::string::const_iterator end = count.end();
333
while (it != end && isspace(*it)) ++it;
334
while (it != end && isdigit(*it)) { n *= 10; n += *it++ - '0'; }
335
while (it != end && isspace(*it)) ++it;
337
delete _pPurgeStrategy;
338
_pPurgeStrategy = new PurgeByCountStrategy(n);
343
void FileChannel::purge()
349
_pPurgeStrategy->purge(_path);