]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/log/example/doc/expressions_has_attr_stat_accum.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / log / example / doc / expressions_has_attr_stat_accum.cpp
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 <cstddef>
9 #include <string>
10 #include <map>
11 #include <iostream>
12 #include <fstream>
13 #include <boost/smart_ptr/shared_ptr.hpp>
14 #include <boost/smart_ptr/make_shared_object.hpp>
15 #include <boost/log/sinks.hpp>
16 #include <boost/log/expressions.hpp>
17 #include <boost/log/attributes/scoped_attribute.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/manipulators/add_value.hpp>
22
23 namespace logging = boost::log;
24 namespace src = boost::log::sources;
25 namespace expr = boost::log::expressions;
26 namespace sinks = boost::log::sinks;
27 namespace keywords = boost::log::keywords;
28
29 //[ example_expressions_has_attr_stat_accumulator
30 // Declare attribute keywords
31 BOOST_LOG_ATTRIBUTE_KEYWORD(stat_stream, "StatisticStream", std::string)
32 BOOST_LOG_ATTRIBUTE_KEYWORD(change, "Change", int)
33
34 // A simple sink backend to accumulate statistic information
35 class my_stat_accumulator :
36 public sinks::basic_sink_backend< sinks::synchronized_feeding >
37 {
38 // A map of accumulated statistic values,
39 // ordered by the statistic information stream name
40 typedef std::map< std::string, int > stat_info_map;
41 stat_info_map m_stat_info;
42
43 public:
44 // Destructor
45 ~my_stat_accumulator()
46 {
47 // Display the accumulated data
48 stat_info_map::const_iterator it = m_stat_info.begin(), end = m_stat_info.end();
49 for (; it != end; ++it)
50 {
51 std::cout << "Statistic stream: " << it->first
52 << ", accumulated value: " << it->second << "\n";
53 }
54 std::cout.flush();
55 }
56
57 // The method is called for every log record being put into the sink backend
58 void consume(logging::record_view const& rec)
59 {
60 // First, acquire statistic information stream name
61 logging::value_ref< std::string, tag::stat_stream > name = rec[stat_stream];
62 if (name)
63 {
64 // Next, get the statistic value change
65 logging::value_ref< int, tag::change > change_amount = rec[change];
66 if (change_amount)
67 {
68 // Accumulate the statistic data
69 m_stat_info[name.get()] += change_amount.get();
70 }
71 }
72 }
73 };
74
75 // The function registers two sinks - one for statistic information,
76 // and another one for other records
77 void init()
78 {
79 boost::shared_ptr< logging::core > core = logging::core::get();
80
81 // Create a backend and attach a stream to it
82 boost::shared_ptr< sinks::text_ostream_backend > backend =
83 boost::make_shared< sinks::text_ostream_backend >();
84 backend->add_stream(
85 boost::shared_ptr< std::ostream >(new std::ofstream("test.log")));
86
87 // Create a frontend and setup filtering
88 typedef sinks::synchronous_sink< sinks::text_ostream_backend > log_sink_type;
89 boost::shared_ptr< log_sink_type > log_sink(new log_sink_type(backend));
90 // All records that don't have a "StatisticStream" attribute attached
91 // will go to the "test.log" file
92 log_sink->set_filter(!expr::has_attr(stat_stream));
93
94 core->add_sink(log_sink);
95
96 // Create another sink that will receive all statistic data
97 typedef sinks::synchronous_sink< my_stat_accumulator > stat_sink_type;
98 boost::shared_ptr< stat_sink_type > stat_sink(new stat_sink_type());
99 // All records with a "StatisticStream" string attribute attached
100 // will go to the my_stat_accumulator sink
101 stat_sink->set_filter(expr::has_attr(stat_stream));
102
103 core->add_sink(stat_sink);
104 }
105
106 // This simple macro will simplify putting statistic data into a logger
107 #define PUT_STAT(lg, stat_stream_name, change)\
108 if (true) {\
109 BOOST_LOG_SCOPED_LOGGER_TAG(lg, "StatisticStream", stat_stream_name);\
110 BOOST_LOG(lg) << logging::add_value("Change", (int)(change));\
111 } else ((void)0)
112
113 void logging_function()
114 {
115 src::logger lg;
116
117 // Put a regular log record, it will go to the "test.log" file
118 BOOST_LOG(lg) << "A regular log record";
119
120 // Put some statistic data
121 PUT_STAT(lg, "StreamOne", 10);
122 PUT_STAT(lg, "StreamTwo", 20);
123 PUT_STAT(lg, "StreamOne", -5);
124 }
125 //]
126
127 int main(int, char*[])
128 {
129 init();
130 logging_function();
131
132 return 0;
133 }