]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/log/example/doc/extension_filter_parser_custom_rel.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / log / example / doc / extension_filter_parser_custom_rel.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 <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/lexical_cast.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/attributes/scoped_attribute.hpp>
19 #include <boost/log/sources/logger.hpp>
20 #include <boost/log/sources/record_ostream.hpp>
21 #include <boost/log/utility/value_ref.hpp>
22 #include <boost/log/utility/formatting_ostream.hpp>
23 #include <boost/log/utility/manipulators/add_value.hpp>
24 #include <boost/log/utility/setup/filter_parser.hpp>
25 #include <boost/log/utility/setup/common_attributes.hpp>
26 #include <boost/log/utility/setup/console.hpp>
27
28 namespace logging = boost::log;
29 namespace attrs = boost::log::attributes;
30 namespace src = boost::log::sources;
31 namespace expr = boost::log::expressions;
32 namespace sinks = boost::log::sinks;
33 namespace keywords = boost::log::keywords;
34
35 struct point
36 {
37 float m_x, m_y;
38
39 point() : m_x(0.0f), m_y(0.0f) {}
40 point(float x, float y) : m_x(x), m_y(y) {}
41 };
42
43 bool operator== (point const& left, point const& right);
44 bool operator!= (point const& left, point const& right);
45
46 template< typename CharT, typename TraitsT >
47 std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, point const& p);
48 template< typename CharT, typename TraitsT >
49 std::basic_istream< CharT, TraitsT >& operator>> (std::basic_istream< CharT, TraitsT >& strm, point& p);
50
51 const float epsilon = 0.0001f;
52
53 bool operator== (point const& left, point const& right)
54 {
55 return (left.m_x - epsilon <= right.m_x && left.m_x + epsilon >= right.m_x) &&
56 (left.m_y - epsilon <= right.m_y && left.m_y + epsilon >= right.m_y);
57 }
58
59 bool operator!= (point const& left, point const& right)
60 {
61 return !(left == right);
62 }
63
64 template< typename CharT, typename TraitsT >
65 std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, point const& p)
66 {
67 if (strm.good())
68 strm << "(" << p.m_x << ", " << p.m_y << ")";
69 return strm;
70 }
71
72 template< typename CharT, typename TraitsT >
73 std::basic_istream< CharT, TraitsT >& operator>> (std::basic_istream< CharT, TraitsT >& strm, point& p)
74 {
75 if (strm.good())
76 {
77 CharT left_brace = static_cast< CharT >(0), comma = static_cast< CharT >(0), right_brace = static_cast< CharT >(0);
78 strm.setf(std::ios_base::skipws);
79 strm >> left_brace >> p.m_x >> comma >> p.m_y >> right_brace;
80 if (left_brace != '(' || comma != ',' || right_brace != ')')
81 strm.setstate(std::ios_base::failbit);
82 }
83 return strm;
84 }
85
86 //[ example_extension_filter_parser_rectangle_definition
87 struct rectangle
88 {
89 point m_top_left, m_bottom_right;
90 };
91
92 template< typename CharT, typename TraitsT >
93 std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, rectangle const& r);
94 template< typename CharT, typename TraitsT >
95 std::basic_istream< CharT, TraitsT >& operator>> (std::basic_istream< CharT, TraitsT >& strm, rectangle& r);
96 //]
97
98 template< typename CharT, typename TraitsT >
99 std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, rectangle const& r)
100 {
101 if (strm.good())
102 strm << "{" << r.m_top_left << " - " << r.m_bottom_right << "}";
103 return strm;
104 }
105
106 template< typename CharT, typename TraitsT >
107 std::basic_istream< CharT, TraitsT >& operator>> (std::basic_istream< CharT, TraitsT >& strm, rectangle& r)
108 {
109 if (strm.good())
110 {
111 CharT left_brace = static_cast< CharT >(0), dash = static_cast< CharT >(0), right_brace = static_cast< CharT >(0);
112 strm.setf(std::ios_base::skipws);
113 strm >> left_brace >> r.m_top_left >> dash >> r.m_bottom_right >> right_brace;
114 if (left_brace != '{' || dash != '-' || right_brace != '}')
115 strm.setstate(std::ios_base::failbit);
116 }
117 return strm;
118 }
119
120
121 //[ example_extension_custom_filter_factory_with_custom_rel
122 // The function checks if the point is inside the rectangle
123 bool is_in_rectangle(logging::value_ref< point > const& p, rectangle const& r)
124 {
125 if (p)
126 {
127 return p->m_x >= r.m_top_left.m_x && p->m_x <= r.m_bottom_right.m_x &&
128 p->m_y >= r.m_top_left.m_y && p->m_y <= r.m_bottom_right.m_y;
129 }
130 return false;
131 }
132
133 // Custom point filter factory
134 class point_filter_factory :
135 public logging::filter_factory< char >
136 {
137 public:
138 logging::filter on_exists_test(logging::attribute_name const& name)
139 {
140 return expr::has_attr< point >(name);
141 }
142
143 logging::filter on_equality_relation(logging::attribute_name const& name, string_type const& arg)
144 {
145 return expr::attr< point >(name) == boost::lexical_cast< point >(arg);
146 }
147
148 logging::filter on_inequality_relation(logging::attribute_name const& name, string_type const& arg)
149 {
150 return expr::attr< point >(name) != boost::lexical_cast< point >(arg);
151 }
152
153 logging::filter on_custom_relation(logging::attribute_name const& name, string_type const& rel, string_type const& arg)
154 {
155 if (rel == "is_in_rectangle")
156 {
157 return boost::phoenix::bind(&is_in_rectangle, expr::attr< point >(name), boost::lexical_cast< rectangle >(arg));
158 }
159 throw std::runtime_error("Unsupported filter relation: " + rel);
160 }
161 };
162
163 void init_factories()
164 {
165 //<-
166 logging::register_simple_formatter_factory< point, char >("Coordinates");
167 //->
168 logging::register_filter_factory("Coordinates", boost::make_shared< point_filter_factory >());
169 }
170 //]
171
172 void init_logging()
173 {
174 init_factories();
175
176 logging::add_console_log
177 (
178 std::clog,
179 keywords::filter = "%Coordinates% is_in_rectangle \"{(0, 0) - (20, 20)}\"",
180 keywords::format = "%TimeStamp% %Coordinates% %Message%"
181 );
182
183 logging::add_common_attributes();
184 }
185
186 int main(int, char*[])
187 {
188 init_logging();
189
190 src::logger lg;
191
192 // We have to use scoped attributes in order coordinates to be passed to filters
193 {
194 BOOST_LOG_SCOPED_LOGGER_TAG(lg, "Coordinates", point(10, 10));
195 BOOST_LOG(lg) << "Hello, world with coordinates (10, 10)!";
196 }
197 {
198 BOOST_LOG_SCOPED_LOGGER_TAG(lg, "Coordinates", point(50, 50));
199 BOOST_LOG(lg) << "Hello, world with coordinates (50, 50)!"; // this message will be suppressed by filter
200 }
201
202 return 0;
203 }