12 Architecture Research and main usage Summary of boost log Library

Source: Internet
Author: User

I have done a lot of boost log examples, now To sum up, the latest code in my open source project: https://gitlab.com/mystudy/boost_log

The architecture diagram of the boost log library is as follows:


The following summarizes the knowledge related to this architecture:

1. How to obtain the Logging core

#include <boost/log/core.hpp>...boost::shared_ptr<logging::core> core = logging::core::get();

2. How to install the Sink object

Multiple sinks can be installed on one core. The following Code assumes that two Sink objects exist and installs them into the core.

  core->add_sink(sink1);...  core->add_sink(sink2);

3. How to Create a Sink object

You must first create a backend object, and then pass the backend object to it when creating the sink object.

  typedef sinks::synchronous_sink<sinks::text_file_backend> TextSink;  // init sink1  boost::shared_ptr<sinks::text_file_backend> backend1 = boost::make_shared<sinks::text_file_backend>(  keywords::file_name = "sign_%Y-%m-%d_%H-%M-%S.%N.log",  keywords::rotation_size = 10 * 1024 * 1024,  keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),  keywords::min_free_space = 30 * 1024 * 1024);  boost::shared_ptr<TextSink> sink1(new TextSink(backend1));

4. How to Create a backend object to specify the frontend type

As shown in the previous Code, note that a frontend type must be set as its template class for the backend type. Therefore, when you create a backend object, you have determined the frontend.

This frontend template can use the synchronous_sink class or asynchronous_sink class. The latter does not block the calling program and will create additional threads to process logs. However, it will be slower and the memory consumption will increase. It is generally recommended that the latter be used first.


Construct parameters with keywords

Here we can see a concept: keywords. There are 27 hpp files in the boost/log/keywords/directory:

auto_flush.hpp  facility.hpp   ident.hpp       log_source.hpp      open_mode.hpp        rotation_size.hpp  target.hppchannel.hpp     file_name.hpp  ip_version.hpp  max_size.hpp        order.hpp            scan_method.hpp    time_based_rotation.hppdelimiter.hpp   filter.hpp     iteration.hpp   message_file.hpp    ordering_window.hpp  severity.hpp       use_impl.hppdepth.hpp       format.hpp     log_name.hpp    min_free_space.hpp  registration.hpp     start_thread.hpp

Keywords is the basic concept of the boost library. It is designed to a macro BOOST_PARAMETER_KEYWORD, which is defined in the boost/parameter/keywords. hpp file. The main function is to create a singleton object in the specified namespace. Therefore, the preceding lines of keywords: The Code assigns values to the singleton objects file_name, rotation, time_based_rotation, and min_free_space In the keywords namespace. The key is to see how the constructor of the following class uses these keywords.
sinks::text_file_backend

Reference:

Http://boost-log.sourceforge.net/libs/log/doc/html/log/detailed/sink_backends.html

Http://www.boost.org/doc/libs/1_55_0/libs/log/doc/html/boost/log/sinks/text_file_backend.html

Note: The text_file_backend constructor syntax supports variable parameters, but only supports limited keywords:

    template< typename ArgsT >    void construct(ArgsT const& args)    {        construct(            filesystem::path(args[keywords::file_name | filesystem::path()]),            args[keywords::open_mode | (std::ios_base::trunc | std::ios_base::out)],            args[keywords::rotation_size | (std::numeric_limits< uintmax_t >::max)()],            args[keywords::time_based_rotation | time_based_rotation_predicate()],            args[keywords::auto_flush | false]);    }

This is also true in the document. However, the Code for min_free_space is found in the text_file_backend.hpp file:

namespace aux {    //! Creates and returns a file collector with the specified parameters    BOOST_LOG_API shared_ptr< collector > make_collector(        filesystem::path const& target_dir,        uintmax_t max_size,        uintmax_t min_free_space    );    template< typename ArgsT >    inline shared_ptr< collector > make_collector(ArgsT const& args)    {        return aux::make_collector(            filesystem::path(args[keywords::target]),            args[keywords::max_size | (std::numeric_limits< uintmax_t >::max)()],            args[keywords::min_free_space | static_cast< uintmax_t >(0)]);    }} // namespace aux

Therefore, it is estimated that the keywords such as target, max_size, and min_free_space can still be used. You will know it after trying it.

5. How to specify the format in sink

The following describes the specified log format, which must be specified in the sink, for example:

  sink1->set_formatter (expr::format("[%1%]<%2%>(%3%): %4%")% expr::format_date_time< boost::posix_time::ptime>("TimeStamp", "%Y-%m-%d %H:%M:%S")% expr::attr<sign_severity_level>("Severity")% expr::attr<attrs::current_thread_id::value_type>("ThreadID")% expr::smessage);


Boost: Format the key here is understanding expr: format. Documentation here: http://www.boost.org/doc/libs/1_55_0/libs/log/doc/html/log/detailed/expressions.html#log.detailed.expressions.formatters

I am using the Boost: Format style.


Attributes

Reference: http://boost-log.sourceforge.net/libs/log/doc/html/log/detailed/attributes.html

According to the design, log records are composed of attributes, so the printed content must be transmitted to the sink object in the form of attribute.

