Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An infinite loop occurs when boost writes to the log file #209

Closed
alvin906 opened this issue Apr 19, 2023 · 4 comments
Closed

An infinite loop occurs when boost writes to the log file #209

alvin906 opened this issue Apr 19, 2023 · 4 comments

Comments

@alvin906
Copy link

  • boost version: 1.81.0
  • FileSink keywords::rotation_size = (200<<20)
  • log file size now: 209,945,411 byte
    Snipaste_2023-04-19_16-02-18
  • formartted message size: 226 byte
    Snipaste_2023-04-19_16-03-33
  • FileRotationSize: 209,945,411 byte
    Snipaste_2023-04-19_16-03-57

debugging:

boostlog

I write the log to the file in this way:

         // global define
          BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(boost_logger, src::logger_mt)
           ...
           // Append log to log file
            BOOST_LOG(boost_logger::get()) << strHeader << strBody;
@mclow mclow transferred this issue from boostorg/boost Apr 19, 2023
@Lastique
Copy link
Member

Please, provide a minimal compilable code sample that reproduces the problem.

@Lastique
Copy link
Member

From your debugging gif, it looks like you have lots of log files in the logging directory, and the backend iterates over them trying to find the log file name that is not yet used. This isn't an infinite loop, unless you have 4 billion log files in the directory.

@christapley
Copy link

christapley commented May 10, 2023

I've ran into the same problem. It was introduced by #179

#include <vector>

#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/file.hpp>

namespace logging = boost::log;
namespace keywords = boost::log::keywords;

void init_logging()
{
    logging::register_simple_formatter_factory<logging::trivial::severity_level, char>("Severity");

    auto file = logging::add_file_log(
        keywords::file_name        = "sample_%N.log",    //
        keywords::target           = "./",               //
        keywords::target_file_name = "sample_%N.log",    //
        keywords::open_mode        = std::ios_base::app, //
        keywords::auto_flush       = true,               //
        keywords::rotation_size    = 500*1024,           //
        keywords::max_size         = 6*1024*1024,        //
        keywords::max_files        = 6,
        keywords::format =
            "%LineID%. [%TimeStamp%][%ThreadID%] [%Severity%] - %Message%");

    file->locked_backend()->scan_for_files();

    logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::info);

    logging::add_common_attributes();
}

int main()
{
    init_logging();

    std::vector<char> value(static_cast<size_t>(1024*1024), 'a');
    value.push_back('\0');

    BOOST_LOG_TRIVIAL(info) << value.data();
    BOOST_LOG_TRIVIAL(info) << value.data();
    BOOST_LOG_TRIVIAL(info) << value.data();
    BOOST_LOG_TRIVIAL(info) << value.data();

}

If the log line exceeds the rotation size then we'll be stuck in an infinite loop.

This is a possible resolution

diff --git a/src/text_file_backend.cpp b/src/text_file_backend.cpp
index 8b8920e..8b0b6a7 100644
--- a/src/text_file_backend.cpp
+++ b/src/text_file_backend.cpp
@@ -1480,8 +1480,10 @@ BOOST_LOG_API void text_file_backend::consume(record_view const& rec, string_typ
         m_pImpl->m_IsFirstFile = false;
 
         // Check the file size before invoking the open handler, as it may write more data to the file
+        // But don't rotate the file if the current log message itself exceeds the rotate file size
         m_pImpl->m_CharactersWritten = static_cast< std::streamoff >(m_pImpl->m_File.tellp());
-        if (m_pImpl->m_CharactersWritten + formatted_message.size() >= m_pImpl->m_FileRotationSize)
+        if (m_pImpl->m_CharactersWritten + formatted_message.size() >= m_pImpl->m_FileRotationSize
+            && formatted_message.size() < m_pImpl->m_FileRotationSize)
         {
             // Avoid running the close handler, as we haven't run the open handler yet
             struct close_handler_backup_guard

Any hints on what sort of solution boost would accept @Lastique ?

@Lastique
Copy link
Member

@christapley Thank you for the reproducer, although I'm not sure your case is the same as the OP's. In the original problem description, the log message size is definitely smaller than the rotation_size limit, and it looks like every time a log file is open on his system, it is already too large to fit a new record.

In any case, I have committed a fix for your reproducer in b5c4277 and also an additional safeguard in 407260f. I'm not sure it'll fix the OP's problem, but I haven't heard from him, so I'm closing this report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants