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

Adding more information to log: Attributes

Boost , Chapter 1. Boost.Log v2 , Tutorial

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

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

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

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

Ниже приводится описание процесса регистрации атрибутов.

Commonly used attributes

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

logging::add_common_attributes();

С помощью этого вызова атрибуты «LineID», «TimeStamp», «ProcessID» и «ThreadID» регистрируются по всему миру. Атрибут «LineID» является счетчиком, который увеличивает для каждой сделанной записи, первая запись получает идентификатор. 1.Атрибут "TimeStamp" всегда дает текущее время (т.е. время, когда создается запись журнала, а не время, когда она была записана в раковину). Последние два атрибута идентифицируют процесс и поток, в котором испускается каждая запись журнала.

[Note]Note

В однопоточной сборке атрибут «ThreadID» не регистрируется.

[Tip]Tip

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

Функция add_common_attributes является одним из нескольких помощников удобства, описанных here.

Некоторые атрибуты автоматически регистрируются при строительстве лесозаготовителей. Например, severity_logger регистрирует атрибут "Severity", который может быть использован для добавления уровня акцента для различных записей журнала. Например:

// We define our own severity levels
enum severity_level
{
    normal,
    notification,
    warning,
    error,
    critical
};
void logging_function()
{
    // The logger implicitly adds a source-specific attribute 'Severity'
    // of type 'severity_level' on construction
    src::severity_logger< severity_level > slg;
    BOOST_LOG_SEV(slg, normal) << "A regular message";
    BOOST_LOG_SEV(slg, warning) << "Something bad is going on but I can handle it";
    BOOST_LOG_SEV(slg, critical) << "Everything crumbles, shoot me now!";
}

[Tip]Tip

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

BOOST_LOG_SEV Макро действует очень похоже на BOOST_LOG за исключением того, что для метода регистратора open_record требуется дополнительный аргумент. Макрос BOOST_LOG_SEV можно заменить следующим эквивалентом:

void manual_logging()
{
    src::severity_logger< severity_level > slg;
    logging::record rec = slg.open_record(keywords::severity = normal);
    if (rec)
    {
        logging::record_ostream strm(rec);
        strm << "A regular message";
        strm.flush();
        slg.push_record(boost::move(rec));
    }
}

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

More attributes

Давайте посмотрим, что находится под капотом этой функции add_common_attributes, которую мы использовали в разделе простой формы. Это может выглядеть примерно так:

void add_common_attributes()
{
    boost::shared_ptr< logging::core > core = logging::core::get();
    core->add_global_attribute("LineID", attrs::counter< unsigned int >(1));
    core->add_global_attribute("TimeStamp", attrs::local_clock());
    // other attributes skipped for brevity
}

Здесь компоненты counter и local_clock являются классами атрибутов, они происходят из общего интерфейса атрибутов attribute. Библиотека предоставляет ряд других классов атрибутов , в том числе атрибут функция , который вызывает некоторый объект функции на приобретение стоимости. Например, мы можем аналогичным образом зарегистрировать атрибут named_scope:

core->add_global_attribute("Scope", attrs::named_scope());

Это даст нам возможность хранить имена областей в журнале для каждой записи журнала, которую делает приложение. Вот как он используется:

void named_scope_logging()
{
    BOOST_LOG_NAMED_SCOPE("named_scope_logging");
    src::severity_logger< severity_level > slg;
    BOOST_LOG_SEV(slg, normal) << "Hello from the function named_scope_logging!";
}

Специфические атрибуты логгера не менее полезны, чем глобальные. Уровни жесткости и названия каналов являются наиболее очевидными кандидатами для реализации на исходном уровне. Ничто не мешает вам добавлять больше атрибутов к вашим лесозаготовителям, например:

void tagged_logging()
{
    src::severity_logger< severity_level > slg;
    slg.add_attribute("Tag", attrs::constant< std::string >("My tag value"));
    BOOST_LOG_SEV(slg, normal) << "Here goes the tagged record";
}

Теперь все записи журнала, сделанные через этого регистратора, будут помечены конкретным атрибутом. Это значение атрибута может быть использовано позже в фильтрации и форматировании.

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

void timed_logging()
{
    BOOST_LOG_SCOPED_THREAD_ATTR("Timeline", attrs::timer());
    src::severity_logger< severity_level > slg;
    BOOST_LOG_SEV(slg, normal) << "Starting to time nested functions";
    logging_function();
    BOOST_LOG_SEV(slg, normal) << "Stopping to time nested functions";
}

Теперь каждая запись журнала, сделанная из функции logging_function или любой другой функции, которую она вызывает, будет содержать атрибут «Timeline» с высокой точностью продолжительности времени, прошедшей с момента регистрации атрибута. На основе этих показаний можно определить, какие части кода требуют больше или меньше времени для выполнения. Атрибут «Timeline» будет незарегистрирован при выходе из объема функции timed_logging.

См. раздел Атрибуты для подробного описания атрибутов, предоставляемых библиотекой. Полный код для этого раздела доступен здесь .

Defining attribute placeholders

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

BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int)
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string)
BOOST_LOG_ATTRIBUTE_KEYWORD(scope, "Scope", attrs::named_scope::value_type)
BOOST_LOG_ATTRIBUTE_KEYWORD(timeline, "Timeline", attrs::timer::value_type)

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


PrevUpHomeNext

Статья Adding more information to log: Attributes раздела Chapter 1. Boost.Log v2 Tutorial может быть полезна для разработчиков на c++ и boost.




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



:: Главная :: Tutorial ::


реклама


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

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