Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Detailed features description

Boost , Chapter 1. Boost.Log v2 , Chapter 1. Boost.Log v2

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext
#include <boost/log/core/record.hpp>

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

enum severity_level { ... };
std::ostream& operator<< (std::ostream& strm, severity_level level);
struct print_visitor
{
    typedef void result_type;
    result_type operator() (severity_level level) const
    {
        std::cout << level << std::endl;
    };
};
// Prints severity level through visitation API
void print_severity_visitation(logging::record const& rec)
{
    logging::visit< severity_level >("Severity", rec, print_visitor());
}
// Prints severity level through extraction API
void print_severity_extraction(logging::record const& rec)
{
    logging::value_ref< severity_level > level = logging::extract< severity_level >("Severity", rec);
    std::cout << level << std::endl;
}

// Prints severity level by searching the attribute values
void print_severity_lookup(logging::record const& rec)
{
    logging::attribute_value_set const& values = rec.attribute_values();
    logging::attribute_value_set::const_iterator it = values.find("Severity");
    if (it != values.end())
    {
        logging::attribute_value const& value = it->second;
        // A single attribute value can also be visited or extracted
        std::cout << value.extract< severity_level >() << std::endl;
    }
}

  • Применяя оператора subscript с ключевым словом атрибута. На самом деле это удобная обертка вокруг API извлечения ценности.

BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
// Prints severity level by using the subscript operator
void print_severity_subscript(logging::record const& rec)
{
    // Use the attribute keyword to communicate the name and type of the value
    logging::value_ref< severity_level, tag::severity > level = rec[severity];
    std::cout << level << std::endl;
}

Записи журнала не могут быть скопированы, только перемещены. Запись может быть построена по умолчанию, и в этом случае она находится в пустом состоянии; такие записи в основном непригодны для использования и не должны передаваться в библиотеку для обработки. Непустые журнальные записи могут быть созданы только ядромжурналированияв результате успешной фильтрации. Непустая запись содержит значения атрибутов, полученные из атрибутов. Дополнительные значения атрибутов могут быть добавлены к непустой записи после фильтрации. Добавленные значения не влияют на результаты фильтрации, но все еще могут использоваться формататорами и поглотителями.

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

Record views
#include <boost/log/core/record_view.hpp>

В то время как записи используются для заполнения информации, библиотека использует другой тип для ее обработки. Виды записей обеспечивают аналогичный интерфейс для записей с несколькими заметными отличиями:

  • Виды записей неизменны. Это предотвращает изменение форматировщиками и поглотителями записи во время ее обработки.
  • Просмотр записей является копируемым. Поскольку его содержимое постоянно, копирование неглубоко и, следовательно, дешево.

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

#include <boost/log/core/core.hpp>

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

  • Поддерживает глобальные и нитевидные наборы атрибутов.
  • Выполняет глобальную фильтрацию журнальных записей.
  • Отправляет записи журнала между раковинами, применяя фильтры, специфичные для раковины.
  • Обеспечивает глобальный крюк для обработчиков исключений.
  • Предоставляет точку входа для источников журнала, чтобы поставить записи журнала.
  • Предоставляетметод промывки, который может использоваться для обеспечения синхронизированного состояния для всех бревенчатых раковин.

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

void foo()
{
    boost::shared_ptr< logging::core > core = logging::core::get();
    // ...
}

Для добавления или удаления глобальных или нитевидных атрибутов в ядро существуют соответствующие методы:add_global_attribute,remove_global_attribute,add_thread_attributeиremove_thread_attribute. Наборы атрибутов обеспечивают интерфейс, аналогичныйstd::map, так чтоadd_*методы принимают строку имени атрибута (ключ) и указатель на атрибут (картированное значение) и возвращают пару итератораstd::map<...>::вставкаделает. Способыудалить_*принимают итератор к ранее добавленному атрибуту.

void foo()
{
    boost::shared_ptr< logging::core > core = logging::core::get();
    // Add a global attribute
    std::pair< logging::attribute_set::iterator, bool > res =
        core->add_global_attribute("LineID", attrs::counter< unsigned int >());
    // ...
    // Remove the added attribute
    core->remove_global_attribute(res.first);
}
[Tip]Tip

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

Можно приобрести копию всего набора атрибутов (глобального или нитевидного) или установить его в ядро. Методыget_global_attributes,set_global_attributes,get_thread_attributesиset_thread_attributesслужат этой цели.

[Warning]Warning

После установки целого набора атрибутов в ядро все итераторы, которые ранее были возвращены соответствующимиметодами add_*, признаются недействительными. В частности, он влияет наатрибуты, поэтому пользователь должен быть осторожным при переключении наборов атрибутов.

