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 
31 namespace media = core::ubuntu::media;
32 
33 namespace {
34 namespace attrs {
35 BOOST_LOG_ATTRIBUTE_KEYWORD(Severity, "core::ubuntu::media::Severity", media::Logger::Severity)
36 BOOST_LOG_ATTRIBUTE_KEYWORD(Location, "Location", media::Logger::Location)
37 BOOST_LOG_ATTRIBUTE_KEYWORD(Timestamp, "Timestamp", boost::posix_time::ptime)
38 }
39 
40 struct 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 
93 private:
94  bool initialized_;
95 };
96 
97 std::shared_ptr<media::Logger>& MutableInstance() {
98  static std::shared_ptr<media::Logger> instance{new BoostLogLogger()};
99  return instance;
100 }
101 
102 void SetInstance(const std::shared_ptr<media::Logger>& logger) {
103  MutableInstance() = logger;
104 }
105 }
106 
107 void media::Logger::Trace(const std::string& message, const boost::optional<Location>& location) {
108  Log(Severity::kTrace, message, location);
109 }
110 
111 void media::Logger::Debug(const std::string& message, const boost::optional<Location>& location) {
112  Log(Severity::kDebug, message, location);
113 }
114 
115 void media::Logger::Info(const std::string& message, const boost::optional<Location>& location) {
116  Log(Severity::kInfo, message, location);
117 }
118 
119 void media::Logger::Warning(const std::string& message, const boost::optional<Location>& location) {
120  Log(Severity::kWarning, message, location);
121 }
122 
123 void media::Logger::Error(const std::string& message, const boost::optional<Location>& location) {
124  Log(Severity::kError, message, location);
125 }
126 
127 void media::Logger::Fatal(const std::string& message, const boost::optional<Location>& location) {
128  Log(Severity::kFatal, message, location);
129 }
130 
131 namespace core {
132 namespace ubuntu {
133 namespace media {
134 
135 std::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 
147 std::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 
155 void SetLogger(const std::shared_ptr<Logger>& logger) {
156  SetInstance(logger);
157 }
158 
159 } // namespace media
160 } // namespace ubuntu
161 } // namespace core
virtual void Info(const std::string &message, const boost::optional< Location > &location=boost::optional< Location >{})
Definition: logger.cpp:115
Logger & Log()
Definition: logger.cpp:151
virtual void Warning(const std::string &message, const boost::optional< Location > &location=boost::optional< Location >{})
Definition: logger.cpp:119
Definition: player.h:33
Definition: logger.cpp:34
void SetLogger(const std::shared_ptr< Logger > &logger)
Definition: logger.cpp:155
virtual void Error(const std::string &message, const boost::optional< Location > &location=boost::optional< Location >{})
Definition: logger.cpp:123
static std::string Sprintf(const std::string &fmt_str, Types &&...args)
Definition: utils.h:64
std::ostream & operator<<(std::ostream &out, const Logger::Location &location)
Definition: logger.cpp:147
virtual void Trace(const std::string &message, const boost::optional< Location > &location=boost::optional< Location >{})
Definition: logger.cpp:107
virtual void Debug(const std::string &message, const boost::optional< Location > &location=boost::optional< Location >{})
Definition: logger.cpp:111
virtual void Fatal(const std::string &message, const boost::optional< Location > &location=boost::optional< Location >{})
Definition: logger.cpp:127