  sink1->set_formatter (expr::format("[%1%]<%2%>(%3%)(%4%): %5%")% expr::attr<unsigned int>("LineID")% expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")% expr::attr<sign_severity_level>("Severity")% expr::attr<attrs::current_thread_id::value_type >("ThreadID")% expr::smessage);

Do not forget to add commont attributes

  logging::add_common_attributes();
This function is defined in the boost/log/utility/setup/common_attributes.hpp file, which contains four attributes:

inline void add_common_attributes(){    shared_ptr< core > pCore = core::get();    pCore->add_global_attribute(        aux::default_attribute_names::line_id(),        attributes::counter< unsigned int >(1));    pCore->add_global_attribute(        aux::default_attribute_names::timestamp(),        attributes::local_clock());    pCore->add_global_attribute(        aux::default_attribute_names::process_id(),        attributes::current_process_id());#if !defined(BOOST_LOG_NO_THREADS)    pCore->add_global_attribute(        aux::default_attribute_names::thread_id(),        attributes::current_thread_id());#endif}


6. Name scope

Name scope is also a solution in the preceding format, but it is described separately because it is complicated.

Stack element

First understand the structure named_scope_entry, the document in: http://www.boost.org/doc/libs/1_55_0/libs/log/doc/html/boost/log/attributes/named_scope_entry.html

Named_scope_entry contains scope_name, file_name, and line (source code line number). Each stack element is a name_scope_entry object.

Scope stack

Scope has a variety of, see the document: http://en.wikipedia.org/wiki/Scope_ (computer_science)

The most common function is the function stack. In this case, the scope stack is the function stack.

Boost log can print the scope stack information to the log.

Named_scope attributes

The named scope attribute can be added to the global attribute, Which is thread-related. Add the Property Code as follows:

logging::core::get()->add_global_attribute("Scope", attrs::named_scope());
Reference: http://www.boost.org/doc/libs/1_55_0/libs/log/doc/html/boost/log/attributes/named_scope.html

Set format

Document: http://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/log/detailed/expressions.html#log.detailed.expressions.formatters.named_scope

The following is a simple example:

First, add a format when setting the format:

% expr::format_named_scope("Scopes", boost::log::keywords::format = "%n (%f : %l)")

Then add the property:

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

Then call the code to add a Bar and Foo function, here refer to the official documentation: http://www.boost.org/doc/libs/1_55_0/libs/log/doc/html/log/detailed/attributes.html#log.detailed.attributes.named_scope

void Bar() {  int x = 0;}void Foo(int n) {  src::severity_logger_mt<sign_severity_level>& lg = my_logger::get();  // Mark the scope of the function foo  BOOST_LOG_FUNCTION();  switch (n)    {    case 0:      {// Mark the current scopeBOOST_LOG_NAMED_SCOPE("case 0");BOOST_LOG(lg) << "Some log record";Bar(); // call some function      }      break;    case 1:      {// Mark the current scopeBOOST_LOG_NAMED_SCOPE("case 1");BOOST_LOG(lg) << "Some log record";Bar(); // call some function      }      break;    default:      {// Mark the current scopeBOOST_LOG_NAMED_SCOPE("default");BOOST_LOG(lg) << "Some log record";Bar(); // call some function      }      break;    }}

Finally, call the following in the main. cc function:

  Foo(1);

Execution result:

[8]<2014-03-01 23:49:19>(0)(0x00007f21bf00e740)(void Foo(int) (./main.cc : 11)->case 1 (./main.cc : 27)): Some log record


Note that two macros are used in the above Code: BOOST_LOG_NAMED_SCOPE and BOOST_LOG_FUNCTION. In fact, it is a macro. The macro is just a simplified version of the previous macro, and the current function can be used as the scope name automatically. Defined in the/boost/log/attributes/named_scope.hpp File

/*! * Macro for function scope markup. The scope name is constructed with help of compiler and contains current function name. * The scope name is pushed to the end of the current thread scope list. * * Not all compilers have support for this macro. The exact form of the scope name may vary from one compiler to another. */#define BOOST_LOG_FUNCTION() BOOST_LOG_NAMED_SCOPE(BOOST_CURRENT_FUNCTION)
The BOOST_LOG_NAMED_SCOPE macro is also defined in this file:

/*! * Macro for scope markup. The specified scope name is pushed to the end of the current thread scope list. */#define BOOST_LOG_NAMED_SCOPE(name)\    BOOST_LOG_NAMED_SCOPE_INTERNAL(BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_named_scope_sentry_), name, __FILE__, __LINE__)

#define BOOST_LOG_NAMED_SCOPE_INTERNAL(var, name, file, line)\    BOOST_LOG_UNUSED_VARIABLE(::boost::log::attributes::named_scope::sentry, var, (name, file, line));
The GCC compiler instruction _ attribute _ is used in the file/boost/log/utility/unused_variable.hpp __

#if defined(__GNUC__)//! The macro suppresses compiler warnings for \c var being unused#define BOOST_LOG_UNUSED_VARIABLE(type, var, initializer) __attribute__((unused)) type var initializer#else


So when BOOST_LOG_FUNCTION is used in the FOO function, this line of code is written:

__attribute__((unused)) ::boost::log::attributes::named_scope::sentry _boost_log_named_scope_sentry_18 (__PRETTY_FUNCTION__, "./main.cc", 18);;

So we can see that the number of lines of code here is fixed to 18. Therefore, if you want to display the number of lines of code when logging, you must write at least two rows of macros into the log:

BOOST_LOG_FUNCTION and BOOST_LOG_SEV macro.




7. filter

Filter can filter the log level and more. The following is an example:

  sink1->set_filter(expr::attr<sign_severity_level>("Severity") >= trace);

The advanced filter documentation is here:

Http://www.boost.org/doc/libs/1_55_0/libs/log/doc/html/log/tutorial/advanced_filtering.html






Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.