Coverage Report

Created: 2025-07-11 07:00

/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
477
  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&){}
Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::initMMapFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, log4cxx::helpers::Pool&)
Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::initMMapFile(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, log4cxx::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
477
  m_priv(std::make_unique<TimeBasedRollingPolicyPrivate>())
265
477
{
266
477
}
Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::TimeBasedRollingPolicy()
log4cxx::rolling::TimeBasedRollingPolicy::TimeBasedRollingPolicy()
Line
Count
Source
264
477
  m_priv(std::make_unique<TimeBasedRollingPolicyPrivate>())
265
477
{
266
477
}
267
268
477
TimeBasedRollingPolicy::~TimeBasedRollingPolicy(){}
269
270
void TimeBasedRollingPolicy::activateOptions(LOG4CXX_NS::helpers::Pool& pool)
271
2.38k
{
272
  // find out period from the filename pattern
273
2.38k
  if (getFileNamePattern().length() > 0)
274
2.38k
  {
275
2.38k
    parseFileNamePattern();
276
2.38k
  }
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
2.38k
  PatternConverterPtr dtc(getDatePatternConverter());
285
286
2.38k
  if (dtc == NULL)
287
0
  {
288
0
    throw NullPointerException(LOG4CXX_STR("DatePatternConverter"));
289
0
  }
290
291
2.38k
  LogString buf;
292
2.38k
  ObjectPtr obj = std::make_shared<Date>();
293
2.38k
  formatFileName(obj, buf, pool);
294
2.38k
  m_priv->lastFileName = buf;
295
296
2.38k
  m_priv->suffixLength = 0;
297
298
2.38k
  if (m_priv->lastFileName.length() >= 3)
299
2.38k
  {
300
2.38k
    if (m_priv->lastFileName.compare(m_priv->lastFileName.length() - 3, 3, LOG4CXX_STR(".gz")) == 0)
301
1.07k
    {
302
1.07k
      m_priv->suffixLength = 3;
303
1.07k
    }
304
1.31k
    else if (m_priv->lastFileName.length() >= 4 && m_priv->lastFileName.compare(m_priv->lastFileName.length() - 4, 4, LOG4CXX_STR(".zip")) == 0)
305
1.31k
    {
306
1.31k
      m_priv->suffixLength = 4;
307
1.31k
    }
308
2.38k
  }
309
2.38k
}
310
311
312
#define RULES_PUT(spec, cls) \
313
4.77k
  specs.insert(PatternMap::value_type(LogString(LOG4CXX_STR(spec)), (PatternConstructor) cls ::newInstance))
314
315
LOG4CXX_NS::pattern::PatternMap TimeBasedRollingPolicy::getFormatSpecifiers() const
316
2.38k
{
317
2.38k
  PatternMap specs;
318
2.38k
  RULES_PUT("d", FileDatePatternConverter);
319
2.38k
  RULES_PUT("date", FileDatePatternConverter);
320
2.38k
  return specs;
321
2.38k
}
322
323
/**
324
 * {@inheritDoc}
325
 */
326
RolloverDescriptionPtr TimeBasedRollingPolicy::initialize(
327
  const   LogString&  currentActiveFile,
328
  const   bool        append,
329
  Pool&       pool)
330
954
{
331
954
  Date now;
332
954
  log4cxx_time_t n = now.getTime();
333
954
  m_priv->nextCheck = now.getNextSecond();
334
335
954
  File currentFile(currentActiveFile);
336
337
954
  LogString buf;
338
954
  ObjectPtr obj = std::make_shared<Date>(currentFile.exists(pool) ? currentFile.lastModified(pool) : n);
339
954
  formatFileName(obj, buf, pool);
340
954
  m_priv->lastFileName = buf;
341
342
954
  ActionPtr noAction;
343
344
954
  if (currentActiveFile.length() > 0)
345
954
  {
346
954
    return std::make_shared<RolloverDescription>(
347
954
          currentActiveFile, append, noAction, noAction);
348
954
  }
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
954
}
log4cxx::rolling::TimeBasedRollingPolicy::initialize(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, log4cxx::helpers::Pool&)
Line
Count
Source
330
954
{
331
954
  Date now;
332
954
  log4cxx_time_t n = now.getTime();
333
954
  m_priv->nextCheck = now.getNextSecond();
334
335
954
  File currentFile(currentActiveFile);
336
337
954
  LogString buf;
338
954
  ObjectPtr obj = std::make_shared<Date>(currentFile.exists(pool) ? currentFile.lastModified(pool) : n);
339
954
  formatFileName(obj, buf, pool);
340
954
  m_priv->lastFileName = buf;
341
342
954
  ActionPtr noAction;
343
344
954
  if (currentActiveFile.length() > 0)
345
954
  {
346
954
    return std::make_shared<RolloverDescription>(
347
954
          currentActiveFile, append, noAction, noAction);
348
954
  }
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
954
}
Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::initialize(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, bool, log4cxx::helpers::Pool&)
357
358
RolloverDescriptionPtr TimeBasedRollingPolicy::rollover(
359
  const   LogString&  currentActiveFile,
360
  const   bool        append,
361
  Pool&       pool)
362
954
{
363
954
  Date now;
364
954
  log4cxx_time_t n = now.getTime();
365
954
  m_priv->nextCheck = now.getNextSecond();
366
367
954
  LogString buf;
368
954
  ObjectPtr obj = std::make_shared<Date>(n);
369
954
  formatFileName(obj, buf, pool);
370
371
954
  LogString newFileName(buf);
372
373
954
  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
954
  if (newFileName == m_priv->lastFileName)
424
952
  {
425
952
    RolloverDescriptionPtr desc;
426
952
    return desc;
427
952
  }
428
429
2
  ActionPtr renameAction;
430
2
  ActionPtr compressAction;
431
2
  LogString lastBaseName(
432
2
    m_priv->lastFileName.substr(0, m_priv->lastFileName.length() - m_priv->suffixLength));
433
2
  LogString nextActiveFile(
434
2
    newFileName.substr(0, newFileName.length() - m_priv->suffixLength));
435
436
2
  if(getCreateIntermediateDirectories()){
437
2
    File compressedFile(m_priv->lastFileName);
438
2
    File compressedParent (compressedFile.getParent(pool));
439
2
    compressedParent.mkdirs(pool);
440
2
  }
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
2
  if (currentActiveFile != lastBaseName)
447
2
  {
448
2
    renameAction = std::make_shared<FileRenameAction>(
449
2
          File().setPath(currentActiveFile), File().setPath(lastBaseName), true);
450
2
    nextActiveFile = currentActiveFile;
451
2
  }
452
453
2
  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
2
  if (m_priv->suffixLength == 4)
462
2
  {
463
2
    ZipCompressActionPtr comp = std::make_shared<ZipCompressAction>(
464
2
          File().setPath(lastBaseName), File().setPath(m_priv->lastFileName), true);
465
2
    comp->setThrowIOExceptionOnForkFailure(m_priv->throwIOExceptionOnForkFailure);
466
2
    compressAction = comp;
467
2
  }
468
469
2
  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
2
  }else{
493
2
    m_priv->lastFileName = newFileName;
494
2
  }
495
496
2
  return std::make_shared<RolloverDescription>(nextActiveFile, append, renameAction, compressAction);
497
954
}
log4cxx::rolling::TimeBasedRollingPolicy::rollover(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, log4cxx::helpers::Pool&)
Line
Count
Source
362
954
{
363
954
  Date now;
364
954
  log4cxx_time_t n = now.getTime();
365
954
  m_priv->nextCheck = now.getNextSecond();
366
367
954
  LogString buf;
368
954
  ObjectPtr obj = std::make_shared<Date>(n);
369
954
  formatFileName(obj, buf, pool);
370
371
954
  LogString newFileName(buf);
372
373
954
  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
954
  if (newFileName == m_priv->lastFileName)
424
952
  {
425
952
    RolloverDescriptionPtr desc;
426
952
    return desc;
427
952
  }
428
429
2
  ActionPtr renameAction;
430
2
  ActionPtr compressAction;
431
2
  LogString lastBaseName(
432
2
    m_priv->lastFileName.substr(0, m_priv->lastFileName.length() - m_priv->suffixLength));
433
2
  LogString nextActiveFile(
434
2
    newFileName.substr(0, newFileName.length() - m_priv->suffixLength));
435
436
2
  if(getCreateIntermediateDirectories()){
437
2
    File compressedFile(m_priv->lastFileName);
438
2
    File compressedParent (compressedFile.getParent(pool));
439
2
    compressedParent.mkdirs(pool);
440
2
  }
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
2
  if (currentActiveFile != lastBaseName)
447
2
  {
448
2
    renameAction = std::make_shared<FileRenameAction>(
449
2
          File().setPath(currentActiveFile), File().setPath(lastBaseName), true);
450
2
    nextActiveFile = currentActiveFile;
451
2
  }
452
453
2
  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
2
  if (m_priv->suffixLength == 4)
462
2
  {
463
2
    ZipCompressActionPtr comp = std::make_shared<ZipCompressAction>(
464
2
          File().setPath(lastBaseName), File().setPath(m_priv->lastFileName), true);
465
2
    comp->setThrowIOExceptionOnForkFailure(m_priv->throwIOExceptionOnForkFailure);
466
2
    compressAction = comp;
467
2
  }
468
469
2
  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
2
  }else{
493
2
    m_priv->lastFileName = newFileName;
494
2
  }
495
496
2
  return std::make_shared<RolloverDescription>(nextActiveFile, append, renameAction, compressAction);
497
954
}
Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::rollover(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, bool, log4cxx::helpers::Pool&)
498
499
bool TimeBasedRollingPolicy::isTriggeringEvent(
500
  Appender* appender,
501
  const LOG4CXX_NS::spi::LoggingEventPtr& /* event */,
502
  const LogString&  filename,
503
  size_t /* fileLength */)
504
4.77k
{
505
4.77k
  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
4.77k
  return Date::currentTime() > m_priv->nextCheck;
526
4.77k
}
log4cxx::rolling::TimeBasedRollingPolicy::isTriggeringEvent(log4cxx::Appender*, std::__1::shared_ptr<log4cxx::spi::LoggingEvent> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long)
Line
Count
Source
504
4.77k
{
505
4.77k
  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
4.77k
  return Date::currentTime() > m_priv->nextCheck;
526
4.77k
}
Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::isTriggeringEvent(log4cxx::Appender*, std::__1::shared_ptr<log4cxx::spi::LoggingEvent> const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, unsigned long)
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
}
Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::setOption(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: log4cxx::rolling::TimeBasedRollingPolicy::setOption(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&)
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
}