• 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 <cstddef>
9 #include <string>
10 #include <fstream>
11 #include <boost/smart_ptr/shared_ptr.hpp>
12 #include <boost/smart_ptr/make_shared_object.hpp>
13 #include <boost/log/core.hpp>
14 #include <boost/log/expressions.hpp>
15 #include <boost/log/attributes/constant.hpp>
16 #include <boost/log/attributes/scoped_attribute.hpp>
17 #include <boost/log/sources/channel_logger.hpp>
18 #include <boost/log/sources/record_ostream.hpp>
19 #include <boost/log/sinks/sync_frontend.hpp>
20 #include <boost/log/sinks/text_ostream_backend.hpp>
21 #include <boost/log/utility/setup/common_attributes.hpp>
22 #include <boost/log/utility/manipulators/add_value.hpp>
23 
24 namespace logging = boost::log;
25 namespace src = boost::log::sources;
26 namespace expr = boost::log::expressions;
27 namespace sinks = boost::log::sinks;
28 namespace attrs = boost::log::attributes;
29 namespace keywords = boost::log::keywords;
30 
31 BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int)
32 BOOST_LOG_ATTRIBUTE_KEYWORD(channel, "Channel", std::string)
33 BOOST_LOG_ATTRIBUTE_KEYWORD(remote_address, "RemoteAddress", std::string)
34 BOOST_LOG_ATTRIBUTE_KEYWORD(received_size, "ReceivedSize", std::size_t)
35 BOOST_LOG_ATTRIBUTE_KEYWORD(sent_size, "SentSize", std::size_t)
36 
37 //[ example_sources_network_connection_channels
38 class network_connection
39 {
40     src::channel_logger< > m_net, m_stat;
41     logging::attribute_set::iterator m_net_remote_addr, m_stat_remote_addr;
42 
43 public:
network_connection()44     network_connection() :
45         // We can dump network-related messages through this logger
46         // and be able to filter them later
47         m_net(keywords::channel = "net"),
48         // We also can separate statistic records in a different channel
49         // in order to route them to a different sink
50         m_stat(keywords::channel = "stat")
51     {
52     }
53 
on_connected(std::string const & remote_addr)54     void on_connected(std::string const& remote_addr)
55     {
56         // Add the remote address to both channels
57         attrs::constant< std::string > addr(remote_addr);
58         m_net_remote_addr = m_net.add_attribute("RemoteAddress", addr).first;
59         m_stat_remote_addr = m_stat.add_attribute("RemoteAddress", addr).first;
60 
61         // Put message to the "net" channel
62         BOOST_LOG(m_net) << "Connection established";
63     }
64 
on_disconnected()65     void on_disconnected()
66     {
67         // Put message to the "net" channel
68         BOOST_LOG(m_net) << "Connection shut down";
69 
70         // Remove the attribute with the remote address
71         m_net.remove_attribute(m_net_remote_addr);
72         m_stat.remove_attribute(m_stat_remote_addr);
73     }
74 
on_data_received(std::size_t size)75     void on_data_received(std::size_t size)
76     {
77         BOOST_LOG(m_stat) << logging::add_value("ReceivedSize", size) << "Some data received";
78     }
79 
on_data_sent(std::size_t size)80     void on_data_sent(std::size_t size)
81     {
82         BOOST_LOG(m_stat) << logging::add_value("SentSize", size) << "Some data sent";
83     }
84 };
85 //]
86 
main(int,char * [])87 int main(int, char*[])
88 {
89     // Construct the sink for the "net" channel
90     typedef sinks::synchronous_sink< sinks::text_ostream_backend > text_sink;
91     boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();
92 
93     sink->locked_backend()->add_stream(
94         boost::make_shared< std::ofstream >("net.log"));
95 
96     sink->set_formatter
97     (
98         expr::stream << line_id << ": [" << remote_address << "] " << expr::smessage
99     );
100 
101     sink->set_filter(channel == "net");
102 
103     logging::core::get()->add_sink(sink);
104 
105     // Construct the sink for the "stat" channel
106     sink = boost::make_shared< text_sink >();
107 
108     sink->locked_backend()->add_stream(
109         boost::make_shared< std::ofstream >("stat.log"));
110 
111     sink->set_formatter
112     (
113         expr::stream
114             << remote_address
115             << expr::if_(expr::has_attr(received_size))
116                [
117                     expr::stream << " -> " << received_size << " bytes: "
118                ]
119             << expr::if_(expr::has_attr(sent_size))
120                [
121                     expr::stream << " <- " << sent_size << " bytes: "
122                ]
123             << expr::smessage
124     );
125 
126     sink->set_filter(channel == "stat");
127 
128     logging::core::get()->add_sink(sink);
129 
130     // Register other common attributes, such as time stamp and record counter
131     logging::add_common_attributes();
132 
133     // Emulate network activity
134     network_connection conn;
135 
136     conn.on_connected("11.22.33.44");
137     conn.on_data_received(123);
138     conn.on_data_sent(321);
139     conn.on_disconnected();
140 
141     return 0;
142 }
143