/src/logging-log4cxx/src/main/cpp/timebasedrollingpolicy.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
3 | | * contributor license agreements. See the NOTICE file distributed with |
4 | | * this work for additional information regarding copyright ownership. |
5 | | * The ASF licenses this file to You under the Apache License, Version 2.0 |
6 | | * (the "License"); you may not use this file except in compliance with |
7 | | * the License. You may obtain a copy of the License at |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | */ |
17 | | #define NOMINMAX /* tell windows to not define min/max macros */ |
18 | | #include <log4cxx/log4cxx.h> |
19 | | #include <log4cxx/logstring.h> |
20 | | #include <log4cxx/rolling/timebasedrollingpolicy.h> |
21 | | #include <log4cxx/pattern/filedatepatternconverter.h> |
22 | | #include <log4cxx/helpers/date.h> |
23 | | #include <log4cxx/rolling/filerenameaction.h> |
24 | | #include <log4cxx/helpers/loglog.h> |
25 | | #include <log4cxx/helpers/exception.h> |
26 | | #include <log4cxx/rolling/gzcompressaction.h> |
27 | | #include <log4cxx/rolling/zipcompressaction.h> |
28 | | #include <log4cxx/helpers/stringhelper.h> |
29 | | #include <log4cxx/helpers/optionconverter.h> |
30 | | #include <log4cxx/helpers/transcoder.h> |
31 | | #include <log4cxx/fileappender.h> |
32 | | #include <iostream> |
33 | | #include <apr_mmap.h> |
34 | | |
35 | | using namespace LOG4CXX_NS; |
36 | | using namespace LOG4CXX_NS::rolling; |
37 | | using namespace LOG4CXX_NS::helpers; |
38 | | using namespace LOG4CXX_NS::pattern; |
39 | | |
40 | | IMPLEMENT_LOG4CXX_OBJECT(TimeBasedRollingPolicy) |
41 | | |
42 | | struct TimeBasedRollingPolicy::TimeBasedRollingPolicyPrivate{ |
43 | | #if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER |
44 | | TimeBasedRollingPolicyPrivate() : |
45 | | _mmap(nullptr), |
46 | | _file_map(nullptr), |
47 | | _lock_file(nullptr), |
48 | | bAlreadyInitialized(false), |
49 | | bRefreshCurFile(false){} |
50 | | #else |
51 | 0 | TimeBasedRollingPolicyPrivate(){} |
52 | | #endif |
53 | | |
54 | | /** |
55 | | * Time for next determination if time for rollover. |
56 | | */ |
57 | | log4cxx_time_t nextCheck; |
58 | | |
59 | | /** |
60 | | * File name at last rollover. |
61 | | */ |
62 | | LogString lastFileName; |
63 | | |
64 | | /** |
65 | | * Length of any file type suffix (.gz, .zip). |
66 | | */ |
67 | | int suffixLength; |
68 | | |
69 | | /** |
70 | | * mmap pointer |
71 | | */ |
72 | | apr_mmap_t* _mmap; |
73 | | |
74 | | /* |
75 | | * pool for mmap handler |
76 | | * */ |
77 | | LOG4CXX_NS::helpers::Pool _mmapPool; |
78 | | |
79 | | /** |
80 | | * mmap file descriptor |
81 | | */ |
82 | | apr_file_t* _file_map; |
83 | | |
84 | | /** |
85 | | * mmap file name |
86 | | */ |
87 | | std::string _mapFileName; |
88 | | |
89 | | /* |
90 | | * lock file handle |
91 | | * */ |
92 | | apr_file_t* _lock_file; |
93 | | |
94 | | /** |
95 | | * Check nextCheck if it has already been set |
96 | | * Timebased rolling policy has an issue when working at low rps. |
97 | | * Under low rps, multiple processes will not be scheduled in time for the second chance(do rolling), |
98 | | * so the rolling mechanism will not be triggered even if the time period is out of date. |
99 | | * This results in log entries will be accumulated for serveral minutes to be rolling. |
100 | | * Adding this flag to provide rolling opportunity for a process even if it is writing the first log entry |
101 | | */ |
102 | | bool bAlreadyInitialized; |
103 | | |
104 | | /* |
105 | | * If the current file name contains date information, retrieve the current writting file from mmap |
106 | | * */ |
107 | | bool bRefreshCurFile; |
108 | | |
109 | | /* |
110 | | * mmap file name |
111 | | * */ |
112 | | LogString _fileNamePattern; |
113 | | |
114 | | bool multiprocess = false; |
115 | | bool throwIOExceptionOnForkFailure = true; |
116 | | }; |
117 | | |
118 | | |
119 | | #define MMAP_FILE_SUFFIX ".map" |
120 | | #define LOCK_FILE_SUFFIX ".maplck" |
121 | | #define MAX_FILE_LEN 2048 |
122 | | |
123 | | #if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER |
124 | | bool TimeBasedRollingPolicy::isMapFileEmpty(LOG4CXX_NS::helpers::Pool& pool) |
125 | | { |
126 | | apr_finfo_t finfo; |
127 | | apr_status_t st = apr_stat(&finfo, m_priv->_mapFileName.c_str(), APR_FINFO_SIZE, pool.getAPRPool()); |
128 | | |
129 | | if (st != APR_SUCCESS) |
130 | | { |
131 | | LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_stat"), st)); |
132 | | } |
133 | | |
134 | | if (st == APR_SUCCESS && (0 == finfo.size || |
135 | | (m_priv->_mmap && 0 == *static_cast<logchar*>(m_priv->_mmap->mm)))) |
136 | | { |
137 | | return true; |
138 | | } |
139 | | |
140 | | return false; |
141 | | } |
142 | | |
143 | | void TimeBasedRollingPolicy::initMMapFile(const LogString& lastFileName, LOG4CXX_NS::helpers::Pool& pool) |
144 | | { |
145 | | int iRet = 0; |
146 | | |
147 | | if (!m_priv->_mmap) |
148 | | { |
149 | | LOG4CXX_ENCODE_CHAR(mapFile, m_priv->_fileNamePattern); |
150 | | iRet = createMMapFile(mapFile, pool); |
151 | | } |
152 | | |
153 | | if (!iRet && isMapFileEmpty(pool)) |
154 | | { |
155 | | lockMMapFile(APR_FLOCK_EXCLUSIVE); |
156 | | memset(m_priv->_mmap->mm, 0, MAX_FILE_LEN); |
157 | | size_t byteCount = sizeof (logchar) * lastFileName.size(); |
158 | | if (byteCount <= MAX_FILE_LEN - sizeof (logchar)) |
159 | | memcpy(m_priv->_mmap->mm, lastFileName.c_str(), byteCount); |
160 | | unLockMMapFile(); |
161 | | } |
162 | | } |
163 | | |
164 | | const std::string TimeBasedRollingPolicy::createFile(const std::string& fileName, const std::string& suffix, LOG4CXX_NS::helpers::Pool& pool) |
165 | | { |
166 | | char szUid[MAX_FILE_LEN] = "0000"; |
167 | | #ifndef _WIN32 // The uid provided by the Windows version of apr_uid_current is not a constant value |
168 | | apr_uid_t uid; |
169 | | apr_gid_t groupid; |
170 | | if (APR_SUCCESS == apr_uid_current(&uid, &groupid, pool.getAPRPool())) |
171 | | snprintf(szUid, MAX_FILE_LEN, "%u", uid); |
172 | | #endif |
173 | | return fileName + szUid + suffix; |
174 | | } |
175 | | |
176 | | int TimeBasedRollingPolicy::createMMapFile(const std::string& fileName, LOG4CXX_NS::helpers::Pool& pool) |
177 | | { |
178 | | m_priv->_mapFileName = createFile(fileName, MMAP_FILE_SUFFIX, pool); |
179 | | |
180 | | apr_status_t stat = apr_file_open(&m_priv->_file_map, m_priv->_mapFileName.c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, m_priv->_mmapPool.getAPRPool()); |
181 | | |
182 | | if (stat != APR_SUCCESS) |
183 | | { |
184 | | LogString msg = helpers::Exception::makeMessage(LOG4CXX_STR("apr_file_open"), stat); |
185 | | msg += LOG4CXX_STR(". Check the privilege or try to remove ["); |
186 | | helpers::Transcoder::decode(m_priv->_mapFileName, msg); |
187 | | msg += LOG4CXX_STR("] if it exists."); |
188 | | LogLog::warn(msg); |
189 | | return -1; |
190 | | } |
191 | | |
192 | | if (isMapFileEmpty(pool)) |
193 | | { |
194 | | stat = apr_file_trunc(m_priv->_file_map, MAX_FILE_LEN + 1); |
195 | | |
196 | | if (stat != APR_SUCCESS) |
197 | | { |
198 | | LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_file_trunc"), stat)); |
199 | | apr_file_close(m_priv->_file_map); |
200 | | return -1; |
201 | | } |
202 | | } |
203 | | |
204 | | stat = apr_mmap_create(&m_priv->_mmap, m_priv->_file_map, 0, MAX_FILE_LEN, APR_MMAP_WRITE | APR_MMAP_READ, m_priv->_mmapPool.getAPRPool()); |
205 | | |
206 | | if (stat != APR_SUCCESS) |
207 | | { |
208 | | LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_mmap_create"), stat)); |
209 | | apr_file_close(m_priv->_file_map); |
210 | | return -1; |
211 | | } |
212 | | |
213 | | return 0; |
214 | | } |
215 | | |
216 | | int TimeBasedRollingPolicy::lockMMapFile(int type) |
217 | | { |
218 | | apr_status_t stat = apr_file_lock(m_priv->_lock_file, type); |
219 | | |
220 | | if (stat != APR_SUCCESS) |
221 | | { |
222 | | LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_file_lock for mmap"), stat)); |
223 | | } |
224 | | |
225 | | return stat; |
226 | | } |
227 | | |
228 | | int TimeBasedRollingPolicy::unLockMMapFile() |
229 | | { |
230 | | apr_status_t stat = apr_file_unlock(m_priv->_lock_file); |
231 | | |
232 | | if (stat != APR_SUCCESS) |
233 | | { |
234 | | LogLog::warn(helpers::Exception::makeMessage(LOG4CXX_STR("apr_file_unlock for mmap"), stat)); |
235 | | } |
236 | | |
237 | | return stat; |
238 | | } |
239 | | #else |
240 | 0 | int TimeBasedRollingPolicy::createMMapFile(const std::string&, LOG4CXX_NS::helpers::Pool&) { |
241 | 0 | return 0; |
242 | 0 | } |
243 | | |
244 | 0 | bool TimeBasedRollingPolicy::isMapFileEmpty(LOG4CXX_NS::helpers::Pool&){ |
245 | 0 | return true; |
246 | 0 | } |
247 | | |
248 | 0 | void TimeBasedRollingPolicy::initMMapFile(const LogString&, LOG4CXX_NS::helpers::Pool&){} |
249 | | |
250 | 0 | int TimeBasedRollingPolicy::lockMMapFile(int){ |
251 | 0 | return 0; |
252 | 0 | } |
253 | | |
254 | 0 | int TimeBasedRollingPolicy::unLockMMapFile(){ |
255 | 0 | return 0; |
256 | 0 | } |
257 | | |
258 | 0 | const std::string TimeBasedRollingPolicy::createFile(const std::string&, const std::string&, LOG4CXX_NS::helpers::Pool&){ |
259 | 0 | return ""; |
260 | 0 | } |
261 | | #endif |
262 | | |
263 | | TimeBasedRollingPolicy::TimeBasedRollingPolicy() : |
264 | 0 | m_priv(std::make_unique<TimeBasedRollingPolicyPrivate>()) |
265 | 0 | { |
266 | 0 | } Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::TimeBasedRollingPolicy() Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::TimeBasedRollingPolicy() |
267 | | |
268 | 0 | TimeBasedRollingPolicy::~TimeBasedRollingPolicy(){} |
269 | | |
270 | | void TimeBasedRollingPolicy::activateOptions(LOG4CXX_NS::helpers::Pool& pool) |
271 | 0 | { |
272 | | // find out period from the filename pattern |
273 | 0 | if (getFileNamePattern().length() > 0) |
274 | 0 | { |
275 | 0 | parseFileNamePattern(); |
276 | 0 | } |
277 | 0 | else |
278 | 0 | { |
279 | 0 | LogLog::warn( |
280 | 0 | LOG4CXX_STR("The FileNamePattern option must be set before using TimeBasedRollingPolicy. ")); |
281 | 0 | throw IllegalStateException(); |
282 | 0 | } |
283 | | |
284 | 0 | PatternConverterPtr dtc(getDatePatternConverter()); |
285 | |
|
286 | 0 | if (dtc == NULL) |
287 | 0 | { |
288 | 0 | throw NullPointerException(LOG4CXX_STR("DatePatternConverter")); |
289 | 0 | } |
290 | | |
291 | 0 | LogString buf; |
292 | 0 | ObjectPtr obj = std::make_shared<Date>(); |
293 | 0 | formatFileName(obj, buf, pool); |
294 | 0 | m_priv->lastFileName = buf; |
295 | |
|
296 | 0 | m_priv->suffixLength = 0; |
297 | |
|
298 | 0 | if (m_priv->lastFileName.length() >= 3) |
299 | 0 | { |
300 | 0 | if (m_priv->lastFileName.compare(m_priv->lastFileName.length() - 3, 3, LOG4CXX_STR(".gz")) == 0) |
301 | 0 | { |
302 | 0 | m_priv->suffixLength = 3; |
303 | 0 | } |
304 | 0 | else if (m_priv->lastFileName.length() >= 4 && m_priv->lastFileName.compare(m_priv->lastFileName.length() - 4, 4, LOG4CXX_STR(".zip")) == 0) |
305 | 0 | { |
306 | 0 | m_priv->suffixLength = 4; |
307 | 0 | } |
308 | 0 | } |
309 | 0 | } |
310 | | |
311 | | |
312 | | #define RULES_PUT(spec, cls) \ |
313 | 0 | specs.insert(PatternMap::value_type(LogString(LOG4CXX_STR(spec)), (PatternConstructor) cls ::newInstance)) |
314 | | |
315 | | LOG4CXX_NS::pattern::PatternMap TimeBasedRollingPolicy::getFormatSpecifiers() const |
316 | 0 | { |
317 | 0 | PatternMap specs; |
318 | 0 | RULES_PUT("d", FileDatePatternConverter); |
319 | 0 | RULES_PUT("date", FileDatePatternConverter); |
320 | 0 | return specs; |
321 | 0 | } |
322 | | |
323 | | /** |
324 | | * {@inheritDoc} |
325 | | */ |
326 | | RolloverDescriptionPtr TimeBasedRollingPolicy::initialize( |
327 | | const LogString& currentActiveFile, |
328 | | const bool append, |
329 | | Pool& pool) |
330 | 0 | { |
331 | 0 | Date now; |
332 | 0 | log4cxx_time_t n = now.getTime(); |
333 | 0 | m_priv->nextCheck = now.getNextSecond(); |
334 | |
|
335 | 0 | File currentFile(currentActiveFile); |
336 | |
|
337 | 0 | LogString buf; |
338 | 0 | ObjectPtr obj = std::make_shared<Date>(currentFile.exists(pool) ? currentFile.lastModified(pool) : n); |
339 | 0 | formatFileName(obj, buf, pool); |
340 | 0 | m_priv->lastFileName = buf; |
341 | |
|
342 | 0 | ActionPtr noAction; |
343 | |
|
344 | 0 | if (currentActiveFile.length() > 0) |
345 | 0 | { |
346 | 0 | return std::make_shared<RolloverDescription>( |
347 | 0 | currentActiveFile, append, noAction, noAction); |
348 | 0 | } |
349 | 0 | else |
350 | 0 | { |
351 | 0 | m_priv->bRefreshCurFile = true; |
352 | 0 | return std::make_shared<RolloverDescription>( |
353 | 0 | m_priv->lastFileName.substr(0, m_priv->lastFileName.length() - m_priv->suffixLength), append, |
354 | 0 | noAction, noAction); |
355 | 0 | } |
356 | 0 | } |
357 | | |
358 | | RolloverDescriptionPtr TimeBasedRollingPolicy::rollover( |
359 | | const LogString& currentActiveFile, |
360 | | const bool append, |
361 | | Pool& pool) |
362 | 0 | { |
363 | 0 | Date now; |
364 | 0 | log4cxx_time_t n = now.getTime(); |
365 | 0 | m_priv->nextCheck = now.getNextSecond(); |
366 | |
|
367 | 0 | LogString buf; |
368 | 0 | ObjectPtr obj = std::make_shared<Date>(n); |
369 | 0 | formatFileName(obj, buf, pool); |
370 | |
|
371 | 0 | LogString newFileName(buf); |
372 | |
|
373 | 0 | if( m_priv->multiprocess ){ |
374 | | #if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER |
375 | | |
376 | | if (!m_priv->bAlreadyInitialized) |
377 | | { |
378 | | if (getPatternConverterList().size()) |
379 | | { |
380 | | (*(getPatternConverterList().begin()))->format(obj, m_priv->_fileNamePattern, pool); |
381 | | } |
382 | | else |
383 | | { |
384 | | m_priv->_fileNamePattern = m_priv->lastFileName; |
385 | | } |
386 | | |
387 | | if (!m_priv->_lock_file) |
388 | | { |
389 | | LOG4CXX_ENCODE_CHAR(mapFile, m_priv->_fileNamePattern); |
390 | | const std::string lockname = createFile(mapFile, LOCK_FILE_SUFFIX, m_priv->_mmapPool); |
391 | | apr_status_t stat = apr_file_open(&m_priv->_lock_file, lockname.c_str(), APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, m_priv->_mmapPool.getAPRPool()); |
392 | | |
393 | | if (stat != APR_SUCCESS) |
394 | | { |
395 | | LOG4CXX_DECODE_CHAR(msg, lockname); |
396 | | msg += LOG4CXX_STR(": apr_file_open"); |
397 | | LogLog::warn(helpers::Exception::makeMessage(msg, stat)); |
398 | | } |
399 | | } |
400 | | |
401 | | initMMapFile(m_priv->lastFileName, m_priv->_mmapPool); |
402 | | } |
403 | | m_priv->bAlreadyInitialized = true; |
404 | | |
405 | | if (m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool)) |
406 | | { |
407 | | lockMMapFile(APR_FLOCK_SHARED); |
408 | | LogString mapLastFile(static_cast<logchar*>(m_priv->_mmap->mm)); |
409 | | m_priv->lastFileName = mapLastFile; |
410 | | unLockMMapFile(); |
411 | | } |
412 | | else |
413 | | { |
414 | | m_priv->_mmap = NULL; |
415 | | initMMapFile(m_priv->lastFileName, m_priv->_mmapPool); |
416 | | } |
417 | | #endif |
418 | 0 | } |
419 | | |
420 | | // |
421 | | // if file names haven't changed, no rollover |
422 | | // |
423 | 0 | if (newFileName == m_priv->lastFileName) |
424 | 0 | { |
425 | 0 | RolloverDescriptionPtr desc; |
426 | 0 | return desc; |
427 | 0 | } |
428 | | |
429 | 0 | ActionPtr renameAction; |
430 | 0 | ActionPtr compressAction; |
431 | 0 | LogString lastBaseName( |
432 | 0 | m_priv->lastFileName.substr(0, m_priv->lastFileName.length() - m_priv->suffixLength)); |
433 | 0 | LogString nextActiveFile( |
434 | 0 | newFileName.substr(0, newFileName.length() - m_priv->suffixLength)); |
435 | |
|
436 | 0 | if(getCreateIntermediateDirectories()){ |
437 | 0 | File compressedFile(m_priv->lastFileName); |
438 | 0 | File compressedParent (compressedFile.getParent(pool)); |
439 | 0 | compressedParent.mkdirs(pool); |
440 | 0 | } |
441 | | |
442 | | // |
443 | | // if currentActiveFile is not lastBaseName then |
444 | | // active file name is not following file pattern |
445 | | // and requires a rename plus maintaining the same name |
446 | 0 | if (currentActiveFile != lastBaseName) |
447 | 0 | { |
448 | 0 | renameAction = std::make_shared<FileRenameAction>( |
449 | 0 | File().setPath(currentActiveFile), File().setPath(lastBaseName), true); |
450 | 0 | nextActiveFile = currentActiveFile; |
451 | 0 | } |
452 | |
|
453 | 0 | if (m_priv->suffixLength == 3) |
454 | 0 | { |
455 | 0 | GZCompressActionPtr comp = std::make_shared<GZCompressAction>( |
456 | 0 | File().setPath(lastBaseName), File().setPath(m_priv->lastFileName), true); |
457 | 0 | comp->setThrowIOExceptionOnForkFailure(m_priv->throwIOExceptionOnForkFailure); |
458 | 0 | compressAction = comp; |
459 | 0 | } |
460 | |
|
461 | 0 | if (m_priv->suffixLength == 4) |
462 | 0 | { |
463 | 0 | ZipCompressActionPtr comp = std::make_shared<ZipCompressAction>( |
464 | 0 | File().setPath(lastBaseName), File().setPath(m_priv->lastFileName), true); |
465 | 0 | comp->setThrowIOExceptionOnForkFailure(m_priv->throwIOExceptionOnForkFailure); |
466 | 0 | compressAction = comp; |
467 | 0 | } |
468 | |
|
469 | 0 | if( m_priv->multiprocess ){ |
470 | | #if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER |
471 | | size_t byteCount = sizeof (logchar) * newFileName.size(); |
472 | | if (MAX_FILE_LEN - sizeof (logchar) < byteCount) |
473 | | { |
474 | | LogString msg(newFileName + LOG4CXX_STR(": cannot exceed ")); |
475 | | StringHelper::toString(MAX_FILE_LEN / sizeof (logchar), pool, msg); |
476 | | msg += LOG4CXX_STR(" characters"); |
477 | | throw IllegalArgumentException(msg); |
478 | | } |
479 | | if (m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool)) |
480 | | { |
481 | | lockMMapFile(APR_FLOCK_EXCLUSIVE); |
482 | | memset(m_priv->_mmap->mm, 0, MAX_FILE_LEN); |
483 | | memcpy(m_priv->_mmap->mm, newFileName.c_str(), byteCount); |
484 | | unLockMMapFile(); |
485 | | } |
486 | | else |
487 | | { |
488 | | m_priv->_mmap = NULL; |
489 | | initMMapFile(newFileName, m_priv->_mmapPool); |
490 | | } |
491 | | #endif |
492 | 0 | }else{ |
493 | 0 | m_priv->lastFileName = newFileName; |
494 | 0 | } |
495 | |
|
496 | 0 | return std::make_shared<RolloverDescription>(nextActiveFile, append, renameAction, compressAction); |
497 | 0 | } |
498 | | |
499 | | bool TimeBasedRollingPolicy::isTriggeringEvent( |
500 | | Appender* appender, |
501 | | const LOG4CXX_NS::spi::LoggingEventPtr& /* event */, |
502 | | const LogString& filename, |
503 | | size_t /* fileLength */) |
504 | 0 | { |
505 | 0 | if( m_priv->multiprocess ){ |
506 | | #if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER |
507 | | if (m_priv->bRefreshCurFile && m_priv->_mmap && !isMapFileEmpty(m_priv->_mmapPool)) |
508 | | { |
509 | | lockMMapFile(APR_FLOCK_SHARED); |
510 | | LogString mapCurrent(static_cast<logchar*>(m_priv->_mmap->mm)); |
511 | | unLockMMapFile(); |
512 | | LogString mapCurrentBase(mapCurrent.substr(0, mapCurrent.length() - m_priv->suffixLength)); |
513 | | |
514 | | if (!mapCurrentBase.empty() && mapCurrentBase != filename) |
515 | | { |
516 | | if (auto fappend = dynamic_cast<FileAppender*>(appender)) |
517 | | fappend->setFile(mapCurrentBase); |
518 | | } |
519 | | } |
520 | | |
521 | | return ( Date::currentTime() > m_priv->nextCheck) || (!m_priv->bAlreadyInitialized); |
522 | | #endif |
523 | 0 | } |
524 | |
|
525 | 0 | return Date::currentTime() > m_priv->nextCheck; |
526 | 0 | } |
527 | | |
528 | 0 | void TimeBasedRollingPolicy::setMultiprocess(bool multiprocess){ |
529 | | #if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER |
530 | | // If we don't have the multiprocess stuff, disregard any attempt to set this value |
531 | | m_priv->multiprocess = multiprocess; |
532 | | #endif |
533 | 0 | } |
534 | | |
535 | | void TimeBasedRollingPolicy::setOption(const LogString& option, |
536 | | const LogString& value) |
537 | 0 | { |
538 | 0 | if (StringHelper::equalsIgnoreCase(option, |
539 | 0 | LOG4CXX_STR("THROWIOEXCEPTIONONFORKFAILURE"), |
540 | 0 | LOG4CXX_STR("throwioexceptiononforkfailure"))) |
541 | 0 | { |
542 | 0 | m_priv->throwIOExceptionOnForkFailure = OptionConverter::toBoolean(value, true); |
543 | 0 | } |
544 | 0 | else |
545 | 0 | { |
546 | 0 | RollingPolicyBase::setOption(option, value); |
547 | 0 | } |
548 | 0 | } |
549 | | |
550 | | /** |
551 | | * Was the name in shared memory set by this process? |
552 | | */ |
553 | | bool TimeBasedRollingPolicy::isLastFileNameUnchanged() |
554 | 0 | { |
555 | 0 | bool result = true; |
556 | 0 | if( m_priv->multiprocess ){ |
557 | | #if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER |
558 | | if (m_priv->_mmap) |
559 | | { |
560 | | lockMMapFile(APR_FLOCK_SHARED); |
561 | | LogString mapCurrent(static_cast<logchar*>(m_priv->_mmap->mm)); |
562 | | unLockMMapFile(); |
563 | | result = (mapCurrent == m_priv->lastFileName); |
564 | | } |
565 | | #endif |
566 | 0 | } |
567 | 0 | return result; |
568 | 0 | } |
569 | | |
570 | | /** |
571 | | * Load the name (set by some other process) from shared memory |
572 | | */ |
573 | | void TimeBasedRollingPolicy::loadLastFileName() |
574 | 0 | { |
575 | 0 | if( m_priv->multiprocess ){ |
576 | | #if LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER |
577 | | if (m_priv->_mmap) |
578 | | { |
579 | | lockMMapFile(APR_FLOCK_SHARED); |
580 | | LogString mapLastFile(static_cast<logchar*>(m_priv->_mmap->mm)); |
581 | | unLockMMapFile(); |
582 | | if (!mapLastFile.empty()) |
583 | | m_priv->lastFileName = mapLastFile; |
584 | | } |
585 | | #endif |
586 | 0 | } |
587 | 0 | } |