| 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 | /// following 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 message 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 | void unsafeOpen(); |
| 244 | |
| 245 | private: |
| 246 | bool setNoPurge(const std::string& value); |
| 247 | int (const std::string& value, std::string::const_iterator* nextToDigit = NULL) const; |
| 248 | void setPurgeStrategy(PurgeStrategy* strategy); |
| 249 | Timespan::TimeDiff (const std::string& value, std::string::const_iterator start) const; |
| 250 | |
| 251 | std::string _path; |
| 252 | std::string _times; |
| 253 | std::string _rotation; |
| 254 | std::string _archive; |
| 255 | bool _compress; |
| 256 | std::string _purgeAge; |
| 257 | std::string _purgeCount; |
| 258 | bool _flush; |
| 259 | bool _rotateOnOpen; |
| 260 | LogFile* _pFile; |
| 261 | RotateStrategy* _pRotateStrategy; |
| 262 | ArchiveStrategy* _pArchiveStrategy; |
| 263 | PurgeStrategy* _pPurgeStrategy; |
| 264 | FastMutex _mutex; |
| 265 | }; |
| 266 | |
| 267 | |
| 268 | } // namespace Poco |
| 269 | |
| 270 | |
| 271 | #endif // Foundation_FileChannel_INCLUDED |
| 272 | |