UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
LogMacros.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
6#include "CoreTypes.h"
10#include "Logging/LogTrace.h"
13#include "Misc/Build.h"
14#include "Misc/VarArgs.h"
16#include "Templates/EnableIf.h"
20
21#include <type_traits>
22
23#ifndef UE_LOG_INCLUDE_SOURCE_LOCATION
24#define UE_LOG_INCLUDE_SOURCE_LOCATION 1
25#endif
26
27#if UE_LOG_INCLUDE_SOURCE_LOCATION || LOGTRACE_ENABLED
28#define UE_PRIVATE_LOG_USE_STATIC_RECORD 1
29#else
30#define UE_PRIVATE_LOG_USE_STATIC_RECORD 0
31#endif
32
33/*----------------------------------------------------------------------------
34 Logging
35----------------------------------------------------------------------------*/
36
37// Define NO_LOGGING to strip out all writing to log files, OutputDebugString(), etc.
38
43struct FMsg
44{
46 CORE_API static void SendNotificationString( const TCHAR* Message );
47
49 template <typename FmtType, typename... Types>
50 static void SendNotificationStringf(const FmtType& Fmt, Types... Args)
51 {
52 static_assert(TIsArrayOrRefOfTypeByPredicate<FmtType, TIsCharEncodingCompatibleWithTCHAR>::Value, "Formatting string must be a const TCHAR array.");
53 static_assert((TIsValidVariadicFunctionArg<Types>::Value && ...), "Invalid argument(s) passed to FMsg::SendNotificationStringf");
54
55 SendNotificationStringfImpl((const TCHAR*)Fmt, Args...);
56 }
57
59 template <typename FmtType, typename... Types>
60 static void Logf(const ANSICHAR* File, int32 Line, const FLogCategoryName& Category, ELogVerbosity::Type Verbosity, const FmtType& Fmt, Types... Args)
61 {
62 static_assert(TIsArrayOrRefOfTypeByPredicate<FmtType, TIsCharEncodingCompatibleWithTCHAR>::Value, "Formatting string must be a const TCHAR array.");
63 static_assert((TIsValidVariadicFunctionArg<Types>::Value && ...), "Invalid argument(s) passed to FMsg::Logf");
64
65 LogfImpl(File, Line, Category, Verbosity, (const TCHAR*)Fmt, Args...);
66 }
67
69 template <typename FmtType, typename... Types>
70 static void Logf_Internal(const ANSICHAR* File, int32 Line, const FLogCategoryName& Category, ELogVerbosity::Type Verbosity, const FmtType& Fmt, Types... Args)
71 {
72 static_assert(TIsArrayOrRefOfTypeByPredicate<FmtType, TIsCharEncodingCompatibleWithTCHAR>::Value, "Formatting string must be a const TCHAR array.");
73 static_assert((TIsValidVariadicFunctionArg<Types>::Value && ...), "Invalid argument(s) passed to FMsg::Logf_Internal");
74
75 Logf_InternalImpl(File, Line, Category, Verbosity, (const TCHAR*)Fmt, Args...);
76 }
77
78 CORE_API static void LogV(const ANSICHAR* File, int32 Line, const FLogCategoryName& Category, ELogVerbosity::Type Verbosity, const TCHAR* Fmt, va_list Args);
79
80private:
81 CORE_API static void VARARGS LogfImplV(const ANSICHAR* File, int32 Line, const FLogCategoryName& Category, ELogVerbosity::Type Verbosity, void* ReturnAddress, const TCHAR* Fmt, va_list Args);
82 CORE_API static void VARARGS LogfImpl(const ANSICHAR* File, int32 Line, const FLogCategoryName& Category, ELogVerbosity::Type Verbosity, const TCHAR* Fmt, ...);
83 CORE_API static void VARARGS Logf_InternalImpl(const ANSICHAR* File, int32 Line, const FLogCategoryName& Category, ELogVerbosity::Type Verbosity, const TCHAR* Fmt, ...);
84 CORE_API static void VARARGS SendNotificationStringfImpl(const TCHAR* Fmt, ...);
85};
86
87/*----------------------------------------------------------------------------
88 Logging suppression
89----------------------------------------------------------------------------*/
90
91#ifndef COMPILED_IN_MINIMUM_VERBOSITY
92 #define COMPILED_IN_MINIMUM_VERBOSITY VeryVerbose
93#else
94 #if !IS_MONOLITHIC
95 #error COMPILED_IN_MINIMUM_VERBOSITY can only be defined in monolithic builds.
96 #endif
97#endif
98
99#define UE_LOG_EXPAND_IS_FATAL(Verbosity, ActiveBlock, InactiveBlock) UE_JOIN(UE_LOG_EXPAND_IS_FATAL_, Verbosity)(ActiveBlock, InactiveBlock)
100
101#define UE_LOG_EXPAND_IS_FATAL_Fatal( ActiveBlock, InactiveBlock) ActiveBlock
102#define UE_LOG_EXPAND_IS_FATAL_Error( ActiveBlock, InactiveBlock) InactiveBlock
103#define UE_LOG_EXPAND_IS_FATAL_Warning( ActiveBlock, InactiveBlock) InactiveBlock
104#define UE_LOG_EXPAND_IS_FATAL_Display( ActiveBlock, InactiveBlock) InactiveBlock
105#define UE_LOG_EXPAND_IS_FATAL_Log( ActiveBlock, InactiveBlock) InactiveBlock
106#define UE_LOG_EXPAND_IS_FATAL_Verbose( ActiveBlock, InactiveBlock) InactiveBlock
107#define UE_LOG_EXPAND_IS_FATAL_VeryVerbose(ActiveBlock, InactiveBlock) InactiveBlock
108#define UE_LOG_EXPAND_IS_FATAL_All( ActiveBlock, InactiveBlock) InactiveBlock
109#define UE_LOG_EXPAND_IS_FATAL_SetColor( ActiveBlock, InactiveBlock) InactiveBlock
110
111#if DO_CHECK
112 #define UE_LOG_SOURCE_FILE(File) File
113#else
114 #define UE_LOG_SOURCE_FILE(File) "Unknown"
115#endif
116
117namespace UE::Logging::Private
118{
119
121struct FStaticBasicLogDynamicData
122{
123#if LOGTRACE_ENABLED
124 std::atomic<bool> bInitializedTrace = false;
125#endif
126};
127
129struct FStaticBasicLogRecord
130{
131 const TCHAR* Format = nullptr;
132 UE_IF(UE_LOG_INCLUDE_SOURCE_LOCATION,, inline static constexpr) const ANSICHAR* File = nullptr;
133 UE_IF(UE_LOG_INCLUDE_SOURCE_LOCATION,, inline static constexpr) int32 Line = 0;
134#if LOGTRACE_ENABLED
135 FStaticBasicLogDynamicData& DynamicData;
136#endif
137
138 // Workaround for https://developercommunity.visualstudio.com/t/Incorrect-warning-C4700-with-unrelated-s/10285950
139 constexpr FStaticBasicLogRecord(
140 const TCHAR* InFormat,
141 const ANSICHAR* InFile,
143 FStaticBasicLogDynamicData* InDynamicData)
145 #if UE_LOG_INCLUDE_SOURCE_LOCATION
146 , File(InFile)
147 , Line(InLine)
148 #endif
149 #if LOGTRACE_ENABLED
150 , DynamicData(*InDynamicData)
151 #endif
152 {
153 }
154
155#if !UE_PRIVATE_LOG_USE_STATIC_RECORD
156 // Delete the address-of operator because it is unsafe to pass pointers to records
157 // when they do not have static storage duration.
158 FStaticBasicLogRecord* operator&() const = delete;
159#endif
160};
161
162// Pass FStaticBasicLogRecord by value when the record is not static, because in that
163// configuration it is simply a wrapper for the format string pointer.
164#if UE_PRIVATE_LOG_USE_STATIC_RECORD
165using FStaticBasicLogRecordParam = const FStaticBasicLogRecord&;
166#else
167using FStaticBasicLogRecordParam = FStaticBasicLogRecord;
168#endif
169
170template <ELogVerbosity::Type Verbosity>
171CORE_API void BasicLog(FStaticBasicLogRecordParam Log, const FLogCategoryBase* Category, ...);
172CORE_API void BasicFatalLog(FStaticBasicLogRecordParam Log, const FLogCategoryBase* Category, ...);
173CORE_API void BasicFatalLogWithProgramCounter(FStaticBasicLogRecordParam Log, const FLogCategoryBase* Category, void* ProgramCounter, ...);
174
175} // UE::Logging::Private
176
177#if NO_LOGGING
178
179 struct FNoLoggingCategory {};
180
181 // This will only log Fatal errors
182 #define UE_LOG(CategoryName, Verbosity, Format, ...) \
183 { \
184 if constexpr ((ELogVerbosity::Verbosity & ELogVerbosity::VerbosityMask) == ELogVerbosity::Fatal) \
185 { \
186 LowLevelFatalError(Format, ##__VA_ARGS__); \
187 CA_ASSUME(false); \
188 } \
189 }
190 #define UE_LOG_REF(CategoryRef, Verbosity, Format, ...) \
191 { \
192 if constexpr ((ELogVerbosity::Verbosity & ELogVerbosity::VerbosityMask) == ELogVerbosity::Fatal) \
193 { \
194 LowLevelFatalError(Format, ##__VA_ARGS__); \
195 CA_ASSUME(false); \
196 } \
197 }
198 #define UE_LOG_CLINKAGE(CategoryName, Verbosity, Format, ...) \
199 { \
200 if constexpr ((ELogVerbosity::Verbosity & ELogVerbosity::VerbosityMask) == ELogVerbosity::Fatal) \
201 { \
202 LowLevelFatalError(Format, ##__VA_ARGS__); \
203 CA_ASSUME(false); \
204 } \
205 }
206
207 // Conditional logging (fatal errors only).
208 #define UE_CLOG(Condition, CategoryName, Verbosity, Format, ...) \
209 { \
210 if constexpr ((ELogVerbosity::Verbosity & ELogVerbosity::VerbosityMask) == ELogVerbosity::Fatal) \
211 { \
212 if (Condition) \
213 { \
214 LowLevelFatalError(Format, ##__VA_ARGS__); \
215 CA_ASSUME(false); \
216 } \
217 } \
218 }
219
220 #define UE_LOG_ACTIVE(...) (0)
221 #define UE_LOG_ANY_ACTIVE(...) (0)
222 #define UE_SUPPRESS(...) {}
223 #define UE_GET_LOG_VERBOSITY(...) (ELogVerbosity::NoLogging)
224 #define UE_SET_LOG_VERBOSITY(...)
225 #define DECLARE_LOG_CATEGORY_EXTERN(CategoryName, DefaultVerbosity, CompileTimeVerbosity) extern FNoLoggingCategory CategoryName;
226 #define DEFINE_LOG_CATEGORY(CategoryName, ...) FNoLoggingCategory CategoryName;
227 #define DEFINE_LOG_CATEGORY_STATIC(...)
228 #define DECLARE_LOG_CATEGORY_CLASS(...)
229 #define DEFINE_LOG_CATEGORY_CLASS(...)
230
231#else
232
234 {
235 template <int32 VerbosityToCheck, typename CategoryType>
237 {
238 if constexpr (((VerbosityToCheck & ELogVerbosity::VerbosityMask) <= CategoryType::CompileTimeVerbosity &&
239 (VerbosityToCheck & ELogVerbosity::VerbosityMask) <= ELogVerbosity::COMPILED_IN_MINIMUM_VERBOSITY))
240 {
241 return !Category.IsSuppressed((ELogVerbosity::Type)VerbosityToCheck);
242 }
243 else
244 {
245 return false;
246 }
247 }
248 }
249
255 #define UE_LOG_ACTIVE(CategoryName, Verbosity) (::UEAsserts_Private::IsLogActive<(int32)ELogVerbosity::Verbosity>(CategoryName))
256
257 #define UE_GET_LOG_VERBOSITY(CategoryName) \
258 CategoryName.GetVerbosity()
259
260 #define UE_SET_LOG_VERBOSITY(CategoryName, Verbosity) \
261 CategoryName.SetVerbosity(ELogVerbosity::Verbosity);
262
270 #define UE_LOG(CategoryName, Verbosity, Format, ...) \
271 UE_PRIVATE_LOG(UE_EMPTY, constexpr, CategoryName, Verbosity, Format, ##__VA_ARGS__)
272
282 #define UE_LOG_REF(CategoryRef, Verbosity, Format, ...) \
283 UE_PRIVATE_LOG(UE_EMPTY, UE_EMPTY, CategoryRef, Verbosity, Format, ##__VA_ARGS__)
284
285 // DO NOT USE. Use UE_LOG because this will be deprecated in a future release.
286 #define UE_LOG_CLINKAGE UE_LOG
287
298 #define UE_CLOG(Condition, CategoryName, Verbosity, Format, ...) \
299 UE_PRIVATE_LOG(if (Condition), constexpr, CategoryName, Verbosity, Format, ##__VA_ARGS__)
300
302 #define UE_PRIVATE_LOG(Condition, CategoryConst, Category, Verbosity, Format, ...) \
303 { \
304 static_assert(std::is_const_v<std::remove_reference_t<decltype(Format)>>, "Formatting string must be a const TCHAR array."); \
305 static_assert(TIsArrayOrRefOfTypeByPredicate<decltype(Format), TIsCharEncodingCompatibleWithTCHAR>::Value, "Formatting string must be a TCHAR array."); \
306 UE_VALIDATE_FORMAT_STRING(Format, ##__VA_ARGS__); \
307 UE_IF(LOGTRACE_ENABLED, static ::UE::Logging::Private::FStaticBasicLogDynamicData LOG_Dynamic, ); \
308 UE_IF(UE_PRIVATE_LOG_USE_STATIC_RECORD, static,) constexpr ::UE::Logging::Private::FStaticBasicLogRecord LOG_Static(Format, __builtin_FILE(), __builtin_LINE(), UE_IF(LOGTRACE_ENABLED, &LOG_Dynamic, nullptr)); \
309 static_assert((::ELogVerbosity::Verbosity & ::ELogVerbosity::VerbosityMask) < ::ELogVerbosity::NumVerbosity && ::ELogVerbosity::Verbosity > 0, "Verbosity must be constant and in range."); \
310 if constexpr ((::ELogVerbosity::Verbosity & ELogVerbosity::VerbosityMask) == ::ELogVerbosity::Fatal) \
311 { \
312 Condition \
313 { \
314 ::UE::Logging::Private::BasicFatalLog(LOG_Static, &Category, ##__VA_ARGS__); \
315 CA_ASSUME(false); \
316 } \
317 } \
318 else if constexpr ((::ELogVerbosity::Verbosity & ::ELogVerbosity::VerbosityMask) <= ::ELogVerbosity::COMPILED_IN_MINIMUM_VERBOSITY) \
319 { \
320 if CategoryConst ((::ELogVerbosity::Verbosity & ::ELogVerbosity::VerbosityMask) <= Category.GetCompileTimeVerbosity()) \
321 { \
322 if (!Category.IsSuppressed(::ELogVerbosity::Verbosity)) \
323 { \
324 Condition \
325 { \
326 ::UE::Logging::Private::BasicLog<::ELogVerbosity::Verbosity>(LOG_Static, &Category, ##__VA_ARGS__); \
327 } \
328 } \
329 } \
330 } \
331 }
332
341 #define UE_SUPPRESS(CategoryName, Verbosity, ExecuteIfUnsuppressed) \
342 { \
343 static_assert((ELogVerbosity::Verbosity & ELogVerbosity::VerbosityMask) < ELogVerbosity::NumVerbosity && ELogVerbosity::Verbosity > 0, "Verbosity must be constant and in range."); \
344 CA_CONSTANT_IF((ELogVerbosity::Verbosity & ELogVerbosity::VerbosityMask) <= ELogVerbosity::COMPILED_IN_MINIMUM_VERBOSITY && (ELogVerbosity::Verbosity & ELogVerbosity::VerbosityMask) <= FLogCategory##CategoryName::CompileTimeVerbosity) \
345 { \
346 if (!CategoryName.IsSuppressed(ELogVerbosity::Verbosity)) \
347 { \
348 FScopedCategoryAndVerbosityOverride TEMP__##CategoryName(CategoryName.GetCategoryName(), ELogVerbosity::Type(ELogVerbosity::Verbosity & ELogVerbosity::VerbosityMask)); \
349 ExecuteIfUnsuppressed; \
350 CategoryName.PostTrigger(ELogVerbosity::Verbosity); \
351 } \
352 } \
353 }
354
361 #define DECLARE_LOG_CATEGORY_EXTERN(CategoryName, DefaultVerbosity, CompileTimeVerbosity) \
362 extern struct FLogCategory##CategoryName : public FLogCategory<ELogVerbosity::DefaultVerbosity, ELogVerbosity::CompileTimeVerbosity> \
363 { \
364 UE_FORCEINLINE_HINT FLogCategory##CategoryName() : FLogCategory(TEXT(#CategoryName)) {} \
365 } CategoryName;
366
371 #define DEFINE_LOG_CATEGORY(CategoryName) FLogCategory##CategoryName CategoryName;
372
379 //-V:DEFINE_LOG_CATEGORY_STATIC:501
380 #define DEFINE_LOG_CATEGORY_STATIC(CategoryName, DefaultVerbosity, CompileTimeVerbosity) \
381 static struct FLogCategory##CategoryName : public FLogCategory<ELogVerbosity::DefaultVerbosity, ELogVerbosity::CompileTimeVerbosity> \
382 { \
383 static_assert(ELogVerbosity::DefaultVerbosity <= ELogVerbosity::CompileTimeVerbosity, "Default verbosity of log category cannot be higher than its compile time verbosity"); \
384 UE_FORCEINLINE_HINT FLogCategory##CategoryName() : FLogCategory(TEXT(#CategoryName)) {} \
385 } CategoryName;
386
393 //-V:DECLARE_LOG_CATEGORY_CLASS:501
394 #define DECLARE_LOG_CATEGORY_CLASS(CategoryName, DefaultVerbosity, CompileTimeVerbosity) \
395 DEFINE_LOG_CATEGORY_STATIC(CategoryName, DefaultVerbosity, CompileTimeVerbosity)
396
401 #define DEFINE_LOG_CATEGORY_CLASS(Class, CategoryName) Class::FLogCategory##CategoryName Class::CategoryName;
402
403#endif // NO_LOGGING
404
405#if UE_BUILD_SHIPPING
406#define NOTIFY_CLIENT_OF_SECURITY_EVENT_IF_NOT_SHIPPING(NetConnection, SecurityPrint) ;
407#else
408#define NOTIFY_CLIENT_OF_SECURITY_EVENT_IF_NOT_SHIPPING(NetConnection, SecurityPrint) \
409 FNetControlMessage<NMT_SecurityViolation>::Send(NetConnection, SecurityPrint); \
410 NetConnection->FlushNet(true)
411#endif
412
414
415// Macro to either log an error or ensure on a NaN error.
416#if DO_CHECK && !USING_CODE_ANALYSIS
417namespace UEAsserts_Private
418{
419 CORE_API void VARARGS InternalLogNANDiagnosticMessage(const TCHAR* FormattedMsg, ...); // UE_LOG(LogCore, Error, _FormatString_, ##__VA_ARGS__);
420}
421#define logOrEnsureNanError(_FormatString_, ...) \
422 if (!GEnsureOnNANDiagnostic)\
423 {\
424 static bool OnceOnly = false;\
425 if (!OnceOnly)\
426 {\
427 UEAsserts_Private::InternalLogNANDiagnosticMessage(_FormatString_, ##__VA_ARGS__); \
428 OnceOnly = true;\
429 }\
430 }\
431 else\
432 {\
433 ensureMsgf(!GEnsureOnNANDiagnostic, _FormatString_, ##__VA_ARGS__); \
434 }
435#else
436#define logOrEnsureNanError(_FormatString_, ...)
437#endif // DO_CHECK
constexpr EUpdateTransformFlags operator&(EUpdateTransformFlags Left, EUpdateTransformFlags Right)
Definition ActorComponent.h:111
#define VARARGS
Definition AndroidPlatform.h:134
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
FPlatformTypes::ANSICHAR ANSICHAR
An ANSI character. Normally a signed type.
Definition Platform.h:1131
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define UE_LOG_INCLUDE_SOURCE_LOCATION
Definition LogMacros.h:24
CORE_API int32 GEnsureOnNANDiagnostic
Definition CoreMisc.cpp:503
#define UE_IF(OneOrZero, Token1, Token0)
Definition PreprocessorHelpers.h:18
Definition NameTypes.h:617
Type
Definition LogVerbosity.h:17
@ VerbosityMask
Definition LogVerbosity.h:58
Definition LogMacros.h:234
UE_FORCEINLINE_HINT bool IsLogActive(const CategoryType &Category)
Definition LogMacros.h:236
Definition StructuredLog.cpp:48
Definition LogCategory.h:21
Definition LogMacros.h:44
static CORE_API void LogV(const ANSICHAR *File, int32 Line, const FLogCategoryName &Category, ELogVerbosity::Type Verbosity, const TCHAR *Fmt, va_list Args)
Definition LogMacros.cpp:67
static void Logf(const ANSICHAR *File, int32 Line, const FLogCategoryName &Category, ELogVerbosity::Type Verbosity, const FmtType &Fmt, Types... Args)
Definition LogMacros.h:60
static CORE_API void SendNotificationString(const TCHAR *Message)
Definition LogMacros.cpp:132
static void SendNotificationStringf(const FmtType &Fmt, Types... Args)
Definition LogMacros.h:50
static void Logf_Internal(const ANSICHAR *File, int32 Line, const FLogCategoryName &Category, ELogVerbosity::Type Verbosity, const FmtType &Fmt, Types... Args)
Definition LogMacros.h:70
Definition IsArrayOrRefOfTypeByPredicate.h:13
Definition IsValidVariadicFunctionArg.h:14