# Crear categorías de log para nuestros sistemas en Unreal Engine

En muchos libros y tutoriales sobre C++ en Unreal Engine se pueden ver ejemplos dónde se usa `UE_LOG` para mostrar mensajes que nos ayudan a depurar nuestro código y detectar problemas:

```cpp
UE_LOG(LogTemp, Warning, TEXT("Hello, I'm here"));
```

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">La macro <code>UE_LOG</code> no es la única manera de mostrar mensajes. En Unreal Engine 5.2 se añadió <code>UE_LOGFMT</code>, que ofrece <a target="_self" rel="noopener noreferrer nofollow" href="https://dev.epicgames.com/documentation/en-us/unreal-engine/logging-in-unreal-engine#ue-logfmt" style="pointer-events: none">una interfaz más cómoda</a>. Y también esta <a target="_self" rel="noopener noreferrer nofollow" href="https://dev.epicgames.com/documentation/en-us/unreal-engine/fstring-in-unreal-engine#printtoviewport" style="pointer-events: none">AddOnScreenDebugMessages()</a></div>
</div>

Imprimir mensajes de con `UE_LOG` en la categoría `LogTemp` es una buena opción durante la depuración de problemas.

Sin embargo, podemos querer dejar de forma permanente algunos de estos mensajes para que se emitan en condiciones que podrían ser problemáticas. En ese caso, usar `LogTemp` como categoría de los mensajes no es buena idea, porque se hace complicado determinar en qué sistema o componente está el problema. En su lugar, es preferible que definamos nuestras propias categorías, de forma que así sea más sencillo localizar los mensajes de un componente e identificar rápidamente el origen del problema.

En Unreal Engine, para definir una categoría de *log* necesitamos un archivo `.h` donde declaramos las nuevas categorías y un archivo `.cpp` donde las definimos. Por ejemplo: `LogCategories.h` y `LogCtegories.cpp`.

En la declaración de las nuevas categorías en el archivo `.h` usamos la macro `DECLARE_LOG_CATEGORY_EXTERN` así:

```cpp
// LogCategories.h

DECLARE_LOG_CATEGORY_EXTERN(LogInventorySystem, Log, All);
DECLARE_LOG_CATEGORY_EXTERN(LogMyAnimSystem, Log, All);
//...
```

De tal forma que:

* `LogInventorySystem` es el nombre de la nueva categoría de *logs*.
    
* `Log` indica el nivel de verbosidad utilizado por defecto. Será el nivel usado si no se indica ninguno a usar `UE_LOG`. Los valores admitidos son: `Fatal`, `Error`, `Warning`, `Display`, `Log`, `Verbose` y `VeryVerbose`.
    
* El tercer argumento indica el nivel de verbosidad más alto que será incluido al compilar el proyecto. Sí, por ejemplo, se indica `All`, se incluyen todos los niveles, pero si se indica `Warning`, no es posible ver mensajes en los niveles de verbosidad `Display`, `Log`, `Verbose` o `VeryVerbose`. Por tanto, este argumento ofrece una forma sencilla de suprimir todos los mensajes a partir de cierto nivel de verbosidad en la categoría indicada.
    

Luego, en la definición en el archivo `.cpp` usamos la macro `DEFINE_LOG_CATEGORY` indicando solo el nombre de la nueva categoría:

```cpp
// LogCategories.cpp

DEFINE_CATEGORY_EXTERN(LogInventorySystem);
DEFINE_CATEGORY_EXTERN(LogMyAnimSystem);
//...
```

Finalmente, podemos incluir `LogCategories.h` en aquellos archivos donde queramos usar una de estas categorías y utilizarla con `UE_LOG` con normalidad:

```cpp
#include "LogCategories.h"

UE_LOG(LogInventorySystem, Warning, TEXT("Inventory component not found"));
UE_LOG(LogInventorySystem, Log, TEXT("%d items added"), NumOfItems);
```

O con la nueva macro `UE_LOGFMT`:

```cpp
#include "LogCategories.h"

UE_LOGFMT(LogInventorySystem, Warning, "Inventory component not found: {0}", GetName());
UE_LOGFMT(LogInventorySystem, Log, "{Count} items added: {OwnerName}",
    ("Count", NumOfItems), ("OwnerName", GetOwner()->GetName()));
```

# Referencias adicionales

* [Unreal Engine 5.5 Documentation — Logging in Unreal](https://dev.epicgames.com/documentation/en-us/unreal-engine/logging-in-unreal-engine)
    
* [Epic Development Community — Snippets — Print to screen in C++](https://dev.epicgames.com/community/snippets/Vm9/unreal-engine-print-to-screen-in-c)
