Skip to content

Commit 36c564f

Browse files
committed
Add extended log options
Adds `logs.writeSrcLocation.*` cvars. If `<source_location>` is supported, this will add the source of the log to the log line itself.
1 parent a772627 commit 36c564f

File tree

2 files changed

+194
-52
lines changed

2 files changed

+194
-52
lines changed

src/common/Log.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3131
#include "Common.h"
3232

3333
namespace Log {
34+
Cvar::Cvar<bool> logExtendAll(
35+
"logs.writeSrcLocation.all", "Always print source code location for logs", Cvar::NONE, false );
36+
Cvar::Cvar<bool> logExtendWarn(
37+
"logs.writeSrcLocation.warn", "Print source code location for Warn logs", Cvar::NONE, false );
38+
Cvar::Cvar<bool> logExtendNotice(
39+
"logs.writeSrcLocation.notice", "Print source code location for Notice logs", Cvar::NONE, false );
40+
Cvar::Cvar<bool> logExtendVerbose(
41+
"logs.writeSrcLocation.verbose", "Print source code location for Verbose logs", Cvar::NONE, false );
42+
Cvar::Cvar<bool> logExtendDebug(
43+
"logs.writeSrcLocation.debug", "Print source code location for Debug logs", Cvar::NONE, false );
3444

3545
Logger::Logger(Str::StringRef name, std::string prefix, Level defaultLevel)
3646
: filterLevel(new Cvar::Cvar<Log::Level>(

src/common/Log.h

Lines changed: 184 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3131
#ifndef COMMON_LOG_H_
3232
#define COMMON_LOG_H_
3333

34+
#include "CPPStandard.h"
35+
36+
#include "engine/qcommon/q_shared.h"
37+
38+
#if defined( CPP_SOURCE_LOCATION )
39+
#include <source_location>
40+
#endif
41+
3442
namespace Log {
3543

3644
/*
@@ -51,6 +59,12 @@ namespace Log {
5159
// The default filtering level
5260
const Level DEFAULT_FILTER_LEVEL = Level::WARNING;
5361

62+
extern Cvar::Cvar<bool> logExtendAll;
63+
extern Cvar::Cvar<bool> logExtendWarn;
64+
extern Cvar::Cvar<bool> logExtendNotice;
65+
extern Cvar::Cvar<bool> logExtendVerbose;
66+
extern Cvar::Cvar<bool> logExtendDebug;
67+
5468
/*
5569
* Loggers are used to group logs by subsystems and allow logs
5670
* to be filtered by log level by subsystem. They are used like so
@@ -83,17 +97,31 @@ namespace Log {
8397
public:
8498
Logger(Str::StringRef name, std::string prefix = "", Level defaultLevel = DEFAULT_FILTER_LEVEL);
8599

86-
template<typename ... Args>
87-
void Warn(Str::StringRef format, Args&& ... args);
100+
#if defined( CPP_SOURCE_LOCATION )
101+
template<typename ... Args>
102+
void WarnExt( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args );
103+
104+
template<typename ... Args>
105+
void NoticeExt( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args );
106+
107+
template<typename ... Args>
108+
void VerboseExt( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args );
88109

89-
template<typename ... Args>
90-
void Notice(Str::StringRef format, Args&& ... args);
110+
template<typename ... Args>
111+
void DebugExt( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args );
112+
#else
113+
template<typename ... Args>
114+
void WarnExt( Str::StringRef format, Args&& ... args );
91115

92-
template<typename ... Args>
93-
void Verbose(Str::StringRef format, Args&& ... args);
116+
template<typename ... Args>
117+
void NoticeExt( Str::StringRef format, Args&& ... args );
94118

95-
template<typename ... Args>
96-
void Debug(Str::StringRef format, Args&& ... args);
119+
template<typename ... Args>
120+
void VerboseExt( Str::StringRef format, Args&& ... args );
121+
122+
template<typename ... Args>
123+
void DebugExt( Str::StringRef format, Args&& ... args );
124+
#endif
97125

98126
template<typename F>
99127
void DoWarnCode(F&& code);
@@ -130,17 +158,31 @@ namespace Log {
130158
* cannot be filtered and will clutter the console.
131159
*/
132160

133-
template<typename ... Args>
134-
void Warn(Str::StringRef format, Args&& ... args);
161+
#if defined( CPP_SOURCE_LOCATION )
162+
template<typename ... Args>
163+
void Warn( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args );
164+
165+
template<typename ... Args>
166+
void Notice( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args );
167+
168+
template<typename ... Args>
169+
void Verbose( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args );
135170

136-
template<typename ... Args>
137-
void Notice(Str::StringRef format, Args&& ... args);
171+
template<typename ... Args>
172+
void Debug( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args );
173+
#else
174+
template<typename ... Args>
175+
void Warn( Str::StringRef format, Args&& ... args );
138176

139-
template<typename ... Args>
140-
void Verbose(Str::StringRef format, Args&& ... args);
177+
template<typename ... Args>
178+
void Notice( Str::StringRef format, Args&& ... args );
141179

142-
template<typename ... Args>
143-
void Debug(Str::StringRef format, Args&& ... args);
180+
template<typename ... Args>
181+
void Verbose( Str::StringRef format, Args&& ... args );
182+
183+
template<typename ... Args>
184+
void Debug( Str::StringRef format, Args&& ... args );
185+
#endif
144186

145187
/*
146188
* For messages which are not true log messages, but rather are produced by
@@ -193,33 +235,90 @@ namespace Log {
193235

194236
// Logger
195237

196-
template<typename ... Args>
197-
void Logger::Warn(Str::StringRef format, Args&& ... args) {
198-
if (filterLevel->Get() <= Level::WARNING) {
199-
this->Dispatch(Prefix(Str::Format(format, std::forward<Args>(args) ...)), Level::WARNING, format);
238+
#if defined( CPP_SOURCE_LOCATION )
239+
inline std::string AddSrcLocation( const std::string& message, const std::source_location& srcLocation, const bool extend ) {
240+
if ( logExtendAll.Get() || extend ) {
241+
const char* start = Q_stristr( srcLocation.file_name(), "/src/" );
242+
243+
if( !start ) {
244+
start = Q_stristr( srcLocation.file_name(), "\\src\\" );
245+
}
246+
247+
if ( !start ) {
248+
start = srcLocation.file_name();
249+
}
250+
251+
return message + Str::Format( " ^F(file: %s, line: %u:%u, func: %s)",
252+
start, srcLocation.line(), srcLocation.column(), srcLocation.function_name() );
253+
}
254+
255+
return message;
200256
}
201-
}
202257

203-
template<typename ... Args>
204-
void Logger::Notice(Str::StringRef format, Args&& ... args) {
205-
if (filterLevel->Get() <= Level::NOTICE) {
206-
this->Dispatch(Prefix(Str::Format(format, std::forward<Args>(args) ...)), Level::NOTICE, format);
258+
template<typename ... Args>
259+
void Logger::WarnExt( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args ) {
260+
if ( filterLevel->Get() <= Level::WARNING ) {
261+
this->Dispatch(
262+
AddSrcLocation( Prefix( Str::Format( format, std::forward<Args>( args ) ... ) ), srcLocation, logExtendWarn.Get() ),
263+
Level::WARNING, format );
264+
}
207265
}
208-
}
209266

210-
template<typename ... Args>
211-
void Logger::Verbose(Str::StringRef format, Args&& ... args) {
212-
if (filterLevel->Get() <= Level::VERBOSE) {
213-
this->Dispatch(Prefix(Str::Format(format, std::forward<Args>(args) ...)), Level::VERBOSE, format);
267+
template<typename ... Args>
268+
void Logger::NoticeExt( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args ) {
269+
if ( filterLevel->Get() <= Level::NOTICE ) {
270+
this->Dispatch(
271+
AddSrcLocation( Prefix( Str::Format( format, std::forward<Args>( args ) ... ) ), srcLocation, logExtendNotice.Get() ),
272+
Level::NOTICE, format );
273+
}
214274
}
215-
}
216275

217-
template<typename ... Args>
218-
void Logger::Debug(Str::StringRef format, Args&& ... args) {
219-
if (filterLevel->Get() <= Level::DEBUG) {
220-
this->Dispatch(Prefix(Str::Format(format, std::forward<Args>(args) ...)), Level::DEBUG, format);
276+
template<typename ... Args>
277+
void Logger::VerboseExt( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args ) {
278+
if ( filterLevel->Get() <= Level::VERBOSE ) {
279+
this->Dispatch(
280+
AddSrcLocation( Prefix( Str::Format( format, std::forward<Args>( args ) ... ) ), srcLocation, logExtendVerbose.Get() ),
281+
Level::VERBOSE, format );
282+
}
221283
}
222-
}
284+
285+
template<typename ... Args>
286+
void Logger::DebugExt( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args ) {
287+
if ( filterLevel->Get() <= Level::DEBUG ) {
288+
this->Dispatch(
289+
AddSrcLocation( Prefix( Str::Format( format, std::forward<Args>( args ) ... ) ), srcLocation, logExtendDebug.Get() ),
290+
Level::DEBUG, format );
291+
}
292+
}
293+
#else
294+
template<typename ... Args>
295+
void Logger::WarnExt( Str::StringRef format, Args&& ... args ) {
296+
if ( filterLevel->Get() <= Level::WARNING ) {
297+
this->Dispatch( Prefix( Str::Format( format, std::forward<Args>( args ) ... ) ), Level::WARNING, format );
298+
}
299+
}
300+
301+
template<typename ... Args>
302+
void Logger::NoticeExt( Str::StringRef format, Args&& ... args ) {
303+
if ( filterLevel->Get() <= Level::NOTICE ) {
304+
this->Dispatch( Prefix( Str::Format( format, std::forward<Args>( args ) ... ) ), Level::NOTICE, format );
305+
}
306+
}
307+
308+
template<typename ... Args>
309+
void Logger::VerboseExt( Str::StringRef format, Args&& ... args ) {
310+
if ( filterLevel->Get() <= Level::VERBOSE ) {
311+
this->Dispatch( Prefix( Str::Format( format, std::forward<Args>( args ) ... ) ), Level::VERBOSE, format );
312+
}
313+
}
314+
315+
template<typename ... Args>
316+
void Logger::DebugExt( Str::StringRef format, Args&& ... args ) {
317+
if ( filterLevel->Get() <= Level::DEBUG ) {
318+
this->Dispatch( Prefix( Str::Format( format, std::forward<Args>( args ) ... ) ), Level::DEBUG, format );
319+
}
320+
}
321+
#endif
223322

224323
template<typename F>
225324
inline void Logger::DoWarnCode(F&& code) {
@@ -252,25 +351,58 @@ namespace Log {
252351
// Quick Logs
253352
extern Logger defaultLogger;
254353

255-
template<typename ... Args>
256-
void Warn(Str::StringRef format, Args&& ... args) {
257-
defaultLogger.Warn(format, std::forward<Args>(args) ...);
258-
}
354+
#if defined( CPP_SOURCE_LOCATION )
355+
template<typename ... Args>
356+
void WarnExt( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args ) {
357+
defaultLogger.WarnExt( srcLocation, format, std::forward<Args>( args ) ... );
358+
}
259359

260-
template<typename ... Args>
261-
void Notice(Str::StringRef format, Args&& ... args) {
262-
defaultLogger.Notice(format, std::forward<Args>(args) ...);
263-
}
360+
template<typename ... Args>
361+
void NoticeExt( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args ) {
362+
defaultLogger.NoticeExt( srcLocation, format, std::forward<Args>( args ) ... );
363+
}
264364

265-
template<typename ... Args>
266-
void Verbose(Str::StringRef format, Args&& ... args) {
267-
defaultLogger.Verbose(format, std::forward<Args>(args) ...);
268-
}
365+
template<typename ... Args>
366+
void VerboseExt( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args ) {
367+
defaultLogger.VerboseExt( srcLocation, format, std::forward<Args>( args ) ... );
368+
}
269369

270-
template<typename ... Args>
271-
void Debug(Str::StringRef format, Args&& ... args) {
272-
defaultLogger.Debug(format, std::forward<Args>(args) ...);
273-
}
370+
template<typename ... Args>
371+
void DebugExt( const std::source_location& srcLocation, Str::StringRef format, Args&& ... args ) {
372+
defaultLogger.DebugExt( srcLocation, format, std::forward<Args>( args ) ... );
373+
}
374+
375+
// Use ##__VA_ARGS__ instead of __VA_ARGS__ because args may be empty. __VA_OPT__( , ) currently doesn't seem to work on MSVC
376+
#define Warn( format, ... ) WarnExt( std::source_location::current(), format, ##__VA_ARGS__ )
377+
#define Notice( format, ... ) NoticeExt( std::source_location::current(), format, ##__VA_ARGS__ )
378+
#define Verbose( format, ... ) VerboseExt( std::source_location::current(), format, ##__VA_ARGS__ )
379+
#define Debug( format, ... ) DebugExt( std::source_location::current(), format, ##__VA_ARGS__ )
380+
#else
381+
template<typename ... Args>
382+
void WarnExt( Str::StringRef format, Args&& ... args ) {
383+
defaultLogger.WarnExt( format, std::forward<Args>( args ) ... );
384+
}
385+
386+
template<typename ... Args>
387+
void NoticeExt( Str::StringRef format, Args&& ... args ) {
388+
defaultLogger.NoticeExt( format, std::forward<Args>( args ) ... );
389+
}
390+
391+
template<typename ... Args>
392+
void VerboseExt( Str::StringRef format, Args&& ... args ) {
393+
defaultLogger.VerboseExt( format, std::forward<Args>( args ) ... );
394+
}
395+
396+
template<typename ... Args>
397+
void DebugExt( Str::StringRef format, Args&& ... args ) {
398+
defaultLogger.DebugExt( format, std::forward<Args>( args ) ... );
399+
}
400+
401+
#define Warn WarnExt
402+
#define Notice NoticeExt
403+
#define Verbose VerboseExt
404+
#define Debug DebugExt
405+
#endif
274406
}
275407

276408
namespace Cvar {

0 commit comments

Comments
 (0)