Boost Log Установка поворота и максимального размера файла приводит к добавлению 2-й раковины, когда ранее вызывается Remove_All_Sinks () - PullRequest
0 голосов
/ 05 февраля 2019

Использование Boost log для целей ведения журнала (duh) - и я успешно инициализируюсь:

BOOST_LOG_GLOBAL_LOGGER_INIT(logger, logger_t) {
    logger_t lg;
    logging::add_common_attributes();
    boost::shared_ptr< file_sink > sink(new file_sink(
        boost::log::keywords::file_name = "appLog_%N.log",
        boost::log::keywords::rotation_size = 2 * 1024 * 1024,
        boost::log::keywords::max_size = 10 * 1024 * 1024,
        boost::log::keywords::scan_method = 
        boost::log::sinks::file::scan_method::scan_matching,
        boost::log::keywords::open_mode = std::ios_base::app,
        boost::log::keywords::auto_flush = true
    ));

    sink->set_formatter(
        expr::stream
        << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%dT%H:%M:%S.%fz")
        << ": [" << logging::trivial::severity
        << "]\t" << expr::smessage
    );

    sink->locked_backend()->set_file_collector(boost::log::sinks::file::make_collector(
        boost::log::keywords::target = "",                      /*< the target directory >*/
        boost::log::keywords::max_size = 10 * 1024 * 1024,          /*< maximum total size of the stored files, in bytes >*/
        boost::log::keywords::min_free_space = 1 * 1024 * 1024,   /*< minimum free space on the drive, in bytes >*/
        boost::log::keywords::max_files = 10                       /*< maximum number of stored files >*/
    ));

    sink->locked_backend()->scan_for_files(boost::log::sinks::file::scan_method::scan_matching, true);

    logging::core::get()->add_sink(sink);

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

    return lg;
}

Однако после считывания и обработки файла конфигурации приложения, который включает значения, указывающие вращение_size и max_size для ведения журнала. У меня возникают проблемы с удалением всех приемников, прежде чем создавать новый приемник с указанными значениями вращением_size, а max_size просто добавляет приемник поверх существующего приемника, который был инициализирован глобально (чтов результате каждое сообщение регистрируется дважды).

Функция обновления размеров журнала выглядит следующим образом:

void setLoggerSizes(int rotationSize, int maxSize)
{
    //INFO << "";

    logging::core::get()->remove_all_sinks();

    logging::add_common_attributes();

    boost::shared_ptr< file_sink > sink(new file_sink(
        boost::log::keywords::file_name = "appLog_%N.log",
        boost::log::keywords::rotation_size = rotationSize * 1024 * 1024,
        boost::log::keywords::max_size = maxSize * 1024 * 1024,
        boost::log::keywords::scan_method = boost::log::sinks::file::scan_method::scan_matching,
        boost::log::keywords::open_mode = std::ios_base::app,
        boost::log::keywords::auto_flush = true
    ));

    sink->set_formatter(
        expr::stream
        << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%dT%H:%M:%S.%fz")
        << ": [" << logging::trivial::severity
        << "]\t" << expr::smessage
    );

    sink->locked_backend()->set_file_collector(
        boost::log::sinks::file::make_collector(
            boost::log::keywords::target = "",
            boost::log::keywords::max_size = maxSize * 1024 * 1024,
            boost::log::keywords::min_free_space = 1 * 1024 * 1024
        )
    );

    sink->locked_backend()->scan_for_files();   

    logging::core::get()->add_sink(sink);
}

Тем не менее, если я добавлю INFO << ""; в началеэтой функции, кажется, вызывает принудительное удаление всех приемников, и при добавлении приемника с правильными размерами файла получается один приемник (и, следовательно, только одна копия сообщений для передачи в журнал).

Итак, мои вопросы:

  1. Почему это происходит с INFO << "";?Это не имеет никакого логического смысла относительно того, почему добавление этой строки действительно приведет к удалению всех приемников, вызываемых в следующей строке, и, следовательно, приведет к регистрации одной копии сообщений.Принимая во внимание, что, за исключением строки INFO, вызов logging::core::get()->remove_all_sinks(); игнорируется, а приемник, который добавляется с правильными размерами файлов, добавляется поверх инициализированного приемника, что приводит к двум копиям каждого сообщения, которое необходимо регистрировать.
  2. Как правильно установить вращение и максимальные размеры, если я не делаю это сейчас, при ведении глобального регистратора?

Для справки, это Logger.hфайл:

#pragma once

#include <boost/log/expressions.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup.hpp>

#define FATAL  BOOST_LOG_SEV(logger::get(), boost::log::trivial::fatal)
#define WARNING  BOOST_LOG_SEV(logger::get(), boost::log::trivial::warning)
#define INFO BOOST_LOG_SEV(logger::get(), boost::log::trivial::info)
#define DEBUG BOOST_LOG_SEV(logger::get(), boost::log::trivial::debug)
#define TRACE BOOST_LOG_SEV(logger::get(), boost::log::trivial::trace)

typedef boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> logger_t;
typedef boost::log::sinks::synchronous_sink< boost::log::sinks::text_file_backend > file_sink;

BOOST_LOG_GLOBAL_LOGGER(logger, logger_t)

void setLoggerSizes(int rotationSize, int maxSize);

1 Ответ

0 голосов
/ 06 февраля 2019

Проблема, с которой вы сталкиваетесь, наиболее вероятна из-за порядка выполнения операторов логирования в вашей программе.

Тело BOOST_LOG_GLOBAL_LOGGER_INIT и аналогичного макроса BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT выполняется один разкогда программа запрашивает глобальный регистратор в первый раз (см. здесь ).Итак, поскольку вы запрашиваете регистратор из макроса INFO, это тело выполняется перед вызовом remove_all_sinks и дальнейшей инициализацией библиотеки журналирования.Когда вы комментируете эту строку, эта инициализация откладывается до вашего первого выполненного оператора записи в журнал, что, по-видимому, происходит после возврата setLoggerSizes.Следовательно, remove_all_sinks не имеет никакого эффекта, поскольку в точке этого вызова нет приемников, которые нужно удалить.

Макросы _INIT действительно предназначены для инициализации logger , а не всегобиблиотека журналов (т.е. приемники, фильтры и что нет).Вы можете инициализировать библиотеку из этих макросов, но, как вы выяснили, полезность этого довольно ограничена (в основном, она, скорее всего, не будет работать должным образом, если у вас нет единого глобального регистратора, который также является единственным регистратором, который выиспользовать во всем приложении, и вам не нужно обновлять конфигурацию журналирования после ее инициализации).Правильный способ сделать это - отдельно инициализировать библиотеку журналов в функции, которую вы будете вызывать в начале main, и использовать макросы _INIT только для инициализации регистраторов.

...