Fawkes API  Fawkes Development Version
mongodb_log_logger_thread.cpp
1 
2 /***************************************************************************
3  * mongodb_logger_thread.cpp - MongoDB logger thread
4  *
5  * Created: Tue Dec 07 22:59:47 2010
6  * Copyright 2006-2017 Tim Niemueller [www.niemueller.de]
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include "mongodb_log_logger_thread.h"
23 
24 #include <core/threading/mutex.h>
25 #include <core/threading/mutex_locker.h>
26 
27 #include <bsoncxx/builder/basic/document.hpp>
28 #include <mongocxx/client.hpp>
29 #include <mongocxx/exception/operation_exception.hpp>
30 
31 using namespace mongocxx;
32 using namespace fawkes;
33 
34 /** @class MongoLogLoggerThread "mongodb_log_logger_thread.h"
35  * Thread that provides a logger writing to MongoDB.
36  * This thread provides a logger, which writes log information to a
37  * MongoDB collection.
38  * @author Tim Niemueller
39  */
40 
41 /** Constructor. */
43 : Thread("MongoLogLoggerThread", Thread::OPMODE_WAITFORWAKEUP),
44  LoggerAspect(this),
45  MongoDBAspect("default")
46 {
47  mutex_ = new Mutex();
48 }
49 
50 /** Destructor. */
52 {
53  delete mutex_;
54 }
55 
56 void
58 {
59  database_ = config->get_string_or_default("/plugins/mongodb/logger/database", "fawkes");
60  collection_ = config->get_string_or_default("/plugins/mongodb/logger/collection", "msglog");
61 }
62 
63 void
65 {
66 }
67 
68 void
70 {
71 }
72 
73 void
74 MongoLogLoggerThread::insert_message(LogLevel ll,
75  const char *component,
76  const char *format,
77  va_list va)
78 {
79  if (log_level <= ll) {
80  MutexLocker lock(mutex_);
81  bsoncxx::types::b_date nowd{std::chrono::high_resolution_clock::now()};
82 
83  char *msg;
84  if (vasprintf(&msg, format, va) == -1) {
85  // Cannot do anything useful, drop log message
86  return;
87  }
88 
89  using namespace bsoncxx::builder;
90  basic::document b;
91  switch (ll) {
92  case LL_DEBUG: b.append(basic::kvp("level", "DEBUG")); break;
93  case LL_INFO: b.append(basic::kvp("level", "INFO")); break;
94  case LL_WARN: b.append(basic::kvp("level", "WARN")); break;
95  case LL_ERROR: b.append(basic::kvp("level", "ERROR")); break;
96  default: b.append(basic::kvp("level", "UNKN")); break;
97  }
98  b.append(basic::kvp("component", component));
99  b.append(basic::kvp("time", nowd));
100  b.append(basic::kvp("message", msg));
101 
102  free(msg);
103 
104  try {
105  mongodb_client->database(database_)[collection_].insert_one(b.view());
106  } catch (operation_exception &e) {
107  } // ignored
108  }
109 }
110 
111 void
112 MongoLogLoggerThread::insert_message(LogLevel ll, const char *component, Exception &e)
113 {
114  if (log_level <= ll) {
115  MutexLocker lock(mutex_);
116  bsoncxx::types::b_date nowd{std::chrono::high_resolution_clock::now()};
117 
118  for (Exception::iterator i = e.begin(); i != e.end(); ++i) {
119  using namespace bsoncxx::builder;
120  basic::document b;
121  switch (ll) {
122  case LL_DEBUG: b.append(basic::kvp("level", "DEBUG")); break;
123  case LL_INFO: b.append(basic::kvp("level", "INFO")); break;
124  case LL_WARN: b.append(basic::kvp("level", "WARN")); break;
125  case LL_ERROR: b.append(basic::kvp("level", "ERROR")); break;
126  default: b.append(basic::kvp("level", "UNKN")); break;
127  }
128  b.append(basic::kvp("component", component));
129  b.append(basic::kvp("time", nowd));
130  b.append(basic::kvp("message", std::string("[EXCEPTION] ") + *i));
131  try {
132  mongodb_client->database(database_)[collection_].insert_one(b.view());
133  } catch (operation_exception &e) {
134  } // ignored
135  }
136  }
137 }
138 
139 void
140 MongoLogLoggerThread::vlog_debug(const char *component, const char *format, va_list va)
141 {
142  insert_message(LL_DEBUG, component, format, va);
143 }
144 
145 void
146 MongoLogLoggerThread::vlog_info(const char *component, const char *format, va_list va)
147 {
148  insert_message(LL_INFO, component, format, va);
149 }
150 
151 void
152 MongoLogLoggerThread::vlog_warn(const char *component, const char *format, va_list va)
153 {
154  insert_message(LL_WARN, component, format, va);
155 }
156 
157 void
158 MongoLogLoggerThread::vlog_error(const char *component, const char *format, va_list va)
159 {
160  insert_message(LL_ERROR, component, format, va);
161 }
162 
163 void
164 MongoLogLoggerThread::log_debug(const char *component, const char *format, ...)
165 {
166  va_list arg;
167  va_start(arg, format);
168  insert_message(LL_DEBUG, component, format, arg);
169  va_end(arg);
170 }
171 
172 void
173 MongoLogLoggerThread::log_info(const char *component, const char *format, ...)
174 {
175  va_list arg;
176  va_start(arg, format);
177  insert_message(LL_INFO, component, format, arg);
178  va_end(arg);
179 }
180 
181 void
182 MongoLogLoggerThread::log_warn(const char *component, const char *format, ...)
183 {
184  va_list arg;
185  va_start(arg, format);
186  insert_message(LL_WARN, component, format, arg);
187  va_end(arg);
188 }
189 
190 void
191 MongoLogLoggerThread::log_error(const char *component, const char *format, ...)
192 {
193  va_list arg;
194  va_start(arg, format);
195  insert_message(LL_ERROR, component, format, arg);
196  va_end(arg);
197 }
198 
199 void
200 MongoLogLoggerThread::log_debug(const char *component, Exception &e)
201 {
202  insert_message(LL_DEBUG, component, e);
203 }
204 
205 void
206 MongoLogLoggerThread::log_info(const char *component, Exception &e)
207 {
208  insert_message(LL_INFO, component, e);
209 }
210 
211 void
212 MongoLogLoggerThread::log_warn(const char *component, Exception &e)
213 {
214  insert_message(LL_WARN, component, e);
215 }
216 
217 void
218 MongoLogLoggerThread::log_error(const char *component, Exception &e)
219 {
220  insert_message(LL_ERROR, component, e);
221 }
222 
223 void
224 MongoLogLoggerThread::tlog_insert_message(LogLevel ll,
225  struct timeval *t,
226  const char * component,
227  const char * format,
228  va_list va)
229 {
230  if (log_level <= ll) {
231  MutexLocker lock(mutex_);
232  char * msg;
233  if (vasprintf(&msg, format, va) == -1) {
234  return;
235  }
236 
237  bsoncxx::types::b_date nowd{
238  std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>{
239  std::chrono::milliseconds{t->tv_sec * 1000 + t->tv_usec / 1000}}};
240 
241  using namespace bsoncxx::builder;
242  basic::document b;
243  switch (ll) {
244  case LL_DEBUG: b.append(basic::kvp("level", "DEBUG")); break;
245  case LL_INFO: b.append(basic::kvp("level", "INFO")); break;
246  case LL_WARN: b.append(basic::kvp("level", "WARN")); break;
247  case LL_ERROR: b.append(basic::kvp("level", "ERROR")); break;
248  default: b.append(basic::kvp("level", "UNKN")); break;
249  }
250  b.append(basic::kvp("component", component));
251  b.append(basic::kvp("time", nowd));
252  b.append(basic::kvp("message", msg));
253  try {
254  mongodb_client->database(database_)[collection_].insert_one(b.view());
255  } catch (operation_exception &e) {
256  } // ignored
257 
258  free(msg);
259 
260  mutex_->unlock();
261  }
262 }
263 
264 void
265 MongoLogLoggerThread::tlog_insert_message(LogLevel ll,
266  struct timeval *t,
267  const char * component,
268  Exception & e)
269 {
270  if (log_level <= ll) {
271  MutexLocker lock(mutex_);
272  bsoncxx::types::b_date nowd{
273  std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>{
274  std::chrono::milliseconds{t->tv_sec * 1000 + t->tv_usec / 1000}}};
275  for (Exception::iterator i = e.begin(); i != e.end(); ++i) {
276  using namespace bsoncxx::builder;
277  basic::document b;
278  switch (ll) {
279  case LL_DEBUG: b.append(basic::kvp("level", "DEBUG")); break;
280  case LL_INFO: b.append(basic::kvp("level", "INFO")); break;
281  case LL_WARN: b.append(basic::kvp("level", "WARN")); break;
282  case LL_ERROR: b.append(basic::kvp("level", "ERROR")); break;
283  default: b.append(basic::kvp("level", "UNKN")); break;
284  }
285  b.append(basic::kvp("component", component));
286  b.append(basic::kvp("time", nowd));
287  b.append(basic::kvp("message", std::string("[EXCEPTION] ") + *i));
288  try {
289  mongodb_client->database(database_)[collection_].insert_one(b.view());
290  } catch (operation_exception &e) {
291  } // ignored
292  }
293  }
294 }
295 
296 void
297 MongoLogLoggerThread::tlog_debug(struct timeval *t, const char *component, const char *format, ...)
298 {
299  va_list arg;
300  va_start(arg, format);
301  tlog_insert_message(LL_DEBUG, t, component, format, arg);
302  va_end(arg);
303 }
304 
305 void
306 MongoLogLoggerThread::tlog_info(struct timeval *t, const char *component, const char *format, ...)
307 {
308  va_list arg;
309  va_start(arg, format);
310  tlog_insert_message(LL_INFO, t, component, format, arg);
311  va_end(arg);
312 }
313 
314 void
315 MongoLogLoggerThread::tlog_warn(struct timeval *t, const char *component, const char *format, ...)
316 {
317  va_list arg;
318  va_start(arg, format);
319  tlog_insert_message(LL_WARN, t, component, format, arg);
320  va_end(arg);
321 }
322 
323 void
324 MongoLogLoggerThread::tlog_error(struct timeval *t, const char *component, const char *format, ...)
325 {
326  va_list arg;
327  va_start(arg, format);
328  tlog_insert_message(LL_ERROR, t, component, format, arg);
329  va_end(arg);
330 }
331 
332 void
333 MongoLogLoggerThread::tlog_debug(struct timeval *t, const char *component, Exception &e)
334 {
335  tlog_insert_message(LL_DEBUG, t, component, e);
336 }
337 
338 void
339 MongoLogLoggerThread::tlog_info(struct timeval *t, const char *component, Exception &e)
340 {
341  tlog_insert_message(LL_INFO, t, component, e);
342 }
343 
344 void
345 MongoLogLoggerThread::tlog_warn(struct timeval *t, const char *component, Exception &e)
346 {
347  tlog_insert_message(LL_WARN, t, component, e);
348 }
349 
350 void
351 MongoLogLoggerThread::tlog_error(struct timeval *t, const char *component, Exception &e)
352 {
353  tlog_insert_message(LL_ERROR, t, component, e);
354 }
355 
356 void
358  const char * component,
359  const char * format,
360  va_list va)
361 {
362  tlog_insert_message(LL_DEBUG, t, component, format, va);
363 }
364 
365 void
367  const char * component,
368  const char * format,
369  va_list va)
370 {
371  tlog_insert_message(LL_INFO, t, component, format, va);
372 }
373 
374 void
376  const char * component,
377  const char * format,
378  va_list va)
379 {
380  tlog_insert_message(LL_WARN, t, component, format, va);
381 }
382 
383 void
385  const char * component,
386  const char * format,
387  va_list va)
388 {
389  tlog_insert_message(LL_ERROR, t, component, format, va);
390 }
fawkes::MongoDBAspect
Thread aspect to access MongoDB.
Definition: mongodb.h:39
MongoLogLoggerThread::log_debug
virtual void log_debug(const char *component, const char *format,...)
Log debug message.
Definition: mongodb_log_logger_thread.cpp:164
MongoLogLoggerThread::tlog_error
virtual void tlog_error(struct timeval *t, const char *component, const char *format,...)
Log error message for specific time.
Definition: mongodb_log_logger_thread.cpp:324
MongoLogLoggerThread::vtlog_warn
virtual void vtlog_warn(struct timeval *t, const char *component, const char *format, va_list va)
Log warning message for specific time.
Definition: mongodb_log_logger_thread.cpp:375
MongoLogLoggerThread::finalize
virtual void finalize()
Finalize the thread.
Definition: mongodb_log_logger_thread.cpp:64
MongoLogLoggerThread::vtlog_info
virtual void vtlog_info(struct timeval *t, const char *component, const char *format, va_list va)
Log informational message for specific time.
Definition: mongodb_log_logger_thread.cpp:366
fawkes::Exception::end
iterator end()
Get end iterator for messages.
Definition: exception.cpp:692
MongoLogLoggerThread::vlog_debug
virtual void vlog_debug(const char *component, const char *format, va_list va)
Log debug message.
Definition: mongodb_log_logger_thread.cpp:140
fawkes::Logger::log_level
LogLevel log_level
Minimum log level.
Definition: logger.h:126
fawkes::Mutex
Mutex mutual exclusion lock.
Definition: mutex.h:33
fawkes::MongoDBAspect::mongodb_client
mongocxx::client * mongodb_client
MongoDB client to use to interact with the database.
Definition: mongodb.h:54
MongoLogLoggerThread::log_error
virtual void log_error(const char *component, const char *format,...)
Log error message.
Definition: mongodb_log_logger_thread.cpp:191
MongoLogLoggerThread::vlog_info
virtual void vlog_info(const char *component, const char *format, va_list va)
Log informational message.
Definition: mongodb_log_logger_thread.cpp:146
MongoLogLoggerThread::log_warn
virtual void log_warn(const char *component, const char *format,...)
Log warning message.
Definition: mongodb_log_logger_thread.cpp:182
MongoLogLoggerThread::init
virtual void init()
Initialize the thread.
Definition: mongodb_log_logger_thread.cpp:57
fawkes::MutexLocker
Mutex locking helper.
Definition: mutex_locker.h:34
MongoLogLoggerThread::vtlog_error
virtual void vtlog_error(struct timeval *t, const char *component, const char *format, va_list va)
Log error message for specific time.
Definition: mongodb_log_logger_thread.cpp:384
MongoLogLoggerThread::tlog_warn
virtual void tlog_warn(struct timeval *t, const char *component, const char *format,...)
Log warning message for specific time.
Definition: mongodb_log_logger_thread.cpp:315
MongoLogLoggerThread::tlog_debug
virtual void tlog_debug(struct timeval *t, const char *component, const char *format,...)
Log debug message for specific time.
Definition: mongodb_log_logger_thread.cpp:297
MongoLogLoggerThread::vlog_error
virtual void vlog_error(const char *component, const char *format, va_list va)
Log error message.
Definition: mongodb_log_logger_thread.cpp:158
fawkes::Logger::LL_DEBUG
@ LL_DEBUG
debug output, relevant only when tracking down problems
Definition: logger.h:52
MongoLogLoggerThread::vlog_warn
virtual void vlog_warn(const char *component, const char *format, va_list va)
Log warning message.
Definition: mongodb_log_logger_thread.cpp:152
MongoLogLoggerThread::loop
virtual void loop()
Code to execute in the thread.
Definition: mongodb_log_logger_thread.cpp:69
fawkes::LoggerAspect
Thread aspect that allows to provide a logger to Fawkes.
Definition: logger.h:34
fawkes::Logger::LL_INFO
@ LL_INFO
informational output about normal procedures
Definition: logger.h:53
fawkes
Fawkes library namespace.
fawkes::Logger::LL_ERROR
@ LL_ERROR
error, may be recoverable (software still running) or not (software has to terminate).
Definition: logger.h:57
fawkes::ConfigurableAspect::config
Configuration * config
This is the Configuration member used to access the configuration.
Definition: configurable.h:41
fawkes::Exception::begin
iterator begin()
Get iterator for messages.
Definition: exception.cpp:676
MongoLogLoggerThread::tlog_info
virtual void tlog_info(struct timeval *t, const char *component, const char *format,...)
Log informational message for specific time.
Definition: mongodb_log_logger_thread.cpp:306
MongoLogLoggerThread::MongoLogLoggerThread
MongoLogLoggerThread()
Constructor.
Definition: mongodb_log_logger_thread.cpp:42
MongoLogLoggerThread::log_info
virtual void log_info(const char *component, const char *format,...)
Log informational message.
Definition: mongodb_log_logger_thread.cpp:173
fawkes::Logger::LogLevel
LogLevel
Log level.
Definition: logger.h:51
fawkes::Thread
Thread class encapsulation of pthreads.
Definition: thread.h:46
fawkes::Configuration::get_string_or_default
virtual std::string get_string_or_default(const char *path, const std::string &default_val)
Get value from configuration which is of type string, or the given default if the path does not exist...
Definition: config.cpp:736
fawkes::Logger::LL_WARN
@ LL_WARN
warning, should be investigated but software still functions, an example is that something was reques...
Definition: logger.h:54
fawkes::Exception::iterator
Message iterator for exceptions.
Definition: exception.h:73
MongoLogLoggerThread::~MongoLogLoggerThread
virtual ~MongoLogLoggerThread()
Destructor.
Definition: mongodb_log_logger_thread.cpp:51
MongoLogLoggerThread::vtlog_debug
virtual void vtlog_debug(struct timeval *t, const char *component, const char *format, va_list va)
Log debug message for specific time.
Definition: mongodb_log_logger_thread.cpp:357
fawkes::Exception
Base class for exceptions in Fawkes.
Definition: exception.h:36