Ubuntu Download Manager  1.2.0
A session-wide downloading service
logger.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2014 Canonical Ltd.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of version 3 of the GNU Lesser General Public
6  * License 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 GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the
15  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  * Boston, MA 02110-1301, USA.
17  */
18 
19 #include <boost/log/expressions/attr_fwd.hpp>
20 #include <boost/log/expressions/attr.hpp>
21 #include <boost/log/expressions/formatters/date_time.hpp>
22 #include <boost/log/keywords/channel.hpp>
23 #include <boost/log/sources/severity_channel_logger.hpp>
24 #include <boost/log/sources/record_ostream.hpp>
25 #include <boost/log/support/date_time.hpp>
26 #include <boost/log/utility/setup/console.hpp>
27 #include <boost/log/utility/setup/file.hpp>
28 #include <boost/log/utility/setup/common_attributes.hpp>
29 
30 #include <ubuntu/download_manager/download_struct.h>
32 
33 typedef boost::log::sources::severity_channel_logger_mt<
35  std::string> logger_mt;
36 
37 namespace {
38  const std::string DOWNLOAD_MANAGER_CHANNEL = "ubuntu_download_manager";
39  void my_formatter(boost::log::record_view const& rec,
40  boost::log::formatting_ostream& strm) {
41  using namespace Ubuntu::DownloadManager::Logging;
42  // grab the attributes we are interested in
43  strm << boost::log::extract<unsigned int>("LineID", rec) << " [";
44  strm << boost::log::extract<boost::posix_time::ptime>("TimeStamp", rec) << "] ";
45  strm << boost::log::extract<std::string>("Channel", rec) << " [";
46  auto severity = boost::log::extract<Logger::Level>("Severity", rec).get();
47  switch(severity) {
48  case Logger::Debug:
49  strm << "Debug";
50  break;
51  case Logger::Normal:
52  strm << "Normal";
53  break;
54  case Logger::Notification:
55  strm << "Notification";
56  break;
57  case Logger::Warning:
58  strm << "Warning";
59  break;
60  case Logger::Error:
61  strm << "Error";
62  break;
63  default:
64  strm << "Critical";
65  break;
66  }
67  strm << "] ";
68  // Finally, put the record message to the stream
69  strm << rec[boost::log::expressions::smessage];
70  }
71 }
72 
73 namespace Ubuntu {
74 
75 namespace DownloadManager {
76 
77 namespace Logging {
78 
79 class LoggerPrivate {
80  public:
81  LoggerPrivate() { }
82 
83  void init(Logger::Level lvl, const QString& path) {
84  if (_lg == nullptr) {
85  boost::log::add_common_attributes();
86 
87  _lg = new logger_mt(
88  boost::log::keywords::channel = DOWNLOAD_MANAGER_CHANNEL,
89  boost::log::keywords::severity = lvl);
90  // create a sink with the given file name and then add a filter
91  // to ensure that just the download manager logs are written in it
92  auto sink = boost::log::add_file_log(
93  boost::log::keywords::file_name = path.toStdString(),
94  boost::log::keywords::auto_flush = true
95  );
96 
97  sink->set_formatter(&my_formatter);
98 
99  sink->set_filter
100  (
101  boost::log::expressions::attr<std::string>("Channel") == DOWNLOAD_MANAGER_CHANNEL
102  );
103 
104  } else {
105  log(Logger::Critical, "Logger init called more than once.");
106  }
107  }
108 
109  void log(Logger::Level lvl, const QString& msg) {
110  if (_lg != nullptr) {
111  auto rec = _lg->open_record(boost::log::keywords::severity = lvl);
112  if (rec) {
113  boost::log::record_ostream strm(rec);
114  strm << msg.toStdString();
115  strm.flush();
116  _lg->push_record(boost::move(rec));
117  }
118  }
119  }
120 
121  void log(Logger::Level lvl, const QStringList& msgList) {
122  auto msg = msgList.join(" ");
123  log(lvl, msg);
124  }
125 
126  void log(Logger::Level lvl, const QString& msg, QMap<QString, QString> map) {
127  auto fmtMsg = msg.arg(toString(map));
128  log(lvl, fmtMsg);
129  }
130 
131  void log(Logger::Level lvl, const QString& msg, QMap<QString, QVariant> map) {
132  auto fmtMsg = msg.arg(toString(map));
133  log(lvl, fmtMsg);
134  }
135 
136  void log(Logger::Level lvl, const QString& msg, DownloadStruct downStruct) {
137  QStringList list;
138 
139  list << "\n\t\tUrl: " << downStruct.getUrl()
140  << "\n\t\tHash Algorithm: '" << downStruct.getAlgorithm() << "'"
141  << "\n\t\tMetadata: " << toString(downStruct.getMetadata())
142  << "\n\t\tHeaders: " << toString(downStruct.getHeaders());
143 
144  auto fmtMsg = msg.arg(list.join(""));
145  log(lvl, fmtMsg);
146  }
147 
148  private:
149  QString toString(QMap<QString, QString> map) {
150  QStringList list;
151  list << "{";
152  int index = map.keys().count();
153  foreach(const QString& key, map.keys()) {
154  list << "'" << key << "': '" << map[key] << "'";
155  if (index != 1) {
156  list << ", ";
157  }
158  index--;
159  }
160  list << "}";
161  return list.join("");
162  }
163 
164  QString toString(QVariantMap map) {
165  QStringList list;
166  list << "{";
167  int index = map.keys().count();
168  foreach(const QString& key, map.keys()) {
169  list << "'" << key << "': '"
170  << map[key].toString() << "'";
171  if (index != 1) {
172  list << ", ";
173  }
174  index--;
175  }
176  list << "}";
177  return list.join("");
178  }
179 
180  private:
181  logger_mt* _lg = nullptr;
182 };
183 
184 LoggerPrivate* Logger::_private = new LoggerPrivate();
185 QMutex Logger::_mutex;
186 
187 void
188 Logger::init(Logger::Level lvl, const QString& path) {
189  _mutex.lock();
190  _private->init(lvl, path);
191  _mutex.unlock();
192 }
193 
194 void
195 Logger::log(Logger::Level lvl, const QString& msg) {
196  _private->log(lvl, msg);
197 }
198 
199 void
200 Logger::log(Logger::Level lvl, const QStringList& msg) {
201  _private->log(lvl, msg);
202 }
203 
204 void
205 Logger::log(Level lvl, const QString& msg, QMap<QString, QString> map) {
206  _private->log(lvl, msg, map);
207 }
208 
209 void
210 Logger::log(Level lvl, const QString& msg, QMap<QString, QVariant> map) {
211  _private->log(lvl, msg, map);
212 }
213 
214 void
215 Logger::log(Level lvl, const QString& msg, DownloadStruct downStruct) {
216  _private->log(lvl, msg, downStruct);
217 }
218 
219 } // logging
220 
221 } // Transfers
222 
223 } // Ubuntu
boost::log::sources::severity_channel_logger_mt< Ubuntu::DownloadManager::Logging::Logger::Level, std::string > logger_mt
Definition: logger.cpp:35