Skip to content

Commit 4499610

Browse files
authored
Merge pull request #40 from kimkulling/feature/add_logger
Feature/add logger
2 parents cef37da + 85a8c28 commit 4499610

File tree

4 files changed

+608
-16
lines changed

4 files changed

+608
-16
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ SET(cppcore_src
7575

7676
SET(cppcore_common_src
7777
include/cppcore/Common/Hash.h
78+
include/cppcore/Common/Logger.h
79+
code/Common/Logger.cpp
7880
include/cppcore/Common/TStringBase.h
7981
include/cppcore/Common/TStringView.h
8082
include/cppcore/Common/Variant.h

code/Common/Logger.cpp

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
/*-----------------------------------------------------------------------------------------------
2+
The MIT License (MIT)
3+
4+
Copyright (c) 2014-2025 Kim Kulling
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy of
7+
this software and associated documentation files (the "Software"), to deal in
8+
the Software without restriction, including without limitation the rights to
9+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10+
the Software, and to permit persons to whom the Software is furnished to do so,
11+
subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22+
-----------------------------------------------------------------------------------------------*/
23+
#include <cppcore/Common/Logger.h>
24+
25+
#include <cassert>
26+
#include <iomanip>
27+
#include <iostream>
28+
#include <sstream>
29+
#include <string>
30+
31+
namespace cppcore {
32+
33+
static void appendDomain(const String &domain, String &logMsg) {
34+
if (!domain.isEmpty()) {
35+
logMsg += '(';
36+
logMsg += domain;
37+
logMsg += ')';
38+
}
39+
}
40+
41+
static ::std::string stripFilename(const ::std::string &filename) {
42+
if (filename.empty()) {
43+
return filename;
44+
}
45+
46+
::std::string::size_type pos = filename.find_last_of("/");
47+
if (pos == ::std::string::npos) {
48+
return filename;
49+
}
50+
const ::std::string strippedName = filename.substr(pos + 1, filename.size() - pos - 1);
51+
52+
return strippedName;
53+
}
54+
55+
static void addTraceInfo(const String &file, int line, String &msg) {
56+
if (Logger::getInstance()->getVerboseMode() == Logger::VerboseMode::Trace) {
57+
msg += String(" (", 2);
58+
std::string stripped = stripFilename(file.c_str());
59+
msg += String(stripped.c_str(), stripped.size());
60+
msg += String(", ", 2);
61+
std::stringstream ss;
62+
ss << line;
63+
std::string lineno = ss.str();
64+
msg += String(lineno.c_str(), lineno.size());
65+
msg += ')';
66+
}
67+
}
68+
69+
void AbstractLogStream::activate() {
70+
mIsActive = true;
71+
}
72+
73+
void AbstractLogStream::deactivate() {
74+
mIsActive = false;
75+
}
76+
77+
bool AbstractLogStream::isActive() const {
78+
return mIsActive;
79+
}
80+
81+
Logger *Logger::sLogger = nullptr;
82+
83+
Logger *Logger::create() {
84+
if (nullptr == sLogger) {
85+
sLogger = new Logger;
86+
}
87+
88+
return sLogger;
89+
}
90+
91+
Logger *Logger::getInstance() {
92+
if (nullptr == sLogger) {
93+
static_cast<void>(create());
94+
}
95+
96+
return sLogger;
97+
}
98+
99+
void Logger::kill() {
100+
if (sLogger) {
101+
delete sLogger;
102+
sLogger = nullptr;
103+
}
104+
}
105+
106+
void Logger::setVerboseMode(VerboseMode sev) {
107+
mVerboseMode = sev;
108+
}
109+
110+
Logger::VerboseMode Logger::getVerboseMode() const {
111+
return mVerboseMode;
112+
}
113+
114+
void Logger::trace(const String &domain, const String &msg) {
115+
if (getVerboseMode() == VerboseMode::Trace) {
116+
String logMsg;
117+
logMsg += String("Trace: ", 6);
118+
logMsg += msg;
119+
appendDomain(domain, logMsg);
120+
121+
print(logMsg);
122+
}
123+
}
124+
125+
void Logger::debug(const String &domain, const String &msg) {
126+
if (getVerboseMode() == VerboseMode::Debug || getVerboseMode() == VerboseMode::Trace) {
127+
String logMsg;
128+
logMsg += String("Dbg: ", 6);
129+
logMsg += msg;
130+
appendDomain(domain, logMsg);
131+
132+
print(logMsg);
133+
}
134+
}
135+
136+
void Logger::info(const String &domain, const String &msg) {
137+
if (getVerboseMode() == VerboseMode::Normal || getVerboseMode() == VerboseMode::Verbose || getVerboseMode() == VerboseMode::Debug || getVerboseMode() == VerboseMode::Trace) {
138+
String logMsg;
139+
140+
logMsg += String("Info: ", 6);
141+
logMsg += msg;
142+
143+
appendDomain(domain, logMsg);
144+
145+
print(logMsg);
146+
}
147+
}
148+
149+
void Logger::print(const String &msg, PrintMode mode) {
150+
if (msg.isEmpty()) {
151+
return;
152+
}
153+
154+
if (msg.size() > 8 && msg[6] == '<' && msg[7] == '=') {
155+
mIntention -= 2;
156+
}
157+
158+
String logMsg;
159+
if (0 != mIntention) {
160+
for (uint32_t i = 0; i < mIntention; i++) {
161+
logMsg += ' ';
162+
}
163+
}
164+
165+
logMsg += msg;
166+
if (PrintMode::WithDateTime == mode) {
167+
logMsg += String(" (", 2);
168+
logMsg += this->getDateTime();
169+
logMsg += ')';
170+
}
171+
172+
logMsg += String(" \n", 2);
173+
for (size_t i = 0; i < mLogStreams.size(); ++i) {
174+
AbstractLogStream *stream = mLogStreams[i];
175+
if (stream != nullptr) {
176+
stream->write(logMsg);
177+
}
178+
}
179+
180+
if (msg.size() > 8) {
181+
if (msg[6] == '=' && msg[7] == '>') {
182+
mIntention += 2;
183+
}
184+
}
185+
}
186+
187+
void Logger::warn(const String &domain, const String &msg) {
188+
String logMsg;
189+
logMsg += String("Warn: ", 6);
190+
logMsg += msg;
191+
appendDomain(domain, logMsg);
192+
193+
print(logMsg);
194+
}
195+
196+
void Logger::error(const String &domain, const String &msg) {
197+
String logMsg;
198+
logMsg += String("Err: ", 6);
199+
logMsg += msg;
200+
appendDomain(domain, logMsg);
201+
202+
print(logMsg);
203+
}
204+
205+
void Logger::fatal(const String &domain, const String &msg) {
206+
String logMsg;
207+
logMsg += String("Fatal:", 6);
208+
logMsg += msg;
209+
appendDomain(domain, logMsg);
210+
211+
print(logMsg);
212+
}
213+
214+
void Logger::registerLogStream(AbstractLogStream *pLogStream) {
215+
if (nullptr == pLogStream) {
216+
return;
217+
}
218+
219+
mLogStreams.add(pLogStream);
220+
}
221+
222+
void Logger::unregisterLogStream(AbstractLogStream *logStream) {
223+
if (nullptr == logStream) {
224+
return;
225+
}
226+
227+
for (size_t i = 0; i < mLogStreams.size(); ++i) {
228+
if (mLogStreams[i] == logStream) {
229+
delete mLogStreams[i];
230+
mLogStreams.remove(i);
231+
}
232+
}
233+
}
234+
235+
Logger::Logger() {
236+
mLogStreams.add(new StdLogStream);
237+
}
238+
239+
Logger::~Logger() {
240+
for (size_t i = 0; i < mLogStreams.size(); ++i) {
241+
delete mLogStreams[i];
242+
}
243+
}
244+
245+
String Logger::getDateTime() {
246+
//static const uint32_t Space = 2;
247+
/* DateTime currentDateTime = DateTime::getCurrentUTCTime();
248+
std::stringstream stream;
249+
stream.fill('0');
250+
stream << std::setw(Space) << currentDateTime.getCurrentDay() << "."
251+
<< std::setw(Space) << currentDateTime.getCurrentMonth() << "."
252+
<< std::setw(Space * 2) << currentDateTime.getCurrentYear() << " "
253+
<< std::setw(Space) << currentDateTime.getCurrentHour() << ":"
254+
<< std::setw(Space) << currentDateTime.getCurrentMinute() << ":"
255+
<< std::setw(Space) << currentDateTime.getCurrentSeconds();
256+
*/
257+
String todo("none", 4);
258+
return todo;
259+
}
260+
261+
void Logger::StdLogStream::write(const String &msg) {
262+
std::cout << msg.c_str();
263+
}
264+
265+
void tracePrint(const String &domain, const String &file, int line, const String &msg) {
266+
String message;
267+
message += msg;
268+
addTraceInfo(file, line, message);
269+
Logger::getInstance()->trace(domain, message);
270+
}
271+
272+
void debugPrint(const String &domain, const String &file, int line, const String &msg) {
273+
String message;
274+
message += msg;
275+
addTraceInfo(file, line, message);
276+
Logger::getInstance()->debug(domain, message);
277+
}
278+
279+
void infoPrint(const String &domain, const String &file, int line, const String &msg) {
280+
String message;
281+
message += msg;
282+
addTraceInfo(file, line, message);
283+
Logger::getInstance()->info(domain, message);
284+
}
285+
286+
void warnPrint(const String &domain, const String &file, int line, const String &message) {
287+
String msg;
288+
msg += message;
289+
addTraceInfo(file, line, msg);
290+
Logger::getInstance()->warn(domain, msg);
291+
}
292+
293+
void errorPrint(const String &domain, const String &file, int line, const String &message) {
294+
String msg;
295+
msg += message;
296+
addTraceInfo(file, line, msg);
297+
Logger::getInstance()->error(domain, msg);
298+
}
299+
300+
void fatalPrint(const String &domain, const String &file, int line, const String &message) {
301+
String msg;
302+
msg += message;
303+
addTraceInfo(file, line, msg);
304+
Logger::getInstance()->fatal(domain, msg);
305+
}
306+
307+
} // namespace cppcore

0 commit comments

Comments
 (0)