Boost Log вызывает сбой при попытке первого оператора журнала (если не администратор)

Я пытаюсь развернуть свое приложение прямо сейчас, которое использует журнал Boost (Boost 1.58). Это простое консольное приложение, работающее в Windows 7. Ведение журнала отлично работает на моем личном рабочем столе.

Однако, когда я развертываю приложение на виртуальной машине Win7, оно вылетает при первом же операторе журнала:

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

каталог журнала создается, но файл журнала так и не создается, и приложение аварийно завершает работу.

Я попробовал каталог файлов журнала в моем каталоге %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);

который в основном взят отсюда: 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()));

А затем добавить обработчик. Когда я затем запускаю, я могу поймать следующее исключение перед сбоем:

std::exception: Failed to open file for writing: Input/output error: "C:\Program Files\My App\log_0000000.log"

ВТФ? Я определенно устанавливаю местоположение файла журнала в значение appData, которое я проверил правильно. Кроме того, если я запускаю это приложение от имени администратора, файл журнала оказывается в том месте, где я его ожидаю (папка appdata). Так что это должно быть просто создание временного файла в месте исполняемого файла. Это нормальное поведение? Я не могу представить, что это... так что я сделал??


person dan-O    schedule 29.07.2015    source источник
comment
Где твой MCVE? stackoverflow.com/help/mcve   -  person inetknght    schedule 30.07.2015
comment
@inetknght Я добавил в пост важные обновления.   -  person dan-O    schedule 30.07.2015
comment
Я только когда-либо видел ошибку ввода/вывода, когда файловая система повреждена (например, вам нужно запустить fdisk для проверки целостности)   -  person inetknght    schedule 30.07.2015


Ответы (1)


Хорошо, я понял это.

Проблема заключалась в этой строке здесь, в настройке текстового бэкэнда:

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
    ));

Определенно временный файл журнала записывался в локальный каталог (каталог 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
    ));

Обратите внимание, что теперь я указываю, что file_name находится в каталоге AppData.

Это решило проблему.

Мне трудно поверить, что я первый, кто столкнулся с этой проблемой, но я не смог найти ее нигде в Интернете. Это будет часто повторяющейся проблемой для разработчиков Windows, поэтому, надеюсь, это будет полезно кому-то еще.

person dan-O    schedule 30.07.2015
comment
Могу подтвердить это как повторяющуюся проблему. Спасибо за исправление - person Sergio Basurco; 06.02.2017