Как выставить и зарегистрировать одно ядро ​​журнала буста в другом

И dll, и исполняемый файл используют boost::log. В конечном итоге они используют разные одноэлементные ядра журнала. Как я могу открыть ядро ​​​​dll для исполняемого файла и зарегистрировать ядро ​​​​dll для исполняемого ядра, чтобы я мог перенаправить оба в один файл журнала.

Я написал минимальный пример, чтобы проиллюстрировать, где я спотыкаюсь:

Логусер.hpp

#pragma once

#ifdef DYNLIB_EXPORTS
#define DYNLIB_API __declspec(dllexport)
#else
#define DYNLIB_API __declspec(dllimport)
#endif

class DYNLIB_API LogUser
{
public:
    LogUser();
    ~LogUser() {}
};

Логусер.cpp

#include "LogUser.hpp"
#include <boost\log\trivial.hpp>
LogUser::LogUser()
{
    BOOST_LOG_TRIVIAL(trace) << "LogUser constructed";
}

Main.cpp

#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>

#pragma comment (lib, "dynlib.lib")
#include <dynlib/LogUser.hpp>

void setupLogging();

int main()
{
    setupLogging();
    BOOST_LOG_TRIVIAL(trace) << "main enter";
    LogUser dynamicLogUser;
    BOOST_LOG_TRIVIAL(trace) << "main exit";
    return 0;
}

void setupLogging()
{
    using namespace boost::log;
    add_common_attributes();
    register_simple_formatter_factory< trivial::severity_level, char >("Severity");
    add_file_log
        (
        keywords::file_name = "file.log",
        keywords::format = "[%TimeStamp%] [%ThreadID%] [%Severity%]: %Message%"
        );
}

LogUser компилируется в LogUser.dll. Конструктор LogUser создает сообщение трассировки, которое заканчивается на консоли. Main перенаправляет свой вывод в файл журнала, но не перенаправляет вывод dll в тот же файл журнала. Я предполагаю, что dll содержит собственное ядро ​​журнала, и мне сначала придется перенаправить его сообщения на другое ядро. Я погуглил проблему и не могу найти простого решения, хотя мне кажется, что это должен быть однострочный вызов в main во время установки. И геттер для синглтона boost logcore в интерфейсе dll.

Есть ли стандартный способ, который мне не хватает? Как бы я перенаправил этот журнал сюда?

Правка №1: - вывод в моей системе и выдумка того, что я хочу сделать. введите здесь описание изображения

Изменить № 2: - Я нашел возможное решение здесь. - Если этот совет решит проблему, я удалю этот вопрос, потому что я клон.

Редактировать № 3: я реализовал предложенное решение из РЕДАКТИРОВАТЬ № 2. Это работает, но это не то, что я хочу.

По сути, вы должны #define BOOST_LOG_DYN_LINK . К сожалению, это не работает, так как журнал использует другие библиотеки, которые также необходимо добавлять рекурсивно. Я закончил с #define BOOST_ALL_DYN_LINK . Весь буст теперь сделан динамическим, и с V1.59 это может быть 30 dll. В моем минимальном примере мне пришлось предоставить dll для хроно, date_time, файловой системы, log_setup, журнала, регулярного выражения, системы и потока (.count = 8).

Таким образом, несмотря на то, что результат именно тот, который я хотел получить, отличается, это отличает этот вопрос от другого вопроса. Подход DLL гарантирует, что есть только один синглтон dll ядра. Я предпочитаю иметь 2 ядра, а не поставлять DLL, поэтому для меня приемлемо их объединение в цепочку.

Есть ли способ получить тот же результат при статической компоновке?


person Johannes    schedule 02.11.2015    source источник


Ответы (2)


Boost.Log требуется для сборки в виде разделяемой библиотеки, если вы используете ее из нескольких модулей. Дизайн библиотеки основан на этом требовании, и ядро ​​ведения журнала — не единственный синглтон в библиотеке. В зависимости от того, какие функции библиотеки вы используете, вы с большей или меньшей вероятностью столкнетесь с трудными для отладки проблемами, если нарушите это предварительное условие. Также возможно, что код, который работает с вашей текущей версией Boost.Log, не работает с другой версией.

person Andrey Semashev    schedule 03.11.2015
comment
Вы участвуете в разработке Boost.Log, верно? Как мне связаться с вами? Я хотел бы поделиться видением того, как это можно сделать, и посмотреть, стоит ли, по вашему мнению, затраченных усилий. Я хотел бы помочь реализовать изменения, участвуя в качестве программиста. - person Johannes; 03.11.2015
comment
Конечно. Вы можете отправлять запросы на вытягивание и проблемы на GitHub: github.com/boostorg/log. Обсуждения библиотеки ведутся в списке рассылки разработчиков Boost: boost.org/community/groups .html#основной. - person Andrey Semashev; 04.11.2015

Все это сводится к глобальным переменным. «Singleton» — это просто другое название глобальной переменной.

Если вы статически свяжете свой исполняемый файл и свою DLL с Boost, то у каждого из них будет свой синглтон (глобальная переменная). Если вы хотите поделиться ими, вам нужно связать свой исполняемый файл и вашу DLL с общей библиотекой журналов, чтобы они использовали один и тот же глобальный синглтон.

Это просто следствие использования разделяемых библиотек: они имеют тенденцию заставлять другие библиотеки также совместно использоваться из-за глобальных данных.

person legalize    schedule 02.11.2015
comment
@legalze Спасибо за отзыв - я смог сделать то, что вы описываете, но мне все еще интересно, есть ли другой (встроенный) способ. Одним из примеров может быть создание приемника/логгера. Один конец соединяется с одним из сердечников, а другой конец соединяется с другим сердечником. Поскольку я не знаю конструкции, возможно даже, что ядра представляют собой оболочку с внутренним представлением, которое можно соединить. Обе возможности допускают статическое связывание и общее ведение журнала. Я спрашиваю, возможно ли что-то в этом роде с дизайном журнала повышения. - person Johannes; 02.11.2015
comment
В документации показан только один статический геттер для получения ядра; похоже, нет другого способа поделиться им, кроме как через этот глобальный синглтон. Таким образом, у вас не остается никаких других вариантов без изменения исходного кода. - person legalize; 02.11.2015