Giter Club home page Giter Club logo

Comments (10)

UMU618 avatar UMU618 commented on September 2, 2024 1

@Lastique How about specifying m_TargetStorageDir as m_StorageDir, when m_TargetStorageDir is empty?

from log.

debuggingbug avatar debuggingbug commented on September 2, 2024 1

I don't like introducing this kind of non-obvious behavior.

When I wrote the following codes, I would naturally assume that target_file_name would be in the same directory as file_name. New log file is temporarily create in m_TargetStorageDir, and will be move to m_StorageDir. So I think this behavior do some good.

keywords::file_name = log_file,
keywords::target_file_name = config.stem + L"_%Y%m%d_%H%M%S_%5N.log"

from log.

Lastique avatar Lastique commented on September 2, 2024

As any filesystem operation, rotating log files may fail, this is to be expected. From your information, it isn't clear what exactly happened, so I can't tell whether the error is legitimate.

In any case, in order to handle exceptions, you can set an exception handler to the sink frontend.

from log.

debuggingbug avatar debuggingbug commented on September 2, 2024

@Lastique I already set exception handler, still can NOT catch the exception.

struct ExceptionHandler {
    typedef void result_type;

    void operator()(std::exception const& e) const noexcept {
        OutputDebugStringA(std::format("std::runtime_error: {}\n", e.what()).data());
    }
    void operator()(boost::filesystem::filesystem_error const& e) const noexcept {
        OutputDebugStringA(
            std::format("boost::filesystem::filesystem_error: {}\n", e.what()).data());
    }
};

// catch nothing
auto core = logging::core::get();
core->set_exception_handler(
    boost::log::make_exception_handler<std::exception, boost::filesystem::filesystem_error>(
        ExceptionHandler()));

// catch nothing
file_sink->set_exception_handler(
    boost::log::make_exception_handler<std::exception, boost::filesystem::filesystem_error>(
        ExceptionHandler()));

from log.

Lastique avatar Lastique commented on September 2, 2024

If it doesn't catch then the exception is not one of the types you listed. BTW, it doesn't make sense to list std::exception first, because it will be caught before filesystem_error by the handler function object. Exceptions should be listed from the most specific ones to the most general ones, similar to how you order them in the catch blocks.

Also note that std::format is not noexcept.

Getting back to the problem, you should debug to see what the exception type is and where it is being thrown.

from log.

debuggingbug avatar debuggingbug commented on September 2, 2024

Thank you! I'll improve my codes.

From minidump, I see the exception is a boost::filesystem::filesystem_error. Since the crash is on other users' machine, I can't debug.

from log.

Lastique avatar Lastique commented on September 2, 2024

For the record, the basic_formatting_sink_frontend::feed_record function is here:

template< typename BackendMutexT, typename BackendT >
void feed_record(record_view const& rec, BackendMutexT& backend_mutex, BackendT& backend)
{
formatting_context* context;
#if !defined(BOOST_LOG_NO_THREADS)
context = m_pContext.get();
if (!context || context->m_Version != m_Version.load(boost::memory_order_relaxed))
{
{
boost::log::aux::shared_lock_guard< mutex_type > lock(this->frontend_mutex());
context = new formatting_context(m_Version.load(boost::memory_order_relaxed), m_Locale, m_Formatter);
}
m_pContext.reset(context);
}
#else
context = &m_Context;
#endif
typename formatting_context::cleanup_guard cleanup(*context);
try
{
// Perform the formatting
context->m_Formatter(rec, context->m_FormattingStream);
context->m_FormattingStream.flush();
// Feed the record
BOOST_LOG_EXPR_IF_MT(boost::log::aux::exclusive_lock_guard< BackendMutexT > lock(backend_mutex);)
backend.consume(rec, context->m_FormattedRecord);
}
#if !defined(BOOST_LOG_NO_THREADS)
catch (thread_interrupted&)
{
throw;
}
#endif
catch (...)
{
BOOST_LOG_EXPR_IF_MT(boost::log::aux::shared_lock_guard< mutex_type > lock(this->frontend_mutex());)
if (this->exception_handler().empty())
throw;
this->exception_handler()();
}
}

As you can see, the function does catch all exceptions thrown by backend.consume(), so the fact that the exception keeps propagating after that means that the exception handler is not set or that it has rethrown the exception. Or that the exception fails to be caught in the first place, but then this sounds like an ABI issue (e.g. when multiple different versions of filesystem_error exist in the process, or the language runtime fails to catch the exception for some other unknown reason).

from log.

debuggingbug avatar debuggingbug commented on September 2, 2024

I think I've solved this issue by adding directory to target_file_name.

 keywords::target_file_name =
                    config.directory / (config.stem + L"_%Y%m%d_%H%M%S_%5N.log")

If the directory is not specified, the new log file will be created on %ProgramFiles%\<Company>\<ProductName>, which is readonly. See the following code, m_pImpl->m_TargetStorageDir is null. filesystem::create_directories(new_file_name.parent_path()); will throw.

//! The method rotates the file
BOOST_LOG_API void text_file_backend::rotate_file()
{
    filesystem::path prev_file_name = m_pImpl->m_FileName;
    close_file();

    // Check if the file has been created in the first place
    system::error_code ec;
    filesystem::file_status status = filesystem::status(prev_file_name, ec);
    if (status.type() == filesystem::regular_file)
    {
        if (!!m_pImpl->m_TargetFileNameGenerator)
        {
            filesystem::path new_file_name = m_pImpl->m_TargetStorageDir / m_pImpl->m_TargetFileNameGenerator(m_pImpl->m_FileCounter);

            if (new_file_name != prev_file_name)
            {
                filesystem::create_directories(new_file_name.parent_path());
                move_file(prev_file_name, new_file_name);

                prev_file_name.swap(new_file_name);
            }
        }

        if (!!m_pImpl->m_pFileCollector)
            m_pImpl->m_pFileCollector->store_file(prev_file_name);
    }
}

from log.

Lastique avatar Lastique commented on September 2, 2024

I think I've solved this issue by adding directory to target_file_name.

Good, it explains why you were getting an exception. It doesn't explain why the exception wasn't caught, though. Which means, if an exception is thrown for whatever other reason, you will have the same problem again. I'd recommend continuing debugging to fix this. Double-check that you set an exception handler for all sinks. Check if it's actually being called by setting a custom function object with console output or something instead of the one generated by make_exception_handler.

from log.

Lastique avatar Lastique commented on September 2, 2024

@Lastique How about specifying m_TargetStorageDir as m_StorageDir, when m_TargetStorageDir is empty?

I don't like introducing this kind of non-obvious behavior. Currently, any relative paths you provide to the library are interpreted the same way as anywhere else in the process - they are relative to the current path for the process. Which means, it is probably a good idea to always provide absolute paths. But that doesn't mean it is a good idea to replace the path behind user's back.

from log.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.