1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#ifndef LOGGER_H
#define LOGGER_H
#include <map>
#include <stdarg.h>
#include <stdlib.h>
#include <syslog.h> // Pulled in for easy client lookups of LOG_* priorties
#include <boost/intrusive_ptr.hpp>
#include <boost/format.hpp>
#include "intrusivePtrBase.h"
#include "genLoader.h"
#include <misc.h>
/// Base class for classes providing a logging facility
class LogDriverBase : public virtual IntrusivePtrBase {
public:
LogDriverBase();
virtual ~LogDriverBase();
virtual void message(int priority, const char * msg) const = 0;
};
class LogDriverLoader : public GenLoader<LogDriverBase, std::string> {
public:
virtual int loggerLevel() const = 0;
};
class Log {
public:
typedef boost::intrusive_ptr<LogDriverBase> LogDriverBasePtr;
typedef std::map<LogDriverLoader *, LogDriverBasePtr> LogDrivers;
Log();
~Log();
void setLoggerAt(LogDriverLoader *, int level);
void message(int priority, const char * msg) const;
void messagef(int priority, const char * msgfmt, ...) const __attribute__ ((format (printf, 3, 4)));
template <typename... Args>
void messagebf(int priority, const char * msgfmt, const Args & ... args) const {
if (priority > lowestLevel) return;
boost::shared_ptr<boost::format> fmt = getFormat(msgfmt);
messagebf(priority, *fmt, args...);
}
void vmessagef(int priority, const char * msgfmt, va_list) const;
static const char * priorityName(int priority); // Look up the priority as defined in syslog.h
private:
template <typename Arg, typename... OtherArgs>
void messagebf(int priority, boost::format & f, const Arg & arg, const OtherArgs & ... otherargs) const {
f % arg;
messagebf(priority, f, otherargs...);
}
void messagebf(int priority, const boost::format & f) const;
LogDrivers logs;
int lowestLevel;
int nextId;
};
class Logger {
public:
Log * operator->() const;
private:
static Log log;
};
template<typename LoggerType>
class LogDriverLoaderImpl : public LogDriverLoader::For<LoggerType, LogDriverLoader> {
public:
LogDriverLoaderImpl() :
level(LoggerType::level)
{
}
virtual void onConfigLoad() override {
Logger()->setLoggerAt(this, level);
if (level == -1) {
instance.reset();
}
}
inline LoggerType * create() const {
if (!instance) {
instance = new LoggerType();
}
return instance.get();
}
int loggerLevel() const {
return level;
}
const int & level;
private:
mutable boost::intrusive_ptr<LoggerType> instance;
};
#define DECLARE_LOGGER_LOADER(N, T) \
DECLARE_CUSTOM_COMPONENT_LOADER(N, T, LogDriverLoaderImpl<T>, LogDriverLoader);
#endif
|