UE_LOG with format as variable

All I want to do is pass a variable into the 3rd parameter of UE_LOG. No matter what I do, whether I pass an FString, const char*, or even a TCHAR*, it still complains.


UE_LOG(LogTemp, Warning, ???, FString(TEXT("text here")));

2 Likes

Logging | UE4 Community Wiki

1 Like

If you read the documentation yourself, you’d see that it doesn’t answer my question.

1 Like

My macro skills are weak. Passing a macro into a macro where the TEXT macro is putting an L in front of the “xxx” to make a unicode TCHAR array.


 /**
* A macro that outputs a formatted message to log if a given logging category is active at a given verbosity level
* @param CategoryName name of the logging category
* @param Verbosity, verbosity level to test against
* @param Format, format text
***/
#define UE_LOG(CategoryName, Verbosity, Format, ...) \
{ \
static_assert(TIsArrayOrRefOfType<decltype(Format), TCHAR>::Value, "Formatting string must be a TCHAR array."); \
static_assert((ELogVerbosity::Verbosity & ELogVerbosity::VerbosityMask) < ELogVerbosity::NumVerbosity && ELogVerbosity::Verbosity > 0, "Verbosity must be constant and in range."); \
CA_CONSTANT_IF((ELogVerbosity::Verbosity & ELogVerbosity::VerbosityMask) <= ELogVerbosity::COMPILED_IN_MINIMUM_VERBOSITY && (ELogVerbosity::Warning & ELogVerbosity::VerbosityMask) <= FLogCategory##CategoryName::CompileTimeVerbosity) \
{ \
UE_LOG_EXPAND_IS_FATAL(Verbosity, PREPROCESSOR_NOTHING, if (!CategoryName.IsSuppressed(ELogVerbosity::Verbosity))) \
{ \
auto UE_LOG_noinline_lambda = ](const auto& LCategoryName, const auto& LFormat, const auto&... UE_LOG_Args) FORCENOINLINE \
{ \
TRACE_LOG_MESSAGE(LCategoryName, Verbosity, LFormat, UE_LOG_Args...) \
UE_LOG_EXPAND_IS_FATAL(Verbosity, \
{ \
FMsg::Logf_Internal(UE_LOG_SOURCE_FILE(__FILE__), __LINE__, LCategoryName.GetCategoryName(), ELogVerbosity::Verbosity, LFormat, UE_LOG_Args...); \
_DebugBreakAndPromptForRemote(); \
FDebug::ProcessFatalError(); \
}, \
{ \
FMsg::Logf_Internal(nullptr, 0, LCategoryName.GetCategoryName(), ELogVerbosity::Verbosity, LFormat, UE_LOG_Args...); \
} \
) \
}; \
UE_LOG_noinline_lambda(CategoryName, Format, ##__VA_ARGS__); \
UE_LOG_EXPAND_IS_FATAL(Verbosity, CA_ASSUME(false);, PREPROCESSOR_NOTHING) \
} \
} \
}

We use the following. The project is called “Sandbox”.

Put this in your ProjectName.h file:



// custom log category
DECLARE_LOG_CATEGORY_EXTERN(Sandbox, Log, All);

// custom log macro
#define LOG(x, ...) UE_LOG(Sandbox, Log, TEXT(x), __VA_ARGS__)
#define LOG_WARNING(x, ...) UE_LOG(Sandbox, Warning, TEXT(x), __VA_ARGS__)
#define LOG_ERROR(x, ...) UE_LOG(Sandbox, Error, TEXT(x), __VA_ARGS__)


Put this in your ProjectName.cpp file:



// custom log category
DEFINE_LOG_CATEGORY(Sandbox);


Now you can log like this anywhere you include “ProjectName.h”:



// simple text
LOG("Some stuff to put in the log");

// errors and warnings
LOG_WARNING("something bad happened!");
LOG_ERROR("something really bad happened!");

// log an fstring
LOG("AGameMode::ProcessLoadMapRequest(): %s", *requestedMapName);

// log int
LOG("AGameMode:: player %i has logged out!", playerId);

// log bool
bool myBool = false;
LOG("T or F? %s", *FString(myBool ? "True" : "False"));

// log multiple fstrings
FString cameraPos = cameraViewInfo.Location.ToString();
FString boomPos = _cameraBoom->GetComponentLocation().ToString();
LOG("AInteractiveCamera:: Camera:%s Boom:%s", *cameraPos, *boomPos);


This is about the simplest logging I’ve seen. If anyone knows of anything even more convenient please let us know. :wink:

9 Likes

this makes life easy, thank you very much for this

2 Likes

:saluting_face: If someone get compile syntax error.
Use ##VA_ARGS instead of VA_ARGS in UE5

#define LOG(x, ...) UE_LOG(RTSGame, Log, TEXT(x), ##__VA_ARGS__)
#define LOG_WARNING(x, ...) UE_LOG(RTSGame, Warning, TEXT(x), ##__VA_ARGS__)
#define LOG_ERROR(x, ...) UE_LOG(RTSGame, Error, TEXT(x), ##__VA_ARGS__)
2 Likes

Hmm, just checked our UE5 code.

Looks like this “YourGame.h” file:

/**
* Custom log category.
* DECLARE_LOG_CATEGORY_EXTERN() in .h file.
* DEFINE_LOG_CATEGORY() in .cpp file.
*/
DECLARE_LOG_CATEGORY_EXTERN(MBT, Log, Log);

/**
* Custom logging macros.
*/
#define LOG(x, ...)         UE_LOG(MBT, Log, TEXT(x), __VA_ARGS__)
#define LOG_FINE(x, ...)    UE_LOG(MBT, Verbose, TEXT(x), __VA_ARGS__)
#define LOG_FINER(x, ...)   UE_LOG(MBT, VeryVerbose, TEXT(x), __VA_ARGS__)
#define LOG_WARNING(x, ...) UE_LOG(MBT, Warning, TEXT(x), __VA_ARGS__)
#define LOG_ERROR(x, ...)   UE_LOG(MBT, Error, TEXT(x), __VA_ARGS__)

And like this in “YourGame.cpp” file:

/**
* Custom log category.
* DECLARE_LOG_CATEGORY_EXTERN() in .h file.
* DEFINE_LOG_CATEGORY() in .cpp file.
*/
DEFINE_LOG_CATEGORY(MBT);

No pound signs needed that I am aware of? Is that a compiler other than Visual Studio? Or maybe not in Windows?

1 Like

I compiled this on Windows with VS2022, probably because I’m using the engine source code version of UE5.31. The code for UE_LOG also utilizes ##VA_ARGS.

1 Like