退出时提升日志锁定

问题描述

我有以下(精简的)记录器代码,它们按预期工作,除非应用程序存在于特定场景中。 当记录器似乎正在写入日志文件并且应用程序存在时,记录器会锁定并且应用程序不会退出。 以下是记录器代码示例以及可以重现问题的主要代码

#include <boost/log/sinks/async_frontend.hpp>
#include <boost/log/sinks/drop_on_overflow.hpp>
#include <boost/log/sinks/bounded_fifo_queue.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/attributes/clock.hpp>
#include <boost/log/attributes/current_process_name.hpp>
#include <boost/log/attributes/current_process_id.hpp>
#include <boost/log/attributes/current_thread_id.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/utility/setup/console.hpp>

namespace blog = boost::log;

constexpr uint32_t LOG_QUEUE_BOUND_LInes = 10000;
constexpr uint32_t MAX_FILE_SIZE_FOR_ROTATION_MB = (10 * 1024 * 1024); // 10MB
constexpr uint32_t MAX_TIME_FOR_ROTATION_IN_HOURS = (24 * 7); // 1 week

using LogAsyncSink = boost::log::sinks::asynchronous_sink<boost::log::sinks::text_file_backend,boost::log::sinks::bounded_fifo_queue<
    LOG_QUEUE_BOUND_LInes_NUM,boost::log::sinks::drop_on_overflow>>;

boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> _logger;

boost::shared_ptr<LogAsyncSink> fileGlobalSink;

#define LOG_FORMAT blog::expressions::stream \
    << blog::expressions::format_date_time<boost::posix_time::ptime>("TimeStamp","%Y-%m-%d %H:%M:%s.%f") \
    << " [" \
    << blog::expressions::attr<blog::trivial::severity_level>("Severity") \
    << "] " \
    << blog::expressions::attr<std::string>("Process") \
    << ":" \
    << blog::expressions::attr<blog::process_id>("ProcessID") \
    << ":" \
    << blog::expressions::attr<blog::thread_id>("ThreadID") \
    << " " \
    << blog::expressions::message

boost::shared_ptr<LogAsyncSink> AddFile(const std::string& fileName)
{
    // No need to guard since this can be called only from functions that are guarded
    boost::shared_ptr<LogAsyncSink> returnSink(nullptr);
    boost::shared_ptr<blog::sinks::text_file_backend> textFile =
        boost::make_shared<blog::sinks::text_file_backend>(blog::keywords::file_name = fileName);

    textFile->set_file_name_pattern(fileName);

    // set rolling mechanism
    textFile->set_rotation_size(MAX_FILE_SIZE_FOR_ROTATION_MB);
    textFile->set_time_based_rotation(
        blog::sinks::file::rotation_at_time_interval(boost::posix_time::hours(MAX_TIME_FOR_ROTATION_IN_HOURS)));

    boost::shared_ptr<LogAsyncSink> fileSink(new LogAsyncSink(textFile));
    fileSink->set_formatter(
        LOG_FORMAT
    );
    fileSink->locked_backend()->auto_flush(true);

    returnSink = fileSink;
    return returnSink;
}

void LoggerInit()
{
    std::string fileName = "logfilename.txt";
    boost::shared_ptr<LogAsyncSink> fileAdded;

    fileAdded = AddFile(fileName);
    auto core = blog::core::get();
    if (core != nullptr)
    {
        core->add_global_attribute("TimeStamp",blog::attributes::local_clock());
        core->add_global_attribute("Process",blog::attributes::current_process_name());
        core->add_global_attribute("ProcessID",blog::attributes::current_process_id());
        core->add_global_attribute("ThreadID",blog::attributes::current_thread_id());

        core->add_sink(fileAdded);
        fileGlobalSink = fileAdded;
    }
}

void StopLogging()
{
    boost::shared_ptr<blog::core> core = blog::core::get();

    if (fileGlobalSink != nullptr)
    {
        if (core != nullptr)
        {
            // Remove the sink from the core,so that no records are passed to it
            core->remove_sink(fileGlobalSink);
        }

        // Flush all log records that may have left buffered
        fileGlobalSink->flush();

        // Break the Feeding loop
        fileGlobalSink->stop();

        fileGlobalSink.reset();
    }
}

/******************************* main ****************************************/
int main(int argc,char* argv[])
{
    LoggerInit();
    BOOST_LOG_SEV(_logger,boost::log::trivial::trace) << "Test";
//    Sleep(10); -> Min exists correctly no lock
//    StopLogging(); -> everything closes correctly
}

正如您所看到的,如果我添加睡眠,记录器将完成记录并正确存在,如果我将调用添加StopLogging(),那么记录器会正确关闭所有内容并正确结束应用程序。 没有这两个函数,boost 锁定在: stop() 函数中的 async_frontend.cpp:

                while (m_StopRequested.load(boost::memory_order_acquire))
                    m_BlockCond.wait(lock);

知道如何解决这个问题吗?我在记录器定义中做错了什么吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...