1 //
2 // FileChannel.h
3 //
4 // Library: Foundation
5 // Package: Logging
6 // Module:  FileChannel
7 //
8 // Definition of the FileChannel class.
9 //
10 // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11 // and Contributors.
12 //
13 // SPDX-License-Identifier:	BSL-1.0
14 //
15 
16 
17 #ifndef Foundation_FileChannel_INCLUDED
18 #define Foundation_FileChannel_INCLUDED
19 
20 
21 #include "Poco/Foundation.h"
22 #include "Poco/Channel.h"
23 #include "Poco/Timestamp.h"
24 #include "Poco/Timespan.h"
25 #include "Poco/Mutex.h"
26 
27 
28 namespace Poco {
29 
30 
31 class LogFile;
32 class RotateStrategy;
33 class ArchiveStrategy;
34 class PurgeStrategy;
35 
36 
37 class Foundation_API FileChannel: public Channel
38 	/// A Channel that writes to a file. This class supports
39 	/// flexible log file rotation and archiving, as well
40 	/// as automatic purging of archived log files.
41 	///
42 	/// Only the message's text is written, followed
43 	/// by a newline.
44 	///
45 	/// Chain this channel to a FormattingChannel with an
46 	/// appropriate Formatter to control what is in the text.
47 	///
48 	/// The FileChannel support log file rotation based
49 	/// on log file size or time intervals.
50 	/// Archived log files can be compressed in gzip format.
51 	/// Older archived files can be automatically deleted
52 	/// (purged).
53 	///
54 	/// The rotation strategy can be specified with the
55 	/// "rotation" property, which can take one of the
56 	/// follwing values:
57 	///
58 	///   * never:         no log rotation
59 	///   * [day,][hh]:mm: the file is rotated on specified day/time
60 	///                    day - day is specified as long or short day name (Monday|Mon, Tuesday|Tue, ... );
61 	///                          day can be omitted, in which case log is rotated every day
62 	///                    hh  - valid hour range is 00-23;
63 	///                          hour can be omitted, in which case log is rotated every hour
64 	///                    mm  - valid minute range is 00-59;
65 	///                          minute must be specified
66 	///   * daily:         the file is rotated daily
67 	///   * weekly:        the file is rotated every seven days
68 	///   * monthly:       the file is rotated every 30 days
69 	///   * <n> minutes:   the file is rotated every <n> minutes,
70 	///                    where <n> is an integer greater than zero.
71 	///   * <n> hours:     the file is rotated every <n> hours, where
72 	///                    <n> is an integer greater than zero.
73 	///   * <n> days:      the file is rotated every <n> days, where
74 	///                    <n> is an integer greater than zero.
75 	///   * <n> weeks:     the file is rotated every <n> weeks, where
76 	///                    <n> is an integer greater than zero.
77 	///   * <n> months:    the file is rotated every <n> months, where
78 	///                    <n> is an integer greater than zero and
79 	///                    a month has 30 days.
80 	///   * <n>:           the file is rotated when its size exceeds
81 	///                    <n> bytes.
82 	///   * <n> K:         the file is rotated when its size exceeds
83 	///                    <n> Kilobytes.
84 	///   * <n> M:         the file is rotated when its size exceeds
85 	///                    <n> Megabytes.
86 	///
87 	/// NOTE: For periodic log file rotation (daily, weekly, monthly, etc.),
88 	/// the date and time of log file creation or last rotation is
89 	/// written into the first line of the log file. This is because
90 	/// there is no reliable way to find out the real creation date of
91 	/// a file on many platforms (e.g., most Unix platforms do not
92 	/// provide the creation date, and Windows has its own issues
93 	/// with its "File System Tunneling Capabilities").
94 	///
95 	/// Using the "archive" property it is possible to specify
96 	/// how archived log files are named. The following values
97 	/// for the "archive" property are supported:
98 	///
99 	///   * number:     A number, starting with 0, is appended to
100 	///                 the name of archived log files. The newest
101 	///                 archived log file always has the number 0.
102 	///                 For example, if the log file is named
103 	///                 "access.log", and it fulfils the criteria
104 	///                 for rotation, the file is renamed to
105 	///                 "access.log.0". If a file named "access.log.0"
106 	///                 already exists, it is renamed to "access.log.1",
107 	///                 and so on.
108 	///   * timestamp:  A timestamp is appended to the log file name.
109 	///                 For example, if the log file is named
110 	///                 "access.log", and it fulfils the criteria
111 	///                 for rotation, the file is renamed to
112 	///                 "access.log.20050802110300".
113 	///
114 	/// Using the "times" property it is possible to specify
115 	/// time mode for the day/time based rotation. The following values
116 	/// for the "times" property are supported:
117 	///
118 	///   * utc:        Rotation strategy is based on UTC time (default).
119 	///   * local:      Rotation strategy is based on local time.
120 	///
121 	/// Archived log files can be compressed using the gzip compression
122 	/// method. Compressing can be controlled with the "compress"
123 	/// property. The following values for the "compress" property
124 	/// are supported:
125 	///
126 	///   * true:       Compress archived log files.
127 	///   * false:      Do not compress archived log files.
128 	///
129 	/// Archived log files can be automatically purged, either if
130 	/// they reach a certain age, or if the number of archived
131 	/// log files reaches a given maximum number. This is
132 	/// controlled by the purgeAge and purgeCount properties.
133 	///
134 	/// The purgeAge property can have the following values:
135 	///
136 	///   * <n> [seconds]: the maximum age is <n> seconds.
137 	///   * <n> minutes:   the maximum age is <n> minutes.
138 	///   * <n> hours:     the maximum age is <n> hours.
139 	///   * <n> days:      the maximum age is <n> days.
140 	///   * <n> weeks:     the maximum age is <n> weeks.
141 	///   * <n> months:    the maximum age is <n> months, where a month has 30 days.
142 	///
143 	/// The purgeCount property has an integer value that specifies the maximum number
144 	/// of archived log files. If the number is exceeded, archived log files are
145 	/// deleted, starting with the oldest. When "none" or empty string are
146 	/// supplied, they reset purgeCount to none (no purging).
147 	///
148 	/// The flush property specifies whether each log message is flushed
149 	/// immediately to the log file (which may hurt application performance,
150 	/// but ensures that everything is in the log in case of a system crash),
151 	//  or whether it's allowed to stay in the system's file buffer for some time.
152 	/// Valid values are:
153 	///
154 	///   * true:  Every essages is immediately flushed to the log file (default).
155 	///   * false: Messages are not immediately flushed to the log file.
156 	///
157 	/// The rotateOnOpen property specifies whether an existing log file should be
158 	/// rotated (and archived) when the channel is opened. Valid values are:
159 	///
160 	///   * true:  The log file is rotated (and archived) when the channel is opened.
161 	///   * false: Log messages will be appended to an existing log file,
162 	///            if it exists (unless other conditions for a rotation are met).
163 	///            This is the default.
164 	///
165 	/// For a more lightweight file channel class, see SimpleFileChannel.
166 {
167 public:
168 	FileChannel();
169 		/// Creates the FileChannel.
170 
171 	FileChannel(const std::string& path);
172 		/// Creates the FileChannel for a file with the given path.
173 
174 	void open();
175 		/// Opens the FileChannel and creates the log file if necessary.
176 
177 	void close();
178 		/// Closes the FileChannel.
179 
180 	void log(const Message& msg);
181 		/// Logs the given message to the file.
182 
183 	void setProperty(const std::string& name, const std::string& value);
184 		/// Sets the property with the given name.
185 		///
186 		/// The following properties are supported:
187 		///   * path:         The log file's path.
188 		///   * rotation:     The log file's rotation mode. See the
189 		///                   FileChannel class for details.
190 		///   * archive:      The log file's archive mode. See the
191 		///                   FileChannel class for details.
192 		///   * times:        The log file's time mode. See the
193 		///                   FileChannel class for details.
194 		///   * compress:     Enable or disable compression of
195 		///                   archived files. See the FileChannel class
196 		///                   for details.
197 		///   * purgeAge:     Maximum age of an archived log file before
198 		///                   it is purged. See the FileChannel class for
199 		///                   details.
200 		///   * purgeCount:   Maximum number of archived log files before
201 		///                   files are purged. See the FileChannel class
202 		///                   for details.
203 		///   * flush:        Specifies whether messages are immediately
204 		///                   flushed to the log file. See the FileChannel class
205 		///                   for details.
206 		///   * rotateOnOpen: Specifies whether an existing log file should be
207 		///                   rotated and archived when the channel is opened.
208 
209 	std::string getProperty(const std::string& name) const;
210 		/// Returns the value of the property with the given name.
211 		/// See setProperty() for a description of the supported
212 		/// properties.
213 
214 	Timestamp creationDate() const;
215 		/// Returns the log file's creation date.
216 
217 	UInt64 size() const;
218 		/// Returns the log file's current size in bytes.
219 
220 	const std::string& path() const;
221 		/// Returns the log file's path.
222 
223 	static const std::string PROP_PATH;
224 	static const std::string PROP_ROTATION;
225 	static const std::string PROP_ARCHIVE;
226 	static const std::string PROP_TIMES;
227 	static const std::string PROP_COMPRESS;
228 	static const std::string PROP_PURGEAGE;
229 	static const std::string PROP_PURGECOUNT;
230 	static const std::string PROP_FLUSH;
231 	static const std::string PROP_ROTATEONOPEN;
232 
233 protected:
234 	~FileChannel();
235 	void setRotation(const std::string& rotation);
236 	void setArchive(const std::string& archive);
237 	void setCompress(const std::string& compress);
238 	void setPurgeAge(const std::string& age);
239 	void setPurgeCount(const std::string& count);
240 	void setFlush(const std::string& flush);
241 	void setRotateOnOpen(const std::string& rotateOnOpen);
242 	void purge();
243 
244 private:
245 	bool setNoPurge(const std::string& value);
246 	int extractDigit(const std::string& value, std::string::const_iterator* nextToDigit = NULL) const;
247 	void setPurgeStrategy(PurgeStrategy* strategy);
248 	Timespan::TimeDiff extractFactor(const std::string& value, std::string::const_iterator start) const;
249 
250 	std::string      _path;
251 	std::string      _times;
252 	std::string      _rotation;
253 	std::string      _archive;
254 	bool             _compress;
255 	std::string      _purgeAge;
256 	std::string      _purgeCount;
257 	bool             _flush;
258 	bool             _rotateOnOpen;
259 	LogFile*         _pFile;
260 	RotateStrategy*  _pRotateStrategy;
261 	ArchiveStrategy* _pArchiveStrategy;
262 	PurgeStrategy*   _pPurgeStrategy;
263 	FastMutex        _mutex;
264 };
265 
266 
267 } // namespace Poco
268 
269 
270 #endif // Foundation_FileChannel_INCLUDED
271