-
Notifications
You must be signed in to change notification settings - Fork 273
/
logger.h
168 lines (132 loc) · 5.28 KB
/
logger.h
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#pragma once
#include <string>
#include <chrono>
#include <atomic>
#include <map>
#include <memory>
#include <thread>
#include <mutex>
#include <functional>
#include "concurrentmap.h"
#include "selectableevent.h"
namespace swss {
#define SWSS_LOG_ERROR(MSG, ...) swss::Logger::getInstance().write(swss::Logger::SWSS_ERROR, ":- %s: " MSG, __FUNCTION__, ##__VA_ARGS__)
#define SWSS_LOG_WARN(MSG, ...) swss::Logger::getInstance().write(swss::Logger::SWSS_WARN, ":- %s: " MSG, __FUNCTION__, ##__VA_ARGS__)
#define SWSS_LOG_NOTICE(MSG, ...) swss::Logger::getInstance().write(swss::Logger::SWSS_NOTICE, ":- %s: " MSG, __FUNCTION__, ##__VA_ARGS__)
#define SWSS_LOG_INFO(MSG, ...) swss::Logger::getInstance().write(swss::Logger::SWSS_INFO, ":- %s: " MSG, __FUNCTION__, ##__VA_ARGS__)
#define SWSS_LOG_DEBUG(MSG, ...) swss::Logger::getInstance().write(swss::Logger::SWSS_DEBUG, ":- %s: " MSG, __FUNCTION__, ##__VA_ARGS__)
#define SWSS_LOG_ENTER() swss::Logger::ScopeLogger logger ## __LINE__ (__LINE__, __FUNCTION__)
#define SWSS_LOG_TIMER(msg, ...) swss::Logger::ScopeTimer scopetimer ## __LINE__ (__LINE__, __FUNCTION__, msg, ##__VA_ARGS__)
#define SWSS_LOG_THROW(MSG, ...) swss::Logger::getInstance().wthrow(swss::Logger::SWSS_ERROR, ":- %s: " MSG, __FUNCTION__, ##__VA_ARGS__)
static constexpr const char * const DAEMON_LOGLEVEL = "LOGLEVEL";
static constexpr const char * const DAEMON_LOGOUTPUT = "LOGOUTPUT";
void err_exit(const char *fn, int ln, int e, const char *fmt, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 4, 5)))
__attribute__ ((noreturn))
#endif
;
#define ABORT_IF_NOT(x, fmt, args...) \
if (!(x)) { \
int e = errno; \
err_exit(__FUNCTION__, __LINE__, e, (fmt), ##args); \
}
#ifdef __GNUC__
# define ATTRIBUTE_NORTEURN __attribute__ ((noreturn))
#else
# define ATTRIBUTE_NORTEURN
#endif
class Logger
{
public:
enum Priority
{
SWSS_EMERG,
SWSS_ALERT,
SWSS_CRIT,
SWSS_ERROR,
SWSS_WARN,
SWSS_NOTICE,
SWSS_INFO,
SWSS_DEBUG
};
typedef std::map<std::string, Priority> PriorityStringMap;
static const PriorityStringMap priorityStringMap;
typedef std::function<void (std::string component, std::string prioStr)> PriorityChangeNotify;
enum Output
{
SWSS_SYSLOG,
SWSS_STDOUT,
SWSS_STDERR
};
typedef std::map<std::string, Output> OutputStringMap;
static const OutputStringMap outputStringMap;
typedef std::function<void (std::string component, std::string outputStr)> OutputChangeNotify;
static Logger& getInstance();
static void setMinPrio(Priority prio);
static Priority getMinPrio();
static void linkToDbWithOutput(
const std::string& dbName,
const PriorityChangeNotify& prioNotify,
const std::string& defPrio,
const OutputChangeNotify& outputNotify,
const std::string& defOutput);
static void linkToDb(const std::string& dbName, const PriorityChangeNotify& notify, const std::string& defPrio);
// Must be called after all linkToDb to start select from DB
static void linkToDbNative(const std::string& dbName, const char * defPrio="NOTICE");
static void restartLogger();
void write(Priority prio, const char *fmt, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 3, 4)))
#endif
;
void wthrow(Priority prio, const char *fmt, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 3, 4)))
__attribute__ ((noreturn))
#endif
;
static std::string priorityToString(Priority prio);
static std::string outputToString(Output output);
static void swssOutputNotify(const std::string& component, const std::string& outputStr);
class ScopeLogger
{
public:
ScopeLogger(int line, const char *fun);
~ScopeLogger();
private:
const int m_line;
const char *m_fun;
};
class ScopeTimer
{
typedef std::chrono::duration<double, std::ratio<1>> second_t;
public:
ScopeTimer(int line, const char* fun, const char *msg, ...);
~ScopeTimer();
private:
const int m_line;
const char *m_fun;
std::string m_msg;
std::chrono::time_point<std::chrono::high_resolution_clock> m_start;
};
private:
Logger() = default;
~Logger();
Logger(const Logger&);
Logger& operator=(const Logger&);
static void swssPrioNotify(const std::string& component, const std::string& prioStr);
void settingThread();
void terminateSettingThread();
void restartSettingThread();
typedef ConcurrentMap<std::string, std::pair<PriorityChangeNotify, OutputChangeNotify>> LogSettingChangeObservers;
LogSettingChangeObservers m_settingChangeObservers;
ConcurrentMap<std::string, std::string> m_currentPrios;
std::atomic<Priority> m_minPrio = { SWSS_NOTICE };
ConcurrentMap<std::string, std::string> m_currentOutputs;
std::atomic<Output> m_output = { SWSS_SYSLOG };
std::unique_ptr<std::thread> m_settingThread;
std::mutex m_mutex;
std::unique_ptr<SelectableEvent> m_stopEvent;
};
}