PLCnext API Documentation 23.6.0.37
LoggerBase.hxx
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6#pragma once
8#include "Arp/System/Commons/Diagnostics/Logging/LogLevel.hpp"
9#include "Arp/System/Commons/Diagnostics/Logging/LogStream.hpp"
10#include "Arp/System/Commons/Diagnostics/Logging/LogManager.hpp"
11#include "Arp/System/Commons/Diagnostics/Logging/Internal/LogAdapter.hpp"
12#include "Arp/System/Commons/Text/Formatter.hxx"
13#include "Arp/System/Commons/Threading/LockGuard.hpp"
14
15#include <atomic>
16
17namespace Arp { namespace System { namespace Commons { namespace Diagnostics { namespace Logging
18{
19
20using namespace Arp::System::Commons::Text;
21
22//forwards
23template<typename T, bool, bool> class Loggable;
24
26{
27 template<typename T, bool, bool> friend class Loggable;
28
29public: // usings
31
32protected: // construction/destruction
33 LoggerBase(void);
34 LoggerBase(const String& loggerName);
35 LoggerBase(const char* pLoggerName);
36 LoggerBase(const LoggerBase& arg) = default;
37 ~LoggerBase(void) = default;
38
39public: // log operations for function call style: Log::Info(format, arg1, arg2, arg3, ...)
40 template<typename... Args> void Trace(const char* format, const Args& ... args);
41 template<typename... Args> void Debug(const char* format, const Args& ... args);
42 template<typename... Args> void Info(const char* format, const Args& ... args);
43 template<typename... Args> void Warning(const char* format, const Args& ... args);
44 template<typename... Args> void Critical(const char* format, const Args& ... args);
45 template<typename... Args> void Error(const char* format, const Args& ... args);
46 template<typename... Args> void Fatal(const char* format, const Args& ... args);
47
48 template<typename... Args> void PrintTrace(const char* format, const Args& ... args);
49 template<typename... Args> void PrintDebug(const char* format, const Args& ... args);
50 template<typename... Args> void PrintInfo(const char* format, const Args& ... args);
51 template<typename... Args> void PrintWarning(const char* format, const Args& ... args);
52 template<typename... Args> void PrintCritical(const char* format, const Args& ... args);
53 template<typename... Args> void PrintError(const char* format, const Args& ... args);
54 template<typename... Args> void PrintFatal(const char* format, const Args& ... args);
55
56public: // log operations for stream call style: Log::Info()<<".."<<arg1<<".."<<arg2<<".."<<arg3;
57 LogStream Trace(void);
58 LogStream Debug(void);
59 LogStream Info(void);
60 LogStream Warning(void);
61 LogStream Critical(void);
62 LogStream Error(void);
63 LogStream Fatal(void);
64
65public: // generic log operations
66 template<typename... Args>
67 void Log(LogLevel logLevel, const char* format, const Args& ... args);
68
69public: // setter/getter
70 LogLevel GetLogLevel(void);
71
72protected: // methods
73 void Initialize(const String& loggerName);
74 LogStream GetLogStream(LogLevel logLevel);
75 template<typename... Args>
76 void LogCommonFormat(LogLevel logLevel, const char* format, const Args& ... args);
77
78private: // fields
79 LogAdapter logAdapter;
80 std::atomic<bool> initialized;
81};
82
84// inline methods of class LoggerBase
85inline LoggerBase::LoggerBase()
86 : logAdapter()
87{
88 this->initialized = false;
89}
90
91inline LoggerBase::LoggerBase(const String& loggerName)
92 : LoggerBase(loggerName.CStr())
93{
94 //initialized is initialized to true in LoggerBase::LoggerBase(const char* pLoggerName)
95}
96
97inline LoggerBase::LoggerBase(const char* pLoggerName)
98 : logAdapter(LogManager::GetInstance().CreateLogAdapter(pLoggerName))
99{
100 this->initialized = true;
101}
102
103inline void LoggerBase::Initialize(const String& loggerName)
104{
105 // implement this using "double checked locking" pattern
106 if (!this->initialized)
107 {
108 LockGuard syncGuard(LogManager::GetInstance().GetSyncRoot());
109 if (!this->initialized)
110 {
111 this->logAdapter = LogManager::GetInstance().CreateLogAdapter(loggerName);
112 this->initialized = true;
113 }
114 }
115}
116
117inline LogLevel LoggerBase::GetLogLevel()
118{
119 return this->logAdapter.GetLogLevel();
120}
121
122inline LogStream LoggerBase::GetLogStream(LogLevel logLevel)
123{
124 return this->logAdapter.GetLogStream(logLevel);
125}
126
127template<typename... Args>
128inline void LoggerBase::Log(LogLevel logLevel, const char* format, const Args& ...args)
129{
130 LogCommonFormat(logLevel, format, args...);
131}
132
133template<typename... Args>
134inline void LoggerBase::LogCommonFormat(LogLevel logLevel, const char* format, const Args& ...args)
135{
136 if(this->GetLogLevel() < logLevel)
137 {
138 return;
139 }
140
141 String message;
142 try
143 {
144 message = Formatter::FormatCommon(format, args...);
145 }
146 catch(const Arp::Exception& ex)
147 {
148 this->logAdapter.Log(LogLevel::Error, String("Exception occurs during format of log message: ") + ex.GetMessage());
149 message = format;
150 }
151 catch(const std::exception& ex)
152 {
153 this->logAdapter.Log(LogLevel::Error, String("Exception occurs during format of log message: ") + ex.what());
154 message = format;
155 }
156 catch(...)
157 {
158 this->logAdapter.Log(LogLevel::Error, "Exception occurs during format of log message: Unknown exception");
159 message = format;
160 }
161 // else
162 this->logAdapter.Log(logLevel, message);
163}
164
165inline LogStream LoggerBase::Trace()
166{
167 return (this->GetLogLevel() < LogLevel::Trace) ? LogStream::Null : this->GetLogStream(LogLevel::Trace);
168}
169
170inline LogStream LoggerBase::Debug()
171{
172 return (this->GetLogLevel() < LogLevel::Debug) ? LogStream::Null : this->GetLogStream(LogLevel::Debug);
173}
174
175inline LogStream LoggerBase::Info()
176{
177 return (this->GetLogLevel() < LogLevel::Info) ? LogStream::Null : this->GetLogStream(LogLevel::Info);
178}
179
180inline LogStream LoggerBase::Warning()
181{
182 return (this->GetLogLevel() < LogLevel::Warning) ? LogStream::Null : this->GetLogStream(LogLevel::Warning);
183}
184
185inline LogStream LoggerBase::Critical()
186{
187 return (this->GetLogLevel() < LogLevel::Critical) ? LogStream::Null : this->GetLogStream(LogLevel::Critical);
188}
189
190inline LogStream LoggerBase::Error()
191{
192 return (this->GetLogLevel() < LogLevel::Error) ? LogStream::Null : this->GetLogStream(LogLevel::Error);
193}
194
195inline LogStream LoggerBase::Fatal()
196{
197 return (this->GetLogLevel() < LogLevel::Fatal) ? LogStream::Null : this->GetLogStream(LogLevel::Fatal);
198}
199
200template<typename... Args>
201inline void LoggerBase::Trace(const char* format, const Args& ... args)
202{
203 this->LogCommonFormat(LogLevel::Trace, format, args...);
204}
205
206template<typename... Args>
207inline void LoggerBase::Debug(const char* format, const Args& ... args)
208{
209 this->LogCommonFormat(LogLevel::Debug, format, args...);
210}
211
212template<typename... Args>
213inline void LoggerBase::Info(const char* format, const Args& ... args)
214{
215 this->LogCommonFormat(LogLevel::Info, format, args...);
216}
217
218template<typename... Args>
219inline void LoggerBase::Warning(const char* format, const Args& ... args)
220{
221 this->LogCommonFormat(LogLevel::Warning, format, args...);
222}
223
224template<typename... Args>
225inline void LoggerBase::Critical(const char* format, const Args& ... args)
226{
227 this->LogCommonFormat(LogLevel::Critical, format, args...);
228}
229
230template<typename... Args>
231inline void LoggerBase::Error(const char* format, const Args& ... args)
232{
233 this->LogCommonFormat(LogLevel::Error, format, args...);
234}
235
236template<typename... Args>
237inline void LoggerBase::Fatal(const char* format, const Args& ... args)
238{
239 if (this->GetLogLevel() < LogLevel::Fatal)
240 {
241 return;
242 }
243 // else
244 this->LogCommonFormat(LogLevel::Fatal, format, args...);
245}
246
247template<typename... Args>
248inline void LoggerBase::PrintTrace(const char* format, const Args& ... args)
249{
250 if (this->GetLogLevel() < LogLevel::Trace)
251 {
252 return;
253 }
254 // else
255 this->logAdapter.Log(LogLevel::Trace, Formatter::FormatPrintf(format, args...));
256}
257
258template<typename... Args>
259inline void LoggerBase::PrintDebug(const char* format, const Args& ... args)
260{
261 if (this->GetLogLevel() < LogLevel::Debug)
262 {
263 return;
264 }
265 // else
266 this->logAdapter.Log(LogLevel::Debug, Formatter::FormatPrintf(format, args...));
267}
268
269template<typename... Args>
270inline void LoggerBase::PrintInfo(const char* format, const Args& ... args)
271{
272 if (this->GetLogLevel() < LogLevel::Info)
273 {
274 return;
275 }
276 // else
277 this->logAdapter.Log(LogLevel::Info, Formatter::FormatPrintf(format, args...));
278}
279
280template<typename... Args>
281inline void LoggerBase::PrintWarning(const char* format, const Args& ... args)
282{
283 if (this->GetLogLevel() < LogLevel::Warning)
284 {
285 return;
286 }
287 // else
288 this->logAdapter.Log(LogLevel::Warning, Formatter::FormatPrintf(format, args...));
289}
290
291template<typename... Args>
292inline void LoggerBase::PrintCritical(const char* format, const Args& ... args)
293{
294 if (this->GetLogLevel() < LogLevel::Critical)
295 {
296 return;
297 }
298 // else
299 this->logAdapter.Log(LogLevel::Critical, Formatter::FormatPrintf(format, args...));
300}
301
302template<typename... Args>
303inline void LoggerBase::PrintError(const char* format, const Args& ... args)
304{
305 if (this->GetLogLevel() < LogLevel::Error)
306 {
307 return;
308 }
309 // else
310 this->logAdapter.Log(LogLevel::Error, Formatter::FormatPrintf(format, args...));
311}
312
313template<typename... Args>
314inline void LoggerBase::PrintFatal(const char* format, const Args& ... args)
315{
316 if (this->GetLogLevel() < LogLevel::Fatal)
317 {
318 return;
319 }
320 // else
321 this->logAdapter.Log(LogLevel::Fatal, Formatter::FormatPrintf(format, args...));
322}
323
324}}}}} // end of namesapce Arp::System::Commons::Diagnostics::Logging
static LogManager & GetInstance(void)
Gets a reference of the singleton instance.
Definition: AppDomainSingleton.hxx:107
This is the base class of all Arp exception classes.
Definition: Exception.hpp:16
const String & GetMessage(void) const
Gets the error message of this exception.
Definition: Exception.hpp:137
static String FormatPrintf(const String &format, const Args &... args)
Uses Ansi-C printf syntax for the placeholders in the format string like 's'.
Definition: Formatter.hxx:53
static String FormatCommon(const String &format, const Args &... args)
Uses common CLR syntax (.Net) for the placeholders in the format string like '{0}'.
Definition: Formatter.hxx:39
Simple lock guard, acquiring lock on construction and release it on destruction.
Definition: LockGuard.hpp:15
Arp::BasicString< char8 > String
The Arp String class.
Definition: TypeSystem.h:27
@ System
System components used by the System, Device, Plc or Io domains.
Namespace for classes handling text
Definition: Formatter.hxx:11
Root namespace for the PLCnext API