Logging in UE4

April 5, 2020, noon

How to log in Unreal Engine 4.


Macros that I use for logging/printing.

Use them via PRINT("MyStringToPrint"); or LOG("MyStringToLog"); or LOG("MyStringToLog %f", 3.0f); etc.

#if 1
#include "Engine/Engine.h"
#include "DrawDebugHelpers.h"

#define GETSTR(text, ...) *FString::Printf(TEXT(text), ##__VA_ARGS__)

#define PRINT(color, text, ...) if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 10.f, color, CUR_CLASS_LINE + ": " + GETSTR(text, ##__VA_ARGS__))
#define PRINT_S(text, ...) if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Yellow, CUR_CLASS_LINE + ": [SUCCESS] " + GETSTR(text, ##__VA_ARGS__))
#define PRINT_E(text, ...) if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, CUR_CLASS_LINE + ": [ERROR] " + GETSTR(text, ##__VA_ARGS__))
#define PRINT_W(text, ...) if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Orange, CUR_CLASS_LINE + ": [WARNING] " + GETSTR(text, ##__VA_ARGS__))
#define LOG(text, ...) UE_LOG(LogTemp, Log, TEXT("%s: %s"), *CUR_CLASS, GETSTR(text, ##__VA_ARGS__))
#define LOG_S(text, ...) UE_LOG(LogTemp, Log, TEXT("%s: [SUCCESS] %s"), *CUR_CLASS, GETSTR(text, ##__VA_ARGS__))
#define LOG_W(text, ...) UE_LOG(LogTemp, Warning, TEXT("%s: [WARNING] %s"), *CUR_CLASS, GETSTR(text, ##__VA_ARGS__))
#define LOG_E(text, ...) UE_LOG(LogTemp, Error, TEXT("%s: [ERROR] %s"), *CUR_CLASS, GETSTR(text, ##__VA_ARGS__))
#define LOG_D(text, ...) UE_LOG(LogTemp, Display, TEXT("%s: [WARNING] %s"), *CUR_CLASS, GETSTR(text, ##__VA_ARGS__))

#define PRINT_LOG(color, text, ...) PRINT(color, text, ##__VA_ARGS__); LOG(text, ##__VA_ARGS__);
#define PRINT_LOG_S(text, ...) PRINT_S(text, ##__VA_ARGS__); LOG_S(text, ##__VA_ARGS__);
#define PRINT_LOG_W(text, ...) PRINT_W(text, ##__VA_ARGS__); LOG_W(text, ##__VA_ARGS__);
#define PRINT_LOG_E(text, ...) PRINT_E(text, ##__VA_ARGS__); LOG_E(text, ##__VA_ARGS__);

/** Current Class Name + Function Name where this is called! */
#define CUR_CLASS_FUNC (FString(__FUNCTION__))

/** Current Class where this is called! */
#define CUR_CLASS (FString(__FUNCTION__).Left(FString(__FUNCTION__).Find(TEXT(":"))) )

/** Current Function Name where this is called! */
#define CUR_FUNC (FString(__FUNCTION__).Right(FString(__FUNCTION__).Len() - FString(__FUNCTION__).Find(TEXT("::")) - 2 ))

/** Current Line Number in the code where this is called! */
#define CUR_LINE  (FString::FromInt(__LINE__))

/** Current Class and Line Number where this is called! */
#define CUR_CLASS_LINE (CUR_CLASS + "(" + CUR_LINE + ")")

/** Current Function Signature where this is called! */
#define CUR_FUNCSIG (FString(__FUNCSIG__))
#else
#define PRINT(color, text)
#define PRINT_S(text)
#define PRINT_E(text)
#define LOG(text, ...)
#define LOG_S(text, ...)
#define LOG_W(text, ...)
#define LOG_E(text, ...)
#define LOG_D(text, ...)
#define PRINT_LOG_S(text)
#define PRINT_LOG_W(text)
#define PRINT_LOG_E(text)
#endif

UE_LOG

Custom categories

You can change the log category (LogTemp) to your own by defining your category like so.

MyGame.H

//General Log
DECLARE_LOG_CATEGORY_EXTERN(LogMyGame, Log, All);
//Logging during game startup
DECLARE_LOG_CATEGORY_EXTERN(LogMyGameInit, Log, All);
//Logging for your AI system
DECLARE_LOG_CATEGORY_EXTERN(LogMyGameAI, Log, All);
//Logging for a that troublesome system
DECLARE_LOG_CATEGORY_EXTERN(LogMyGameSomeSystem, Log, All);
//Logging for Critical Errors that must always be addressed
DECLARE_LOG_CATEGORY_EXTERN(LogMyGameCriticalErrors, Log, All);

MyGame.CPP

#include "MyGame.h"

//General Log
DEFINE_LOG_CATEGORY(LogMyGame);
//Logging during game startup
DEFINE_LOG_CATEGORY(LogMyGameInit);
//Logging for your AI system
DEFINE_LOG_CATEGORY(LogMyGameAI);
//Logging for some system
DEFINE_LOG_CATEGORY(LogMyGameSomeSystem);
//Logging for Critical Errors that must always be addressed
DEFINE_LOG_CATEGORY(LogMyGameCriticalErrors);

So then after you have your own category you'd use it like UE_LOG(LogMyGame, Log, TEXT("Your message"));.

Verbosity

UE_LOG(LogTemp, Warning, TEXT("Your message"));

You can change the Warning to be one of the following.

  • Fatal - Fatal level logs are always printed to console and log files and crashes even if logging is disabled.
  • Error - Error level logs are printed to console and log files. These appear red by default.
  • Warning - Warning level logs are printed to console and log files. These appear yellow by default.
  • Display - Display level logs are printed to console and log files.
  • Log - Log level logs are printed to log files but not to the in-game console. They can still be viewed in the editor as they appear via the Output Log window.
  • Verbose - Verbose level logs are printed to log files but not the in-game console. This is usually used for detailed logging and debugging.
  • VeryVerbose - VeryVerbose level logs are printed to log files but not the in-game console. This is usually used for very detailed logging that would otherwise spam output.

Formatting

  • FString - UE_LOG(YourLog,Warning,TEXT("MyCharacter's Name is %s"), *MyCharacter->GetName() );
  • bool - UE_LOG(YourLog,Warning,TEXT("MyCharacter's Bool is %s"), (MyCharacter->MyBool ? TEXT("True") : TEXT("False")));
  • int - UE_LOG(YourLog,Warning,TEXT("MyCharacter's Health is %d"), MyCharacter->Health);
  • float - UE_LOG(YourLog,Warning,TEXT("MyCharacter's Health is %f"), MyCharacter->Health);
  • FVector - UE_LOG(YourLog,Warning,TEXT("MyCharacter's Location is %s"), *MyCharacter->GetActorLocation().ToString());
  • FName - UE_LOG(YourLog,Warning,TEXT("MyCharacter's FName is %s"), *MyCharacter->GetFName().ToString());
  • FString, int, and float - UE_LOG(YourLog,Warning,TEXT("%s has health %d, which is %f percent of total health"), *MyCharacter->GetName(), MyCharacter->Health, MyCharacter->HealthPercent);

 

GEngine->AddOnScreenDebugMessage works very similar to UE_LOG so no need to add info for it.

Most of this was written by Rama (from the UE4 wiki that was closed down).

 

until next time