Skip to content

Commit 724e888

Browse files
committed
Only reuse the old counter if the file name pattern has a counter placeholder.
If text_file_backend is set up to append to a previously written file, and the actively written file name pattern does not include a file counter placeholder but the target file name pattern does, we used to skip incrementing the file counter in an attempt to generate the same file name as was last used, so that we open the last used file for appending. While it did result in reusing the last written file, since the counter was not incremented, the next rotation would generate the last used target file name, which would result in overwriting the last rotated file instead of adding a new file to the storage. To mitigate this, only skip incrementing the counter if the file name pattern for the actively written file actually has a counter placeholder. This way, the counter will get incremented in the case described above, and on rotation a new target file name will be generated. Fixes #245.
1 parent 6366d73 commit 724e888

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

doc/changelog.qbk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[/
2-
Copyright Andrey Semashev 2007 - 2024.
2+
Copyright Andrey Semashev 2007 - 2025.
33
Distributed under the Boost Software License, Version 1.0.
44
(See accompanying file LICENSE_1_0.txt or copy at
55
http://www.boost.org/LICENSE_1_0.txt)
@@ -13,6 +13,7 @@
1313

1414
* Disabled usage of `std::codecvt<char16_t>` and `std::codecvt<char32_t>` locale facets in C++20 and later modes as they were deprecated in C++20. This means character code conversions to/from `char16_t` and `char32_t` is no longer available in C++20 and later.
1515
* Fixed building issues when using CMake and MinGW-w64. ([pull_request 241])
16+
* Fixed incorrect file counter used by `text_file_backend` when the backend was configured to append to an existing file and the actively written file name pattern didn't have a counter placeholder but the target file name pattern did, and the log files were written directly into the target storage. ([github_issue 245])
1617

1718
[heading 2.30, Boost 1.87]
1819

src/text_file_backend.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright Andrey Semashev 2007 - 2015.
2+
* Copyright Andrey Semashev 2007 - 2025.
33
* Distributed under the Boost Software License, Version 1.0.
44
* (See accompanying file LICENSE_1_0.txt or copy at
55
* http://www.boost.org/LICENSE_1_0.txt)
@@ -507,7 +507,14 @@ BOOST_LOG_ANONYMOUS_NAMESPACE {
507507
}
508508

509509
//! The function parses file name pattern and splits it into path and filename and creates a function object that will generate the actual filename from the pattern
510-
void parse_file_name_pattern(filesystem::path const& pattern, filesystem::path& storage_dir, filesystem::path& file_name_pattern, boost::log::aux::light_function< path_string_type (unsigned int) >& file_name_generator)
510+
void parse_file_name_pattern
511+
(
512+
filesystem::path const& pattern,
513+
filesystem::path& storage_dir,
514+
filesystem::path& file_name_pattern,
515+
boost::log::aux::light_function< path_string_type (unsigned int) >& file_name_generator,
516+
bool& has_file_counter
517+
)
511518
{
512519
// Note: avoid calling Boost.Filesystem functions that involve path::codecvt()
513520
// https://svn.boost.org/trac/boost/ticket/9119
@@ -606,6 +613,8 @@ BOOST_LOG_ANONYMOUS_NAMESPACE {
606613
// No placeholders detected
607614
file_name_generator = empty_formatter(name_pattern);
608615
}
616+
617+
has_file_counter = counter_found;
609618
}
610619

611620

@@ -1271,6 +1280,8 @@ struct text_file_backend::implementation
12711280
filesystem::path m_StorageDir;
12721281
//! File name generator (according to m_FileNamePattern)
12731282
boost::log::aux::light_function< path_string_type (unsigned int) > m_FileNameGenerator;
1283+
//! The flag indicates whether m_FileNamePattern has a file counter placeholder
1284+
bool m_FileNamePatternHasCounter;
12741285

12751286
//! Target file name pattern
12761287
filesystem::path m_TargetFileNamePattern;
@@ -1316,6 +1327,7 @@ struct text_file_backend::implementation
13161327
bool m_IsFirstFile;
13171328

13181329
implementation(uintmax_t rotation_size, auto_newline_mode auto_newline, bool auto_flush, bool enable_final_rotation) :
1330+
m_FileNamePatternHasCounter(false),
13191331
m_FileCounter(0u),
13201332
m_FileOpenMode(std::ios_base::trunc | std::ios_base::out),
13211333
m_CharactersWritten(0u),
@@ -1449,11 +1461,11 @@ BOOST_LOG_API void text_file_backend::consume(record_view const& rec, string_typ
14491461
unsigned int file_counter = m_pImpl->m_FileCounter;
14501462
if (BOOST_LIKELY(m_pImpl->m_FileCounterIsLastUsed))
14511463
{
1452-
// If the sink backend is configured to append to a previously written file, don't
1453-
// increment the file counter and try to open the existing file. Only do this if the
1454-
// file is not moved to a different storage location by the file collector.
1464+
// If the sink backend is configured to append to a previously written file and the file pattern
1465+
// includes a file counter, don't increment the counter and try to open the existing file, with the last
1466+
// used counter value. Only do this if the file is not moved to a different storage location by the file collector.
14551467
bool increment_file_counter = true;
1456-
if (BOOST_UNLIKELY(m_pImpl->m_IsFirstFile && (m_pImpl->m_FileOpenMode & std::ios_base::app) != 0))
1468+
if (BOOST_UNLIKELY(m_pImpl->m_IsFirstFile && (m_pImpl->m_FileOpenMode & std::ios_base::app) != 0 && m_pImpl->m_FileNamePatternHasCounter))
14571469
{
14581470
filesystem::path last_file_name = m_pImpl->m_StorageDir / m_pImpl->m_FileNameGenerator(file_counter);
14591471
if (!!m_pImpl->m_pFileCollector)
@@ -1575,7 +1587,8 @@ BOOST_LOG_API void text_file_backend::set_file_name_pattern_internal(filesystem:
15751587
!pattern.empty() ? pattern : filesystem::path(traits_t::default_file_name_pattern()),
15761588
m_pImpl->m_StorageDir,
15771589
m_pImpl->m_FileNamePattern,
1578-
m_pImpl->m_FileNameGenerator
1590+
m_pImpl->m_FileNameGenerator,
1591+
m_pImpl->m_FileNamePatternHasCounter
15791592
);
15801593
}
15811594

@@ -1584,7 +1597,8 @@ BOOST_LOG_API void text_file_backend::set_target_file_name_pattern_internal(file
15841597
{
15851598
if (!pattern.empty())
15861599
{
1587-
parse_file_name_pattern(pattern, m_pImpl->m_TargetStorageDir, m_pImpl->m_TargetFileNamePattern, m_pImpl->m_TargetFileNameGenerator);
1600+
bool has_file_counter = false;
1601+
parse_file_name_pattern(pattern, m_pImpl->m_TargetStorageDir, m_pImpl->m_TargetFileNamePattern, m_pImpl->m_TargetFileNameGenerator, has_file_counter);
15881602
}
15891603
else
15901604
{

0 commit comments

Comments
 (0)