comparison OrthancServer/Resources/Samples/CppHelpers/Logging/ILogger.h @ 4044:d25f4c0fa160 framework

splitting code into OrthancFramework and OrthancServer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 10 Jun 2020 20:30:34 +0200
parents Resources/Samples/CppHelpers/Logging/ILogger.h@427a13084241
children c847b0dfd255
comparison
equal deleted inserted replaced
4043:6c6239aec462 4044:d25f4c0fa160
1 #pragma once
2
3 #include <string>
4 #include <vector>
5 #include <boost/algorithm/string.hpp>
6 #include <boost/thread.hpp>
7
8 namespace OrthancHelpers
9 {
10
11
12 inline std::string ShortenId(const std::string& orthancUuid)
13 {
14 size_t firstHyphenPos = orthancUuid.find_first_of('-');
15 if (firstHyphenPos == std::string::npos)
16 {
17 return orthancUuid;
18 }
19 else
20 {
21 return orthancUuid.substr(0, firstHyphenPos);
22 }
23 }
24
25
26 // Interface for loggers providing the same interface
27 // in Orthanc framework or in an Orthanc plugins.
28 // Furthermore, compared to the LOG and VLOG macros,
29 // these loggers will provide "contexts".
30 class ILogger
31 {
32 public:
33 virtual ~ILogger() {}
34 virtual void Trace(const char* message) = 0;
35 virtual void Trace(const std::string& message) = 0;
36 virtual void Info(const char* message) = 0;
37 virtual void Info(const std::string& message) = 0;
38 virtual void Warning(const char* message) = 0;
39 virtual void Warning(const std::string& message) = 0;
40 virtual void Error(const char* message) = 0;
41 virtual void Error(const std::string& message) = 0;
42
43 virtual void EnterContext(const char* message, bool forceLogContextChange = false) = 0;
44 virtual void EnterContext(const std::string& message, bool forceLogContextChange = false) = 0;
45 virtual void LeaveContext(bool forceLogContextChange = false) = 0;
46 };
47
48
49 // Implements ILogger by providing contexts. Contexts defines
50 // the "call-stack" of the logs and are prepended to the log.
51 // check LogContext class for more details
52 class BaseLogger : public ILogger
53 {
54 #if ORTHANC_ENABLE_THREADS == 1
55 boost::thread_specific_ptr<std::vector<std::string>> contexts_;
56 #else
57 std::auto_ptr<std::vector<std::string>> contexts_;
58 #endif
59 bool logContextChanges_;
60
61 public:
62
63 BaseLogger()
64 : logContextChanges_(false)
65 {
66 }
67
68 void EnableLogContextChanges(bool enable)
69 {
70 logContextChanges_ = enable;
71 }
72
73 virtual void EnterContext(const char* message, bool forceLogContextChange = false)
74 {
75 EnterContext(std::string(message), forceLogContextChange);
76 }
77
78 virtual void EnterContext(const std::string& message, bool forceLogContextChange = false)
79 {
80 if (!contexts_.get())
81 {
82 contexts_.reset(new std::vector<std::string>());
83 }
84 contexts_->push_back(message);
85
86 if (logContextChanges_ || forceLogContextChange)
87 {
88 Info(".. entering");
89 }
90 }
91
92 virtual void LeaveContext(bool forceLogContextChange = false)
93 {
94 if (logContextChanges_ || forceLogContextChange)
95 {
96 Info(".. leaving");
97 }
98
99 contexts_->pop_back();
100 if (contexts_->size() == 0)
101 {
102 contexts_.reset(NULL);
103 }
104 }
105
106 protected:
107
108 virtual std::string GetContext()
109 {
110 if (contexts_.get() != NULL && contexts_->size() > 0)
111 {
112 return "|" + boost::algorithm::join(*contexts_, " | ") + "|";
113 }
114 else
115 {
116 return std::string("|");
117 }
118 }
119 };
120
121
122 /* RAII to set a Log context.
123 * Example:
124 * ILogger* logger = new OrthancPluginLogger(..);
125 * {
126 * LogContext logContext(logger, "A");
127 * {
128 * LogContext nestedLogContext(logger, "B");
129 * logger->Error("out of memory");
130 * }
131 * }
132 * will produce:
133 * |A | B| out of memory
134 *
135 * furthermore, if LogContextChanges are enabled in the BaseLogger,
136 * you'll get;
137 * |A| .. entering
138 * |A | B| .. entering
139 * |A | B| out of memory
140 * |A | B| .. leaving
141 * |A| .. leaving
142 */
143 class LogContext
144 {
145 ILogger* logger_;
146 bool forceLogContextChange_;
147 public:
148 LogContext(ILogger* logger, const char* context, bool forceLogContextChange = false) :
149 logger_(logger),
150 forceLogContextChange_(forceLogContextChange)
151 {
152 logger_->EnterContext(context, forceLogContextChange_);
153 }
154
155 LogContext(ILogger* logger, const std::string& context, bool forceLogContextChange = false) :
156 logger_(logger),
157 forceLogContextChange_(forceLogContextChange)
158 {
159 logger_->EnterContext(context, forceLogContextChange_);
160 }
161
162 ~LogContext()
163 {
164 logger_->LeaveContext(forceLogContextChange_);
165 }
166
167 };
168 }