• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *          Copyright Andrey Semashev 2007 - 2015.
3  * Distributed under the Boost Software License, Version 1.0.
4  *    (See accompanying file LICENSE_1_0.txt or copy at
5  *          http://www.boost.org/LICENSE_1_0.txt)
6  */
7 
8 #include <string>
9 #include <iostream>
10 #include <stdexcept>
11 #include <boost/smart_ptr/shared_ptr.hpp>
12 #include <boost/smart_ptr/make_shared_object.hpp>
13 #include <boost/format.hpp>
14 #include <boost/phoenix.hpp>
15 #include <boost/log/core.hpp>
16 #include <boost/log/expressions.hpp>
17 #include <boost/log/attributes/attribute_name.hpp>
18 #include <boost/log/sources/logger.hpp>
19 #include <boost/log/sources/record_ostream.hpp>
20 #include <boost/log/utility/value_ref.hpp>
21 #include <boost/log/utility/formatting_ostream.hpp>
22 #include <boost/log/utility/manipulators/add_value.hpp>
23 #include <boost/log/utility/setup/formatter_parser.hpp>
24 #include <boost/log/utility/setup/common_attributes.hpp>
25 #include <boost/log/utility/setup/console.hpp>
26 
27 namespace logging = boost::log;
28 namespace attrs = boost::log::attributes;
29 namespace src = boost::log::sources;
30 namespace expr = boost::log::expressions;
31 namespace sinks = boost::log::sinks;
32 namespace keywords = boost::log::keywords;
33 
34 //[ example_extension_formatter_parser_point_definition
35 struct point
36 {
37     float m_x, m_y;
38 
pointpoint39     point() : m_x(0.0f), m_y(0.0f) {}
pointpoint40     point(float x, float y) : m_x(x), m_y(y) {}
41 };
42 
43 template< typename CharT, typename TraitsT >
operator <<(std::basic_ostream<CharT,TraitsT> & strm,point const & p)44 std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, point const& p)
45 {
46     strm << "(" << p.m_x << ", " << p.m_y << ")";
47     return strm;
48 }
49 //]
50 
51 #if 0
52 //[ example_extension_simple_formatter_factory
53 void init_factories()
54 {
55     logging::register_simple_formatter_factory< point, char >("Coordinates");
56 }
57 //]
58 #endif
59 
60 //[ example_extension_custom_formatter_factory
61 // Custom point formatter
62 class point_formatter
63 {
64 public:
65     typedef void result_type;
66 
67 public:
point_formatter(std::string const & fmt)68     explicit point_formatter(std::string const& fmt) : m_format(fmt)
69     {
70     }
71 
operator ()(logging::formatting_ostream & strm,logging::value_ref<point> const & value) const72     void operator() (logging::formatting_ostream& strm, logging::value_ref< point > const& value) const
73     {
74         if (value)
75         {
76             point const& p = value.get();
77             m_format % p.m_x % p.m_y;
78             strm << m_format;
79             m_format.clear();
80         }
81     }
82 
83 private:
84     mutable boost::format m_format;
85 };
86 
87 // Custom point formatter factory
88 class point_formatter_factory :
89     public logging::basic_formatter_factory< char, point >
90 {
91 public:
create_formatter(logging::attribute_name const & name,args_map const & args)92     formatter_type create_formatter(logging::attribute_name const& name, args_map const& args)
93     {
94         args_map::const_iterator it = args.find("format");
95         if (it != args.end())
96             return boost::phoenix::bind(point_formatter(it->second), expr::stream, expr::attr< point >(name));
97         else
98             return expr::stream << expr::attr< point >(name);
99     }
100 };
101 
init_factories()102 void init_factories()
103 {
104     logging::register_formatter_factory("Coordinates", boost::make_shared< point_formatter_factory >());
105 }
106 //]
107 
init_logging()108 void init_logging()
109 {
110     init_factories();
111 
112     logging::add_console_log(std::clog, keywords::format = "%TimeStamp% %Coordinates(format=\"{%0.3f; %0.3f}\")% %Message%");
113 
114     logging::add_common_attributes();
115 }
116 
main(int,char * [])117 int main(int, char*[])
118 {
119     init_logging();
120 
121     src::logger lg;
122     BOOST_LOG(lg) << logging::add_value("Coordinates", point(10.5f, 20.2f)) << "Hello, world with coordinates!";
123 
124     return 0;
125 }
126