14
14
#include " consumerstatetable.h"
15
15
#include " producerstatetable.h"
16
16
17
- namespace swss {
17
+ using namespace swss ;
18
18
19
- void err_exit (const char *fn, int ln, int e, const char *fmt, ...)
19
+ #define MUTEX std::lock_guard<std::mutex> _lock (getInstance().m_mutex);
20
+
21
+ void swss::err_exit (const char *fn, int ln, int e, const char *fmt, ...)
20
22
{
21
23
va_list ap;
22
24
char buff[1024 ];
@@ -31,13 +33,34 @@ void err_exit(const char *fn, int ln, int e, const char *fmt, ...)
31
33
abort ();
32
34
}
33
35
34
- Logger::~Logger () {
35
- if (m_settingThread) {
36
- terminateSettingThread = true ;
36
+ Logger::~Logger ()
37
+ {
38
+ terminateSettingThread ();
39
+ }
40
+
41
+ void Logger::terminateSettingThread ()
42
+ {
43
+ // can't be executed under mutex, since it can cause deadlock
44
+
45
+ if (m_settingThread)
46
+ {
47
+ m_runSettingThread = false ;
48
+
37
49
m_settingThread->join ();
50
+
51
+ m_settingThread = nullptr ;
38
52
}
39
53
}
40
54
55
+ void Logger::restartSettingThread ()
56
+ {
57
+ terminateSettingThread ();
58
+
59
+ m_runSettingThread = true ;
60
+
61
+ m_settingThread.reset (new std::thread (&Logger::settingThread, this ));
62
+ }
63
+
41
64
const Logger::PriorityStringMap Logger::priorityStringMap = {
42
65
{ " EMERG" , SWSS_EMERG },
43
66
{ " ALERT" , SWSS_ALERT },
@@ -49,7 +72,7 @@ const Logger::PriorityStringMap Logger::priorityStringMap = {
49
72
{ " DEBUG" , SWSS_DEBUG }
50
73
};
51
74
52
- void Logger::swssPrioNotify (const std::string & component, const std::string & prioStr)
75
+ void Logger::swssPrioNotify (const std::string& component, const std::string& prioStr)
53
76
{
54
77
auto & logger = getInstance ();
55
78
@@ -70,7 +93,7 @@ const Logger::OutputStringMap Logger::outputStringMap = {
70
93
{ " STDERR" , SWSS_STDERR }
71
94
};
72
95
73
- void Logger::swssOutputNotify (const std::string & component, const std::string & outputStr)
96
+ void Logger::swssOutputNotify (const std::string& component, const std::string& outputStr)
74
97
{
75
98
auto & logger = getInstance ();
76
99
@@ -85,22 +108,27 @@ void Logger::swssOutputNotify(const std::string &component, const std::string &o
85
108
}
86
109
}
87
110
88
- void Logger::linkToDbWithOutput (const std::string &dbName, const PriorityChangeNotify& prioNotify, const std::string& defPrio, const OutputChangeNotify& outputNotify, const std::string& defOutput)
111
+ void Logger::linkToDbWithOutput (
112
+ const std::string& dbName,
113
+ const PriorityChangeNotify& prioNotify,
114
+ const std::string& defPrio,
115
+ const OutputChangeNotify& outputNotify,
116
+ const std::string& defOutput)
89
117
{
90
118
auto & logger = getInstance ();
91
119
92
120
// Initialize internal DB with observer
93
121
logger.m_settingChangeObservers .insert (std::make_pair (dbName, std::make_pair (prioNotify, outputNotify)));
122
+
94
123
DBConnector db (" LOGLEVEL_DB" , 0 );
95
- auto keys = db.keys (" *" );
96
124
97
125
std::string key = dbName + " :" + dbName;
98
126
std::string prio, output;
99
127
bool doUpdate = false ;
100
128
auto prioPtr = db.hget (key, DAEMON_LOGLEVEL);
101
129
auto outputPtr = db.hget (key, DAEMON_LOGOUTPUT);
102
130
103
- if ( prioPtr == nullptr )
131
+ if (prioPtr == nullptr )
104
132
{
105
133
prio = defPrio;
106
134
doUpdate = true ;
@@ -110,7 +138,7 @@ void Logger::linkToDbWithOutput(const std::string &dbName, const PriorityChangeN
110
138
prio = *prioPtr;
111
139
}
112
140
113
- if ( outputPtr == nullptr )
141
+ if (outputPtr == nullptr )
114
142
{
115
143
output = defOutput;
116
144
doUpdate = true ;
@@ -130,26 +158,26 @@ void Logger::linkToDbWithOutput(const std::string &dbName, const PriorityChangeN
130
158
table.set (dbName, fieldValues);
131
159
}
132
160
133
- logger.m_currentPrios [dbName] = prio;
134
- logger.m_currentOutputs [dbName] = output;
161
+ logger.m_currentPrios .set (dbName, prio);
162
+ logger.m_currentOutputs .set (dbName, output);
163
+
135
164
prioNotify (dbName, prio);
136
165
outputNotify (dbName, output);
137
166
}
138
167
139
- void Logger::linkToDb (const std::string & dbName, const PriorityChangeNotify& prioNotify, const std::string& defPrio)
168
+ void Logger::linkToDb (const std::string& dbName, const PriorityChangeNotify& prioNotify, const std::string& defPrio)
140
169
{
141
170
linkToDbWithOutput (dbName, prioNotify, defPrio, swssOutputNotify, " SYSLOG" );
142
171
}
143
172
144
- void Logger::linkToDbNative (const std::string & dbName, const char * defPrio)
173
+ void Logger::linkToDbNative (const std::string& dbName, const char * defPrio)
145
174
{
146
- auto & logger = getInstance ();
147
-
148
175
linkToDb (dbName, swssPrioNotify, defPrio);
149
- logger.m_settingThread .reset (new std::thread (&Logger::settingThread, &logger));
176
+
177
+ getInstance ().restartSettingThread ();
150
178
}
151
179
152
- Logger & Logger::getInstance ()
180
+ Logger& Logger::getInstance ()
153
181
{
154
182
static Logger m_logger;
155
183
return m_logger;
@@ -171,13 +199,13 @@ void Logger::settingThread()
171
199
DBConnector db (" LOGLEVEL_DB" , 0 );
172
200
std::map<std::string, std::shared_ptr<ConsumerStateTable>> selectables;
173
201
174
- while (!terminateSettingThread )
202
+ while (m_runSettingThread )
175
203
{
176
204
if (selectables.size () < m_settingChangeObservers.size ())
177
205
{
178
- for (const auto & i : m_settingChangeObservers)
206
+ for (const auto & i : m_settingChangeObservers. getCopy () )
179
207
{
180
- const std::string & dbName = i.first ;
208
+ const std::string& dbName = i.first ;
181
209
if (selectables.find (dbName) == selectables.end ())
182
210
{
183
211
auto table = std::make_shared<ConsumerStateTable>(&db, dbName);
@@ -208,27 +236,28 @@ void Logger::settingThread()
208
236
dynamic_cast <ConsumerStateTable *>(selectable)->pop (koValues);
209
237
std::string key = kfvKey (koValues), op = kfvOp (koValues);
210
238
211
- if (( op != SET_COMMAND) || ( m_settingChangeObservers.find (key) == m_settingChangeObservers. end () ))
239
+ if (op != SET_COMMAND || ! m_settingChangeObservers.contains (key))
212
240
{
213
241
continue ;
214
242
}
215
243
216
- auto values = kfvFieldsValues (koValues);
217
- for (const auto & i : values)
244
+ const auto & values = kfvFieldsValues (koValues);
245
+
246
+ for (auto & i : values)
218
247
{
219
- const std::string &field = fvField (i), &value = fvValue (i);
220
- if ((field == DAEMON_LOGLEVEL) && (value != m_currentPrios[key]))
248
+ auto & field = fvField (i);
249
+ auto & value = fvValue (i);
250
+
251
+ if ((field == DAEMON_LOGLEVEL) && (value != m_currentPrios.get (key)))
221
252
{
222
- m_currentPrios[ key] = value;
223
- m_settingChangeObservers[ key] .first (key, value);
253
+ m_currentPrios. set ( key, value) ;
254
+ m_settingChangeObservers. get ( key) .first (key, value);
224
255
}
225
- else if ((field == DAEMON_LOGOUTPUT) && (value != m_currentOutputs[ key] ))
256
+ else if ((field == DAEMON_LOGOUTPUT) && (value != m_currentOutputs. get ( key) ))
226
257
{
227
- m_currentOutputs[ key] = value;
228
- m_settingChangeObservers[ key] .second (key, value);
258
+ m_currentOutputs. set ( key, value) ;
259
+ m_settingChangeObservers. get ( key) .second (key, value);
229
260
}
230
-
231
- break ;
232
261
}
233
262
}
234
263
}
@@ -246,14 +275,16 @@ void Logger::write(Priority prio, const char *fmt, ...)
246
275
247
276
if (m_output == SWSS_SYSLOG)
248
277
{
249
- vsyslog (prio, fmt, ap);
278
+ vsyslog (prio, fmt, ap);
250
279
}
251
280
else
252
281
{
253
282
std::stringstream ss;
254
283
ss << std::setw (6 ) << std::right << priorityToString (prio);
255
284
ss << fmt << std::endl;
256
- std::lock_guard<std::mutex> lock (m_mutex);
285
+
286
+ MUTEX;
287
+
257
288
if (m_output == SWSS_STDOUT)
258
289
{
259
290
vprintf (ss.str ().c_str (), ap);
@@ -283,7 +314,9 @@ void Logger::wthrow(Priority prio, const char *fmt, ...)
283
314
std::stringstream ss;
284
315
ss << std::setw (6 ) << std::right << priorityToString (prio);
285
316
ss << fmt << std::endl;
286
- std::lock_guard<std::mutex> lock (m_mutex);
317
+
318
+ MUTEX;
319
+
287
320
if (m_output == SWSS_STDOUT)
288
321
{
289
322
vprintf (ss.str ().c_str (), ap);
@@ -363,5 +396,3 @@ Logger::ScopeTimer::~ScopeTimer()
363
396
364
397
Logger::getInstance ().write (swss::Logger::SWSS_NOTICE, " :- %s: %s took %lf sec" , m_fun, m_msg.c_str (), duration);
365
398
}
366
-
367
- };
0 commit comments