How to Configure the Logging System for Production Deployments of TradingAgents-CN

Enable the [logging.production] block in config/logging.toml, set environment variables like TRADINGAGENTS_LOG_LEVEL, and call init_logging() at application startup to activate structured JSON logging for production monitoring.

TradingAgents-CN provides a hierarchical logging framework built on Python’s standard logging module, designed specifically for high-throughput trading environments. Configuring this system correctly for production ensures you capture audit trails, error alerts, and structured telemetry without impacting performance.

Understanding the TradingAgents-CN Logging Architecture

The logging system centers on two core modules in the tradingagents/utils/ directory:

  • logging_manager.py – Defines the TradingAgentsLogger class, StructuredFormatter, and handler factories. The _load_default_config() method parses TOML settings at line 334, while _setup_logging() (lines 886-907) constructs the handler hierarchy.
  • logging_init.py – Provides bootstrap helpers including init_logging() and get_session_logger() for request-scoped tracking.

Runtime configuration flows from config/logging.toml (or config/logging_docker.toml for containers) and environment variables such as DOCKER_CONTAINER, TRADINGAGENTS_LOG_LEVEL, and TRADINGAGENTS_LOG_DIR.

Step 1: Enable the Production Configuration Block

Edit config/logging.toml and activate the production-specific settings:

[logging.production]
enabled = true                # Activates production mode

structured_only = true        # Emits only JSON-structured logs

error_notification = true     # Hooks for alerting on severe errors

max_log_size = "100MB"        # Larger rotation for long-running services

When production.enabled is true, TradingAgentsLogger._load_default_config() (line 334 in logging_manager.py) respects the structured_only flag and attaches only the structured JSON handler to the root logger, suppressing human-readable console output unsuitable for log aggregators.

Step 2: Configure Production Handlers

Define handlers under [logging.handlers.*] to capture different log streams:

File Handler for Audit Trails

[logging.handlers.file]
enabled = true
level = "INFO"
max_size = "100MB"
backup_count = 10
directory = "/app/logs"
filename = "tradingagents.log"

Error Handler for Critical Issues

[logging.handlers.error]
enabled = true
level = "WARNING"
max_size = "100MB"
backup_count = 10
directory = "/app/logs"
filename = "error.log"

Structured Handler for Log Aggregation

[logging.handlers.structured]
enabled = true
level = "INFO"
directory = "/app/logs"
filename = "tradingagents_structured.log"

The StructuredFormatter class (lines 44-69 in logging_manager.py) automatically injects extra fields like session_id and stock_symbol into the JSON payload, making these logs ready for ingestion into ELK, Loki, or Splunk.

Step 3: Set Production Environment Variables

Export these variables before starting the process:

export DOCKER_CONTAINER=true            # Required for Docker-specific paths

export TRADINGAGENTS_LOG_LEVEL=INFO       # Global fallback level

export TRADINGAGENTS_LOG_DIR=/app/logs   # Base directory for all handlers

The bootstrap logger in logging_manager.py (line 19) reads these variables before any user code executes, ensuring the correct log level and directory are applied even if the TOML file omits specific settings.

Step 4: Initialize the Logger in Your Application

Call init_logging() as the very first operation in your entry point to prevent unconfigured log messages:

from tradingagents.utils.logging_init import init_logging, log_startup_info

# Must execute before importing any module that might log

init_logging()

log_startup_info()

# Application logic follows...

The init_logging() function (lines 19-34 in logging_init.py) invokes setup_logging() to build the handler hierarchy and emits a concise startup banner with environment details.

Step 5: Use Session-Scoped Loggers for Request Tracking

For per-request or per-session logging, use the session helper to automatically inject context fields:

from tradingagents.utils.logging_init import get_session_logger

def run_analysis(session_id, stock_symbol):
    logger = get_session_logger(session_id, module_name='analysis')
    logger.info(
        "Analysis started",
        extra={'stock_symbol': stock_symbol, 'analysis_type': 'fundamentals'}
    )
    # ... analysis logic ...

    logger.info("Analysis finished", extra={'stock_symbol': stock_symbol})

The StructuredFormatter captures these extra fields and outputs them as JSON properties, enabling correlation of log entries by session_id or stock_symbol in your aggregation platform.

Docker-Specific Configuration

For containerized deployments, generate a dedicated configuration file using the provided utility:

python scripts/fix_logging_config_error.py

This script writes config/logging_docker.toml with production-optimized settings. When DOCKER_CONTAINER=true, the manager automatically selects this file over the default logging.toml (see line 334 in logging_manager.py).

The Docker configuration typically disables console output and writes structured logs to /app/logs/tradingagents_structured.log for collection by the container runtime or sidecar agents.

Verifying Your Production Logging Setup

Run this validation script after deployment:

from tradingagents.utils.logging_init import init_logging, log_startup_info

init_logging()
log_startup_info()

import logging
log = logging.getLogger('tradingagents')
log.info("Production smoke test")
log.warning("Test warning for error handler")

Confirm the following:

  • Structured logs: Check /app/logs/tradingagents_structured.log for JSON lines containing "message": "Production smoke test".
  • Error isolation: Verify /app/logs/error.log contains only the warning message.
  • Startup banner: The console or container logs should display the production mode confirmation from log_startup_info().

Summary

  • Enable production mode by setting enabled = true in the [logging.production] section of config/logging.toml.
  • Use structured logging by setting structured_only = true to emit JSON for log aggregation services.
  • Set environment variables including DOCKER_CONTAINER, TRADINGAGENTS_LOG_LEVEL, and TRADINGAGENTS_LOG_DIR before startup.
  • Initialize early by calling init_logging() before any other imports in your entry point.
  • Leverage session loggers via get_session_logger() to inject request-specific context into structured output.

Frequently Asked Questions

What is the difference between structured and console logging in TradingAgents-CN?

Structured logging outputs JSON-formatted lines containing timestamp, level, message, and custom fields like session_id or stock_symbol, making them ideal for ingestion into ELK, Loki, or Splunk. Console logging emits human-readable text to stdout/stderr, suitable for development but generally disabled in production via structured_only = true to prevent duplicate or non-machine-readable streams.

How do I change the log level without restarting the application?

TradingAgents-CN reads the TRADINGAGENTS_LOG_LEVEL environment variable at startup in logging_manager.py (line 19). For runtime changes without restart, you must implement a signal handler or configuration reload mechanism that calls logging.getLogger('tradingagents').setLevel(new_level), as the current implementation does not provide a built-in hot-reload feature for the TOML configuration.

Where should I place the logging.toml file in a Docker container?

Mount the configuration file at /app/config/logging.toml (or use the auto-generated /app/config/logging_docker.toml) inside the container. Ensure the TRADINGAGENTS_LOG_DIR environment variable points to a writable volume such as /app/logs. The logging_manager.py bootstrap process searches for the TOML file relative to the working directory or uses the Docker-specific path when DOCKER_CONTAINER=true.

Can I send logs directly to an external aggregation service like ELK or Loki?

While TradingAgents-CN does not include built-in network handlers, the structured JSON output is designed for exactly this purpose. Configure the structured handler to write to a file or stdout, then use a sidecar container or log shipper (such as Fluent Bit, Filebeat, or Promtail) to forward the JSON lines to your ELK, Loki, or Splunk cluster. The StructuredFormatter in logging_manager.py (lines 44-69) ensures the JSON schema is consistent for reliable parsing.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →