boost::log закрыть файл журнала и открыть новый

Я использую boost::log для одновременного входа в файл и в консоль. Он инициализируется так:

void Init() {
logging::core::get()->set_filter
    (
        // set logging level to one of trace, debug, info, warning, error, fatal
        logging::trivial::severity >= logging::trivial::trace
    );
logging::add_common_attributes(); // enables timestamps and such
logging::add_file_log
    (
        keywords::file_name     = logfile + "_%N.log",
        keywords::rotation_size = 1024 * 1024 * 50, // 50MB log file max
        //       keywords::format = "[%TimeStamp%]: %Message%"
        keywords::format        = "%Message% #[%TimeStamp%]"
    );

logging::add_console_log(std::cout,
                         keywords::format = "%Message%"
);
}

В определенные моменты моей программы я хотел бы изменить файл журнала вручную. Я могу изменить строку «logfile» в приведенном выше коде и снова вызвать Init(), но затем он продолжит запись в старый файл журнала и запустит новый, и начнет удваивать вывод в журнале консоли.

Есть ли какой-то соответствующий «remove_file_log», который мне не хватает, или вручную сказать ему, чтобы он прекратил запись в исходный журнал и перешел к следующему?


person Aurelius    schedule 01.01.2017    source источник


Ответы (1)


Каждый вызов add_file_log регистрирует новый приемник файлов в ядре ведения журналов, что приводит к одновременной записи нескольких файлов. Существующие раковины не заменяются. В зависимости от того, что вы на самом деле хотите сделать, вы можете сделать несколько вещей.

Во-первых, если вы посмотрите на add_file_log , вы заметите, что он возвращает указатель на созданный приемник. Вы можете передать этот указатель в core::remove_sink, когда вы хотите, чтобы этот приемник перестал использоваться. После уничтожения приемник закроет файл журнала, который он использовал.

typedef sinks::synchronous_sink< sinks::text_file_backend > sink_t;
boost::shared_ptr< sink_t > g_file_sink;

void Init() {
    // ...
    g_file_sink = logging::add_file_log
    (
        keywords::file_name     = logfile + "_%N.log",
        keywords::rotation_size = 1024 * 1024 * 50, // 50MB log file max
        keywords::format        = "%Message% #[%TimeStamp%]"
    );

    // ...
}

void StopFileLogging() {
    logging::core::get()->remove_sink(g_file_sink);
    g_file_sink.reset();
}

Во-вторых, text_file_backend, созданный и возвращенный add_file_log, имеет возможность чередовать файлы журналов. Если вы просто хотите переключать файл журнала в определенных точках программы, это то, что вы, вероятно, ищете. Вы можете добавить именованные параметры, такие как keywords::rotation_size, к вызову add_file_log, и они будут использоваться для настройки автоматической ротации файлов в бэкэнде. Вы также можете повернуть файл вручную, вызвав text_file_backend::rotate_file на серверной части приемника.

void RotateLogFile() {
    g_file_sink->locked_backend()->rotate_file();
}

Обратите внимание, что в этом случае вам не нужно удалять сток из ядра; он остается активным после поворота файла.

person Andrey Semashev    schedule 02.01.2017
comment
могу ли я сбросить бэкэнд в ноль, чтобы преобразовать его с новым файлом журнала? И если он является членом структуры, которая помещена в мультииндексный контейнер, итератор для структуры является константой, что делает ошибку при попытке сбросить общий указатель на бэкенде, как может я конвертирую константный общий указатель на серверную часть в неконстантную ссылку на общий указатель на серверную часть?? - person ahmed allam; 03.01.2020