summaryrefslogtreecommitdiff
path: root/src/main/include/log4cxx/rolling/timebasedrollingpolicy.h
blob: 254b2fe9512b8f12befa1c87b089e416efff7d91 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#if !defined(_LOG4CXX_ROLLING_TIME_BASED_ROLLING_POLICY_H)
#define _LOG4CXX_ROLLING_TIME_BASED_ROLLING_POLICY_H

#include <log4cxx/portability.h>
#include <log4cxx/rolling/rollingpolicybase.h>
#include <log4cxx/rolling/triggeringpolicy.h>
#include <log4cxx/writerappender.h>
#include <log4cxx/helpers/outputstream.h>
#include <apr_mmap.h>

namespace log4cxx {

    namespace rolling {



        /**
         * <code>TimeBasedRollingPolicy</code> is both easy to configure and quite
         * powerful.
         *
         * <p>In order to use  <code>TimeBasedRollingPolicy</code>, the
         * <b>FileNamePattern</b> option must be set. It basically specifies the name of the
         * rolled log files. The value <code>FileNamePattern</code> should consist of
         * the name of the file, plus a suitably placed <code>%d</code> conversion
         * specifier. The <code>%d</code> conversion specifier may contain a date and
         * time pattern as specified by the {@link log4cxx::helpers::SimpleDateFormat} class. If
         * the date and time pattern is ommitted, then the default pattern of
         * "yyyy-MM-dd" is assumed. The following examples should clarify the point.
         *
         * <p>
         * <table cellspacing="5px" border="1">
         *   <tr>
         *     <th><code>FileNamePattern</code> value</th>
         *     <th>Rollover schedule</th>
         *     <th>Example</th>
         *   </tr>
         *   <tr>
         *     <td nowrap="true"><code>/wombat/folder/foo.%d</code></td>
         *     <td>Daily rollover (at midnight).  Due to the omission of the optional
         *         time and date pattern for the %d token specifier, the default pattern
         *         of "yyyy-MM-dd" is assumed, which corresponds to daily rollover.
         *     </td>
         *     <td>During November 23rd, 2004, logging output will go to
         *       the file <code>/wombat/foo.2004-11-23</code>. At midnight and for
         *       the rest of the 24th, logging output will be directed to
         *       <code>/wombat/foo.2004-11-24</code>.
         *     </td>
         *   </tr>
         *   <tr>
         *     <td nowrap="true"><code>/wombat/foo.%d{yyyy-MM}.log</code></td>
         *     <td>Rollover at the beginning of each month.</td>
         *     <td>During the month of October 2004, logging output will go to
         *     <code>/wombat/foo.2004-10.log</code>. After midnight of October 31st
         *     and for the rest of November, logging output will be directed to
         *       <code>/wombat/foo.2004-11.log</code>.
         *     </td>
         *   </tr>
         * </table>
         * <h2>Automatic file compression</h2>
         * <code>TimeBasedRollingPolicy</code> supports automatic file compression.
         * This feature is enabled if the value of the <b>FileNamePattern</b> option
         * ends with <code>.gz</code> or <code>.zip</code>.
         * <p>
         * <table cellspacing="5px" border="1">
         *   <tr>
         *     <th><code>FileNamePattern</code> value</th>
         *     <th>Rollover schedule</th>
         *     <th>Example</th>
         *   </tr>
         *   <tr>
         *     <td nowrap="true"><code>/wombat/foo.%d.gz</code></td>
         *     <td>Daily rollover (at midnight) with automatic GZIP compression of the
         *      arcived files.</td>
         *     <td>During November 23rd, 2004, logging output will go to
         *       the file <code>/wombat/foo.2004-11-23</code>. However, at midnight that
         *       file will be compressed to become <code>/wombat/foo.2004-11-23.gz</code>.
         *       For the 24th of November, logging output will be directed to
         *       <code>/wombat/folder/foo.2004-11-24</code> until its rolled over at the
         *       beginning of the next day.
         *     </td>
         *   </tr>
         * </table>
         *
         * <h2>Decoupling the location of the active log file and the archived log files</h2>
         * <p>The <em>active file</em> is defined as the log file for the current period
         * whereas <em>archived files</em> are thos files which have been rolled over
         * in previous periods.
         *
         * <p>By setting the <b>ActiveFileName</b> option you can decouple the location
         * of the active log file and the location of the archived log files.
         * <p>
         *  <table cellspacing="5px" border="1">
         *   <tr>
         *     <th><code>FileNamePattern</code> value</th>
         *     <th>ActiveFileName</th>
         *     <th>Rollover schedule</th>
         *     <th>Example</th>
         *   </tr>
         *   <tr>
         *     <td nowrap="true"><code>/wombat/foo.log.%d</code></td>
         *     <td nowrap="true"><code>/wombat/foo.log</code></td>
         *     <td>Daily rollover.</td>
         *
         *     <td>During November 23rd, 2004, logging output will go to
         *       the file <code>/wombat/foo.log</code>. However, at midnight that file
         *       will archived as <code>/wombat/foo.log.2004-11-23</code>. For the 24th
         *       of November, logging output will be directed to
         *       <code>/wombat/folder/foo.log</code> until its archived as
         *       <code>/wombat/foo.log.2004-11-24</code> at the beginning of the next
         *       day.
         *     </td>
         *   </tr>
         * </table>
         * <p>
         * If configuring programatically, do not forget to call {@link #activateOptions}
         * method before using this policy. Moreover, {@link #activateOptions} of
         * <code> TimeBasedRollingPolicy</code> must be called <em>before</em> calling
         * the {@link #activateOptions} method of the owning
         * <code>RollingFileAppender</code>.
         *
         * 
         * 
         */
        class LOG4CXX_EXPORT TimeBasedRollingPolicy : public RollingPolicyBase,
             public TriggeringPolicy {
          DECLARE_LOG4CXX_OBJECT(TimeBasedRollingPolicy)
          BEGIN_LOG4CXX_CAST_MAP()
                  LOG4CXX_CAST_ENTRY(TimeBasedRollingPolicy)
                  LOG4CXX_CAST_ENTRY_CHAIN(RollingPolicyBase)
                  LOG4CXX_CAST_ENTRY_CHAIN(TriggeringPolicy)
          END_LOG4CXX_CAST_MAP()

        private:
        /**
         * Time for next determination if time for rollover.
         */
        log4cxx_time_t nextCheck;

        /**
         * File name at last rollover.
         */
        LogString lastFileName;

        /**
         * mmap pointer
         */
        apr_mmap_t* _mmap;

        /*
         * pool for mmap handler
         * */
        log4cxx::helpers::Pool* _mmapPool;
        
        /**
         * mmap file descriptor
         */
        apr_file_t* _file_map;

        /**
         * mmap file name 
         */
        std::string _mapFileName;

        /*
         * lock file handle
         * */
        apr_file_t* _lock_file;
        /**
         * Check nextCheck if it has already been set
         * Timebased rolling policy has an issue when working at low rps.
         * Under low rps, multiple processes will not be scheduled in time for the second chance(do rolling),
         * so the rolling mechanism will not be triggered even if the time period is out of date.
         * This results in log entries will be accumulated for serveral minutes to be rolling.
         * Adding this flag to provide rolling opportunity for a process even if it is writing the first log entry
         */
        bool bAlreadyInitialized;

        /*
         * If the current file name contains date information, retrieve the current writting file from mmap
         * */
        bool bRefreshCurFile;

        /*
         * mmap file name
         * */
        LogString _fileNamePattern;

        /**
         * Length of any file type suffix (.gz, .zip).
         */
        int suffixLength;

        public:
            TimeBasedRollingPolicy();
            void addRef() const;
            void releaseRef() const;
            void activateOptions(log4cxx::helpers::Pool& );

#ifdef LOG4CXX_MULTI_PROCESS
            virtual ~TimeBasedRollingPolicy();

            /**
             * Generate mmap file
             */
            int createMMapFile(const std::string& lastfilename, log4cxx::helpers::Pool& pool);

            /**
             *  Detect if the mmap file is empty
             */
            bool isMapFileEmpty(log4cxx::helpers::Pool& pool);

            /**
             *   init MMapFile
             */
            void initMMapFile(const LogString& lastFileName, log4cxx::helpers::Pool& pool);

            /**
             *   lock MMapFile
             */
            int lockMMapFile(int type);

            /**
             *   unlock MMapFile
             */
            int unLockMMapFile();

            /**
             *   create MMapFile/lockFile
             */
            const std::string createFile(const std::string& filename, const std::string& suffix, log4cxx::helpers::Pool& pool);
#endif

            /**
           * Initialize the policy and return any initial actions for rolling file appender.
           *
           * @param file current value of RollingFileAppender.getFile().
           * @param append current value of RollingFileAppender.getAppend().
           * @param pool pool for any required allocations.
           * @return Description of the initialization, may be null to indicate
           * no initialization needed.
           * @throws SecurityException if denied access to log files.
           */
           RolloverDescriptionPtr initialize(
            const LogString& file,
            const bool append,
            log4cxx::helpers::Pool& pool);

          /**
           * Prepare for a rollover.  This method is called prior to
           * closing the active log file, performs any necessary
           * preliminary actions and describes actions needed
           * after close of current log file.
           *
           * @param activeFile file name for current active log file.
           * @param pool pool for any required allocations.
           * @return Description of pending rollover, may be null to indicate no rollover
           * at this time.
           * @throws SecurityException if denied access to log files.
           */
          RolloverDescriptionPtr rollover(const LogString& activeFile,
            log4cxx::helpers::Pool& pool);

/**
 * Determines if a rollover may be appropriate at this time.  If
 * true is returned, RolloverPolicy.rollover will be called but it
 * can determine that a rollover is not warranted.
 *
 * @param appender A reference to the appender.
 * @param event A reference to the currently event.
 * @param filename The filename for the currently active log file.
 * @param fileLength Length of the file in bytes.
 * @return true if a rollover should occur.
 */
virtual bool isTriggeringEvent(
  Appender* appender,
  const log4cxx::spi::LoggingEventPtr& event,
  const LogString& filename,
  size_t fileLength);

  protected:
               log4cxx::pattern::PatternMap getFormatSpecifiers() const;

        };

        LOG4CXX_PTR_DEF(TimeBasedRollingPolicy);

    }
}

#endif