Keyple Util C++ Library 2.0.0
Reference Terminal Reader API for C++
Logger.h
Go to the documentation of this file.
1/**************************************************************************************************
2 * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ *
3 * *
4 * See the NOTICE file(s) distributed with this work for additional information regarding *
5 * copyright ownership. *
6 * *
7 * This program and the accompanying materials are made available under the terms of the Eclipse *
8 * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 *
9 * *
10 * SPDX-License-Identifier: EPL-2.0 *
11 **************************************************************************************************/
12
13#pragma once
14
15#include <cstdlib>
16#include <iomanip>
17#include <iostream>
18#include <memory>
19#include <mutex>
20#include <stdexcept>
21#include <string>
22#include <cstdio>
23#include <ostream>
24#include <sstream>
25#include <vector>
26#include <set>
27
28#ifdef __GNUG__ // gnu C++ compiler
29#include <cxxabi.h>
30#endif
31
32/* Util */
33#include "KeypleUtilExport.h"
34
35namespace keyple {
36namespace core {
37namespace util {
38namespace cpp {
39
41public:
45 enum class Level {
46 logNone = 0,
47 logError,
48 logWarn,
49 logInfo,
50 logDebug,
51 logTrace
52 };
53
57 Logger(const std::string& className, std::mutex* mtx);
58
62 std::string getClassName();
63
67 static void setLoggerLevel(Level level);
68
72 template <typename... Args>
73 void trace(const std::string& format, Args... args)
74 {
75 if (mLevel >= Level::logTrace)
76 log("TRACE", format, std::forward<Args>(args)...);
77 }
78
82 template <typename... Args>
83 void debug(const std::string& format, Args... args)
84 {
85 if (mLevel >= Level::logDebug)
86 log("DEBUG", format, std::forward<Args>(args)...);
87 }
88
92 template <typename... Args>
93 void warn(const std::string& format, Args... args)
94 {
95 if (mLevel >= Level::logWarn)
96 log("WARN", format, std::forward<Args>(args)...);
97 }
98
102 template <typename... Args>
103 void info(const std::string& format, Args... args)
104 {
105 if (mLevel >= Level::logInfo)
106 log("INFO", format, std::forward<Args>(args)...);
107 }
108
112 template <typename... Args>
113 void error(const std::string& format, Args... args)
114 {
115 if (mLevel >= Level::logError)
116 log("ERROR", format, std::forward<Args>(args)...);
117 }
118
119private:
123 static Level mLevel;
124
128 const size_t maxClassNameLength = 100;
129
133 const std::string className;
134
138 std::mutex* mtx;
139
143 static const std::string getCurrentTimestamp();
144
148#ifdef __GNUG__ // gnu C++ compiler
149 std::string demangle(const char* mangled_name)
150 {
151 std::size_t len = 0;
152 int status = 0;
153 std::unique_ptr<char, decltype(&std::free)> ptr(
154 __cxxabiv1::__cxa_demangle(mangled_name, nullptr, &len, &status),
155 &std::free);
156 std::string s(ptr.get());
157 if (s.size() > maxClassNameLength)
158 s.resize(maxClassNameLength);
159 return s;
160 }
161#else
162 std::string demangle(const char* name)
163 {
164 std::string s(name);
165 if (s.size() > maxClassNameLength)
166 s.resize(maxClassNameLength);
167 return s;
168 }
169#endif // _GNUG_
170
171 void printf(std::ostringstream& os, const char* s)
172 {
173 while (s && *s) {
174 if (*s == '%' && *(s + 1) != '%')
175 throw std::runtime_error("invalid format: missing arguments");
176 os << *s++;
177 }
178 }
179
180 template <typename T, typename... Args>
181 void printf(std::ostringstream& os, const char* s, T& value, Args... args)
182 {
183 while (s && *s) {
184 if (*s == '%' && *(s + 1) != '%') {
185 os << value;
186 return printf(os, ++s, args...);
187 }
188 os << *s++;
189 }
190 throw std::runtime_error("extra arguments provided to printf");
191 }
192
193 template <typename T, typename... Args>
194 void printf(std::ostringstream& os, const char* s, T* value, Args... args)
195 {
196 while (s && *s) {
197 if (*s == '%' && *(s + 1) != '%') {
198 os << *value;
199 return printf(os, ++s, args...);
200 }
201 os << *s++;
202 }
203 throw std::runtime_error("extra arguments provided to printf");
204 }
205
210 template <typename... Args>
211 void log(const std::string& label, const std::string& format, Args... args)
212 {
213 const std::lock_guard<std::mutex> lock(*mtx);
214
215 /* Header */
216 std::string name = className;
217 name.resize(70);
218 std::printf("[%s] [%5s] [%-70s] ",
219 getCurrentTimestamp().c_str(),
220 label.c_str(),
221 name.c_str());
222
223 /* Actual log */
224 std::ostringstream os;
225 printf(os, format.c_str(), args...);
226 const std::string& str = os.str();
227 std::printf("%s", str.c_str());
228 }
229};
230
231}
232}
233}
234}
#define KEYPLEUTIL_API
void trace(const std::string &format, Args... args)
Definition: Logger.h:73
void error(const std::string &format, Args... args)
Definition: Logger.h:113
void info(const std::string &format, Args... args)
Definition: Logger.h:103
void debug(const std::string &format, Args... args)
Definition: Logger.h:83
void warn(const std::string &format, Args... args)
Definition: Logger.h:93