Mercurial > hg > orthanc
comparison OrthancFramework/Sources/Logging.cpp @ 4269:c7bd2f21ccc3
new macro CLOG, and sharing more code between logging engines
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 02 Nov 2020 17:15:57 +0100 |
parents | 0ae2ca210077 |
children | 251a8b07fa37 |
comparison
equal
deleted
inserted
replaced
4268:0ae2ca210077 | 4269:c7bd2f21ccc3 |
---|---|
24 #include "Logging.h" | 24 #include "Logging.h" |
25 | 25 |
26 #include "OrthancException.h" | 26 #include "OrthancException.h" |
27 | 27 |
28 | 28 |
29 namespace Orthanc | |
30 { | |
31 namespace Logging | |
32 { | |
33 const char* EnumerationToString(LogLevel level) | |
34 { | |
35 switch (level) | |
36 { | |
37 case LogLevel_ERROR: | |
38 return "ERROR"; | |
39 | |
40 case LogLevel_WARNING: | |
41 return "WARNING"; | |
42 | |
43 case LogLevel_INFO: | |
44 return "INFO"; | |
45 | |
46 case LogLevel_TRACE: | |
47 return "TRACE"; | |
48 | |
49 default: | |
50 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
51 } | |
52 } | |
53 | |
54 | |
55 LogLevel StringToLogLevel(const char *level) | |
56 { | |
57 if (strcmp(level, "ERROR") == 0) | |
58 { | |
59 return LogLevel_ERROR; | |
60 } | |
61 else if (strcmp(level, "WARNING") == 0) | |
62 { | |
63 return LogLevel_WARNING; | |
64 } | |
65 else if (strcmp(level, "INFO") == 0) | |
66 { | |
67 return LogLevel_INFO; | |
68 } | |
69 else if (strcmp(level, "TRACE") == 0) | |
70 { | |
71 return LogLevel_TRACE; | |
72 } | |
73 else | |
74 { | |
75 throw OrthancException(ErrorCode_InternalError); | |
76 } | |
77 } | |
78 } | |
79 } | |
80 | |
81 | |
82 #if ORTHANC_ENABLE_LOGGING != 1 | |
83 | |
84 namespace Orthanc | |
85 { | |
86 namespace Logging | |
87 { | |
88 void InitializePluginContext(void* pluginContext) | |
89 { | |
90 } | |
91 | |
92 void Initialize() | |
93 { | |
94 } | |
95 | |
96 void Finalize() | |
97 { | |
98 } | |
99 | |
100 void Reset() | |
101 { | |
102 } | |
103 | |
104 void Flush() | |
105 { | |
106 } | |
107 | |
108 void EnableInfoLevel(bool enabled) | |
109 { | |
110 } | |
111 | |
112 void EnableTraceLevel(bool enabled) | |
113 { | |
114 } | |
115 | |
116 bool IsTraceLevelEnabled() | |
117 { | |
118 return false; | |
119 } | |
120 | |
121 bool IsInfoLevelEnabled() | |
122 { | |
123 return false; | |
124 } | |
125 | |
126 void SetTargetFile(const std::string& path) | |
127 { | |
128 } | |
129 | |
130 void SetTargetFolder(const std::string& path) | |
131 { | |
132 } | |
133 } | |
134 } | |
135 | |
136 | |
137 #elif ORTHANC_ENABLE_LOGGING_STDIO == 1 | |
138 | |
139 /********************************************************* | 29 /********************************************************* |
140 * Logger compatible with <stdio.h> OR logger that sends its | 30 * Common section |
141 * output to the emscripten html5 api (depending on the | |
142 * definition of __EMSCRIPTEN__) | |
143 *********************************************************/ | 31 *********************************************************/ |
144 | |
145 #include <stdio.h> | |
146 | |
147 #ifdef __EMSCRIPTEN__ | |
148 # include <emscripten/html5.h> | |
149 #endif | |
150 | 32 |
151 namespace Orthanc | 33 namespace Orthanc |
152 { | 34 { |
153 namespace Logging | 35 namespace Logging |
154 { | 36 { |
155 static bool infoEnabled_ = false; | 37 static bool infoEnabled_ = false; |
156 static bool traceEnabled_ = false; | 38 static bool traceEnabled_ = false; |
157 | 39 |
40 const char* EnumerationToString(LogLevel level) | |
41 { | |
42 switch (level) | |
43 { | |
44 case LogLevel_ERROR: | |
45 return "ERROR"; | |
46 | |
47 case LogLevel_WARNING: | |
48 return "WARNING"; | |
49 | |
50 case LogLevel_INFO: | |
51 return "INFO"; | |
52 | |
53 case LogLevel_TRACE: | |
54 return "TRACE"; | |
55 | |
56 default: | |
57 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
58 } | |
59 } | |
60 | |
61 | |
62 LogLevel StringToLogLevel(const char *level) | |
63 { | |
64 if (strcmp(level, "ERROR") == 0) | |
65 { | |
66 return LogLevel_ERROR; | |
67 } | |
68 else if (strcmp(level, "WARNING") == 0) | |
69 { | |
70 return LogLevel_WARNING; | |
71 } | |
72 else if (strcmp(level, "INFO") == 0) | |
73 { | |
74 return LogLevel_INFO; | |
75 } | |
76 else if (strcmp(level, "TRACE") == 0) | |
77 { | |
78 return LogLevel_TRACE; | |
79 } | |
80 else | |
81 { | |
82 throw OrthancException(ErrorCode_InternalError); | |
83 } | |
84 } | |
85 | |
86 void EnableInfoLevel(bool enabled) | |
87 { | |
88 infoEnabled_ = enabled; | |
89 | |
90 if (!enabled) | |
91 { | |
92 // Also disable the "TRACE" level when info-level debugging is disabled | |
93 traceEnabled_ = false; | |
94 } | |
95 } | |
96 | |
97 bool IsInfoLevelEnabled() | |
98 { | |
99 return infoEnabled_; | |
100 } | |
101 | |
102 void EnableTraceLevel(bool enabled) | |
103 { | |
104 traceEnabled_ = enabled; | |
105 | |
106 if (enabled) | |
107 { | |
108 // Also enable the "INFO" level when trace-level debugging is enabled | |
109 infoEnabled_ = true; | |
110 } | |
111 } | |
112 | |
113 bool IsTraceLevelEnabled() | |
114 { | |
115 return traceEnabled_; | |
116 } | |
117 | |
118 static bool IsLoggingEnabled(LogLevel level, | |
119 LogCategory category) | |
120 { | |
121 if (level == LogLevel_ERROR || | |
122 level == LogLevel_WARNING) | |
123 { | |
124 return true; | |
125 } | |
126 else if (level == LogLevel_INFO) | |
127 { | |
128 return infoEnabled_; | |
129 } | |
130 else if (level == LogLevel_TRACE) | |
131 { | |
132 return traceEnabled_; | |
133 } | |
134 else | |
135 { | |
136 return false; | |
137 } | |
138 } | |
139 } | |
140 } | |
141 | |
142 | |
143 | |
144 #if ORTHANC_ENABLE_LOGGING != 1 | |
145 | |
146 /********************************************************* | |
147 * Section if logging is disabled | |
148 *********************************************************/ | |
149 | |
150 namespace Orthanc | |
151 { | |
152 namespace Logging | |
153 { | |
154 void InitializePluginContext(void* pluginContext) | |
155 { | |
156 } | |
157 | |
158 void Initialize() | |
159 { | |
160 } | |
161 | |
162 void Finalize() | |
163 { | |
164 } | |
165 | |
166 void Reset() | |
167 { | |
168 } | |
169 | |
170 void Flush() | |
171 { | |
172 } | |
173 | |
174 void SetTargetFile(const std::string& path) | |
175 { | |
176 } | |
177 | |
178 void SetTargetFolder(const std::string& path) | |
179 { | |
180 } | |
181 } | |
182 } | |
183 | |
184 | |
185 #elif ORTHANC_ENABLE_LOGGING_STDIO == 1 | |
186 | |
187 /********************************************************* | |
188 * Logger compatible with <stdio.h> OR logger that sends its | |
189 * output to the emscripten html5 api (depending on the | |
190 * definition of __EMSCRIPTEN__) | |
191 *********************************************************/ | |
192 | |
193 #include <stdio.h> | |
194 | |
195 #ifdef __EMSCRIPTEN__ | |
196 # include <emscripten/html5.h> | |
197 #endif | |
198 | |
199 namespace Orthanc | |
200 { | |
201 namespace Logging | |
202 { | |
158 #ifdef __EMSCRIPTEN__ | 203 #ifdef __EMSCRIPTEN__ |
159 static void ErrorLogFunc(const char* msg) | 204 static void ErrorLogFunc(const char* msg) |
160 { | 205 { |
161 emscripten_console_error(msg); | 206 emscripten_console_error(msg); |
162 } | 207 } |
200 | 245 |
201 InternalLogger::~InternalLogger() | 246 InternalLogger::~InternalLogger() |
202 { | 247 { |
203 std::string message = messageStream_.str(); | 248 std::string message = messageStream_.str(); |
204 | 249 |
205 switch (level_) | 250 if (IsLoggingEnabled(level_, category_)) |
206 { | 251 { |
207 case LogLevel_ERROR: | 252 switch (level_) |
208 ErrorLogFunc(message.c_str()); | 253 { |
209 break; | 254 case LogLevel_ERROR: |
210 | 255 ErrorLogFunc(message.c_str()); |
211 case LogLevel_WARNING: | 256 break; |
212 WarningLogFunc(message.c_str()); | 257 |
213 break; | 258 case LogLevel_WARNING: |
214 | 259 WarningLogFunc(message.c_str()); |
215 case LogLevel_INFO: | 260 break; |
216 if (infoEnabled_) | 261 |
217 { | 262 case LogLevel_INFO: |
218 InfoLogFunc(message.c_str()); | 263 InfoLogFunc(message.c_str()); |
219 // TODO: stone_console_info(message_.c_str()); | 264 // TODO: stone_console_info(message_.c_str()); |
265 break; | |
266 | |
267 case LogLevel_TRACE: | |
268 TraceLogFunc(message.c_str()); | |
269 break; | |
270 | |
271 default: | |
272 { | |
273 std::stringstream ss; | |
274 ss << "Unknown log level (" << level_ << ") for message: " << message; | |
275 std::string s = ss.str(); | |
276 ErrorLogFunc(s.c_str()); | |
220 } | 277 } |
221 break; | |
222 | |
223 case LogLevel_TRACE: | |
224 // TODO - Check trace category | |
225 if (traceEnabled_) | |
226 { | |
227 TraceLogFunc(message.c_str()); | |
228 } | |
229 break; | |
230 | |
231 default: | |
232 { | |
233 std::stringstream ss; | |
234 ss << "Unknown log level (" << level_ << ") for message: " << message; | |
235 std::string s = ss.str(); | |
236 ErrorLogFunc(s.c_str()); | |
237 } | 278 } |
238 } | 279 } |
239 } | 280 } |
240 | 281 |
241 void InitializePluginContext(void* pluginContext) | 282 void InitializePluginContext(void* pluginContext) |
254 { | 295 { |
255 } | 296 } |
256 | 297 |
257 void Flush() | 298 void Flush() |
258 { | 299 { |
259 } | |
260 | |
261 void EnableInfoLevel(bool enabled) | |
262 { | |
263 infoEnabled_ = enabled; | |
264 | |
265 if (!enabled) | |
266 { | |
267 // Also disable the "TRACE" level when info-level debugging is disabled | |
268 traceEnabled_ = false; | |
269 } | |
270 } | |
271 | |
272 bool IsInfoLevelEnabled() | |
273 { | |
274 return infoEnabled_; | |
275 } | |
276 | |
277 void EnableTraceLevel(bool enabled) | |
278 { | |
279 traceEnabled_ = enabled; | |
280 } | |
281 | |
282 bool IsTraceLevelEnabled() | |
283 { | |
284 return traceEnabled_; | |
285 } | 300 } |
286 | 301 |
287 void SetTargetFile(const std::string& path) | 302 void SetTargetFile(const std::string& path) |
288 { | 303 { |
289 } | 304 } |
366 | 381 |
367 static std::unique_ptr<LoggingStreamsContext> loggingStreamsContext_; | 382 static std::unique_ptr<LoggingStreamsContext> loggingStreamsContext_; |
368 static boost::mutex loggingStreamsMutex_; | 383 static boost::mutex loggingStreamsMutex_; |
369 static Orthanc::Logging::NullStream nullStream_; | 384 static Orthanc::Logging::NullStream nullStream_; |
370 static OrthancPluginContext* pluginContext_ = NULL; | 385 static OrthancPluginContext* pluginContext_ = NULL; |
371 static bool infoEnabled_ = false; | |
372 static bool traceEnabled_ = false; | |
373 | 386 |
374 | 387 |
375 namespace Orthanc | 388 namespace Orthanc |
376 { | 389 { |
377 namespace Logging | 390 namespace Logging |
494 case LogLevel_TRACE: | 507 case LogLevel_TRACE: |
495 c = 'T'; | 508 c = 'T'; |
496 break; | 509 break; |
497 | 510 |
498 default: | 511 default: |
499 throw OrthancException(ErrorCode_InternalError); | 512 c = '?'; |
513 break; | |
500 } | 514 } |
501 | 515 |
502 char date[64]; | 516 char date[64]; |
503 sprintf(date, "%c%02d%02d %02d:%02d:%02d.%06d ", | 517 sprintf(date, "%c%02d%02d %02d:%02d:%02d.%06d ", |
504 c, | 518 c, |
573 SetTargetFile(old->targetFile_); | 587 SetTargetFile(old->targetFile_); |
574 } | 588 } |
575 } | 589 } |
576 | 590 |
577 | 591 |
578 void EnableInfoLevel(bool enabled) | |
579 { | |
580 infoEnabled_ = enabled; | |
581 | |
582 if (!enabled) | |
583 { | |
584 // Also disable the "TRACE" level when info-level debugging is disabled | |
585 traceEnabled_ = false; | |
586 } | |
587 } | |
588 | |
589 bool IsInfoLevelEnabled() | |
590 { | |
591 return infoEnabled_; | |
592 } | |
593 | |
594 void EnableTraceLevel(bool enabled) | |
595 { | |
596 traceEnabled_ = enabled; | |
597 | |
598 if (enabled) | |
599 { | |
600 // Also enable the "INFO" level when trace-level debugging is enabled | |
601 infoEnabled_ = true; | |
602 } | |
603 } | |
604 | |
605 bool IsTraceLevelEnabled() | |
606 { | |
607 return traceEnabled_; | |
608 } | |
609 | |
610 | |
611 void SetTargetFolder(const std::string& path) | 592 void SetTargetFolder(const std::string& path) |
612 { | 593 { |
613 boost::mutex::scoped_lock lock(loggingStreamsMutex_); | 594 boost::mutex::scoped_lock lock(loggingStreamsMutex_); |
614 if (loggingStreamsContext_.get() != NULL) | 595 if (loggingStreamsContext_.get() != NULL) |
615 { | 596 { |
642 } | 623 } |
643 } | 624 } |
644 | 625 |
645 | 626 |
646 InternalLogger::InternalLogger(LogLevel level, | 627 InternalLogger::InternalLogger(LogLevel level, |
647 TraceCategory category, | 628 LogCategory category, |
648 const char* file, | 629 const char* file, |
649 int line) : | 630 int line) : |
650 lock_(loggingStreamsMutex_, boost::defer_lock_t()), | 631 lock_(loggingStreamsMutex_, boost::defer_lock_t()), |
651 level_(level), | 632 level_(level), |
652 category_(category), | |
653 stream_(&nullStream_) // By default, logging to "/dev/null" is simulated | 633 stream_(&nullStream_) // By default, logging to "/dev/null" is simulated |
654 { | 634 { |
655 if (pluginContext_ != NULL) | 635 if (pluginContext_ != NULL) |
656 { | 636 { |
657 // We are logging using the Orthanc plugin SDK | 637 // We are logging using the Orthanc plugin SDK |
658 | 638 |
659 if (level == LogLevel_TRACE) | 639 if (level == LogLevel_TRACE || |
640 !IsLoggingEnabled(level, category)) | |
660 { | 641 { |
661 // No trace level in plugins, directly exit as the stream is | 642 // No trace level in plugins, directly exit as the stream is |
662 // set to "/dev/null" | 643 // set to "/dev/null" |
663 return; | 644 return; |
664 } | 645 } |
670 } | 651 } |
671 else | 652 else |
672 { | 653 { |
673 // We are logging in a standalone application, not inside an Orthanc plugin | 654 // We are logging in a standalone application, not inside an Orthanc plugin |
674 | 655 |
675 if ((level == LogLevel_INFO && !infoEnabled_) || | 656 if (!IsLoggingEnabled(level, category)) |
676 (level == LogLevel_TRACE && !traceEnabled_)) // TODO - Check trace category | |
677 { | 657 { |
678 // This logging level is disabled, directly exit as the | 658 // This logging level is disabled, directly exit as the |
679 // stream is set to "/dev/null" | 659 // stream is set to "/dev/null" |
680 return; | 660 return; |
681 } | 661 } |
708 case LogLevel_INFO: | 688 case LogLevel_INFO: |
709 case LogLevel_TRACE: | 689 case LogLevel_TRACE: |
710 stream_ = loggingStreamsContext_->info_; | 690 stream_ = loggingStreamsContext_->info_; |
711 break; | 691 break; |
712 | 692 |
713 default: | 693 default: // Should not occur |
714 throw OrthancException(ErrorCode_InternalError); | 694 stream_ = loggingStreamsContext_->error_; |
695 break; | |
715 } | 696 } |
716 | 697 |
717 if (stream_ == &nullStream_) | 698 if (stream_ == &nullStream_) |
718 { | 699 { |
719 // The logging is disabled for this level, we can release | 700 // The logging is disabled for this level, we can release |