Logging

The platform provides logging for both backtesting and live trading using a high-performance logger implemented in Rust. The logger operates in a separate thread and uses a multi-producer single consumer (MPSC) channel to receive log messages. This design ensures that the main thread is not blocked by log string formatting or file I/O operations.

Note

The latest stable Rust MPSC channel is used, which is now based on the crossbeam implementation.

There are two configurable writers for logging:

  • stdout/stderr writer

  • log file writer

Infrastructure such as vector can be configured to collect these log events.

Configuration

Logging can be configured by importing the LoggingConfig object. By default, log events with an ‘INFO’ LogLevel and higher are written to stdout/stderr.

Log level ( LogLevel ) values include:

  • ‘DEBUG’ or ‘DBG’

  • ‘INFO’ or ‘INF’

  • ‘WARNING’ or ‘WRN’

  • ‘ERROR’ or ‘ERR’

Tip

See the LoggingConfig API Reference for further details.

Logging can be configured in the following ways:

  • Minimum LogLevel for stdout/stderr

  • Minimum LogLevel for log files

  • Automatic log file naming and daily rotation, or custom log file name

  • Plain text or JSON log file formatting

  • Bypass logging completely

Standard output logging

Log messages are written to the console via stdout/stderr writers. The minimum log level can be configured using the log_level parameter.

File logging

Log files are written to the current working directory with daily rotation (UTC) by default.

The default naming convention is as follows:

  • Trader ID

  • ISO 8601 datetime

  • Instance ID

  • The log format suffix

{trader_id}_{%Y-%m-%d}_{instance_id}.{log | json}`

e.g. TESTER-001_2023-03-23_635a4539-4fe2-4cb1-9be3-3079ba8d879e.json

You can specify a custom log directory path using the log_directory parameter and/or a custom log file basename using the log_file_name parameter. The log files will always be suffixed with ‘.log’ for plain text, or ‘.json’ for JSON (no need to include a suffix in file names).

If the log file already exists, it will be appended to.

Component filtering

The log_component_levels parameter can be used to set log levels for each component individually. The input value should be a dictionary of component ID strings to log level strings: dict[str, str] .

Below is an example of a trading node logging configuration that includes some of the options mentioned above:

config_node = TradingNodeConfig(
    trader_id="TESTER-001",
    logging=LoggingConfig(
        log_level="INFO",
        log_level_file="DEBUG",
        log_file_format="json",
        log_component_levels={ "Portfolio": "INFO" },
    ),
    ... # Omitted
)

For backtesting, the BacktestEngineConfig class can be used instead of TradingNodeConfig , as the same options are available.