Music Hub ..
A session-wide music playback service
logger.cpp
Go to the documentation of this file.
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#include <thread>
19
20#include "logger.h"
21
22#define BOOST_LOG_DYN_LINK
23#include <boost/date_time.hpp>
24#include <boost/filesystem.hpp>
25#include <boost/log/trivial.hpp>
26#include <boost/log/expressions.hpp>
27#include <boost/log/support/date_time.hpp>
28#include <boost/log/utility/manipulators.hpp>
29#include <boost/log/utility/setup.hpp>
30
31namespace media = core::ubuntu::media;
32
33namespace {
34namespace attrs {
35BOOST_LOG_ATTRIBUTE_KEYWORD(Severity, "core::ubuntu::media::Severity", media::Logger::Severity)
36BOOST_LOG_ATTRIBUTE_KEYWORD(Location, "Location", media::Logger::Location)
37BOOST_LOG_ATTRIBUTE_KEYWORD(Timestamp, "Timestamp", boost::posix_time::ptime)
38}
39
40struct BoostLogLogger : public media::Logger {
41 BoostLogLogger() :
42 initialized_(false) {
43 }
44
45 void Init(const media::Logger::Severity &severity = media::Logger::Severity::kWarning) override {
46 if (initialized_)
47 return;
48
49 boost::log::formatter formatter = boost::log::expressions::stream
50 << "[" << attrs::Severity << " "
51 << boost::log::expressions::format_date_time< boost::posix_time::ptime >("Timestamp", "%Y-%m-%d %H:%M:%S.%f")
52 << "] "
53 << boost::log::expressions::if_(boost::log::expressions::has_attr(attrs::Location))
54 [
55 boost::log::expressions::stream << "[" << attrs::Location << "] "
56 ]
57 << boost::log::expressions::smessage;
58
59 boost::log::core::get()->remove_all_sinks();
60 auto logger = boost::log::add_console_log(std::cout);
61 logger->set_formatter(formatter);
62
63 // FIXME need to enable this once we found how we wrap this
64 // properly into our service architecture. For now left as
65 // it is.
66 boost::ignore_unused_variable_warning(severity);
67 // logger->set_filter(attrs::Severity < severity);
68
69 initialized_ = true;
70 }
71
72 void Log(Severity severity, const std::string& message, const boost::optional<Location> &loc) {
73 if (!initialized_)
74 Init();
75
76 if (auto rec = boost::log::trivial::logger::get().open_record()) {
77 boost::log::record_ostream out{rec};
78 out << boost::log::add_value(attrs::Severity, severity)
79 << boost::log::add_value(attrs::Timestamp, boost::posix_time::microsec_clock::universal_time())
80 << message;
81
82 if (loc) {
83 // We have to pass in a temporary as boost::log (<= 1.55) expects a
84 // mutable reference to be passed to boost::log::add_value(...).
85 auto tmp = *loc;
86 out << boost::log::add_value(attrs::Location, tmp);
87 }
88
89 boost::log::trivial::logger::get().push_record(std::move(rec));
90 }
91 }
92
93private:
94 bool initialized_;
95};
96
97std::shared_ptr<media::Logger>& MutableInstance() {
98 static std::shared_ptr<media::Logger> instance{new BoostLogLogger()};
99 return instance;
100}
101
102void SetInstance(const std::shared_ptr<media::Logger>& logger) {
103 MutableInstance() = logger;
104}
105}
106
107void media::Logger::Trace(const std::string& message, const boost::optional<Location>& location) {
108 Log(Severity::kTrace, message, location);
109}
110
111void media::Logger::Debug(const std::string& message, const boost::optional<Location>& location) {
112 Log(Severity::kDebug, message, location);
113}
114
115void media::Logger::Info(const std::string& message, const boost::optional<Location>& location) {
116 Log(Severity::kInfo, message, location);
117}
118
119void media::Logger::Warning(const std::string& message, const boost::optional<Location>& location) {
120 Log(Severity::kWarning, message, location);
121}
122
123void media::Logger::Error(const std::string& message, const boost::optional<Location>& location) {
124 Log(Severity::kError, message, location);
125}
126
127void media::Logger::Fatal(const std::string& message, const boost::optional<Location>& location) {
128 Log(Severity::kFatal, message, location);
129}
130
131namespace core {
132namespace ubuntu {
133namespace media {
134
135std::ostream& operator<<(std::ostream& strm, Logger::Severity severity) {
136 switch (severity) {
137 case media::Logger::Severity::kTrace: return strm << "TT";
138 case media::Logger::Severity::kDebug: return strm << "DD";
139 case media::Logger::Severity::kInfo: return strm << "II";
140 case media::Logger::Severity::kWarning: return strm << "WW";
141 case media::Logger::Severity::kError: return strm << "EE";
142 case media::Logger::Severity::kFatal: return strm << "FF";
143 default: return strm << static_cast<uint>(severity);
144 }
145}
146
147std::ostream& operator<<(std::ostream& out, const Logger::Location &location) {
148 return out << Utils::Sprintf("%s:%d@%s", boost::filesystem::path(location.file).filename().string(), location.line, location.function);
149}
150
152 return *MutableInstance();
153}
154
155void SetLogger(const std::shared_ptr<Logger>& logger) {
156 SetInstance(logger);
157}
158
159} // namespace media
160} // namespace ubuntu
161} // namespace core
virtual void Debug(const std::string &message, const boost::optional< Location > &location=boost::optional< Location >{})
Definition: logger.cpp:111
virtual void Trace(const std::string &message, const boost::optional< Location > &location=boost::optional< Location >{})
Definition: logger.cpp:107
virtual void Warning(const std::string &message, const boost::optional< Location > &location=boost::optional< Location >{})
Definition: logger.cpp:119
virtual void Log(Severity severity, const std::string &message, const boost::optional< Location > &location)=0
virtual void Fatal(const std::string &message, const boost::optional< Location > &location=boost::optional< Location >{})
Definition: logger.cpp:127
virtual void Error(const std::string &message, const boost::optional< Location > &location=boost::optional< Location >{})
Definition: logger.cpp:123
virtual void Info(const std::string &message, const boost::optional< Location > &location=boost::optional< Location >{})
Definition: logger.cpp:115
Definition: logger.cpp:34
std::ostream & operator<<(std::ostream &out, Player::PlaybackStatus status)
Definition: player.h:217
Logger & Log()
Definition: logger.cpp:151
void SetLogger(const std::shared_ptr< Logger > &logger)
Definition: logger.cpp:155
Definition: player.h:34
static std::string Sprintf(const std::string &fmt_str, Types &&... args)
Definition: utils.h:64