尝试第一个日志语句时,Boost Log 会导致崩溃(当不是管理员时)

dan*_*n-O 4 c++ boost boost-log

我现在正在尝试部署我的应用程序,它使用 Boost Log (Boost 1.58)。它是一个简单的控制台应用程序,在 Windows 7 中运行。日志记录在我的个人桌面上运行得非常好。

但是,当我将应用程序部署到 Win7 虚拟机时,它在我的第一个日志语句处崩溃:

boost::log::sources::severity_logger<SeverityLevel> slg;
BOOST_LOG_SEV(slg, SeverityLevel::Notification) << L"Application loaded"; // <-- Crash here
Run Code Online (Sandbox Code Playgroud)

日志目录已创建,但日志文件从未创建,并且应用程序崩溃。

我已经在我的 %APPDATA% 目录和我的文档目录中尝试了日志文件目录。

奇怪的是:当我以管理员身份运行该应用程序时,它可以工作

所以这一定是一个权限问题,但我有这些文件夹的权限,所以......

有任何想法吗?

* 更多的 *

这是设置我的记录器的代码:

    wstring appData = GetMyAppDataPath();
    boost::shared_ptr< boost::log::sinks::synchronous_sink< boost::log::sinks::text_file_backend > > textFileSink(new boost::log::sinks::synchronous_sink< boost::log::sinks::text_file_backend >(to store rotated files
        boost::log::keywords::file_name = "log_%7N.log",                // file name pattern
        boost::log::keywords::rotation_size = 16384                     // rotation size, in characters
        ));
    // Set up where the rotated files will be stored
    textFileSink->locked_backend()->set_file_collector(boost::log::sinks::file::make_collector(
        boost::log::keywords::target = appData + L"\\logs",         // where to store rotated files
        boost::log::keywords::max_size = 64 * 1024 * 1024,              // maximum total size of the stored files, in bytes (64 MiB)
        boost::log::keywords::min_free_space = 100 * 1024 * 1024        // minimum free space on the drive, in bytes
        ));
    // Upon restart, scan the target directory for files matching the file_name pattern
    textFileSink->locked_backend()->scan_for_files();
    // Set up the format for output to the text file.
    textFileSink->set_formatter(boost::log::expressions::stream
        << "[" << boost::log::expressions::attr< boost::posix_time::ptime >("TimeStamp") 
        << " " << boost::log::expressions::attr< SeverityLevel, severity_tag >("Severity") << "] "
        << boost::log::expressions::message
        );
    // Add it to the core
    boost::log::core::get()->add_sink(textFileSink);
Run Code Online (Sandbox Code Playgroud)

这主要取自这里:http://www.boost.org/doc/libs/1_58_0/libs/log/example/rotating_file/main.cpp

* 还 *

我通过添加以下内容向 Boost Logger 添加了异常处理程序:

boost::log::core::get()->set_exception_handler(boost::log::make_exception_handler<
        std::runtime_error,
        std::logic_error,
        std::exception
    >(pbb_boost_log_exception_handler()));
Run Code Online (Sandbox Code Playgroud)

然后添加处理程序。当我运行时,我能够在崩溃之前捕获以下异常:

std::exception: Failed to open file for writing: Input/output error: "C:\Program Files\My App\log_0000000.log"
Run Code Online (Sandbox Code Playgroud)

搞什么?我确实将日志文件位置设置为appData我已验证正确的值。此外,如果我以管理员身份运行此应用程序,日志文件最终会出现在我期望的位置(appdata 文件夹)。所以它一定只是在可执行文件的位置创建一个临时文件。这是正常行为吗?我无法想象这是......所以我做了什么?

dan*_*n-O 5

好吧,我明白了。

问题是这里的这一行,设置文本后端:

boost::shared_ptr< boost::log::sinks::synchronous_sink< boost::log::sinks::text_file_backend > > textFileSink(new boost::log::sinks::synchronous_sink< boost::log::sinks::text_file_backend >
    boost::log::keywords::file_name = "log_%7N.log",                // file name pattern
    boost::log::keywords::rotation_size = 16384                     // rotation size, in characters
    ));
Run Code Online (Sandbox Code Playgroud)

肯定有一个临时日志文件被写入本地目录(Program Files 目录,这很糟糕)。根据此处的文档,我看到写入了一个临时文件,然后传递给文件收集器。

因此,为了解决这个问题,我将代码更改为:

boost::shared_ptr< boost::log::sinks::synchronous_sink< boost::log::sinks::text_file_backend > > textFileSink(new boost::log::sinks::synchronous_sink< boost::log::sinks::text_file_backend >(
    boost::log::keywords::file_name = appData + L"\\log_%7N.log",   // file name pattern
    boost::log::keywords::rotation_size = 16384                         // rotation size, in characters
    ));
Run Code Online (Sandbox Code Playgroud)

请注意,我现在将 指定file_name为位于 AppData 目录中。

这解决了问题

我很难相信我是第一个遇到这个问题的人,但我在网上找不到这个问题。对于 Windows 开发人员来说,这可能是一个经常出现的问题,因此希望这对其他人有帮助。