fileappender.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. // -*- C++ -*-
  2. // Module: Log4CPLUS
  3. // File: fileappender.h
  4. // Created: 6/2001
  5. // Author: Tad E. Smith
  6. //
  7. //
  8. // Copyright 2001-2017 Tad E. Smith
  9. //
  10. // Licensed under the Apache License, Version 2.0 (the "License");
  11. // you may not use this file except in compliance with the License.
  12. // You may obtain a copy of the License at
  13. //
  14. // http://www.apache.org/licenses/LICENSE-2.0
  15. //
  16. // Unless required by applicable law or agreed to in writing, software
  17. // distributed under the License is distributed on an "AS IS" BASIS,
  18. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. // See the License for the specific language governing permissions and
  20. // limitations under the License.
  21. /** @file */
  22. #ifndef LOG4CPLUS_FILE_APPENDER_HEADER_
  23. #define LOG4CPLUS_FILE_APPENDER_HEADER_
  24. #include <log4cplus/config.hxx>
  25. #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
  26. #pragma once
  27. #endif
  28. #include <log4cplus/appender.h>
  29. #include <log4cplus/fstreams.h>
  30. #include <log4cplus/helpers/timehelper.h>
  31. #include <log4cplus/helpers/lockfile.h>
  32. #include <fstream>
  33. #include <locale>
  34. #include <memory>
  35. namespace log4cplus
  36. {
  37. /**
  38. * Base class for Appenders writing log events to a file.
  39. * It is constructed with uninitialized file object, so all
  40. * classes derived from FileAppenderBase _must_ call init() method.
  41. *
  42. * <h3>Properties</h3>
  43. * <dl>
  44. * <dt><tt>File</tt></dt>
  45. * <dd>This property specifies output file name.</dd>
  46. *
  47. * <dt><tt>ImmediateFlush</tt></dt>
  48. * <dd>When it is set true, output stream will be flushed after
  49. * each appended event.</dd>
  50. *
  51. * <dt><tt>Append</tt></dt>
  52. * <dd>When it is set true, output file will be appended to
  53. * instead of being truncated at opening.</dd>
  54. *
  55. * <dt><tt>ReopenDelay</tt></dt>
  56. * <dd>This property sets a delay after which the appender will try
  57. * to reopen log file again, after last logging failure.
  58. * </dd>
  59. *
  60. * <dt><tt>BufferSize</tt></dt>
  61. * <dd>Non-zero value of this property sets up buffering of output
  62. * stream using a buffer of given size.
  63. * </dd>
  64. *
  65. * <dt><tt>UseLockFile</tt></dt>
  66. * <dd>Set this property to <tt>true</tt> if you want your output
  67. * to go into a log file shared by multiple processes. When this
  68. * property is set to true then log4cplus uses OS specific
  69. * facilities (e.g., <code>lockf()</code>) to provide
  70. * inter-process file locking.
  71. * \sa Appender
  72. * </dd>
  73. *
  74. * <dt><tt>LockFile</tt></dt>
  75. * <dd>This property specifies lock file, file used for
  76. * inter-process synchronization of log file access. When this
  77. * property is not specified, the value is derived from
  78. * <tt>File</tt> property by addition of ".lock" suffix. The
  79. * property is only used when <tt>UseLockFile</tt> is set to true.
  80. * \sa Appender
  81. * </dd>
  82. *
  83. * <dt><tt>Locale</tt></dt>
  84. * <dd>This property specifies a locale name that will be imbued
  85. * into output stream. Locale can be specified either by system
  86. * specific locale name, e.g., <tt>en_US.UTF-8</tt>, or by one of
  87. * four recognized keywords: <tt>GLOBAL</tt>, <tt>DEFAULT</tt>
  88. * (which is an alias for <tt>GLOBAL</tt>), <tt>USER</tt> and
  89. * <tt>CLASSIC</tt>. When specified locale is not available,
  90. * <tt>GLOBAL</tt> is used instead. It is possible to register
  91. * additional locale keywords by registering an instance of
  92. * <code>spi::LocaleFactory</code> in
  93. * <code>spi::LocaleFactoryRegistry</code>.
  94. * \sa spi::getLocaleFactoryRegistry()
  95. * </dd>
  96. *
  97. * <dt><tt>CreateDirs</tt></dt>
  98. * <dd>Set this property to <tt>true</tt> if you want to create
  99. * missing directories in path leading to log file and lock file.
  100. * </dd>
  101. *
  102. * <dt><tt>TextMode</tt></dt>
  103. * <dd>Set this property to <tt>Binary</tt> if the underlying stream should
  104. * not translate EOLs to OS specific character sequence. The default value
  105. * is <tt>Text</tt> and the underlying stream will be opened in text
  106. * mode.</dd>
  107. * </dl>
  108. */
  109. class LOG4CPLUS_EXPORT FileAppenderBase : public Appender {
  110. public:
  111. // Methods
  112. virtual void close();
  113. //! Redefine default locale for output stream. It may be a good idea to
  114. //! provide UTF-8 locale in case UNICODE macro is defined.
  115. virtual std::locale imbue(std::locale const& loc);
  116. //! \returns Locale imbued in fstream.
  117. virtual std::locale getloc () const;
  118. protected:
  119. // Ctors
  120. FileAppenderBase(const log4cplus::tstring& filename,
  121. std::ios_base::openmode mode = std::ios_base::trunc,
  122. bool immediateFlush = true,
  123. bool createDirs = false);
  124. FileAppenderBase(const log4cplus::helpers::Properties& properties,
  125. std::ios_base::openmode mode = std::ios_base::trunc);
  126. void init();
  127. virtual void append(const spi::InternalLoggingEvent& event);
  128. virtual void open(std::ios_base::openmode mode);
  129. bool reopen();
  130. // Data
  131. /**
  132. * Immediate flush means that the underlying writer or output stream
  133. * will be flushed at the end of each append operation. Immediate
  134. * flush is slower but ensures that each append request is actually
  135. * written. If <code>immediateFlush</code> is set to
  136. * <code>false</code>, then there is a good chance that the last few
  137. * logs events are not actually written to persistent media if and
  138. * when the application crashes.
  139. *
  140. * The <code>immediateFlush</code> variable is set to
  141. * <code>true</code> by default.
  142. */
  143. bool immediateFlush;
  144. /**
  145. * When this variable is true, FileAppender will try to create
  146. * missing directories in path leading to log file.
  147. *
  148. * The `createDirs` variable is set to `false` by default.
  149. */
  150. bool createDirs;
  151. /**
  152. * When any append operation fails, <code>reopenDelay</code> says
  153. * for how many seconds the next attempt to re-open the log file and
  154. * resume logging will be delayed. If <code>reopenDelay</code> is zero,
  155. * each failed append operation will cause log file to be re-opened.
  156. * By default, <code>reopenDelay</code> is 1 second.
  157. */
  158. int reopenDelay;
  159. unsigned long bufferSize;
  160. std::unique_ptr<log4cplus::tchar[]> buffer;
  161. log4cplus::tofstream out;
  162. log4cplus::tstring filename;
  163. log4cplus::tstring localeName;
  164. log4cplus::tstring lockFileName;
  165. std::ios_base::openmode fileOpenMode;
  166. log4cplus::helpers::Time reopen_time;
  167. private:
  168. // Disallow copying of instances of this class
  169. FileAppenderBase(const FileAppenderBase&);
  170. FileAppenderBase& operator=(const FileAppenderBase&);
  171. };
  172. /**
  173. * Appends log events to a file.
  174. *
  175. * <h3>Properties</h3>
  176. * <p>It has no properties additional to {@link FileAppenderBase}.
  177. */
  178. class LOG4CPLUS_EXPORT FileAppender : public FileAppenderBase {
  179. public:
  180. // Ctors
  181. FileAppender(const log4cplus::tstring& filename,
  182. std::ios_base::openmode mode = std::ios_base::trunc,
  183. bool immediateFlush = true,
  184. bool createDirs = false);
  185. FileAppender(const log4cplus::helpers::Properties& properties,
  186. std::ios_base::openmode mode = std::ios_base::trunc);
  187. // Dtor
  188. virtual ~FileAppender();
  189. protected:
  190. void init();
  191. };
  192. typedef helpers::SharedObjectPtr<FileAppender> SharedFileAppenderPtr;
  193. /**
  194. * RollingFileAppender extends FileAppender to backup the log
  195. * files when they reach a certain size.
  196. *
  197. * <h3>Properties</h3>
  198. * <p>Properties additional to {@link FileAppender}'s properties:
  199. *
  200. * <dl>
  201. * <dt><tt>MaxFileSize</tt></dt>
  202. * <dd>This property specifies maximal size of output file. The
  203. * value is in bytes. It is possible to use <tt>MB</tt> and
  204. * <tt>KB</tt> suffixes to specify the value in megabytes or
  205. * kilobytes instead.</dd>
  206. *
  207. * <dt><tt>MaxBackupIndex</tt></dt>
  208. * <dd>This property limits the number of backup output
  209. * files; e.g. how many <tt>log.1</tt>, <tt>log.2</tt> etc. files
  210. * will be kept.</dd>
  211. * </dl>
  212. */
  213. class LOG4CPLUS_EXPORT RollingFileAppender : public FileAppender {
  214. public:
  215. // Ctors
  216. RollingFileAppender(const log4cplus::tstring& filename,
  217. long maxFileSize = 10*1024*1024, // 10 MB
  218. int maxBackupIndex = 1,
  219. bool immediateFlush = true,
  220. bool createDirs = false);
  221. RollingFileAppender(const log4cplus::helpers::Properties& properties);
  222. // Dtor
  223. virtual ~RollingFileAppender();
  224. protected:
  225. virtual void append(const spi::InternalLoggingEvent& event);
  226. void rollover(bool alreadyLocked = false);
  227. // Data
  228. long maxFileSize;
  229. int maxBackupIndex;
  230. private:
  231. LOG4CPLUS_PRIVATE void init(long maxFileSize, int maxBackupIndex);
  232. };
  233. typedef helpers::SharedObjectPtr<RollingFileAppender>
  234. SharedRollingFileAppenderPtr;
  235. enum DailyRollingFileSchedule { MONTHLY, WEEKLY, DAILY,
  236. TWICE_DAILY, HOURLY, MINUTELY};
  237. /**
  238. * DailyRollingFileAppender extends {@link FileAppender} so that the
  239. * underlying file is rolled over at a user chosen frequency.
  240. *
  241. * <h3>Properties</h3>
  242. * <p>Properties additional to {@link FileAppender}'s properties:
  243. *
  244. * <dl>
  245. * <dt><tt>Schedule</tt></dt>
  246. * <dd>This property specifies rollover schedule. The possible
  247. * values are <tt>MONTHLY</tt>, <tt>WEEKLY</tt>, <tt>DAILY</tt>,
  248. * <tt>TWICE_DAILY</tt>, <tt>HOURLY</tt> and
  249. * <tt>MINUTELY</tt>.</dd>
  250. *
  251. * <dt><tt>MaxBackupIndex</tt></dt>
  252. * <dd>This property limits how many backup files are kept per
  253. * single logging period; e.g. how many <tt>log.2009-11-07.1</tt>,
  254. * <tt>log.2009-11-07.2</tt> etc. files are kept.</dd>
  255. *
  256. * <dt><tt>RollOnClose</tt></dt>
  257. * <dd>This property specifies whether to rollover log files upon
  258. * shutdown. By default it's set to <code>true</code> to retain compatibility
  259. * with legacy code, however it may lead to undesired behaviour
  260. * as described in the github issue #120.</dd>
  261. *
  262. * <dt><tt>DatePattern</tt></dt>
  263. * <dd>This property specifies filename suffix pattern to use for
  264. * periodical backups of the logfile. The patern should be in
  265. * format supported by {@link log4cplus::helpers::Time::getFormatterTime()}</code>.
  266. * Please notice that the format of the pattern is similar but not identical
  267. * to the one used for this option in the corresponding Log4J class.
  268. * If the property isn't specified a reasonable default for a given
  269. * schedule type is used.</dd>
  270. *
  271. * </dl>
  272. */
  273. class LOG4CPLUS_EXPORT DailyRollingFileAppender : public FileAppender {
  274. public:
  275. // Ctors
  276. DailyRollingFileAppender(const log4cplus::tstring& filename,
  277. DailyRollingFileSchedule schedule = DAILY,
  278. bool immediateFlush = true,
  279. int maxBackupIndex = 10,
  280. bool createDirs = false,
  281. bool rollOnClose = true,
  282. const log4cplus::tstring& datePattern = log4cplus::tstring());
  283. DailyRollingFileAppender(const log4cplus::helpers::Properties& properties);
  284. // Dtor
  285. virtual ~DailyRollingFileAppender();
  286. // Methods
  287. virtual void close();
  288. protected:
  289. virtual void append(const spi::InternalLoggingEvent& event);
  290. void rollover(bool alreadyLocked = false);
  291. log4cplus::helpers::Time calculateNextRolloverTime(const log4cplus::helpers::Time& t) const;
  292. log4cplus::tstring getFilename(const log4cplus::helpers::Time& t) const;
  293. // Data
  294. DailyRollingFileSchedule schedule;
  295. log4cplus::tstring scheduledFilename;
  296. log4cplus::helpers::Time nextRolloverTime;
  297. int maxBackupIndex;
  298. bool rollOnClose;
  299. log4cplus::tstring datePattern;
  300. private:
  301. LOG4CPLUS_PRIVATE void init(DailyRollingFileSchedule schedule);
  302. };
  303. typedef helpers::SharedObjectPtr<DailyRollingFileAppender>
  304. SharedDailyRollingFileAppenderPtr;
  305. /**
  306. * TimeBasedRollingFileAppender extends {@link FileAppenderBase} so that
  307. * the underlying file is rolled over at a user chosen frequency while also
  308. * keeping in check a total maximum number of produced files.
  309. *
  310. * <h3>Properties</h3>
  311. * <p>Properties additional to {@link FileAppenderBase}'s properties:
  312. *
  313. * <dl>
  314. *
  315. * <dt><tt>FilenamePattern</tt></dt>
  316. * <dd>The mandatory fileNamePattern property defines the name of the
  317. * rolled-over (archived) log files. Its value should consist of the name
  318. * of the file, plus a suitably placed %d conversion specifier. The %d
  319. * conversion specifier may contain a date-and-time pattern as specified by
  320. * the java's SimpleDateFormat. The rollover period is inferred from the
  321. * value of fileNamePattern.</dd>
  322. *
  323. * <dt><tt>MaxHistory</tt></dt>
  324. * <dd>The optional maxHistory property controls the maximum number of
  325. * archive files to keep, deleting older files.</dd>
  326. *
  327. * <dt><tt>CleanHistoryOnStart</tt></dt>
  328. * <dd>If set to true, archive removal will be executed on appender start
  329. * up. By default this property is set to false. </dd>
  330. *
  331. * <dt><tt>RollOnClose</tt></dt>
  332. * <dd>This property specifies whether to rollover log files upon
  333. * shutdown. By default it's set to <code>true</code> to retain compatibility
  334. * with legacy code, however it may lead to undesired behaviour
  335. * as described in the github issue #120.</dd>
  336. *
  337. * </dl>
  338. */
  339. class LOG4CPLUS_EXPORT TimeBasedRollingFileAppender : public FileAppenderBase {
  340. public:
  341. // Ctors
  342. TimeBasedRollingFileAppender(const tstring& filename = LOG4CPLUS_TEXT(""),
  343. const tstring& filenamePattern = LOG4CPLUS_TEXT("%d.log"),
  344. int maxHistory = 10,
  345. bool cleanHistoryOnStart = false,
  346. bool immediateFlush = true,
  347. bool createDirs = false,
  348. bool rollOnClose = true);
  349. TimeBasedRollingFileAppender(const helpers::Properties& properties);
  350. // Dtor
  351. ~TimeBasedRollingFileAppender();
  352. protected:
  353. void append(const spi::InternalLoggingEvent& event);
  354. void open(std::ios_base::openmode mode);
  355. void close();
  356. void rollover(bool alreadyLocked = false);
  357. void clean(helpers::Time time);
  358. helpers::Time::duration getRolloverPeriodDuration() const;
  359. helpers::Time calculateNextRolloverTime(const helpers::Time& t) const;
  360. // Data
  361. tstring filenamePattern;
  362. DailyRollingFileSchedule schedule;
  363. tstring scheduledFilename;
  364. int maxHistory;
  365. bool cleanHistoryOnStart;
  366. log4cplus::helpers::Time lastHeartBeat;
  367. log4cplus::helpers::Time nextRolloverTime;
  368. bool rollOnClose;
  369. private:
  370. LOG4CPLUS_PRIVATE void init();
  371. };
  372. typedef helpers::SharedObjectPtr<TimeBasedRollingFileAppender>
  373. SharedTimeBasedRollingFileAppenderPtr;
  374. } // end namespace log4cplus
  375. #endif // LOG4CPLUS_FILE_APPENDER_HEADER_