Глобальная фильтрация обрабатывается объектом функции фильтра, который может быть обеспечен методомset_filter. Более подробная информация о создании фильтров содержится вэтом разделе. Здесь достаточно будет сказать, что фильтр принимает набор значений атрибутов и возвращает булево значение, которое сообщает, прошла ли запись журнала с этими значениями атрибутов фильтрацию или нет. Глобальный фильтр применяется к каждой записи журнала, сделанной во всем приложении, поэтому его можно использовать для быстрого уничтожения чрезмерных записей журнала.

Глобальный фильтр может быть удален методомreset_filter. Когда в ядре нет фильтра, предполагается, что никакие записи не отфильтровываются. Это дефолт после первоначального строительства лесозаготовительного ядра.

enum severity_level
{
    normal,
    warning,
    error,
    critical
};
void foo()
{
    boost::shared_ptr< logging::core > core = logging::core::get();
    // Set a global filter so that only error messages are logged
    core->set_filter(expr::attr< severity_level >("Severity") >= error);
    // ...
}

Ядро также предоставляет еще один способ отключить лесозаготовку. Позвонивset_logging_enabledс булевым аргументом, можно полностью отключить или повторно включить журналирование, включая применение фильтрации. Отключение регистрации с помощью этого метода может быть более полезным с точки зрения производительности приложения, чем установка глобального фильтра, который всегда выходит из строя.

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

void foo()
{
    boost::shared_ptr< logging::core > core = logging::core::get();
    // Set a sink that will write log records to the console
    boost::shared_ptr< sinks::text_ostream_backend > backend =
        boost::make_shared< sinks::text_ostream_backend >();
    backend->add_stream(
        boost::shared_ptr< std::ostream >(&std::clog, boost::null_deleter()));
    typedef sinks::unlocked_sink< sinks::text_ostream_backend > sink_t;
    boost::shared_ptr< sink_t > sink = boost::make_shared< sink_t >(backend);
    core->add_sink(sink);
    // ...
    // Remove the sink
    core->remove_sink(sink);
}

Подробнее о конструкции раковин можно прочитать в следующих разделах:Sink FrontendsиSink Backends.

Ядро обеспечивает способ централизованной обработки исключений. Если исключение происходит во время фильтрации или обработки в одной из добавленных раковин, ядро вызовет обработчик исключений, если он был установлен методомset_ Exception_handler. Обработчик исключений представляет собой объект нулевой функции, который вызывается из пунктаулова. Библиотека предоставляетинструментыдля упрощения построения обработчиков исключений.

[Tip]Tip

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

struct my_handler
{
    typedef void result_type;
    void operator() (std::runtime_error const& e) const
    {
        std::cout << "std::runtime_error: " << e.what() << std::endl;
    }
    void operator() (std::logic_error const& e) const
    {
        std::cout << "std::logic_error: " << e.what() << std::endl;
        throw;
    }
};
void init_exception_handler()
{
    // Setup a global exception handler that will call my_handler::operator()
    // for the specified exception types
    logging::core::get()->set_exception_handler(logging::make_exception_handler<
        std::runtime_error,
        std::logic_error
    >(my_handler()));
}

Одной из наиболее важных функций лесозаготовительного ядра является обеспечение точки входа для всех источников лесозаготовок для подачи записей журналов. Это делается с помощью методовopen_recordиpush_record.

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

Когда источник журнала готов завершить процедуру регистрации, он должен вызвать методpush_recordс записью, возвращенной методомopen_record. Обратите внимание, что не следует звонитьpush_recordс пустой записью. Запись должна быть принята в качестве ссылки на значение r. Во время вызова вид записи будет построен из записи. Затем вид будет передан раковинам, которые приняли его во время фильтрации. Это может включать в себя форматирование записи и дальнейшую обработку, например, хранение ее в файл или отправку по сети. После этого рекордный объект может быть уничтожен.

void logging_function(logging::attribute_set const& attrs)
{
    boost::shared_ptr< logging::core > core = logging::core::get();
    // Attempt to open a log record
    logging::record rec = core->open_record(attrs);
    if (rec)
    {
        // Ok, the record is accepted. Compose the message now.
        logging::record_ostream strm(rec);
        strm << "Hello, World!";
        strm.flush();
        // Deliver the record to the sinks.
        core->push_record(boost::move(rec));
    }
}

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


PrevUpHomeNext

Статья Detailed features description раздела Chapter 1. Boost.Log v2 Chapter 1. Boost.Log v2 может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 1. Boost.Log v2 ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 19:21:05/0.012595176696777/1