# Logging System of Diarkis Module

## Overview

This page explains the logging system of the Diarkis Module.

The Diarkis Module outputs logs from the Diarkis runtime library as well as from its own operations. The output logs can be checked in various ways such as via standard output and file output. If the system does not operate as expected or if you need to verify the running state of the Diarkis runtime, it is recommended to first check the contents of the log file.

## Logging System Configuration

Settings for the Diarkis Module's logging system are controlled via arguments passed to `DiarkisInterfaceBase::DiarkisInit()`. You can configure the log directory name, output methods, whether or not to output logs, etc.

## Log Output Methods of Diarkis Module

The Diarkis Module supports the following output methods:

| enum                      | Description                                                                                                  |
| ------------------------- | ------------------------------------------------------------------------------------------------------------ |
| DEBUG\_OUT                | Outputs logs to the debugger if possible; if not, logs are output to standard output                         |
| FILE\_OUT                 | Outputs logs to a file, specifically named `diarkis-log.log` at the path obtained by `GetLogDirectoryPath()` |
| FILE\_OUT\_SPECIFIC\_PATH | Outputs log files to a specified path                                                                        |
| CONSOLE\_OUT              | Outputs logs to standard output                                                                              |
| DEBUG\_AND\_FILE\_OUT     | Combines the behavior of DEBUG\_OUT and FILE\_OUT                                                            |
| CUSTOM                    | Outputs logs to a user-defined custom logger                                                                 |

## Log Output Levels

The logging system of the Diarkis Module allows for adjustment of the detail level of log outputs. The default log output level is specified in the constructor of `LoggerFactory`, implemented in `diarkis-module\Client\Private\logging\LoggerFactory.cpp`. This default can be changed, and it is also possible to dynamically alter it during application execution using `LoggerFactory::SetSeverity()`.

The log output levels are as follows. The settings lower in the list provide more detailed logs. Higher detailed log levels always include lower levels. Note that using Verbose or Trace may impact the runtime speed of Diarkis or result in large log files, so caution is advised.

| enum    | Description                                                                                 |
| ------- | ------------------------------------------------------------------------------------------- |
| None    | Does not output logs                                                                        |
| Fatal   | Outputs logs for fatal errors                                                               |
| Error   | Outputs logs including general errors                                                       |
| Warning | Outputs logs including warnings                                                             |
| Info    | Outputs logs with additional information                                                    |
| Debug   | Outputs logs with debugging information                                                     |
| Verbose | Outputs logs with detailed debugging information                                            |
| Trace   | Outputs logs as detailed as possible regarding runtime operations and payload transmissions |

## Log Content Checkable by Category

The client library's logging system allows for changes to the log level for each category. Adjust the log level of the necessary category according to the information you wish to verify during debugging.

<table><thead><tr><th width="233">Representative Categories</th><th>Contents Verifiable During Debugging</th></tr></thead><tbody><tr><td>UDP</td><td>Verification of Connect, Disconnect with the UDP server. When unintended disconnection occurs or to check ack, eack during packet loss</td></tr><tr><td>RUDP</td><td>When packet loss occurs, to check the process status of RUDP packets and sequence numbers</td></tr><tr><td>Socket</td><td>To verify socket-related processes when an unintended disconnection happens</td></tr><tr><td>P2P</td><td>To check for any unintended issues during P2P communications such as hole punching or packet transmissions</td></tr><tr><td>Runtime</td><td>To verify when notifications or responses from the server do not arrive during the application implementation</td></tr><tr><td>Room and each Module Category</td><td>To verify packet transmissions and unreceived notifications or responses from the server during the implementation of each module</td></tr></tbody></table>

## Implementing a Custom Logger

Using a custom logger allows the user to freely customize the logger's functionality.\
By inheriting from `ILoggerBackend` and overriding `ILoggerBackend::Log()`, you can handle the log output process of the Diarkis runtime and the Diarkis Module.\
Below is a sample implementation.

```
// Sample implementation for application-specific custom log output
class AppCustomLoggerBackend : public ILoggerBackend
{
    public:
        AppCustomLoggerBackend() {}
        virtual ~AppCustomLoggerBackend() {}

        virtual Result Log(const Diarkis::StdString& message, bool includeNewLine) override
        {
            // Log text is passed as message, allowing for application-specific log output
            // Exclusive control is performed so there is no issue with calls from multiple threads
            DiarkisUtils::Print("%s", message.c_str());
            return Diarkis::Results::SUCCESS;
        }
};

...
// Pseudo code specifying a custom logger during initialization
AppCustomLoggerBackend customLogger;

DiarkisInterface::DiarkisInit(uid, LogOutType::CUSTOM, bOutLog, &customLogger);
```
