2 * @file strict_time_based_rolling_policy.cpp
\r
3 * @brief log4cxx's rolling policy class. (time)
\r
5 * L7VSD: Linux Virtual Server for Layer7 Load Balancing
\r
6 * Copyright (C) 2008 NTT COMWARE Corporation.
\r
8 * This program is free software; you can redistribute it and/or
\r
9 * modify it under the terms of the GNU Lesser General Public
\r
10 * License as published by the Free Software Foundation; either
\r
11 * version 2.1 of the License, or (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
16 * Lesser General Public License for more details.
\r
18 * You should have received a copy of the GNU Lesser General Public
\r
19 * License along with this library; if not, write to the Free Software
\r
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
\r
23 **********************************************************************/
\r
25 #include <log4cxx/logstring.h>
\r
26 #include <log4cxx/rolling/filerenameaction.h>
\r
27 #include <log4cxx/helpers/loglog.h>
\r
28 #include <log4cxx/helpers/exception.h>
\r
29 #include <log4cxx/helpers/stringhelper.h>
\r
30 #include <log4cxx/helpers/optionconverter.h>
\r
32 #include "strict_time_based_rolling_policy.h"
\r
33 #include <boost/lexical_cast.hpp>
\r
34 #include <sys/types.h>
\r
35 #include <sys/stat.h>
\r
38 using namespace l7vs;
\r
39 using namespace log4cxx;
\r
40 using namespace log4cxx::rolling;
\r
41 using namespace log4cxx::helpers;
\r
42 using namespace log4cxx::pattern;
\r
44 #define TIME_BUF_LEN (256)
\r
45 #define LOG_DATE_FORMAT "%Y%m%d%H%M"
\r
46 #define LOG_DATE_FORMAT_WEEK "%Y%m%d%w%H%M"
\r
48 IMPLEMENT_LOG4CXX_OBJECT(StrictTimeBasedRollingPolicy)
\r
51 * default constructor.
\r
52 * initialize member valiables
\r
56 StrictTimeBasedRollingPolicy::StrictTimeBasedRollingPolicy() :
\r
57 nextCheck(0), rotationTiming(LOG_TIM_YEAR), rotationTimingValue("")
\r
62 * increase reffernce count
\r
66 void StrictTimeBasedRollingPolicy::addRef() const
\r
68 TriggeringPolicy::addRef();
\r
72 * decrease reffernce count
\r
76 void StrictTimeBasedRollingPolicy::releaseRef() const
\r
78 TriggeringPolicy::releaseRef();
\r
82 * evaluate and activate options
\r
83 * @param memory pool
\r
86 void StrictTimeBasedRollingPolicy::activateOptions(log4cxx::helpers::Pool& pool)
\r
88 // check for rotationTimingValue
\r
89 if (0 >= rotationTimingValue.length()) {
\r
91 LOG4CXX_STR("The RotationTimingValue option must be set before using StrictTimeBasedRollingPolicy. "));
\r
92 throw IllegalStateException();
\r
95 // call super class's activateOptions
\r
96 FixedWindowRollingPolicy::activateOptions(pool);
\r
100 * rotationTimingValue getter
\r
102 * @return rotationTimingValue
\r
104 std::string StrictTimeBasedRollingPolicy::getRotationTimingValue()
\r
106 return rotationTimingValue;
\r
110 * rotationTimingValue setter
\r
111 * @param rotationTimingValue
\r
114 void StrictTimeBasedRollingPolicy::setRotationTimingValue(const std::string& val)
\r
116 rotationTimingValue = val;
\r
120 * rotationTiming getter
\r
122 * @return rotationTiming
\r
124 LOG_ROTATION_TIMING_TAG StrictTimeBasedRollingPolicy::getRotationTiming()
\r
126 return rotationTiming;
\r
130 * rotationTiming setter
\r
131 * @param rotationTiming
\r
134 void StrictTimeBasedRollingPolicy::setRotationTiming(const LOG_ROTATION_TIMING_TAG val)
\r
136 rotationTiming = val;
\r
141 * @param option name
\r
145 void StrictTimeBasedRollingPolicy::setOption(const LogString& option, const LogString& value)
\r
147 if (StringHelper::equalsIgnoreCase(option,
\r
148 LOG4CXX_STR("ROTATIONTIMINGVALUE"),
\r
149 LOG4CXX_STR("rotationtimingvalue"))) {
\r
150 rotationTimingValue = value;
\r
152 else if (StringHelper::equalsIgnoreCase(option,
\r
153 LOG4CXX_STR("ROTATIONTIMING"),
\r
154 LOG4CXX_STR("rotationtiming"))) {
\r
155 rotationTiming = (LOG_ROTATION_TIMING_TAG)OptionConverter::toInt(value, 0);
\r
158 FixedWindowRollingPolicy::setOption(option, value);
\r
163 * rolling policy initialize
\r
164 * @param filename of current use
\r
165 * @param append or overWrite
\r
166 * @param memory pool
\r
167 * @return Rollover information
\r
169 RolloverDescriptionPtr StrictTimeBasedRollingPolicy::initialize(
\r
170 const LogString& currentActiveFile,
\r
174 // get current time
\r
176 time_t ret_time = time(&now_time);
\r
177 if (-1 == ret_time) {
\r
178 LogLog::warn(LOG4CXX_STR("Fail to get CurrentTime. "));
\r
179 RolloverDescriptionPtr desc;
\r
183 // get next rotation timing
\r
184 nextCheck = getNextCheck(now_time);
\r
185 if (-1 == nextCheck) {
\r
186 LogLog::warn(LOG4CXX_STR("Fail to get nextCheck. "));
\r
187 RolloverDescriptionPtr desc;
\r
191 // call super class's initialize
\r
192 return FixedWindowRollingPolicy::initialize(currentActiveFile, append, pool);
\r
196 * calculate next rollover timing
\r
198 * @return next rollover time
\r
200 time_t StrictTimeBasedRollingPolicy::getNextCheck(time_t now_time)
\r
204 ret_tm = localtime_r(&now_time, &now_tm);
\r
209 char buf[TIME_BUF_LEN];
\r
211 if (LOG_TIM_WEEK == rotationTiming) {
\r
212 ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT_WEEK, &now_tm);
\r
215 ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT, &now_tm);
\r
220 std::string now(buf);
\r
222 int dates[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
\r
223 unsigned long long numNowDate = 0;;
\r
224 unsigned long long numTimingDate = 0;
\r
229 int numNowWeek = 0;
\r
230 int numTimingWeek = 0;
\r
235 memset(&t, 0, sizeof(struct tm));
\r
240 switch (rotationTiming) {
\r
242 numNowDate = boost::lexical_cast<unsigned long long>(now.substr(4));
\r
243 numTimingDate = boost::lexical_cast<unsigned long long>(rotationTimingValue);
\r
245 numYear = boost::lexical_cast<int>(now.substr(0, 4));
\r
246 numMonth =boost::lexical_cast<int>(rotationTimingValue.substr(0, 2));
\r
247 numDate = boost::lexical_cast<int>(rotationTimingValue.substr(2, 2));
\r
248 numHour = boost::lexical_cast<int>(rotationTimingValue.substr(4, 2));
\r
249 numMinute = boost::lexical_cast<int>(rotationTimingValue.substr(6));
\r
251 if (numTimingDate > numNowDate) {
\r
252 t.tm_year = numYear - 1900;
\r
255 t.tm_year = numYear + 1 - 1900;
\r
257 t.tm_mon = numMonth - 1;
\r
258 t.tm_mday = numDate;
\r
259 t.tm_hour = numHour;
\r
260 t.tm_min = numMinute;
\r
268 case LOG_TIM_MONTH:
\r
269 numNowDate = boost::lexical_cast<unsigned long long>(now.substr(6));
\r
270 numTimingDate = boost::lexical_cast<unsigned long long>(rotationTimingValue);
\r
272 numYear = boost::lexical_cast<int>(now.substr(0, 4));
\r
273 numMonth = boost::lexical_cast<int>(now.substr(4, 2));
\r
274 numDate = boost::lexical_cast<int>(rotationTimingValue.substr(0, 2));
\r
275 numHour = boost::lexical_cast<int>(rotationTimingValue.substr(2, 2));
\r
276 numMinute = boost::lexical_cast<int>(rotationTimingValue.substr(4));
\r
278 if (numTimingDate > numNowDate) {
\r
279 t.tm_year = numYear - 1900;
\r
280 t.tm_mon = numMonth - 1;
\r
283 if (12 == numMonth) {
\r
284 t.tm_year = numYear + 1 - 1900;
\r
288 t.tm_year = numYear - 1900;
\r
289 t.tm_mon = numMonth + 1 - 1;
\r
293 if (numDate > dates[t.tm_mon]) {
\r
294 t.tm_mday = dates[t.tm_mon];
\r
297 t.tm_mday = numDate;
\r
300 t.tm_hour = numHour;
\r
301 t.tm_min = numMinute;
\r
310 numNowDate = boost::lexical_cast<unsigned long long>(now.substr(8));
\r
311 numTimingDate = boost::lexical_cast<unsigned long long>(rotationTimingValue);
\r
313 numYear = boost::lexical_cast<int>(now.substr(0, 4));
\r
314 numMonth = boost::lexical_cast<int>(now.substr(4, 2));
\r
315 numDate = boost::lexical_cast<int>(now.substr(6, 2));
\r
316 numNowWeek = boost::lexical_cast<int>(now.substr(8, 1));
\r
317 numTimingWeek = boost::lexical_cast<int>(rotationTimingValue.substr(0, 1));
\r
318 numHour = boost::lexical_cast<int>(rotationTimingValue.substr(1, 2));
\r
319 numMinute = boost::lexical_cast<int>(rotationTimingValue.substr(3));
\r
321 t.tm_year = numYear - 1900;
\r
322 t.tm_mon = numMonth - 1;
\r
323 if (numTimingDate > numNowDate) {
\r
324 t.tm_mday = numDate + (numTimingWeek - numNowWeek);
\r
327 t.tm_mday = numDate + (7 - (numNowWeek - numTimingWeek));
\r
329 t.tm_hour = numHour;
\r
330 t.tm_min = numMinute;
\r
340 numNowDate = boost::lexical_cast<unsigned long long>(now.substr(8));
\r
341 numTimingDate = boost::lexical_cast<unsigned long long>(rotationTimingValue);
\r
343 numYear = boost::lexical_cast<int>(now.substr(0, 4));
\r
344 numMonth = boost::lexical_cast<int>(now.substr(4, 2));
\r
345 numDate = boost::lexical_cast<int>(now.substr(6, 2));
\r
346 numHour = boost::lexical_cast<int>(rotationTimingValue.substr(0, 2));
\r
347 numMinute = boost::lexical_cast<int>(rotationTimingValue.substr(2));
\r
349 t.tm_year = numYear - 1900;
\r
350 t.tm_mon = numMonth - 1;
\r
351 if (numTimingDate > numNowDate) {
\r
352 t.tm_mday = numDate;
\r
355 t.tm_mday = numDate + 1;
\r
357 t.tm_hour = numHour;
\r
358 t.tm_min = numMinute;
\r
367 numNowDate = boost::lexical_cast<unsigned long long>(now.substr(10));
\r
368 numTimingDate = boost::lexical_cast<unsigned long long>(rotationTimingValue);
\r
370 numYear = boost::lexical_cast<int>(now.substr(0, 4));
\r
371 numMonth = boost::lexical_cast<int>(now.substr(4, 2));
\r
372 numDate = boost::lexical_cast<int>(now.substr(6, 2));
\r
373 numHour = boost::lexical_cast<int>(now.substr(8, 2));
\r
374 numMinute = boost::lexical_cast<int>(rotationTimingValue);
\r
376 t.tm_year = numYear - 1900;
\r
377 t.tm_mon = numMonth - 1;
\r
378 t.tm_mday = numDate;
\r
379 if (numTimingDate > numNowDate) {
\r
380 t.tm_hour = numHour;
\r
383 t.tm_hour = numHour + 1;
\r
385 t.tm_min = numMinute;
\r
393 catch (const std::exception& ex) {
\r
401 * log file rollover opration
\r
402 * @param name of current log file
\r
403 * @param memory pool
\r
404 * @return Rollover infomation
\r
406 RolloverDescriptionPtr StrictTimeBasedRollingPolicy::rollover(
\r
407 const LogString& currentActiveFile,
\r
410 // get current time
\r
412 time_t ret_time = time(&now_time);
\r
413 if (-1 == ret_time) {
\r
414 LogLog::warn(LOG4CXX_STR("Fail to get CurrentTime. "));
\r
415 RolloverDescriptionPtr desc;
\r
419 // get next rotation timing
\r
420 nextCheck = getNextCheck(now_time);
\r
421 if (-1 == nextCheck) {
\r
422 LogLog::warn(LOG4CXX_STR("Fail to get nextCheck. "));
\r
423 RolloverDescriptionPtr desc;
\r
427 // call super class's rollover
\r
428 return FixedWindowRollingPolicy::rollover(currentActiveFile, pool);
\r
433 * returns do rollover or not
\r
434 * @param appender (not use)
\r
435 * @param event (not use)
\r
437 * @param fileLength (not use)
\r
438 * @retval true do rollover
\r
439 * @retval false not rollover yet
\r
441 bool StrictTimeBasedRollingPolicy::isTriggeringEvent(
\r
442 Appender* /* appender */,
\r
443 const log4cxx::spi::LoggingEventPtr& /* event */,
\r
444 const LogString& filename,
\r
445 size_t /* fileLength */)
\r
448 time_t ret_time = time(&now_time);
\r
449 if (-1 == ret_time) {
\r
450 LogLog::warn(LOG4CXX_STR("Fail to get time. "));
\r
453 return now_time > nextCheck;
\r