1//
2// ArchiveStrategy.h
3//
4// Library: Foundation
5// Package: Logging
6// Module: FileChannel
7//
8// Definition of the ArchiveStrategy class and subclasses.
9//
10// Copyright (c) 2004-2008, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Foundation_ArchiveStrategy_INCLUDED
18#define Foundation_ArchiveStrategy_INCLUDED
19
20
21#include "Poco/Foundation.h"
22#include "Poco/LogFile.h"
23#include "Poco/File.h"
24#include "Poco/DateTimeFormatter.h"
25#include "Poco/NumberFormatter.h"
26
27
28namespace Poco {
29
30
31class ArchiveCompressor;
32
33
34class Foundation_API ArchiveStrategy
35 /// The ArchiveStrategy is used by FileChannel
36 /// to rename a rotated log file for archiving.
37 ///
38 /// Archived files can be automatically compressed,
39 /// using the gzip file format.
40{
41public:
42 ArchiveStrategy();
43 virtual ~ArchiveStrategy();
44
45 virtual LogFile* archive(LogFile* pFile) = 0;
46 /// Renames the given log file for archiving
47 /// and creates and returns a new log file.
48 /// The given LogFile object is deleted.
49
50 void compress(bool flag = true);
51 /// Enables or disables compression of archived files.
52
53protected:
54 void moveFile(const std::string& oldName, const std::string& newName);
55 bool exists(const std::string& name);
56
57private:
58 ArchiveStrategy(const ArchiveStrategy&);
59 ArchiveStrategy& operator = (const ArchiveStrategy&);
60
61 bool _compress;
62 ArchiveCompressor* _pCompressor;
63};
64
65
66class Foundation_API ArchiveByNumberStrategy: public ArchiveStrategy
67 /// A monotonic increasing number is appended to the
68 /// log file name. The most recent archived file
69 /// always has the number zero.
70{
71public:
72 ArchiveByNumberStrategy();
73 ~ArchiveByNumberStrategy();
74 LogFile* archive(LogFile* pFile);
75};
76
77
78template <class DT>
79class ArchiveByTimestampStrategy: public ArchiveStrategy
80 /// A timestamp (YYYYMMDDhhmmssiii) is appended to archived
81 /// log files.
82{
83public:
84 ArchiveByTimestampStrategy()
85 {
86 }
87
88 ~ArchiveByTimestampStrategy()
89 {
90 }
91
92 LogFile* archive(LogFile* pFile)
93 /// Archives the file by appending the current timestamp to the
94 /// file name. If the new file name exists, additionally a monotonic
95 /// increasing number is appended to the log file name.
96 {
97 std::string path = pFile->path();
98 delete pFile;
99 std::string archPath = path;
100 archPath.append(".");
101 DateTimeFormatter::append(archPath, DT().timestamp(), "%Y%m%d%H%M%S%i");
102
103 if (exists(archPath)) archiveByNumber(archPath);
104 else moveFile(path, archPath);
105
106 return new LogFile(path);
107 }
108
109private:
110 void archiveByNumber(const std::string& basePath)
111 /// A monotonic increasing number is appended to the
112 /// log file name. The most recent archived file
113 /// always has the number zero.
114 {
115 int n = -1;
116 std::string path;
117 do
118 {
119 path = basePath;
120 path.append(".");
121 NumberFormatter::append(path, ++n);
122 }
123 while (exists(path));
124
125 while (n >= 0)
126 {
127 std::string oldPath = basePath;
128 if (n > 0)
129 {
130 oldPath.append(".");
131 NumberFormatter::append(oldPath, n - 1);
132 }
133 std::string newPath = basePath;
134 newPath.append(".");
135 NumberFormatter::append(newPath, n);
136 moveFile(oldPath, newPath);
137 --n;
138 }
139 }
140};
141
142
143} // namespace Poco
144
145
146#endif // Foundation_ArchiveStrategy_INCLUDED
147