PLCnext API Documentation  20.6.0.30321
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
Simple lock guard, acquiring lock on construction and release it on destruction.
Definition: LockGuard.hpp:14
static String FormatCommon(const String &format, const Args &... args)
Uses common CLR syntax (.Net) for the placeholders in the format string like &#39;{0}&#39;.
Definition: Formatter.hxx:39
static LogManager & GetInstance(void)
Gets a reference of the singleton instance.
Definition: AppDomainSingleton.hxx:102
const String & GetMessage(void) const
Gets the error message of this exception.
Definition: Exception.hpp:137
Arp::BasicString< char8 > String
The Arp String class.
Definition: TypeSystem.h:27
static String FormatPrintf(const String &format, const Args &... args)
Uses Ansi-C printf syntax for the placeholders in the format string like &#39;s&#39;.
Definition: Formatter.hxx:53
Namespace for classes handling threads and synchronization
Root namespace for the PLCnext API
Namespace for classes handling text
System components used by the System, Device, Plc or Io domains.
This is the base class of all Arp exception classes.
Definition: Exception.hpp:15