Mercurial > hg > orthanc
comparison Core/Logging.cpp @ 1490:596927722403
support of --logdir by the internal logger
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 04 Aug 2015 14:04:48 +0200 |
parents | 1389834e130f |
children | a13581480b1f |
comparison
equal
deleted
inserted
replaced
1489:1389834e130f | 1490:596927722403 |
---|---|
92 /********************************************************* | 92 /********************************************************* |
93 * Use internal logger, not Google Log | 93 * Use internal logger, not Google Log |
94 *********************************************************/ | 94 *********************************************************/ |
95 | 95 |
96 #include "OrthancException.h" | 96 #include "OrthancException.h" |
97 | 97 #include "Toolbox.h" |
98 | |
99 #include <fstream> | |
98 #include <boost/filesystem.hpp> | 100 #include <boost/filesystem.hpp> |
99 #include <boost/thread.hpp> | 101 #include <boost/thread.hpp> |
100 | 102 |
101 #if BOOST_HAS_DATE_TIME == 1 | 103 #if BOOST_HAS_DATE_TIME == 1 |
102 # include <boost/date_time/posix_time/posix_time.hpp> | 104 # include <boost/date_time/posix_time/posix_time.hpp> |
117 | 119 |
118 | 120 |
119 static boost::mutex mutex_; | 121 static boost::mutex mutex_; |
120 static bool infoEnabled_ = false; | 122 static bool infoEnabled_ = false; |
121 static bool traceEnabled_ = false; | 123 static bool traceEnabled_ = false; |
122 static std::ostream& error_ = std::cerr; | 124 |
123 static std::ostream& warning_ = std::cerr; | 125 static std::ostream* error_ = &std::cerr; |
124 static std::ostream& info_ = std::cerr; | 126 static std::ostream* warning_ = &std::cerr; |
125 static std::ostream& trace_ = std::cerr; | 127 static std::ostream* info_ = &std::cerr; |
126 static NullStream null_; | 128 static NullStream null_; |
129 | |
130 static std::auto_ptr<std::ofstream> errorFile_; | |
131 static std::auto_ptr<std::ofstream> warningFile_; | |
132 static std::auto_ptr<std::ofstream> infoFile_; | |
127 | 133 |
128 namespace Orthanc | 134 namespace Orthanc |
129 { | 135 { |
130 namespace Logging | 136 namespace Logging |
131 { | 137 { |
138 static void GetLogPath(boost::filesystem::path& log, | |
139 boost::filesystem::path& link, | |
140 const char* level, | |
141 const std::string& directory) | |
142 { | |
143 /** | |
144 From Google Log documentation: | |
145 | |
146 Unless otherwise specified, logs will be written to the filename | |
147 "<program name>.<hostname>.<user name>.log.<severity level>.", | |
148 followed by the date, time, and pid (you can't prevent the date, | |
149 time, and pid from being in the filename). | |
150 | |
151 In this implementation : "hostname" and "username" are not used | |
152 **/ | |
153 | |
154 boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); | |
155 boost::filesystem::path root(directory); | |
156 boost::filesystem::path exe(Toolbox::GetPathToExecutable()); | |
157 | |
158 if (!boost::filesystem::exists(root) || | |
159 !boost::filesystem::is_directory(root)) | |
160 { | |
161 throw OrthancException(ErrorCode_CannotWriteFile); | |
162 } | |
163 | |
164 char date[64]; | |
165 sprintf(date, "%04d%02d%02d-%02d%02d%02d.%d", | |
166 static_cast<int>(now.date().year()), | |
167 now.date().month().as_number(), | |
168 now.date().day().as_number(), | |
169 now.time_of_day().hours(), | |
170 now.time_of_day().minutes(), | |
171 now.time_of_day().seconds(), | |
172 Toolbox::GetProcessId()); | |
173 | |
174 std::string programName = exe.filename().replace_extension("").string(); | |
175 | |
176 log = (root / (programName + ".log." + | |
177 std::string(level) + "." + | |
178 std::string(date))); | |
179 | |
180 link = (root / (programName + "." + std::string(level))); | |
181 } | |
182 | |
183 | |
184 static void PrepareLogFile(std::ostream*& stream, | |
185 std::auto_ptr<std::ofstream>& file, | |
186 const char* level, | |
187 const std::string& directory) | |
188 { | |
189 boost::filesystem::path log, link; | |
190 GetLogPath(log, link, level, directory); | |
191 | |
192 printf("[%s]\n", log.string().c_str()); | |
193 | |
194 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) | |
195 boost::filesystem::remove(link); | |
196 boost::filesystem::create_symlink(log.filename(), link); | |
197 #endif | |
198 | |
199 file.reset(new std::ofstream(log.c_str())); | |
200 stream = file.get(); | |
201 } | |
202 | |
203 | |
132 void Initialize() | 204 void Initialize() |
133 { | 205 { |
134 infoEnabled_ = false; | 206 infoEnabled_ = false; |
135 traceEnabled_ = false; | 207 traceEnabled_ = false; |
136 } | 208 } |
137 | 209 |
138 void Finalize() | 210 void Finalize() |
139 { | 211 { |
212 errorFile_.reset(NULL); | |
213 warningFile_.reset(NULL); | |
214 infoFile_.reset(NULL); | |
140 } | 215 } |
141 | 216 |
142 void EnableInfoLevel(bool enabled) | 217 void EnableInfoLevel(bool enabled) |
143 { | 218 { |
144 boost::mutex::scoped_lock lock(mutex_); | 219 boost::mutex::scoped_lock lock(mutex_); |
150 boost::mutex::scoped_lock lock(mutex_); | 225 boost::mutex::scoped_lock lock(mutex_); |
151 traceEnabled_ = enabled; | 226 traceEnabled_ = enabled; |
152 | 227 |
153 if (enabled) | 228 if (enabled) |
154 { | 229 { |
155 // Also enable the "INFO" level when trace-level debugging is | 230 // Also enable the "INFO" level when trace-level debugging is enabled |
156 // enabled | |
157 infoEnabled_ = true; | 231 infoEnabled_ = true; |
158 } | 232 } |
159 } | 233 } |
160 | 234 |
161 void SetTargetFolder(const std::string& path) | 235 void SetTargetFolder(const std::string& path) |
162 { | 236 { |
163 boost::mutex::scoped_lock lock(mutex_); | 237 boost::mutex::scoped_lock lock(mutex_); |
164 // TODO | 238 PrepareLogFile(error_, errorFile_, "ERROR", path); |
239 PrepareLogFile(warning_, warningFile_, "WARNING", path); | |
240 PrepareLogFile(info_, infoFile_, "INFO", path); | |
165 } | 241 } |
166 | 242 |
167 InternalLogger::InternalLogger(const char* level, | 243 InternalLogger::InternalLogger(const char* level, |
168 const char* file, | 244 const char* file, |
169 int line) : | 245 int line) : |
171 { | 247 { |
172 char c; | 248 char c; |
173 | 249 |
174 if (strcmp(level, "ERROR") == 0) | 250 if (strcmp(level, "ERROR") == 0) |
175 { | 251 { |
176 stream_ = &error_; | 252 stream_ = error_; |
177 c = 'E'; | 253 c = 'E'; |
178 } | 254 } |
179 else if (strcmp(level, "WARNING") == 0) | 255 else if (strcmp(level, "WARNING") == 0) |
180 { | 256 { |
181 stream_ = &warning_; | 257 stream_ = warning_; |
182 c = 'W'; | 258 c = 'W'; |
183 } | 259 } |
184 else if (strcmp(level, "INFO") == 0) | 260 else if (strcmp(level, "INFO") == 0) |
185 { | 261 { |
186 stream_ = infoEnabled_ ? &info_ : &null_; | 262 stream_ = infoEnabled_ ? info_ : &null_; |
187 c = 'I'; | 263 c = 'I'; |
188 } | 264 } |
189 else if (strcmp(level, "TRACE") == 0) | 265 else if (strcmp(level, "TRACE") == 0) |
190 { | 266 { |
191 stream_ = traceEnabled_ ? &trace_ : &null_; | 267 stream_ = traceEnabled_ ? info_ : &null_; |
192 c = 'T'; | 268 c = 'T'; |
193 } | 269 } |
194 else | 270 else |
195 { | 271 { |
196 // Unknown logging level | 272 // Unknown logging level |
204 boost::posix_time::time_duration duration = now.time_of_day(); | 280 boost::posix_time::time_duration duration = now.time_of_day(); |
205 | 281 |
206 /** | 282 /** |
207 From Google Log documentation: | 283 From Google Log documentation: |
208 | 284 |
209 Log lines have this form: | 285 "Log lines have this form: |
210 | 286 |
211 Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg... | 287 Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg... |
212 | 288 |
213 where the fields are defined as follows: | 289 where the fields are defined as follows: |
214 | 290 |
217 dd The day (zero padded) | 293 dd The day (zero padded) |
218 hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds | 294 hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds |
219 threadid The space-padded thread ID as returned by GetTID() (this matches the PID on Linux) | 295 threadid The space-padded thread ID as returned by GetTID() (this matches the PID on Linux) |
220 file The file name | 296 file The file name |
221 line The line number | 297 line The line number |
222 msg The user-supplied message | 298 msg The user-supplied message" |
299 | |
300 In this implementation, "threadid" is not printed. | |
223 **/ | 301 **/ |
224 | 302 |
225 char date[32]; | 303 char date[32]; |
226 sprintf(date, "%c%02d%02d %02d:%02d:%02d.%06d ", c, | 304 sprintf(date, "%c%02d%02d %02d:%02d:%02d.%06d ", c, |
227 now.date().month().as_number(), | 305 now.date().month().as_number(), |