Thanks to visit codestin.com
Credit goes to github.com

Skip to content

TimeBasedRollingFileAppender datetime pattern in path #644

@maldag

Description

@maldag

If TimeBasedRollingFileAppender is used and the FilenameProperty is using the datetime pattern in a folder path, this does not work correctly, such as no folders a created upon moving to a new filename.

log4cplus.appender.FILE                 			= log4cplus::TimeBasedRollingFileAppender
log4cplus.appender.FILE.Threshold			= INFO
log4cplus.appender.FILE.FilenamePattern		= D:/myBasePath/%d{yyyyMMddhhmm}/MyApplication/log.txt

I already did some debugging and it seems that

#src/fileappender.cxx:1371
TimeBasedRollingFileAppender::rollover(bool alreadyLocked){
//[...]
 ret = file_rename (filename, scheduledFilename);
//[...]

the file_rename does not account for folder changes. The current file written in filename (D:/myBasePath/202501081347/MyApplication/log.txt) shall be moved to (D:/myBasePath/202501081348/MyApplication/log.txt), but that folder structure is not there so the rename will produce an errocode (2).

Related, but not necessarily the same is another error ocurring in opening the new file after rotating:

#src/fileappender.cxx
void
TimeBasedRollingFileAppender::open(std::ios_base::openmode mode)
{
    scheduledFilename = helpers::getFormattedTime(filenamePattern, helpers::now(), false);
    if (filename.empty())
        filename = scheduledFilename;

    tstring currentFilename = filename;

    if (createDirs)
        internal::make_dirs (currentFilename);

    out.open(LOG4CPLUS_FSTREAM_PREFERED_FILE_NAME(currentFilename).c_str(), mode);
    if(!out.good())
    {
        getErrorHandler()->error(LOG4CPLUS_TEXT("Unable to open file: ") + currentFilename);
        return;
    }
    helpers::getLogLog().debug(LOG4CPLUS_TEXT("Just opened file: ") + currentFilename);
}

The variable scheduledFilename will be calculated correctly (new name with current datetime) but will not used for the new file since filename is not empty. So currentfilename remains the old file.

My idea would be to remove the if clause in the open-Method to always set filename to scheduledFilename or to provide an additional property to the class to keep the old file in place and move to the new file.

# src/fileappender.cxx
# New State after proposal
void
TimeBasedRollingFileAppender::open(std::ios_base::openmode mode)
{
    scheduledFilename = helpers::getFormattedTime(filenamePattern, helpers::now(), false);
    // always set filename to new scheduledFilename
    // or provide configuration option to move on to another new log file
    filename = scheduledFilename;

    tstring currentFilename = filename;

    if (createDirs)
        internal::make_dirs (currentFilename);

    out.open(LOG4CPLUS_FSTREAM_PREFERED_FILE_NAME(currentFilename).c_str(), mode);
    if(!out.good())
    {
        getErrorHandler()->error(LOG4CPLUS_TEXT("Unable to open file: ") + currentFilename);
        return;
    }
    helpers::getLogLog().debug(LOG4CPLUS_TEXT("Just opened file: ") + currentFilename);
}

Also, provide the following information:

  • version: 2.1.2
  • operating system, CPU, bitness: Windows 11, x64
  • MSVC 17.12.3, no special options provided

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions