Skip to content

Logging

Shmellyorc edited this page Aug 27, 2026 · 1 revision

Logging

Void's logging system provides asynchronous, thread-safe logging with multiple output destinations. It runs on a background thread so logging never blocks your game loop.

Basic Usage

Get the logger instance and start logging:

var logger = Logger.Instance;

logger.Info("Game started");
logger.Warning("Low memory warning");
logger.Error("Failed to load texture", exception);

Log Levels

  • Debug: Development and troubleshooting messages
  • Info: Normal application operation
  • Warning: Potentially problematic situations
  • Error: Recoverable failures
  • Fatal: Unrecoverable failures that may cause termination

Messages below the minimum level are discarded. Set the minimum level:

logger.SetLevel(LogLevel.Info);  // Debug messages will be ignored

Categories

Categories help organize logs by subsystem. Use the WithCategory methods:

logger.InfoWithCategory("Network", "Connected to server");
logger.WarningWithCategory("Audio", "Failed to load sound");
logger.ErrorWithCategory("Graphics", exception, "Shader compilation failed");

Sinks

Sinks are destinations where log messages are written. Console and File sinks are automatically added at startup based on your GameSettings. You don't need to add them manually.

To add additional custom sinks:

Logger.Instance.AddSink(new DatabaseSink());

Console Sink Writes color-coded output to the console. Added automatically based on your settings.

File Sink Writes to daily rotating files with size-based rollover. Added automatically based on your settings.

The FileSink creates daily files in the specified folder. When a file exceeds the maximum size, a new file is created for the same day. Old files are automatically cleaned up.

Automatic Sinks

The engine automatically adds ConsoleSink and FileSink when the game starts.

ConsoleSink is always added. It writes color-coded output to the console window.

FileSink is added if the application path is valid. Logs are written to:

  • Windows: %APPDATA%/Company/Game/Logs/
  • macOS: ~/Library/Application Support/Company/Game/Logs/
  • Linux: ~/.config/Company/Game/Logs/

If you're not using application data, logs are written to a Logs folder in your game's root directory.

Both sinks are configured through GameSettings:

  • SetLogMinLevel: Controls the minimum log level for both sinks
  • SetLogMaxFileSizeMB: Controls the maximum size of each log file
  • SetLogMaxFiles: Controls how many log files to keep

Performance

The logging system is designed for high performance:

  • Asynchronous processing: Messages are queued and written on a background thread
  • Batch processing: Messages are processed in batches of 100 for efficiency
  • Queue limit: Maximum of 10,000 messages to prevent unbounded memory growth
  • Discard threshold: Messages below the minimum level are discarded immediately
  • Non-blocking: Logging calls return immediately without waiting for disk I/O

Flushing Fatal messages automatically flush the queue to ensure critical errors are written immediately. You can also manually flush:

Logger.Instance.Flush();

Custom Sinks

Create custom sinks by implementing ILogSink:

public class DatabaseSink : ILogSink
{
    public void Write(LogEntry entry)
    {
        // Send log entry to a database
        var json = JsonSerializer.Serialize(entry);
        // ... send to database
    }
}

Add it to the logger:

Logger.Instance.AddSink(new DatabaseSink());

GameSettings

Configure logging through GameSettings:

GameSettings.Instance
    .SetLogMinLevel(LogLevel.Info)
    .SetLogMaxFileSizeMB(10)
    .SetLogMaxFiles(10);

The minimum log level filters messages below the specified level. The maximum file size and file count control the FileSink's behavior.

Example: Complete Setup

var settings = GameSettings.Instance
    .SetAppCompany("MyStudio")
    .SetAppName("MyGame")
    .SetLogMinLevel(LogLevel.Info)
    .SetLogMaxFileSizeMB(5)
    .SetLogMaxFiles(20)
    .Build();

// Add custom sinks if needed
Logger.Instance.AddSink(new DatabaseSink());

// Start logging
Logger.Instance.Info("Game initialized successfully");

Back to Home

Clone this wiki locally