2 * @file strict_time_based_rolling_policy.cpp
3 * @brief log4cxx's rolling policy class. (time)
5 * L7VSD: Linux Virtual Server for Layer7 Load Balancing
6 * Copyright (C) 2008 NTT COMWARE Corporation.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 **********************************************************************/
25 #include <log4cxx/logstring.h>
26 #include <log4cxx/rolling/filerenameaction.h>
27 #include <log4cxx/helpers/loglog.h>
28 #include <log4cxx/helpers/exception.h>
29 #include <log4cxx/helpers/stringhelper.h>
30 #include <log4cxx/helpers/optionconverter.h>
32 #include "strict_time_based_rolling_policy.h"
33 #include "lexical_cast.h"
34 #include <sys/types.h>
38 using namespace log4cxx;
39 using namespace log4cxx::rolling;
40 using namespace log4cxx::helpers;
41 using namespace log4cxx::pattern;
43 #define TIME_BUF_LEN (256)
44 #define LOG_DATE_FORMAT "%Y%m%d%H%M"
45 #define LOG_DATE_FORMAT_WEEK "%Y%m%d%w%H%M"
47 IMPLEMENT_LOG4CXX_OBJECT(StrictTimeBasedRollingPolicy)
50 * default constructor.
51 * initialize member valiables
55 StrictTimeBasedRollingPolicy::StrictTimeBasedRollingPolicy() :
56 nextCheck(0), rotationTiming(LOG_TIM_YEAR), rotationTimingValue("")
61 * increase reffernce count
65 void StrictTimeBasedRollingPolicy::addRef() const
67 TriggeringPolicy::addRef();
71 * decrease reffernce count
75 void StrictTimeBasedRollingPolicy::releaseRef() const
77 TriggeringPolicy::releaseRef();
81 * evaluate and activate options
85 void StrictTimeBasedRollingPolicy::activateOptions(log4cxx::helpers::Pool& pool)
87 // check for rotationTimingValue
88 if (0 >= rotationTimingValue.length()) {
90 LOG4CXX_STR("The RotationTimingValue option must be set before using StrictTimeBasedRollingPolicy. "));
91 throw IllegalStateException();
94 // call super class's activateOptions
95 FixedWindowRollingPolicy::activateOptions(pool);
99 * rotationTimingValue getter
101 * @return rotationTimingValue
103 std::string StrictTimeBasedRollingPolicy::getRotationTimingValue()
105 return rotationTimingValue;
109 * rotationTimingValue setter
110 * @param rotationTimingValue
113 void StrictTimeBasedRollingPolicy::setRotationTimingValue(const std::string& val)
115 rotationTimingValue = val;
119 * rotationTiming getter
121 * @return rotationTiming
123 LOG_ROTATION_TIMING_TAG StrictTimeBasedRollingPolicy::getRotationTiming()
125 return rotationTiming;
129 * rotationTiming setter
130 * @param rotationTiming
133 void StrictTimeBasedRollingPolicy::setRotationTiming(const LOG_ROTATION_TIMING_TAG val)
135 rotationTiming = val;
144 void StrictTimeBasedRollingPolicy::setOption(const LogString& option, const LogString& value)
146 if (StringHelper::equalsIgnoreCase(option,
147 LOG4CXX_STR("ROTATIONTIMINGVALUE"),
148 LOG4CXX_STR("rotationtimingvalue"))) {
149 rotationTimingValue = value;
151 else if (StringHelper::equalsIgnoreCase(option,
152 LOG4CXX_STR("ROTATIONTIMING"),
153 LOG4CXX_STR("rotationtiming"))) {
154 rotationTiming = (LOG_ROTATION_TIMING_TAG)OptionConverter::toInt(value, 0);
157 FixedWindowRollingPolicy::setOption(option, value);
162 * rolling policy initialize
163 * @param filename of current use
164 * @param append or overWrite
166 * @return Rollover information
168 RolloverDescriptionPtr StrictTimeBasedRollingPolicy::initialize(
169 const LogString& currentActiveFile,
175 time_t ret_time = time(&now_time);
176 if (-1 == ret_time) {
177 LogLog::warn(LOG4CXX_STR("Fail to get CurrentTime. "));
178 RolloverDescriptionPtr desc;
182 // get next rotation timing
183 nextCheck = getNextCheck(now_time);
184 if (-1 == nextCheck) {
185 LogLog::warn(LOG4CXX_STR("Fail to get nextCheck. "));
186 RolloverDescriptionPtr desc;
190 // call super class's initialize
191 return FixedWindowRollingPolicy::initialize(currentActiveFile, append, pool);
195 * calculate next rollover timing
197 * @return next rollover time
199 time_t StrictTimeBasedRollingPolicy::getNextCheck(time_t now_time)
203 ret_tm = localtime_r(&now_time, &now_tm);
208 char buf[TIME_BUF_LEN];
210 if (LOG_TIM_WEEK == rotationTiming) {
211 ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT_WEEK, &now_tm);
214 ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT, &now_tm);
219 std::string now(buf);
221 int dates[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
222 unsigned long long numNowDate = 0;;
223 unsigned long long numTimingDate = 0;
229 int numTimingWeek = 0;
234 memset(&t, 0, sizeof(struct tm));
239 switch (rotationTiming) {
241 numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(4));
242 numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
244 numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
245 numMonth = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));
246 numDate = l7vs::lexical_cast<int>(rotationTimingValue.substr(2, 2));
247 numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(4, 2));
248 numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(6));
250 if (numTimingDate > numNowDate) {
251 t.tm_year = numYear - 1900;
254 #if defined(LOGGER_PROCESS_ADM)
255 t.tm_year = numYear - 1900;
256 #else //LOGGER_PROCESS_VSD or LOGGER_PROCESS_SNM
257 t.tm_year = numYear + 1 - 1900;
260 t.tm_mon = numMonth - 1;
263 t.tm_min = numMinute;
272 numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(6));
273 numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
275 numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
276 numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));
277 numDate = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));
278 numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(2, 2));
279 numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(4));
281 if (numTimingDate > numNowDate) {
282 t.tm_year = numYear - 1900;
283 t.tm_mon = numMonth - 1;
286 #if defined(LOGGER_PROCESS_ADM)
287 t.tm_year = numYear - 1900;
288 t.tm_mon = numMonth - 1;
289 #else //LOGGER_PROCESS_VSD or LOGGER_PROCESS_SNM
290 if (12 == numMonth) {
291 t.tm_year = numYear + 1 - 1900;
295 t.tm_year = numYear - 1900;
296 t.tm_mon = numMonth + 1 - 1;
301 if (numDate > dates[t.tm_mon]) {
302 t.tm_mday = dates[t.tm_mon];
309 t.tm_min = numMinute;
318 numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(8));
319 numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
321 numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
322 numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));
323 numDate = l7vs::lexical_cast<int>(now.substr(6, 2));
324 numNowWeek = l7vs::lexical_cast<int>(now.substr(8, 1));
325 numTimingWeek = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 1));
326 numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(1, 2));
327 numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(3));
329 t.tm_year = numYear - 1900;
330 t.tm_mon = numMonth - 1;
331 if (numTimingDate > numNowDate) {
332 t.tm_mday = numDate + (numTimingWeek - numNowWeek);
335 #if defined(LOGGER_PROCESS_ADM)
336 t.tm_mday = numDate + (numTimingWeek - numNowWeek);
337 #else //LOGGER_PROCESS_VSD or LOGGER_PROCESS_SNM
338 t.tm_mday = numDate + (7 - (numNowWeek - numTimingWeek));
342 t.tm_min = numMinute;
352 numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(8));
353 numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
355 numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
356 numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));
357 numDate = l7vs::lexical_cast<int>(now.substr(6, 2));
358 numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));
359 numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(2));
361 t.tm_year = numYear - 1900;
362 t.tm_mon = numMonth - 1;
363 if (numTimingDate > numNowDate) {
367 #if defined(LOGGER_PROCESS_ADM)
369 #else //LOGGER_PROCESS_VSD or LOGGER_PROCESS_SNM
370 t.tm_mday = numDate + 1;
374 t.tm_min = numMinute;
383 numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(10));
384 numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
386 numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
387 numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));
388 numDate = l7vs::lexical_cast<int>(now.substr(6, 2));
389 numHour = l7vs::lexical_cast<int>(now.substr(8, 2));
390 numMinute = l7vs::lexical_cast<int>(rotationTimingValue);
392 t.tm_year = numYear - 1900;
393 t.tm_mon = numMonth - 1;
395 if (numTimingDate > numNowDate) {
399 #if defined(LOGGER_PROCESS_ADM)
401 #else //LOGGER_PROCESS_VSD or LOGGER_PROCESS_SNM
402 t.tm_hour = numHour + 1;
405 t.tm_min = numMinute;
413 catch (const std::exception& ex) {
421 * log file rollover opration
422 * @param name of current log file
424 * @return Rollover infomation
426 RolloverDescriptionPtr StrictTimeBasedRollingPolicy::rollover(
427 const LogString& currentActiveFile,
432 time_t ret_time = time(&now_time);
433 if (-1 == ret_time) {
434 LogLog::warn(LOG4CXX_STR("Fail to get CurrentTime. "));
435 RolloverDescriptionPtr desc;
439 // get next rotation timing
440 nextCheck = getNextCheck(now_time);
441 if (-1 == nextCheck) {
442 LogLog::warn(LOG4CXX_STR("Fail to get nextCheck. "));
443 RolloverDescriptionPtr desc;
447 // call super class's rollover
448 return FixedWindowRollingPolicy::rollover(currentActiveFile, pool);
453 * returns do rollover or not
454 * @param appender (not use)
455 * @param event (not use)
457 * @param fileLength (not use)
458 * @retval true do rollover
459 * @retval false not rollover yet
461 bool StrictTimeBasedRollingPolicy::isTriggeringEvent(
462 Appender* /* appender */,
463 const log4cxx::spi::LoggingEventPtr& /* event */,
464 const LogString& filename,
465 size_t /* fileLength */)
468 time_t ret_time = time(&now_time);
469 if (-1 == ret_time) {
470 LogLog::warn(LOG4CXX_STR("Fail to get time. "));
473 #if defined(LOGGER_PROCESS_ADM)
476 if (-1 == stat(filename.c_str(), &sb)) {
477 LogLog::warn(LOG4CXX_STR("Fail to get logfile update time. "));
480 if (now_time > nextCheck && nextCheck > sb.st_mtime) {
487 #else //LOGGER_PROCESS_VSD or LOGGER_PROCESS_SNM
488 return now_time > nextCheck;