OSDN Git Service

Merge branch 'packet_edit' into autotools-fix(releng)
[ultramonkey-l7/sslproxy.git] / logger / strict_time_based_rolling_policy.cpp
index 4511b17..8349b3a 100644 (file)
-/*\r
- * @file  strict_time_based_rolling_policy.cpp\r
- * @brief log4cxx's rolling policy class. (time)\r
- *\r
- * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
- * Copyright (C) 2008  NTT COMWARE Corporation.\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *      \r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\r
- * 02110-1301 USA\r
- *\r
- **********************************************************************/\r
-\r
-#include <log4cxx/logstring.h>\r
-#include <log4cxx/rolling/filerenameaction.h>\r
-#include <log4cxx/helpers/loglog.h>\r
-#include <log4cxx/helpers/exception.h>\r
-#include <log4cxx/helpers/stringhelper.h>\r
-#include <log4cxx/helpers/optionconverter.h>\r
-#include <time.h>\r
-#include "strict_time_based_rolling_policy.h"\r
-#include "lexical_cast.h"\r
-#include <sys/types.h>\r
-#include <sys/stat.h>\r
-#include <unistd.h>\r
-\r
-using namespace log4cxx;\r
-using namespace log4cxx::rolling;\r
-using namespace log4cxx::helpers;\r
-using namespace log4cxx::pattern;\r
-\r
-#define TIME_BUF_LEN (256)\r
-#define LOG_DATE_FORMAT "%Y%m%d%H%M"\r
-#define LOG_DATE_FORMAT_WEEK "%Y%m%d%w%H%M"\r
-\r
-IMPLEMENT_LOG4CXX_OBJECT(StrictTimeBasedRollingPolicy)\r
-\r
-/*!\r
- * default constructor.\r
- * initialize member valiables\r
- * @param   void\r
- * @return  void\r
- */\r
-StrictTimeBasedRollingPolicy::StrictTimeBasedRollingPolicy() :\r
-       nextCheck(0), rotationTiming(LOG_TIM_YEAR), rotationTimingValue("")\r
-{\r
-}\r
-\r
-/*!\r
- * increase reffernce count\r
- * @param   void\r
- * @return  void\r
- */\r
-void StrictTimeBasedRollingPolicy::addRef() const\r
-{\r
-       TriggeringPolicy::addRef();\r
-}\r
-\r
-/*!\r
- * decrease reffernce count\r
- * @param   void\r
- * @return  void\r
- */\r
-void StrictTimeBasedRollingPolicy::releaseRef() const\r
-{\r
-       TriggeringPolicy::releaseRef();\r
-}\r
-\r
-/*!\r
- * evaluate and activate options\r
- * @param   memory pool\r
- * @return  void\r
- */\r
-void StrictTimeBasedRollingPolicy::activateOptions(log4cxx::helpers::Pool& pool)\r
-{\r
-       // check for rotationTimingValue\r
-       if (0 >= rotationTimingValue.length()) {\r
-               LogLog::warn(\r
-               LOG4CXX_STR("The RotationTimingValue option must be set before using StrictTimeBasedRollingPolicy. "));\r
-               throw IllegalStateException();\r
-       }\r
-\r
-       // call super class's activateOptions\r
-       FixedWindowRollingPolicy::activateOptions(pool);\r
-}\r
-\r
-/*!\r
- * rotationTimingValue getter\r
- * @param   void\r
- * @return  rotationTimingValue\r
- */\r
-std::string StrictTimeBasedRollingPolicy::getRotationTimingValue()\r
-{\r
-       return rotationTimingValue;\r
-}\r
\r
-/*!\r
- * rotationTimingValue setter\r
- * @param   rotationTimingValue\r
- * @return  void\r
- */\r
-void StrictTimeBasedRollingPolicy::setRotationTimingValue(const std::string& val)\r
-{\r
-       rotationTimingValue = val;\r
-}\r
-\r
-/*!\r
- * rotationTiming getter\r
- * @param   void\r
- * @return  rotationTiming\r
- */\r
-LOG_ROTATION_TIMING_TAG StrictTimeBasedRollingPolicy::getRotationTiming()\r
-{\r
-       return rotationTiming;\r
-}\r
\r
-/*!\r
- * rotationTiming setter\r
- * @param   rotationTiming\r
- * @return  void\r
- */\r
-void StrictTimeBasedRollingPolicy::setRotationTiming(const LOG_ROTATION_TIMING_TAG val)\r
-{\r
-       rotationTiming = val;\r
-}\r
-\r
-/*!\r
- * option setter\r
- * @param   option name\r
- * @param   value\r
- * @return  void\r
- */\r
-void StrictTimeBasedRollingPolicy::setOption(const LogString& option, const LogString& value)\r
-{\r
-       if (StringHelper::equalsIgnoreCase(option,\r
-               LOG4CXX_STR("ROTATIONTIMINGVALUE"),\r
-               LOG4CXX_STR("rotationtimingvalue"))) {\r
-               rotationTimingValue = value;\r
-       }\r
-       else if (StringHelper::equalsIgnoreCase(option,\r
-               LOG4CXX_STR("ROTATIONTIMING"),\r
-               LOG4CXX_STR("rotationtiming"))) {\r
-               rotationTiming = (LOG_ROTATION_TIMING_TAG)OptionConverter::toInt(value, 0);\r
-       }\r
-       else {\r
-               FixedWindowRollingPolicy::setOption(option, value);\r
-       }\r
-}\r
-\r
-/*!\r
- * rolling policy initialize\r
- * @param   filename of current use\r
- * @param   append or overWrite\r
- * @param   memory pool\r
- * @return  Rollover information\r
- */\r
-RolloverDescriptionPtr StrictTimeBasedRollingPolicy::initialize(\r
-       const LogString& currentActiveFile,\r
-       const bool append,\r
-       Pool& pool) \r
-{\r
-       // get current time\r
-       time_t now_time;\r
-       time_t ret_time = time(&now_time);\r
-       if (-1 == ret_time) {\r
-               LogLog::warn(LOG4CXX_STR("Fail to get CurrentTime. "));\r
-               RolloverDescriptionPtr desc;\r
-               return desc;\r
-       }\r
-\r
-       // get next rotation timing\r
-       nextCheck = getNextCheck(now_time);\r
-       if (-1 == nextCheck) {\r
-               LogLog::warn(LOG4CXX_STR("Fail to get nextCheck. "));\r
-               RolloverDescriptionPtr desc;\r
-               return desc;\r
-       }       \r
-\r
-       // call super class's initialize\r
-       return FixedWindowRollingPolicy::initialize(currentActiveFile, append, pool);\r
-}\r
-\r
-/*!\r
- * calculate next rollover timing\r
- * @param   now time\r
- * @return  next rollover time\r
- */\r
-time_t StrictTimeBasedRollingPolicy::getNextCheck(time_t now_time)\r
-{\r
-       struct tm now_tm;\r
-       struct tm *ret_tm;\r
-       ret_tm = localtime_r(&now_time, &now_tm);\r
-       if (0 == ret_tm) {\r
-               return -1;\r
-       }\r
-       \r
-       char buf[TIME_BUF_LEN];\r
-       size_t ret_sz = 0;\r
-       if (LOG_TIM_WEEK == rotationTiming) {\r
-               ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT_WEEK, &now_tm);\r
-       }\r
-       else {\r
-               ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT, &now_tm);\r
-       }\r
-       if (0 == ret_sz) {\r
-               return -1;\r
-       }\r
-       std::string now(buf);\r
-\r
-       int dates[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; \r
-       unsigned long long numNowDate = 0;;\r
-       unsigned long long numTimingDate = 0;\r
-\r
-       int numYear = 0;\r
-       int numMonth = 0;\r
-       int numDate = 0;\r
-       int numNowWeek = 0;\r
-       int numTimingWeek = 0;\r
-       int numHour = 0;\r
-       int numMinute = 0;\r
-\r
-       struct tm t;\r
-       memset(&t, 0, sizeof(struct tm));\r
-\r
-       time_t next = 0;\r
-\r
-       try {\r
-               switch (rotationTiming) {\r
-               case LOG_TIM_YEAR:\r
-                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(4));\r
-                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);\r
-       \r
-                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));\r
-                       numMonth = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));\r
-                       numDate = l7vs::lexical_cast<int>(rotationTimingValue.substr(2, 2));\r
-                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(4, 2));\r
-                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(6));\r
-       \r
-                       if (numTimingDate > numNowDate) {\r
-                               t.tm_year = numYear - 1900;\r
-                       }\r
-                       else {\r
-                               t.tm_year = numYear + 1 - 1900;\r
-                       }\r
-                       t.tm_mon = numMonth - 1;\r
-                       t.tm_mday = numDate;\r
-                       t.tm_hour = numHour;\r
-                       t.tm_min = numMinute;\r
-       \r
-                       next = mktime(&t);\r
-                       if (-1 == next) {\r
-                               return -1;\r
-                       }\r
-                       break;\r
-       \r
-               case LOG_TIM_MONTH:\r
-                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(6));\r
-                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);\r
-       \r
-                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));\r
-                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));\r
-                       numDate = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));\r
-                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(2, 2));\r
-                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(4));\r
-       \r
-                       if (numTimingDate > numNowDate) {\r
-                               t.tm_year = numYear - 1900;\r
-                               t.tm_mon = numMonth - 1;\r
-                       }\r
-                       else {\r
-                               if (12 == numMonth) {\r
-                                       t.tm_year = numYear + 1 - 1900;\r
-                                       t.tm_mon = 0;\r
-                               }\r
-                               else {\r
-                                       t.tm_year = numYear - 1900;\r
-                                       t.tm_mon = numMonth + 1 - 1;\r
-                               }\r
-                       }\r
-       \r
-                       if (numDate > dates[t.tm_mon]) {\r
-                               t.tm_mday = dates[t.tm_mon];\r
-                       }\r
-                       else {\r
-                               t.tm_mday = numDate;\r
-                       }\r
-\r
-                       t.tm_hour = numHour;\r
-                       t.tm_min = numMinute;\r
-       \r
-                       next = mktime(&t);\r
-                       if (-1 == next) {\r
-                               return -1;\r
-                       }\r
-       \r
-                       break;\r
-               case LOG_TIM_WEEK:\r
-                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(8));\r
-                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);\r
-       \r
-                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));\r
-                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));\r
-                       numDate = l7vs::lexical_cast<int>(now.substr(6, 2));\r
-                       numNowWeek = l7vs::lexical_cast<int>(now.substr(8, 1));\r
-                       numTimingWeek = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 1));\r
-                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(1, 2));\r
-                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(3));\r
-       \r
-                       t.tm_year = numYear - 1900;\r
-                       t.tm_mon = numMonth - 1;\r
-                       if (numTimingDate > numNowDate) {       \r
-                               t.tm_mday = numDate + (numTimingWeek - numNowWeek); \r
-                       }\r
-                       else {\r
-                               t.tm_mday = numDate + (7 - (numNowWeek - numTimingWeek));\r
-                       }\r
-                       t.tm_hour = numHour;\r
-                       t.tm_min = numMinute;\r
-       \r
-                       next = mktime(&t);\r
-                       if (-1 == next) {\r
-                               return -1;\r
-                       }\r
-       \r
-                       break;\r
-       \r
-               case LOG_TIM_DATE:\r
-                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(8));\r
-                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);\r
-       \r
-                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));\r
-                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));\r
-                       numDate = l7vs::lexical_cast<int>(now.substr(6, 2));\r
-                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));\r
-                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(2));\r
-       \r
-                       t.tm_year = numYear - 1900;\r
-                       t.tm_mon = numMonth - 1;\r
-                       if (numTimingDate > numNowDate) {       \r
-                               t.tm_mday = numDate;\r
-                       }\r
-                       else {\r
-                               t.tm_mday = numDate + 1; \r
-                       }\r
-                       t.tm_hour = numHour;\r
-                       t.tm_min = numMinute;\r
-       \r
-                       next = mktime(&t);\r
-                       if (-1 == next) {\r
-                               return -1;\r
-                       }\r
-                       break;\r
-       \r
-               default:        //HOUR\r
-                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(10));\r
-                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);\r
-       \r
-                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));\r
-                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));\r
-                       numDate = l7vs::lexical_cast<int>(now.substr(6, 2));\r
-                       numHour = l7vs::lexical_cast<int>(now.substr(8, 2));\r
-                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue);\r
-       \r
-                       t.tm_year = numYear - 1900;\r
-                       t.tm_mon = numMonth - 1;\r
-                       t.tm_mday = numDate;\r
-                       if (numTimingDate > numNowDate) {\r
-                               t.tm_hour = numHour;\r
-                       }\r
-                       else {\r
-                               t.tm_hour = numHour + 1;\r
-                       }\r
-                       t.tm_min = numMinute;\r
-       \r
-                       next = mktime(&t);\r
-                       if (-1 == next) {\r
-                               return -1;\r
-                       }\r
-               }\r
-       }\r
-       catch (const std::exception& ex) {\r
-               return -1;\r
-       }\r
-       return next;\r
-\r
-}\r
-\r
-/*!\r
- * log file rollover opration\r
- * @param   name of current log file\r
- * @param   memory pool\r
- * @return  Rollover infomation\r
- */\r
-RolloverDescriptionPtr StrictTimeBasedRollingPolicy::rollover(\r
-       const LogString& currentActiveFile,\r
-       Pool& pool) \r
-{\r
-       // get current time\r
-       time_t now_time;\r
-       time_t ret_time = time(&now_time);\r
-       if (-1 == ret_time) {\r
-               LogLog::warn(LOG4CXX_STR("Fail to get CurrentTime. "));\r
-               RolloverDescriptionPtr desc;\r
-               return desc;\r
-       }\r
-\r
-       // get next rotation timing\r
-       nextCheck = getNextCheck(now_time);\r
-       if (-1 == nextCheck) {\r
-               LogLog::warn(LOG4CXX_STR("Fail to get nextCheck. "));\r
-               RolloverDescriptionPtr desc;\r
-               return desc;\r
-       }       \r
-\r
-       // call super class's rollover\r
-       return FixedWindowRollingPolicy::rollover(currentActiveFile, pool);\r
-\r
-}\r
-\r
-/*!\r
- * returns do rollover or not\r
- * @param   appender (not use)\r
- * @param   event (not use)\r
- * @param   filename\r
- * @param   fileLength (not use)\r
- * @retval  true do rollover\r
- * @retval  false not rollover yet\r
- */\r
-bool StrictTimeBasedRollingPolicy::isTriggeringEvent(\r
-       Appender* /* appender */,\r
-       const log4cxx::spi::LoggingEventPtr& /* event */,\r
-       const LogString& filename,\r
-       size_t /* fileLength */)  \r
-{\r
-       time_t now_time;\r
-       time_t ret_time = time(&now_time);\r
-       if (-1 == ret_time) {\r
-               LogLog::warn(LOG4CXX_STR("Fail to get time. "));\r
-               return false;\r
-       }\r
-       return now_time > nextCheck;\r
-}\r
+/*
+ * @file  strict_time_based_rolling_policy.cpp
+ * @brief log4cxx's rolling policy class. (time)
+ *
+ * L7VSD: Linux Virtual Server for Layer7 Load Balancing
+ * Copyright (C) 2008  NTT COMWARE Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *      
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ **********************************************************************/
+
+#include <log4cxx/logstring.h>
+#include <log4cxx/rolling/filerenameaction.h>
+#include <log4cxx/helpers/loglog.h>
+#include <log4cxx/helpers/exception.h>
+#include <log4cxx/helpers/stringhelper.h>
+#include <log4cxx/helpers/optionconverter.h>
+#include <time.h>
+#include "strict_time_based_rolling_policy.h"
+#include "lexical_cast.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+using namespace log4cxx;
+using namespace log4cxx::rolling;
+using namespace log4cxx::helpers;
+using namespace log4cxx::pattern;
+
+#define TIME_BUF_LEN (256)
+#define LOG_DATE_FORMAT "%Y%m%d%H%M"
+#define LOG_DATE_FORMAT_WEEK "%Y%m%d%w%H%M"
+
+IMPLEMENT_LOG4CXX_OBJECT(StrictTimeBasedRollingPolicy)
+
+/*!
+ * default constructor.
+ * initialize member valiables
+ * @param   void
+ * @return  void
+ */
+StrictTimeBasedRollingPolicy::StrictTimeBasedRollingPolicy() :
+       nextCheck(0), rotationTiming(LOG_TIM_YEAR), rotationTimingValue("")
+{
+}
+
+/*!
+ * increase reffernce count
+ * @param   void
+ * @return  void
+ */
+void StrictTimeBasedRollingPolicy::addRef() const
+{
+       TriggeringPolicy::addRef();
+}
+
+/*!
+ * decrease reffernce count
+ * @param   void
+ * @return  void
+ */
+void StrictTimeBasedRollingPolicy::releaseRef() const
+{
+       TriggeringPolicy::releaseRef();
+}
+
+/*!
+ * evaluate and activate options
+ * @param   memory pool
+ * @return  void
+ */
+void StrictTimeBasedRollingPolicy::activateOptions(log4cxx::helpers::Pool& pool)
+{
+       // check for rotationTimingValue
+       if (0 >= rotationTimingValue.length()) {
+               LogLog::warn(
+               LOG4CXX_STR("The RotationTimingValue option must be set before using StrictTimeBasedRollingPolicy. "));
+               throw IllegalStateException();
+       }
+
+       // call super class's activateOptions
+       FixedWindowRollingPolicy::activateOptions(pool);
+}
+
+/*!
+ * rotationTimingValue getter
+ * @param   void
+ * @return  rotationTimingValue
+ */
+std::string StrictTimeBasedRollingPolicy::getRotationTimingValue()
+{
+       return rotationTimingValue;
+}
+/*!
+ * rotationTimingValue setter
+ * @param   rotationTimingValue
+ * @return  void
+ */
+void StrictTimeBasedRollingPolicy::setRotationTimingValue(const std::string& val)
+{
+       rotationTimingValue = val;
+}
+
+/*!
+ * rotationTiming getter
+ * @param   void
+ * @return  rotationTiming
+ */
+LOG_ROTATION_TIMING_TAG StrictTimeBasedRollingPolicy::getRotationTiming()
+{
+       return rotationTiming;
+}
+/*!
+ * rotationTiming setter
+ * @param   rotationTiming
+ * @return  void
+ */
+void StrictTimeBasedRollingPolicy::setRotationTiming(const LOG_ROTATION_TIMING_TAG val)
+{
+       rotationTiming = val;
+}
+
+/*!
+ * option setter
+ * @param   option name
+ * @param   value
+ * @return  void
+ */
+void StrictTimeBasedRollingPolicy::setOption(const LogString& option, const LogString& value)
+{
+       if (StringHelper::equalsIgnoreCase(option,
+               LOG4CXX_STR("ROTATIONTIMINGVALUE"),
+               LOG4CXX_STR("rotationtimingvalue"))) {
+               rotationTimingValue = value;
+       }
+       else if (StringHelper::equalsIgnoreCase(option,
+               LOG4CXX_STR("ROTATIONTIMING"),
+               LOG4CXX_STR("rotationtiming"))) {
+               rotationTiming = (LOG_ROTATION_TIMING_TAG)OptionConverter::toInt(value, 0);
+       }
+       else {
+               FixedWindowRollingPolicy::setOption(option, value);
+       }
+}
+
+/*!
+ * rolling policy initialize
+ * @param   filename of current use
+ * @param   append or overWrite
+ * @param   memory pool
+ * @return  Rollover information
+ */
+RolloverDescriptionPtr StrictTimeBasedRollingPolicy::initialize(
+       const LogString& currentActiveFile,
+       const bool append,
+       Pool& pool) 
+{
+       // get current time
+       time_t now_time;
+       time_t ret_time = time(&now_time);
+       if (-1 == ret_time) {
+               LogLog::warn(LOG4CXX_STR("Fail to get CurrentTime. "));
+               RolloverDescriptionPtr desc;
+               return desc;
+       }
+
+       // get next rotation timing
+       nextCheck = getNextCheck(now_time);
+       if (-1 == nextCheck) {
+               LogLog::warn(LOG4CXX_STR("Fail to get nextCheck. "));
+               RolloverDescriptionPtr desc;
+               return desc;
+       }       
+
+       // call super class's initialize
+       return FixedWindowRollingPolicy::initialize(currentActiveFile, append, pool);
+}
+
+/*!
+ * calculate next rollover timing
+ * @param   now time
+ * @return  next rollover time
+ */
+time_t StrictTimeBasedRollingPolicy::getNextCheck(time_t now_time)
+{
+       struct tm now_tm;
+       struct tm *ret_tm;
+       ret_tm = localtime_r(&now_time, &now_tm);
+       if (0 == ret_tm) {
+               return -1;
+       }
+       
+       char buf[TIME_BUF_LEN];
+       size_t ret_sz = 0;
+       if (LOG_TIM_WEEK == rotationTiming) {
+               ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT_WEEK, &now_tm);
+       }
+       else {
+               ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT, &now_tm);
+       }
+       if (0 == ret_sz) {
+               return -1;
+       }
+       std::string now(buf);
+
+       int dates[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 
+       unsigned long long numNowDate = 0;;
+       unsigned long long numTimingDate = 0;
+
+       int numYear = 0;
+       int numMonth = 0;
+       int numDate = 0;
+       int numNowWeek = 0;
+       int numTimingWeek = 0;
+       int numHour = 0;
+       int numMinute = 0;
+
+       struct tm t;
+       memset(&t, 0, sizeof(struct tm));
+
+       time_t next = 0;
+
+       try {
+               switch (rotationTiming) {
+               case LOG_TIM_YEAR:
+                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(4));
+                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
+       
+                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
+                       numMonth = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));
+                       numDate = l7vs::lexical_cast<int>(rotationTimingValue.substr(2, 2));
+                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(4, 2));
+                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(6));
+       
+                       if (numTimingDate > numNowDate) {
+                               t.tm_year = numYear - 1900;
+                       }
+                       else {
+                               t.tm_year = numYear + 1 - 1900;
+                       }
+                       t.tm_mon = numMonth - 1;
+                       t.tm_mday = numDate;
+                       t.tm_hour = numHour;
+                       t.tm_min = numMinute;
+       
+                       next = mktime(&t);
+                       if (-1 == next) {
+                               return -1;
+                       }
+                       break;
+       
+               case LOG_TIM_MONTH:
+                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(6));
+                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
+       
+                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
+                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));
+                       numDate = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));
+                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(2, 2));
+                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(4));
+       
+                       if (numTimingDate > numNowDate) {
+                               t.tm_year = numYear - 1900;
+                               t.tm_mon = numMonth - 1;
+                       }
+                       else {
+                               if (12 == numMonth) {
+                                       t.tm_year = numYear + 1 - 1900;
+                                       t.tm_mon = 0;
+                               }
+                               else {
+                                       t.tm_year = numYear - 1900;
+                                       t.tm_mon = numMonth + 1 - 1;
+                               }
+                       }
+       
+                       if (numDate > dates[t.tm_mon]) {
+                               t.tm_mday = dates[t.tm_mon];
+                       }
+                       else {
+                               t.tm_mday = numDate;
+                       }
+
+                       t.tm_hour = numHour;
+                       t.tm_min = numMinute;
+       
+                       next = mktime(&t);
+                       if (-1 == next) {
+                               return -1;
+                       }
+       
+                       break;
+               case LOG_TIM_WEEK:
+                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(8));
+                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
+       
+                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
+                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));
+                       numDate = l7vs::lexical_cast<int>(now.substr(6, 2));
+                       numNowWeek = l7vs::lexical_cast<int>(now.substr(8, 1));
+                       numTimingWeek = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 1));
+                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(1, 2));
+                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(3));
+       
+                       t.tm_year = numYear - 1900;
+                       t.tm_mon = numMonth - 1;
+                       if (numTimingDate > numNowDate) {       
+                               t.tm_mday = numDate + (numTimingWeek - numNowWeek); 
+                       }
+                       else {
+                               t.tm_mday = numDate + (7 - (numNowWeek - numTimingWeek));
+                       }
+                       t.tm_hour = numHour;
+                       t.tm_min = numMinute;
+       
+                       next = mktime(&t);
+                       if (-1 == next) {
+                               return -1;
+                       }
+       
+                       break;
+       
+               case LOG_TIM_DATE:
+                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(8));
+                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
+       
+                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
+                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));
+                       numDate = l7vs::lexical_cast<int>(now.substr(6, 2));
+                       numHour = l7vs::lexical_cast<int>(rotationTimingValue.substr(0, 2));
+                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue.substr(2));
+       
+                       t.tm_year = numYear - 1900;
+                       t.tm_mon = numMonth - 1;
+                       if (numTimingDate > numNowDate) {       
+                               t.tm_mday = numDate;
+                       }
+                       else {
+                               t.tm_mday = numDate + 1; 
+                       }
+                       t.tm_hour = numHour;
+                       t.tm_min = numMinute;
+       
+                       next = mktime(&t);
+                       if (-1 == next) {
+                               return -1;
+                       }
+                       break;
+       
+               default:        //HOUR
+                       numNowDate = l7vs::lexical_cast<unsigned long long>(now.substr(10));
+                       numTimingDate = l7vs::lexical_cast<unsigned long long>(rotationTimingValue);
+       
+                       numYear = l7vs::lexical_cast<int>(now.substr(0, 4));
+                       numMonth = l7vs::lexical_cast<int>(now.substr(4, 2));
+                       numDate = l7vs::lexical_cast<int>(now.substr(6, 2));
+                       numHour = l7vs::lexical_cast<int>(now.substr(8, 2));
+                       numMinute = l7vs::lexical_cast<int>(rotationTimingValue);
+       
+                       t.tm_year = numYear - 1900;
+                       t.tm_mon = numMonth - 1;
+                       t.tm_mday = numDate;
+                       if (numTimingDate > numNowDate) {
+                               t.tm_hour = numHour;
+                       }
+                       else {
+                               t.tm_hour = numHour + 1;
+                       }
+                       t.tm_min = numMinute;
+       
+                       next = mktime(&t);
+                       if (-1 == next) {
+                               return -1;
+                       }
+               }
+       }
+       catch (const std::exception& ex) {
+               return -1;
+       }
+       return next;
+
+}
+
+/*!
+ * log file rollover opration
+ * @param   name of current log file
+ * @param   memory pool
+ * @return  Rollover infomation
+ */
+RolloverDescriptionPtr StrictTimeBasedRollingPolicy::rollover(
+       const LogString& currentActiveFile,
+       Pool& pool) 
+{
+       // get current time
+       time_t now_time;
+       time_t ret_time = time(&now_time);
+       if (-1 == ret_time) {
+               LogLog::warn(LOG4CXX_STR("Fail to get CurrentTime. "));
+               RolloverDescriptionPtr desc;
+               return desc;
+       }
+
+       // get next rotation timing
+       nextCheck = getNextCheck(now_time);
+       if (-1 == nextCheck) {
+               LogLog::warn(LOG4CXX_STR("Fail to get nextCheck. "));
+               RolloverDescriptionPtr desc;
+               return desc;
+       }       
+
+       // call super class's rollover
+       return FixedWindowRollingPolicy::rollover(currentActiveFile, pool);
+
+}
+
+/*!
+ * returns do rollover or not
+ * @param   appender (not use)
+ * @param   event (not use)
+ * @param   filename
+ * @param   fileLength (not use)
+ * @retval  true do rollover
+ * @retval  false not rollover yet
+ */
+bool StrictTimeBasedRollingPolicy::isTriggeringEvent(
+       Appender* /* appender */,
+       const log4cxx::spi::LoggingEventPtr& /* event */,
+       const LogString& filename,
+       size_t /* fileLength */)  
+{
+       time_t now_time;
+       time_t ret_time = time(&now_time);
+       if (-1 == ret_time) {
+               LogLog::warn(LOG4CXX_STR("Fail to get time. "));
+               return false;
+       }
+       return now_time > nextCheck;
+}