OSDN Git Service

loggerをsslproxy版と統合。ログカテゴリの見直し。parameterでの呼出関数を廃止。parameterのイベント登録関数を追加
[ultramonkey-l7/ultramonkey-l7-v3.git] / logger / strict_time_based_rolling_policy.cpp
1 /*\r
2  * @file  strict_time_based_rolling_policy.cpp\r
3  * @brief log4cxx's rolling policy class. (time)\r
4  *\r
5  * L7VSD: Linux Virtual Server for Layer7 Load Balancing\r
6  * Copyright (C) 2008  NTT COMWARE Corporation.\r
7  *\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
12  *\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
17  *      \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
21  * 02110-1301 USA\r
22  *\r
23  **********************************************************************/\r
24 \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
31 #include <time.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
36 #include <unistd.h>\r
37 \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
43 \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
47 \r
48 IMPLEMENT_LOG4CXX_OBJECT(StrictTimeBasedRollingPolicy)\r
49 \r
50 /*!\r
51  * default constructor.\r
52  * initialize member valiables\r
53  * @param   void\r
54  * @return  void\r
55  */\r
56 StrictTimeBasedRollingPolicy::StrictTimeBasedRollingPolicy() :\r
57         nextCheck(0), rotationTiming(LOG_TIM_YEAR), rotationTimingValue("")\r
58 {\r
59 }\r
60 \r
61 /*!\r
62  * increase reffernce count\r
63  * @param   void\r
64  * @return  void\r
65  */\r
66 void StrictTimeBasedRollingPolicy::addRef() const\r
67 {\r
68         TriggeringPolicy::addRef();\r
69 }\r
70 \r
71 /*!\r
72  * decrease reffernce count\r
73  * @param   void\r
74  * @return  void\r
75  */\r
76 void StrictTimeBasedRollingPolicy::releaseRef() const\r
77 {\r
78         TriggeringPolicy::releaseRef();\r
79 }\r
80 \r
81 /*!\r
82  * evaluate and activate options\r
83  * @param   memory pool\r
84  * @return  void\r
85  */\r
86 void StrictTimeBasedRollingPolicy::activateOptions(log4cxx::helpers::Pool& pool)\r
87 {\r
88         // check for rotationTimingValue\r
89         if (0 >= rotationTimingValue.length()) {\r
90                 LogLog::warn(\r
91                 LOG4CXX_STR("The RotationTimingValue option must be set before using StrictTimeBasedRollingPolicy. "));\r
92                 throw IllegalStateException();\r
93         }\r
94 \r
95         // call super class's activateOptions\r
96         FixedWindowRollingPolicy::activateOptions(pool);\r
97 }\r
98 \r
99 /*!\r
100  * rotationTimingValue getter\r
101  * @param   void\r
102  * @return  rotationTimingValue\r
103  */\r
104 std::string StrictTimeBasedRollingPolicy::getRotationTimingValue()\r
105 {\r
106         return rotationTimingValue;\r
107 }\r
108  \r
109 /*!\r
110  * rotationTimingValue setter\r
111  * @param   rotationTimingValue\r
112  * @return  void\r
113  */\r
114 void StrictTimeBasedRollingPolicy::setRotationTimingValue(const std::string& val)\r
115 {\r
116         rotationTimingValue = val;\r
117 }\r
118 \r
119 /*!\r
120  * rotationTiming getter\r
121  * @param   void\r
122  * @return  rotationTiming\r
123  */\r
124 LOG_ROTATION_TIMING_TAG StrictTimeBasedRollingPolicy::getRotationTiming()\r
125 {\r
126         return rotationTiming;\r
127 }\r
128  \r
129 /*!\r
130  * rotationTiming setter\r
131  * @param   rotationTiming\r
132  * @return  void\r
133  */\r
134 void StrictTimeBasedRollingPolicy::setRotationTiming(const LOG_ROTATION_TIMING_TAG val)\r
135 {\r
136         rotationTiming = val;\r
137 }\r
138 \r
139 /*!\r
140  * option setter\r
141  * @param   option name\r
142  * @param   value\r
143  * @return  void\r
144  */\r
145 void StrictTimeBasedRollingPolicy::setOption(const LogString& option, const LogString& value)\r
146 {\r
147         if (StringHelper::equalsIgnoreCase(option,\r
148                 LOG4CXX_STR("ROTATIONTIMINGVALUE"),\r
149                 LOG4CXX_STR("rotationtimingvalue"))) {\r
150                 rotationTimingValue = value;\r
151         }\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
156         }\r
157         else {\r
158                 FixedWindowRollingPolicy::setOption(option, value);\r
159         }\r
160 }\r
161 \r
162 /*!\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
168  */\r
169 RolloverDescriptionPtr StrictTimeBasedRollingPolicy::initialize(\r
170         const LogString& currentActiveFile,\r
171         const bool append,\r
172         Pool& pool) \r
173 {\r
174         // get current time\r
175         time_t now_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
180                 return desc;\r
181         }\r
182 \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
188                 return desc;\r
189         }       \r
190 \r
191         // call super class's initialize\r
192         return FixedWindowRollingPolicy::initialize(currentActiveFile, append, pool);\r
193 }\r
194 \r
195 /*!\r
196  * calculate next rollover timing\r
197  * @param   now time\r
198  * @return  next rollover time\r
199  */\r
200 time_t StrictTimeBasedRollingPolicy::getNextCheck(time_t now_time)\r
201 {\r
202         struct tm now_tm;\r
203         struct tm *ret_tm;\r
204         ret_tm = localtime_r(&now_time, &now_tm);\r
205         if (0 == ret_tm) {\r
206                 return -1;\r
207         }\r
208         \r
209         char buf[TIME_BUF_LEN];\r
210         size_t ret_sz = 0;\r
211         if (LOG_TIM_WEEK == rotationTiming) {\r
212                 ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT_WEEK, &now_tm);\r
213         }\r
214         else {\r
215                 ret_sz = strftime(buf, sizeof(buf), LOG_DATE_FORMAT, &now_tm);\r
216         }\r
217         if (0 == ret_sz) {\r
218                 return -1;\r
219         }\r
220         std::string now(buf);\r
221 \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
225 \r
226         int numYear = 0;\r
227         int numMonth = 0;\r
228         int numDate = 0;\r
229         int numNowWeek = 0;\r
230         int numTimingWeek = 0;\r
231         int numHour = 0;\r
232         int numMinute = 0;\r
233 \r
234         struct tm t;\r
235         memset(&t, 0, sizeof(struct tm));\r
236 \r
237         time_t next = 0;\r
238 \r
239         try {\r
240                 switch (rotationTiming) {\r
241                 case LOG_TIM_YEAR:\r
242                         numNowDate = boost::lexical_cast<unsigned long long>(now.substr(4));\r
243                         numTimingDate = boost::lexical_cast<unsigned long long>(rotationTimingValue);\r
244         \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
250         \r
251                         if (numTimingDate > numNowDate) {\r
252                                 t.tm_year = numYear - 1900;\r
253                         }\r
254                         else {\r
255                                 t.tm_year = numYear + 1 - 1900;\r
256                         }\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
261         \r
262                         next = mktime(&t);\r
263                         if (-1 == next) {\r
264                                 return -1;\r
265                         }\r
266                         break;\r
267         \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
271         \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
277         \r
278                         if (numTimingDate > numNowDate) {\r
279                                 t.tm_year = numYear - 1900;\r
280                                 t.tm_mon = numMonth - 1;\r
281                         }\r
282                         else {\r
283                                 if (12 == numMonth) {\r
284                                         t.tm_year = numYear + 1 - 1900;\r
285                                         t.tm_mon = 0;\r
286                                 }\r
287                                 else {\r
288                                         t.tm_year = numYear - 1900;\r
289                                         t.tm_mon = numMonth + 1 - 1;\r
290                                 }\r
291                         }\r
292         \r
293                         if (numDate > dates[t.tm_mon]) {\r
294                                 t.tm_mday = dates[t.tm_mon];\r
295                         }\r
296                         else {\r
297                                 t.tm_mday = numDate;\r
298                         }\r
299 \r
300                         t.tm_hour = numHour;\r
301                         t.tm_min = numMinute;\r
302         \r
303                         next = mktime(&t);\r
304                         if (-1 == next) {\r
305                                 return -1;\r
306                         }\r
307         \r
308                         break;\r
309                 case LOG_TIM_WEEK:\r
310                         numNowDate = boost::lexical_cast<unsigned long long>(now.substr(8));\r
311                         numTimingDate = boost::lexical_cast<unsigned long long>(rotationTimingValue);\r
312         \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
320         \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
325                         }\r
326                         else {\r
327                                 t.tm_mday = numDate + (7 - (numNowWeek - numTimingWeek));\r
328                         }\r
329                         t.tm_hour = numHour;\r
330                         t.tm_min = numMinute;\r
331         \r
332                         next = mktime(&t);\r
333                         if (-1 == next) {\r
334                                 return -1;\r
335                         }\r
336         \r
337                         break;\r
338         \r
339                 case LOG_TIM_DATE:\r
340                         numNowDate = boost::lexical_cast<unsigned long long>(now.substr(8));\r
341                         numTimingDate = boost::lexical_cast<unsigned long long>(rotationTimingValue);\r
342         \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
348         \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
353                         }\r
354                         else {\r
355                                 t.tm_mday = numDate + 1; \r
356                         }\r
357                         t.tm_hour = numHour;\r
358                         t.tm_min = numMinute;\r
359         \r
360                         next = mktime(&t);\r
361                         if (-1 == next) {\r
362                                 return -1;\r
363                         }\r
364                         break;\r
365         \r
366                 default:        //HOUR\r
367                         numNowDate = boost::lexical_cast<unsigned long long>(now.substr(10));\r
368                         numTimingDate = boost::lexical_cast<unsigned long long>(rotationTimingValue);\r
369         \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
375         \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
381                         }\r
382                         else {\r
383                                 t.tm_hour = numHour + 1;\r
384                         }\r
385                         t.tm_min = numMinute;\r
386         \r
387                         next = mktime(&t);\r
388                         if (-1 == next) {\r
389                                 return -1;\r
390                         }\r
391                 }\r
392         }\r
393         catch (const std::exception& ex) {\r
394                 return -1;\r
395         }\r
396         return next;\r
397 \r
398 }\r
399 \r
400 /*!\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
405  */\r
406 RolloverDescriptionPtr StrictTimeBasedRollingPolicy::rollover(\r
407         const LogString& currentActiveFile,\r
408         Pool& pool) \r
409 {\r
410         // get current time\r
411         time_t now_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
416                 return desc;\r
417         }\r
418 \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
424                 return desc;\r
425         }       \r
426 \r
427         // call super class's rollover\r
428         return FixedWindowRollingPolicy::rollover(currentActiveFile, pool);\r
429 \r
430 }\r
431 \r
432 /*!\r
433  * returns do rollover or not\r
434  * @param   appender (not use)\r
435  * @param   event (not use)\r
436  * @param   filename\r
437  * @param   fileLength (not use)\r
438  * @retval  true do rollover\r
439  * @retval  false not rollover yet\r
440  */\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
446 {\r
447         time_t now_time;\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
451                 return false;\r
452         }\r
453         return now_time > nextCheck;\r
454 }\r