Plasma Engine  2.0
Loading...
Searching...
No Matches
Log.h
1#pragma once
2
3#include <Foundation/Communication/Event.h>
4#include <Foundation/Strings/FormatString.h>
5#include <Foundation/Strings/StringBuilder.h>
6#include <Foundation/Strings/StringUtils.h>
7#include <Foundation/Threading/AtomicInteger.h>
8#include <Foundation/Time/Time.h>
9
12#define PL_LOG_BLOCK plLogBlock PL_PP_CONCAT(_logblock_, PL_SOURCE_LINE)
13
15#define PL_LOG_BLOCK_MUTE() \
16 plMuteLog PL_PP_CONCAT(_logmuteblock_, PL_SOURCE_LINE); \
17 plLogSystemScope PL_PP_CONCAT(_logscope_, PL_SOURCE_LINE)(&PL_PP_CONCAT(_logmuteblock_, PL_SOURCE_LINE))
18
19// Forward declaration, class is at the end of this file
20class plLogBlock;
21
22
24struct PL_FOUNDATION_DLL plLogMsgType
25{
26 using StorageType = plInt8;
27
28 enum Enum : plInt8
29 {
30 GlobalDefault = -4,
31 Flush = -3,
32 BeginGroup = -2,
33 EndGroup = -1,
34 None = 0,
35 ErrorMsg = 1,
36 SeriousWarningMsg = 2,
37 WarningMsg = 3,
38 SuccessMsg = 4,
39 InfoMsg = 5,
40 DevMsg = 6,
41 DebugMsg = 7,
42 All = 8,
43 ENUM_COUNT,
44 Default = None,
45 };
46};
47
49struct PL_FOUNDATION_DLL plLoggingEventData
50{
53
55 plUInt8 m_uiIndentation = 0;
56
59
63
64#if PL_ENABLED(PL_COMPILE_FOR_DEVELOPMENT)
66 double m_fSeconds = 0;
67#endif
68};
69
71
76class PL_FOUNDATION_DLL plLogInterface
77{
78public:
80 virtual void HandleLogMessage(const plLoggingEventData& le) = 0;
81
84 PL_ALWAYS_INLINE void SetLogLevel(plLogMsgType::Enum logLevel) { m_LogLevel = logLevel; }
85
87 PL_ALWAYS_INLINE plLogMsgType::Enum GetLogLevel() { return m_LogLevel; }
88
89private:
90 friend class plLog;
91 friend class plLogBlock;
92 plLogBlock* m_pCurrentBlock = nullptr;
94 plUInt32 m_uiLoggedMsgsSinceFlush = 0;
95 plTime m_LastFlushTime;
96};
97
98
102{
103public:
104 plMuteLog()
105 {
107 }
108
109 virtual void HandleLogMessage(const plLoggingEventData&) override {}
110};
111
112
117class PL_FOUNDATION_DLL plGlobalLog : public plLogInterface
118{
119public:
120 virtual void HandleLogMessage(const plLoggingEventData& le) override;
121
123 static plEventSubscriptionID AddLogWriter(plLoggingEvent::Handler handler);
124
126 static void RemoveLogWriter(plLoggingEvent::Handler handler);
127
129 static void RemoveLogWriter(plEventSubscriptionID& ref_subscriptionID);
130
132 static plUInt32 GetMessageCount(plLogMsgType::Enum messageType) { return s_uiMessageCount[messageType]; }
133
140 static void SetGlobalLogOverride(plLogInterface* pInterface);
141
142private:
144 static plAtomicInteger32 s_uiMessageCount[plLogMsgType::ENUM_COUNT];
145
147 static plLoggingEvent s_LoggingEvent;
148
149 static plLogInterface* s_pOverrideLog;
150
151private:
152 PL_DISALLOW_COPY_AND_ASSIGN(plGlobalLog);
153
154 friend class plLog; // only plLog may create instances of this class
155 plGlobalLog() = default;
156};
157
166class PL_FOUNDATION_DLL plLog
167{
168public:
173 static void SetThreadLocalLogSystem(plLogInterface* pInterface);
174
176 static plLogInterface* GetThreadLocalLogSystem();
177
179 static void SetDefaultLogLevel(plLogMsgType::Enum logLevel);
180
182 static plLogMsgType::Enum GetDefaultLogLevel();
183
185 static void Error(plLogInterface* pInterface, const plFormatString& string);
186
188 template <typename... ARGS>
189 static void Error(plStringView sFormat, ARGS&&... args)
190 {
191 Error(GetThreadLocalLogSystem(), plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
192 }
193
195 template <typename... ARGS>
196 static void Error(plLogInterface* pInterface, plStringView sFormat, ARGS&&... args)
197 {
198 Error(pInterface, plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
199 }
200
202 static void SeriousWarning(plLogInterface* pInterface, const plFormatString& string);
203
205 template <typename... ARGS>
206 static void SeriousWarning(plStringView sFormat, ARGS&&... args)
207 {
208 SeriousWarning(GetThreadLocalLogSystem(), plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
209 }
210
212 template <typename... ARGS>
213 static void SeriousWarning(plLogInterface* pInterface, plStringView sFormat, ARGS&&... args)
214 {
215 SeriousWarning(pInterface, plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
216 }
217
219 static void Warning(plLogInterface* pInterface, const plFormatString& string);
220
222 template <typename... ARGS>
223 static void Warning(plStringView sFormat, ARGS&&... args)
224 {
225 Warning(GetThreadLocalLogSystem(), plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
226 }
227
229 template <typename... ARGS>
230 static void Warning(plLogInterface* pInterface, plStringView sFormat, ARGS&&... args)
231 {
232 Warning(pInterface, plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
233 }
234
236 static void Success(plLogInterface* pInterface, const plFormatString& string);
237
239 template <typename... ARGS>
240 static void Success(plStringView sFormat, ARGS&&... args)
241 {
242 Success(GetThreadLocalLogSystem(), plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
243 }
244
246 template <typename... ARGS>
247 static void Success(plLogInterface* pInterface, plStringView sFormat, ARGS&&... args)
248 {
249 Success(pInterface, plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
250 }
251
253 static void Info(plLogInterface* pInterface, const plFormatString& string);
254
256 template <typename... ARGS>
257 static void Info(plStringView sFormat, ARGS&&... args)
258 {
259 Info(GetThreadLocalLogSystem(), plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
260 }
261
263 template <typename... ARGS>
264 static void Info(plLogInterface* pInterface, plStringView sFormat, ARGS&&... args)
265 {
266 Info(pInterface, plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
267 }
268
272 static void Dev(plLogInterface* pInterface, const plFormatString& string);
273
277 template <typename... ARGS>
278 static void Dev(plStringView sFormat, ARGS&&... args)
279 {
280 Dev(GetThreadLocalLogSystem(), plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
281 }
282
284 template <typename... ARGS>
285 static void Dev(plLogInterface* pInterface, plStringView sFormat, ARGS&&... args)
286 {
287 Dev(pInterface, plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
288 }
289
293 static void Debug(plLogInterface* pInterface, const plFormatString& string);
294
298 template <typename... ARGS>
299 static void Debug(plStringView sFormat, ARGS&&... args)
300 {
301 Debug(GetThreadLocalLogSystem(), plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
302 }
303
305 template <typename... ARGS>
306 static void Debug(plLogInterface* pInterface, plStringView sFormat, ARGS&&... args)
307 {
308 Debug(pInterface, plFormatStringImpl<ARGS...>(sFormat, std::forward<ARGS>(args)...));
309 }
310
327 static bool Flush(plUInt32 uiNumNewMsgThreshold = 0, plTime timeIntervalThreshold = plTime::MakeFromSeconds(10), plLogInterface* pInterface = GetThreadLocalLogSystem());
328
331 static void BroadcastLoggingEvent(plLogInterface* pInterface, plLogMsgType::Enum type, plStringView sString);
332
339 static void Print(const char* szText);
340
344 static void Printf(const char* szFormat, ...);
345
347 using PrintFunction = void (*)(const char* szText);
348
350 static void SetCustomPrintFunction(PrintFunction func);
351
355 static void OsMessageBox(const plFormatString& text);
356
358 enum class TimestampMode
359 {
360 None = 0,
361 Numeric = 1,
362 Textual = 2,
363 TimeOnly = 3,
364 };
365
366 static void GenerateFormattedTimestamp(TimestampMode mode, plStringBuilder& ref_sTimestampOut);
367
368private:
369 // Needed to call 'EndLogBlock'
370 friend class plLogBlock;
371
373 static plLogMsgType::Enum s_DefaultLogLevel;
374
376 static void EndLogBlock(plLogInterface* pInterface, plLogBlock* pBlock);
377
378 static void WriteBlockHeader(plLogInterface* pInterface, plLogBlock* pBlock);
379
380 static PrintFunction s_CustomPrintFunction;
381};
382
383
385class PL_FOUNDATION_DLL plLogBlock
386{
387public:
398 plLogBlock(plStringView sName, plStringView sContextInfo = {});
399
403 plLogBlock(plLogInterface* pInterface, plStringView sName, plStringView sContextInfo = {});
404
405 ~plLogBlock();
406
407private:
408 friend class plLog;
409
410 plLogInterface* m_pLogInterface;
411 plLogBlock* m_pParentBlock;
412 plStringView m_sName;
413 plStringView m_sContextInfo;
414 plUInt8 m_uiBlockDepth;
415 bool m_bWritten;
416#if PL_ENABLED(PL_COMPILE_FOR_DEVELOPMENT)
417 double m_fSeconds; // for profiling
418#endif
419};
420
423class PL_FOUNDATION_DLL plLogSystemScope
424{
425public:
427 explicit plLogSystemScope(plLogInterface* pInterface)
428 {
429 m_pPrevious = plLog::GetThreadLocalLogSystem();
431 }
432
435
436protected:
437 plLogInterface* m_pPrevious;
438
439private:
440 PL_DISALLOW_COPY_AND_ASSIGN(plLogSystemScope);
441};
442
443
446{
447public:
448 virtual void HandleLogMessage(const plLoggingEventData& le) override
449 {
450 switch (le.m_EventType)
451 {
453 m_sBuffer.Append("Error: ", le.m_sText, "\n");
454 break;
457 m_sBuffer.Append("Warning: ", le.m_sText, "\n");
458 break;
463 m_sBuffer.Append(le.m_sText, "\n");
464 break;
465 default:
466 break;
467 }
468 }
469
470 plStringBuilder m_sBuffer;
471};
472
473#include <Foundation/Logging/Implementation/Log_inl.h>
plDelegate< void(const plLoggingEventData &)> Handler
Definition Event.h:45
Implements formating of strings with placeholders and formatting options.
Definition FormatString.h:59
Definition FormatStringImpl.h:9
This is the standard log system that plLog sends all messages to.
Definition Log.h:118
static plUInt32 GetMessageCount(plLogMsgType::Enum messageType)
Returns how many message of the given type occurred.
Definition Log.h:132
Instances of this class will group messages in a scoped block together.
Definition Log.h:386
Static class that allows to write out logging information.
Definition Log.h:167
static void Debug(plStringView sFormat, ARGS &&... args)
Status information during debugging. Very verbose. Usually only temporarily added to the code.
Definition Log.h:299
static void SeriousWarning(plLogInterface *pInterface, plStringView sFormat, ARGS &&... args)
Overload of SeriousWarning() to output messages to a specific log.
Definition Log.h:213
static void Debug(plLogInterface *pInterface, plStringView sFormat, ARGS &&... args)
Overload of Debug() to output messages to a specific log.
Definition Log.h:306
static void Info(plStringView sFormat, ARGS &&... args)
Status information that is important.
Definition Log.h:257
static void Dev(plLogInterface *pInterface, const plFormatString &string)
Status information that is nice to have during development.
void(*)(const char *szText) PrintFunction
Signature of the custom print function used by plLog::SetCustomPrintFunction.
Definition Log.h:347
static void Info(plLogInterface *pInterface, plStringView sFormat, ARGS &&... args)
Overload of Info() to output messages to a specific log.
Definition Log.h:264
TimestampMode
This enum is used in context of outputting timestamp information to indicate a formatting for said ti...
Definition Log.h:359
static void Error(plStringView sFormat, ARGS &&... args)
An error that needs to be fixed as soon as possible.
Definition Log.h:189
static void Warning(plLogInterface *pInterface, plStringView sFormat, ARGS &&... args)
Overload of Warning() to output messages to a specific log.
Definition Log.h:230
static void Dev(plStringView sFormat, ARGS &&... args)
Status information that is nice to have during development.
Definition Log.h:278
static void Debug(plLogInterface *pInterface, const plFormatString &string)
Status information during debugging. Very verbose. Usually only temporarily added to the code.
static void Error(plLogInterface *pInterface, plStringView sFormat, ARGS &&... args)
Overload of Error() to output messages to a specific log.
Definition Log.h:196
static void Dev(plLogInterface *pInterface, plStringView sFormat, ARGS &&... args)
Overload of Dev() to output messages to a specific log.
Definition Log.h:285
static void Success(plLogInterface *pInterface, plStringView sFormat, ARGS &&... args)
Overload of Success() to output messages to a specific log.
Definition Log.h:247
static void Warning(plStringView sFormat, ARGS &&... args)
A potential problem or a performance warning. Might be possible to ignore it.
Definition Log.h:223
static void SetThreadLocalLogSystem(plLogInterface *pInterface)
Allows to change which logging system is used by default on the current thread. If nothing is set,...
Definition Log.cpp:337
static void Success(plStringView sFormat, ARGS &&... args)
Status information that something was completed successfully.
Definition Log.h:240
static plLogInterface * GetThreadLocalLogSystem()
Returns the currently set default logging system, or a thread local instance of plGlobalLog,...
Definition Log.cpp:345
static void SeriousWarning(plStringView sFormat, ARGS &&... args)
Not an error, but definitely a big problem, that should be looked into very soon.
Definition Log.h:206
Base class for all logging classes.
Definition Log.h:77
PL_ALWAYS_INLINE plLogMsgType::Enum GetLogLevel()
Returns the currently set log level.
Definition Log.h:87
virtual void HandleLogMessage(const plLoggingEventData &le)=0
Override this function to handle logging events.
PL_ALWAYS_INLINE void SetLogLevel(plLogMsgType::Enum logLevel)
LogLevel is between plLogEventType::None and plLogEventType::All and defines which messages will be l...
Definition Log.h:84
A class that sets a custom plLogInterface as the thread local default log system, and resets the prev...
Definition Log.h:424
plLogSystemScope(plLogInterface *pInterface)
The given plLogInterface is passed to plLog::SetThreadLocalLogSystem().
Definition Log.h:427
~plLogSystemScope()
Resets the previous plLogInterface through plLog::SetThreadLocalLogSystem()
Definition Log.h:434
A simple log interface implementation that gathers all messages in a string buffer.
Definition Log.h:446
virtual void HandleLogMessage(const plLoggingEventData &le) override
Override this function to handle logging events.
Definition Log.h:448
Used to ignore all log messages.
Definition Log.h:102
virtual void HandleLogMessage(const plLoggingEventData &) override
Override this function to handle logging events.
Definition Log.h:109
plStringBuilder is a class that is meant for creating and modifying strings.
Definition StringBuilder.h:35
void Append(plUInt32 uiChar)
Appends a single Utf32 character.
Definition StringBuilder_inl.h:94
plStringView represent a read-only sub-string of a larger string, as it can store a dedicated string ...
Definition StringView.h:34
Describes the types of events that plLog sends.
Definition Log.h:25
Enum
Definition Log.h:29
@ SeriousWarningMsg
A serious warning message.
Definition Log.h:36
@ InfoMsg
An info message.
Definition Log.h:39
@ DebugMsg
A debug message.
Definition Log.h:41
@ None
Can be used to disable all log message types.
Definition Log.h:34
@ GlobalDefault
Takes the log level from the plLog default value. See plLog::SetDefaultLogLevel().
Definition Log.h:30
@ SuccessMsg
A success message.
Definition Log.h:38
@ ErrorMsg
An error message.
Definition Log.h:35
@ WarningMsg
A warning message.
Definition Log.h:37
@ DevMsg
A development message.
Definition Log.h:40
The data that is sent through plLogInterface.
Definition Log.h:50
plLogMsgType::Enum m_EventType
The type of information that is sent.
Definition Log.h:52
plStringView m_sText
The information text.
Definition Log.h:58
plStringView m_sTag
An optional tag extracted from the log-string (if it started with "[SomeTag]Logging String....
Definition Log.h:62
The time class encapsulates a double value storing the time in seconds.
Definition Time.h:12
PL_ALWAYS_INLINE static constexpr plTime MakeFromSeconds(double fSeconds)
Creates an instance of plTime that was initialized from seconds.
Definition Time.h:30