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 * \file default_sink.cpp
9 * \author Andrey Semashev
10 * \date 19.04.2007
11 *
12 * \brief This header is the Boost.Log library implementation, see the library documentation
13 * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
14 */
15
16#include <boost/log/detail/config.hpp>
17#include <cstdio>
18#include <boost/optional/optional.hpp>
19#if !defined(BOOST_LOG_NO_THREADS)
20#include <boost/thread/locks.hpp>
21#include <boost/log/detail/thread_id.hpp>
22#endif
23#include <boost/log/detail/default_attribute_names.hpp>
24#include <boost/date_time/microsec_time_clock.hpp>
25#include <boost/date_time/time_resolution_traits.hpp>
26#include <boost/date_time/gregorian/gregorian_types.hpp>
27#include "default_sink.hpp"
28#include <boost/log/detail/header.hpp>
29
30namespace boost {
31
32BOOST_LOG_OPEN_NAMESPACE
33
34#if !defined(BOOST_LOG_NO_THREADS)
35
36namespace aux {
37
38// Defined in thread_id.cpp
39void format_thread_id(char* buf, std::size_t size, thread::id tid);
40
41} // namespace aux
42
43#endif // !defined(BOOST_LOG_NO_THREADS)
44
45namespace sinks {
46
47namespace aux {
48
49BOOST_LOG_ANONYMOUS_NAMESPACE {
50
51//! A special time point type that contains decomposed date and time to avoid excessive calculations
52struct decomposed_time_point
53{
54 struct date_type :
55 public gregorian::greg_year_month_day
56 {
57 date_type(year_type y, month_type m, day_type d) :
58 gregorian::greg_year_month_day(y, m, d)
59 {
60 }
61 };
62
63 struct time_duration_type :
64 public date_time::micro_res
65 {
66 typedef date_time::micro_res rep_type;
67
68 hour_type hours;
69 min_type minutes;
70 sec_type seconds;
71 fractional_seconds_type useconds;
72
73 time_duration_type(hour_type h, min_type m, sec_type s, fractional_seconds_type u) :
74 hours(h),
75 minutes(m),
76 seconds(s),
77 useconds(u)
78 {
79 }
80 };
81
82 date_type date;
83 time_duration_type time;
84
85 decomposed_time_point(date_type const& d, time_duration_type const& t) :
86 date(d),
87 time(t)
88 {
89 }
90};
91
92inline const char* severity_level_to_string(boost::log::trivial::severity_level lvl)
93{
94 switch (lvl)
95 {
96 case boost::log::trivial::trace:
97 return "[trace] ";
98 case boost::log::trivial::debug:
99 return "[debug] ";
100 case boost::log::trivial::info:
101 return "[info] ";
102 case boost::log::trivial::warning:
103 return "[warning]";
104 case boost::log::trivial::error:
105 return "[error] ";
106 case boost::log::trivial::fatal:
107 return "[fatal] ";
108 default:
109 return "[-] ";
110 }
111}
112
113struct message_printer
114{
115 typedef void result_type;
116
117 explicit message_printer(boost::log::trivial::severity_level lvl) : m_level(lvl)
118 {
119 }
120
121#ifdef BOOST_LOG_USE_CHAR
122
123 result_type operator() (std::string const& msg) const
124 {
125#if !defined(BOOST_LOG_NO_THREADS)
126 char thread_id_buf[64];
127 boost::log::aux::format_thread_id(buf: thread_id_buf, size: sizeof(thread_id_buf), tid: boost::log::aux::this_thread::get_id());
128#endif
129
130 const decomposed_time_point now = date_time::microsec_clock< decomposed_time_point >::local_time();
131
132 std::printf(format: "[%04u-%02u-%02u %02u:%02u:%02u.%06u] "
133#if !defined(BOOST_LOG_NO_THREADS)
134 "[%s] "
135#endif
136 "%s %s\n",
137 static_cast< unsigned int >(now.date.year),
138 static_cast< unsigned int >(now.date.month),
139 static_cast< unsigned int >(now.date.day),
140 static_cast< unsigned int >(now.time.hours),
141 static_cast< unsigned int >(now.time.minutes),
142 static_cast< unsigned int >(now.time.seconds),
143 static_cast< unsigned int >(now.time.useconds),
144#if !defined(BOOST_LOG_NO_THREADS)
145 thread_id_buf,
146#endif
147 severity_level_to_string(lvl: m_level),
148 msg.c_str());
149 }
150
151#endif
152
153#ifdef BOOST_LOG_USE_WCHAR_T
154
155 result_type operator() (std::wstring const& msg) const
156 {
157#if !defined(BOOST_LOG_NO_THREADS)
158 char thread_id_buf[64];
159 boost::log::aux::format_thread_id(buf: thread_id_buf, size: sizeof(thread_id_buf), tid: boost::log::aux::this_thread::get_id());
160#endif
161
162 const decomposed_time_point now = date_time::microsec_clock< decomposed_time_point >::local_time();
163
164 std::printf(format: "[%04u-%02u-%02u %02u:%02u:%02u.%06u] "
165#if !defined(BOOST_LOG_NO_THREADS)
166 "[%s] "
167#endif
168 "%s %ls\n",
169 static_cast< unsigned int >(now.date.year),
170 static_cast< unsigned int >(now.date.month),
171 static_cast< unsigned int >(now.date.day),
172 static_cast< unsigned int >(now.time.hours),
173 static_cast< unsigned int >(now.time.minutes),
174 static_cast< unsigned int >(now.time.seconds),
175 static_cast< unsigned int >(now.time.useconds),
176#if !defined(BOOST_LOG_NO_THREADS)
177 thread_id_buf,
178#endif
179 severity_level_to_string(lvl: m_level),
180 msg.c_str());
181 }
182
183#endif
184
185private:
186 const boost::log::trivial::severity_level m_level;
187};
188
189} // namespace
190
191default_sink::default_sink() :
192 sink(false),
193 m_severity_name(boost::log::aux::default_attribute_names::severity()),
194 m_message_name(boost::log::aux::default_attribute_names::message()),
195 m_severity_extractor(boost::log::trivial::info)
196{
197}
198
199default_sink::~default_sink()
200{
201}
202
203bool default_sink::will_consume(attribute_value_set const&)
204{
205 return true;
206}
207
208void default_sink::consume(record_view const& rec)
209{
210 BOOST_LOG_EXPR_IF_MT(lock_guard< mutex_type > lock(m_mutex);)
211 m_message_visitor(m_message_name, rec.attribute_values(), message_printer(m_severity_extractor(m_severity_name, rec).get()));
212 std::fflush(stdout);
213}
214
215void default_sink::flush()
216{
217 BOOST_LOG_EXPR_IF_MT(lock_guard< mutex_type > lock(m_mutex);)
218 std::fflush(stdout);
219}
220
221} // namespace aux
222
223} // namespace sinks
224
225BOOST_LOG_CLOSE_NAMESPACE // namespace log
226
227} // namespace boost
228
229#include <boost/log/detail/footer.hpp>
230

source code of boost/libs/log/src/default_sink.cpp