]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/log/example/doc/extension_stat_collector_settings.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / log / example / doc / extension_stat_collector_settings.cpp
CommitLineData
7c673cae
FG
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 <fstream>
10#include <sstream>
11#include <iostream>
12#include <stdexcept>
13#include <boost/smart_ptr/shared_ptr.hpp>
14#include <boost/smart_ptr/make_shared_object.hpp>
15#include <boost/lexical_cast.hpp>
16#include <boost/optional/optional.hpp>
17#include <boost/date_time/posix_time/posix_time_types.hpp>
18#include <boost/phoenix.hpp>
19#include <boost/log/core.hpp>
20#include <boost/log/expressions.hpp>
21#include <boost/log/sinks/basic_sink_backend.hpp>
22#include <boost/log/sinks/sync_frontend.hpp>
23#include <boost/log/sources/logger.hpp>
24#include <boost/log/sources/record_ostream.hpp>
25#include <boost/log/attributes/value_visitation.hpp>
26#include <boost/log/utility/manipulators/add_value.hpp>
27#include <boost/log/utility/setup/filter_parser.hpp>
28#include <boost/log/utility/setup/from_stream.hpp>
29#include <boost/log/utility/setup/from_settings.hpp>
30
31namespace logging = boost::log;
32namespace src = boost::log::sources;
33namespace expr = boost::log::expressions;
34namespace sinks = boost::log::sinks;
35namespace keywords = boost::log::keywords;
36
37//[ example_extension_stat_collector_settings_definition
38// The backend collects statistical information about network activity of the application
39class stat_collector :
40 public sinks::basic_sink_backend<
41 sinks::combine_requirements<
42 sinks::synchronized_feeding,
43 sinks::flushing
44 >::type
45 >
46{
47private:
48 // The file to write the collected information to
49 std::ofstream m_csv_file;
50
51 // Here goes the data collected so far:
52 // Active connections
53 unsigned int m_active_connections;
54 // Sent bytes
55 unsigned int m_sent_bytes;
56 // Received bytes
57 unsigned int m_received_bytes;
58
59 // The number of collected records since the last write to the file
60 unsigned int m_collected_count;
61 // The time when the collected data has been written to the file last time
62 boost::posix_time::ptime m_last_store_time;
63 // The collected data writing interval
64 boost::posix_time::time_duration m_write_interval;
65
66public:
67 // The constructor initializes the internal data
68 stat_collector(const char* file_name, boost::posix_time::time_duration write_interval);
69
70 // The function consumes the log records that come from the frontend
71 void consume(logging::record_view const& rec);
72 // The function flushes the file
73 void flush();
74
75private:
76 // The function resets statistical accumulators to initial values
77 void reset_accumulators();
78 // The function writes the collected data to the file
79 void write_data();
80};
81//]
82
83// The constructor initializes the internal data
84stat_collector::stat_collector(const char* file_name, boost::posix_time::time_duration write_interval) :
85 m_csv_file(file_name, std::ios::app),
86 m_active_connections(0),
87 m_last_store_time(boost::posix_time::microsec_clock::universal_time()),
88 m_write_interval(write_interval)
89{
90 reset_accumulators();
91 if (!m_csv_file.is_open())
92 throw std::runtime_error("could not open the CSV file");
93}
94
95BOOST_LOG_ATTRIBUTE_KEYWORD(sent, "Sent", unsigned int)
96BOOST_LOG_ATTRIBUTE_KEYWORD(received, "Received", unsigned int)
97
98// The function consumes the log records that come from the frontend
99void stat_collector::consume(logging::record_view const& rec)
100{
101 // Accumulate statistical readings
102 if (rec.attribute_values().count("Connected"))
103 ++m_active_connections;
104 else if (rec.attribute_values().count("Disconnected"))
105 --m_active_connections;
106 else
107 {
108 namespace phoenix = boost::phoenix;
109 logging::visit(sent, rec, phoenix::ref(m_sent_bytes) += phoenix::placeholders::_1);
110 logging::visit(received, rec, phoenix::ref(m_received_bytes) += phoenix::placeholders::_1);
111 }
112 ++m_collected_count;
113
114 // Check if it's time to write the accumulated data to the file
115 boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
116 if (now - m_last_store_time >= m_write_interval)
117 {
118 write_data();
119 m_last_store_time = now;
120 }
121}
122
123// The function writes the collected data to the file
124void stat_collector::write_data()
125{
126 m_csv_file << m_active_connections
127 << ',' << m_sent_bytes
128 << ',' << m_received_bytes
129 << std::endl;
130 reset_accumulators();
131}
132
133// The function resets statistical accumulators to initial values
134void stat_collector::reset_accumulators()
135{
136 m_sent_bytes = m_received_bytes = 0;
137 m_collected_count = 0;
138}
139
140// The function flushes the file
141void stat_collector::flush()
142{
143 // Store any data that may have been collected since the list write to the file
144 if (m_collected_count > 0)
145 {
146 write_data();
147 m_last_store_time = boost::posix_time::microsec_clock::universal_time();
148 }
149
150 m_csv_file.flush();
151}
152
153//[ example_extension_stat_collector_factory
154// Factory for the stat_collector sink
155class stat_collector_factory :
156 public logging::sink_factory< char >
157{
158public:
159 // Creates the sink with the provided parameters
160 boost::shared_ptr< sinks::sink > create_sink(settings_section const& settings)
161 {
162 // Read sink parameters
163 std::string file_name;
164 if (boost::optional< std::string > param = settings["FileName"])
165 file_name = param.get();
166 else
167 throw std::runtime_error("No target file name specified in settings");
168
169 boost::posix_time::time_duration write_interval = boost::posix_time::minutes(1);
170 if (boost::optional< std::string > param = settings["WriteInterval"])
171 {
172 unsigned int sec = boost::lexical_cast< unsigned int >(param.get());
173 write_interval = boost::posix_time::seconds(sec);
174 }
175
176 // Create the sink
177 boost::shared_ptr< stat_collector > backend = boost::make_shared< stat_collector >(file_name.c_str(), write_interval);
178 boost::shared_ptr< sinks::synchronous_sink< stat_collector > > sink = boost::make_shared< sinks::synchronous_sink< stat_collector > >(backend);
179
180 if (boost::optional< std::string > param = settings["Filter"])
181 {
182 sink->set_filter(logging::parse_filter(param.get()));
183 }
184
185 return sink;
186 }
187};
188
189void init_factories()
190{
191 logging::register_sink_factory("StatCollector", boost::make_shared< stat_collector_factory >());
192}
193//]
194
195const char settings[] =
196 "[Sinks.MyStat]\n"
197 "Destination=StatCollector\n"
198 "FileName=stat.csv\n"
199 "WriteInterval=30\n"
200;
201
202void init_logging()
203{
204 init_factories();
205
206 std::istringstream strm(settings);
207 logging::init_from_stream(strm);
208}
209
210int main(int, char*[])
211{
212 init_logging();
213
214 src::logger lg;
215 BOOST_LOG(lg) << logging::add_value("Connected", true);
216 BOOST_LOG(lg) << logging::add_value("Sent", 100u);
217 BOOST_LOG(lg) << logging::add_value("Received", 200u);
218
219 logging::core::get()->flush();
220
221 return 0;
222}