boost::log::sinks::text_ostream_backend: извлечь символы (потокобезопасно)

148
24 октября 2018, 11:10

Используется библиотека Boost.Log v2 1.66.

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

Сессия создается на основании примера из: https://www.boost.org/doc/libs/1_66_0/libs/log/doc/html/log/detailed/sink_backends.html#log.detailed.sink_backends.text_ostream

Пример не точный, демонстрирует исключительно общий подход

using Logger = boost::log::sources::severity_channel_logger_mt<boost::log::trivial::severity_level, std::string>;
class MyClass
{
  mutable std::mutex  m_mutex;
  mutable Logger      m_logger {boost::log::keywords::channel = "MyClass"};
  std::stringstream   m_ss;
  bool                m_completed {false};
public:
  void initLogging(const std::string& id)
  {
    using namespace boost::log;
    using Sink = sinks::synchronous_sink<sinks::text_ostream_backend>;
    auto backend = boost::make_shared<sinks::text_ostream_backend>();
    backend->add_stream(boost::shared_ptr<std::stringstream>(&m_ss, boost::null_deleter()));
    auto sink = boost::make_shared<Sink>(backend);
    sink->set_filter(expressions::has_attr<std::string>("ID") && expressions::attr<std::string>("ID") == id);
    core::get()->add_sink(sink);
    m_logger.add_attribute("ID", attributes::constant<std::string>(id));
  }
  void doSomething()
  {
    BOOST_LOG_SEV(logger, boost::log::trivial::severity_level::debug) << "TEST";
    BOOST_LOG_SEV(logger, boost::log::trivial::severity_level::error) << "TEST";
    // После этого более не будут создаваться сообщения которые бы подпадали под условия нашего фильтра
    std::lock_guard<std::mutex> lock(m_mutex);
    m_completed = true;
  }
  void access()
  {
    std::lock_guard<std::mutex> lock(m_mutex);
    if (m_completed) {
      // Безопасный доступ к m_ss
    }
  }
};

Текущий вариант осуществляет доступ к стриму после того как Boost.Log гарантированно уже ничего не запишет в него (так, как в качестве фронтенда используется sinks::synchronous_sink). Но это не так удобно. Хочется иметь возможность получать данные (копию m_ss) в любой момент времени.

READ ALSO
Ошибка при вызове деструктора

Ошибка при вызове деструктора

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

175
sqlite3_open не получаетсяоткрыть базу в явно указанной директории

sqlite3_open не получаетсяоткрыть базу в явно указанной директории

ОС - Windows Кодировка входной строки - неизвестна, но скорее всего виндовская будетКодировка файлов проекта - набор символов юникода

198
EntityManager persist() не сохраняет данные в БД ( PostgreSQL )

EntityManager persist() не сохраняет данные в БД ( PostgreSQL )

При нажатии на кнопку Register должен добавляться новый пользователь в БДКонсоль выдает :

176
Package is declared in module, which is not in the module graph

Package is declared in module, which is not in the module graph

Сегодня запустил свой проект, обновил Intellij IDEA и произошло нечто такое, из-за чего я не могу писать свой прекрасный код

302