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