# Comprehensive Logging System Documentation **TradingAgents Logging System v1.0** --- ## Overview TradingAgents now includes a comprehensive, production-ready logging system that provides: - **Structured Logging**: Context-rich log messages with metadata - **Multiple Log Levels**: DEBUG, INFO, WARNING, ERROR, CRITICAL - **File and Console Output**: Separate handlers for different purposes - **Log Rotation**: Automatic file rotation to prevent disk space issues - **Component-Specific Loggers**: Dedicated loggers for different parts of the system - **Performance Tracking**: Built-in performance metrics and timing - **API Call Tracking**: Monitor API usage, costs, and errors - **Easy Configuration**: Simple setup with sensible defaults --- ## Quick Start ### Basic Usage ```python from tradingagents.utils import get_logger # Get a logger for your component logger = get_logger("tradingagents.my_component", component="MY_COMP") # Log messages at different levels logger.debug("Detailed debugging information") logger.info("General information about execution") logger.warning("Warning about potential issues") logger.error("Error occurred but execution continues") logger.critical("Critical error, system may be unstable") ``` ### With Context ```python logger.info( "Processing trade decision", extra={ "context": { "ticker": "AAPL", "decision": "BUY", "confidence": 0.85, "timestamp": "2025-01-15T10:30:00Z" } } ) ``` --- ## Configuration ### Using Default Configuration The logging system initializes automatically with defaults: ```python from tradingagents.graph.trading_graph import TradingAgentsGraph # Logging is automatically configured graph = TradingAgentsGraph(["market", "news"]) ``` ### Custom Configuration Configure logging settings in your config dictionary: ```python config = { # ... other config ... # Logging settings "log_level": "DEBUG", # More verbose logging "log_dir": "custom_logs", # Custom log directory "log_to_console": True, # Enable console output "log_to_file": True, # Enable file output } graph = TradingAgentsGraph(["market"], config=config) ``` ### Programmatic Configuration ```python from tradingagents.utils import configure_logging, set_log_level # Configure at application startup configure_logging( level="INFO", # Log level log_dir="my_logs", # Custom directory console=True # Console output ) # Change log level at runtime set_log_level("DEBUG") ``` --- ## Log Levels ### DEBUG **Use for**: Detailed diagnostic information ```python logger.debug("Entering function with params: ticker=AAPL, date=2025-01-15") logger.debug(f"Intermediate calculation: value={intermediate_result}") ``` **Output**: Only to log files (not console by default) ### INFO **Use for**: General informational messages ```python logger.info("Memory enabled with provider: openai") logger.info("Propagation complete for AAPL") ``` **Output**: Console and log files ### WARNING **Use for**: Potential issues that don't prevent execution ```python logger.warning("Failed to get embedding for situation, skipping") logger.warning("API rate limit approaching") ``` **Output**: Console and log files ### ERROR **Use for**: Errors that prevent specific operations ```python logger.error("Failed to initialize ChromaDB collection: Connection timeout") logger.error(f"API call failed: {error_message}") ``` **Output**: Console, main log file, and errors.log ### CRITICAL **Use for**: Severe errors that may crash the system ```python logger.critical("Unable to initialize any LLM provider") logger.critical("Database corruption detected") ``` **Output**: All handlers, highlighted in console --- ## Log Files The logging system creates separate log files in the `logs/` directory: ### Main Logs | File | Purpose | Rotation | Levels | |------|---------|----------|--------| | `tradingagents.log` | All application logs | 10 MB, 5 backups | DEBUG+ | | `errors.log` | Errors only | 5 MB, 3 backups | ERROR+ | | `api_calls.log` | API call tracking | 10 MB, 3 backups | INFO+ | | `memory.log` | Memory operations | 10 MB, 3 backups | DEBUG+ | | `agents.log` | Agent execution | 10 MB, 3 backups | INFO+ | | `performance.log` | Performance metrics | 10 MB, 3 backups | INFO+ | ### Log Rotation Files automatically rotate when they reach the size limit: ``` tradingagents.log # Current tradingagents.log.1 # Previous tradingagents.log.2 # Older ... tradingagents.log.5 # Oldest (then deleted) ``` --- ## Specialized Loggers ### API Call Logger Track all API calls with detailed metrics: ```python from tradingagents.utils import get_api_logger api_logger = get_api_logger() # Log successful API call api_logger.log_call( provider="openai", model="gpt-4", endpoint="/v1/chat/completions", tokens=150, cost=0.003, duration=250.5, status="success" ) # Log failed API call api_logger.log_call( provider="openrouter", model="llama-3", endpoint="/v1/chat/completions", status="error", error="Connection timeout" ) # Get statistics stats = api_logger.get_stats() print(f"Total calls: {stats['total_calls']}") print(f"Total tokens: {stats['total_tokens']}") ``` **Output Format**: ``` 2025-01-15 10:30:15 | INFO | API | API call to openai/gpt-4 - success Context: { "call_number": 42, "provider": "openai", "model": "gpt-4", "endpoint": "/v1/chat/completions", "tokens": 150, "cost": 0.003, "duration_ms": 250.5, "status": "success" } ``` ### Performance Logger Track operation timings and generate performance reports: ```python from tradingagents.utils import get_performance_logger import time perf_logger = get_performance_logger() # Log operation timing start = time.time() # ... do something ... duration = (time.time() - start) * 1000 perf_logger.log_timing( "analyst_execution", duration, context={"analyst": "market", "ticker": "AAPL"} ) # Get average timing avg = perf_logger.get_average_timing("analyst_execution") print(f"Average time: {avg:.2f}ms") # Log performance summary perf_logger.log_summary() ``` **Summary Output**: ``` 2025-01-15 10:35:00 | INFO | PERF | Performance Summary Context: { "analyst_execution": { "count": 10, "avg_ms": 1234.5, "min_ms": 987.3, "max_ms": 2100.8 }, "embedding_generation": { "count": 25, "avg_ms": 45.2, "min_ms": 32.1, "max_ms": 78.9 } } ``` --- ## Log Format ### Console Output ``` 2025-01-15 10:30:15 | INFO | MEMORY | Added 5 situations to 'bull_memory' 2025-01-15 10:30:16 | WARNING | MEMORY | Failed to get embedding for situation 3, skipping 2025-01-15 10:30:17 | ERROR | API | API call failed: Connection timeout ``` Format: `{timestamp} | {level} | {component} | {message}` ### File Output ``` 2025-01-15T10:30:15.123456 | INFO | tradingagents.memory | MEMORY | Added 5 situations to 'bull_memory' Context: { "collection": "bull_memory", "count": 5, "total_in_collection": 15, "duration_ms": 123.45 } ``` Format: `{timestamp} | {level} | {logger_name} | {component} | {message}` --- ## Examples ### Memory Operations ```python from tradingagents.agents.utils.memory import FinancialSituationMemory config = { "embedding_provider": "openai", "enable_memory": True, } memory = FinancialSituationMemory("test_memory", config) # Logs: # INFO | MEMORY | Initialized embedding client for 'test_memory' # INFO | MEMORY | Initialized ChromaDB collection 'test_memory' # Add situations memory.add_situations([ ("High volatility", "Reduce positions"), ("Strong uptrend", "Scale in") ]) # Logs: # DEBUG | MEMORY | Generated embedding for text (15 chars) # DEBUG | MEMORY | Generated embedding for text (14 chars) # INFO | MEMORY | Added 2 situations to 'test_memory' # INFO | API | API call to openai/text-embedding-3-small - success # Query memories results = memory.get_memories("Market showing volatility", n_matches=1) # Logs: # DEBUG | MEMORY | Generated embedding for text (27 chars) # INFO | MEMORY | Retrieved 1 memories from 'test_memory' # INFO | PERF | get_memories completed in 45.23ms ``` ### Trading Graph Execution ```python from tradingagents.graph.trading_graph import TradingAgentsGraph graph = TradingAgentsGraph(["market", "news"]) # Logs: # INFO | GRAPH | Initializing TradingAgentsGraph # INFO | GRAPH | Initializing chat LLMs with provider: openai # INFO | GRAPH | Memory enabled with provider: openai # INFO | MEMORY | Initialized embedding client for 'bull_memory' # INFO | MEMORY | Initialized embedding client for 'bear_memory' # ... # INFO | GRAPH | TradingAgentsGraph initialization complete # Run analysis final_state, decision = graph.propagate("AAPL", "2025-01-15") # Logs: # INFO | GRAPH | Starting propagation for AAPL on 2025-01-15 # DEBUG | GRAPH | Starting graph execution # DEBUG | GRAPH | Running in standard mode # INFO | GRAPH | Propagation complete for AAPL # INFO | PERF | propagation completed in 5432.1ms ``` ### Error Handling ```python # Failed API call try: response = client.embeddings.create(...) except Exception as e: logger.error( f"Failed to get embedding: {e}", extra={ "context": { "provider": "openai", "model": "text-embedding-3-small", "error": str(e) } } ) # Logs: # ERROR | MEMORY | Failed to get embedding: 401 Unauthorized # Context: { # "provider": "openai", # "model": "text-embedding-3-small", # "error": "401 Unauthorized" # } # ERROR | API | API call to openai/text-embedding-3-small - error # Context: { # "provider": "openai", # "model": "text-embedding-3-small", # "endpoint": "embeddings.create", # "status": "error", # "error": "401 Unauthorized" # } ``` --- ## Best Practices ### 1. Use Appropriate Log Levels ```python # ✅ Good logger.debug(f"Processing item {i} of {total}") # Detailed info logger.info("Analysis complete") # Important milestone logger.warning("API rate limit at 80%") # Potential issue logger.error("Failed to connect to database") # Actual error # ❌ Bad logger.info(f"i={i}, j={j}, k={k}") # Too detailed for INFO logger.error("Successfully completed task") # Wrong level ``` ### 2. Include Context ```python # ✅ Good - Rich context logger.info( "Trade decision made", extra={ "context": { "ticker": "AAPL", "decision": "BUY", "confidence": 0.85, "price": 150.50 } } ) # ❌ Bad - No context logger.info("Trade decision made") ``` ### 3. Log Performance Metrics ```python # ✅ Good - Track timing start_time = time.time() result = expensive_operation() duration = (time.time() - start_time) * 1000 perf_logger.log_timing( "expensive_operation", duration, context={"items_processed": len(result)} ) # ❌ Bad - No performance tracking result = expensive_operation() ``` ### 4. Log API Calls ```python # ✅ Good - Track all API interactions try: start_time = time.time() response = api_client.call(...) duration = (time.time() - start_time) * 1000 api_logger.log_call( provider="openai", model="gpt-4", endpoint="/v1/chat", tokens=response.usage.total_tokens, duration=duration, status="success" ) except Exception as e: api_logger.log_call( provider="openai", model="gpt-4", endpoint="/v1/chat", status="error", error=str(e) ) # ❌ Bad - No API tracking response = api_client.call(...) ``` ### 5. Use Component Names ```python # ✅ Good - Component identification logger = get_logger("tradingagents.analyst.market", component="MARKET_ANALYST") # ❌ Bad - Generic logger logger = get_logger("tradingagents") ``` --- ## Troubleshooting ### Logs Not Appearing **Problem**: No logs in console or files **Solution**: 1. Check log level: `set_log_level("DEBUG")` 2. Verify log directory exists and is writable 3. Check if logging was configured: `configure_logging(level="INFO")` ### Too Many Log Files **Problem**: Log directory growing too large **Solution**: 1. Reduce backup count in logging_config.py 2. Increase rotation size to rotate less frequently 3. Set up log cleanup cron job ### Performance Impact **Problem**: Logging slowing down application **Solution**: 1. Increase log level to WARNING or ERROR 2. Disable console logging: `configure_logging(console=False)` 3. Use async logging (future enhancement) ### Missing Context **Problem**: Log messages don't show context dict **Solution**: 1. Ensure you're using `extra={"context": {...}}` 2. Check that StructuredFormatter is being used 3. Verify logger is from TradingAgents system --- ## Advanced Usage ### Custom Logger Configuration ```python from tradingagents.utils.logging_config import TradingAgentsLogger # Get logger instance logger_system = TradingAgentsLogger() # Add custom file handler logger_system.add_file_handler( logger_name="tradingagents.custom", filename="custom_component.log", level=logging.INFO ) # Get logger logger = logger_system.get_logger( "tradingagents.custom", component="CUSTOM" ) ``` ### Filtering Logs View only specific components: ```bash # Only memory logs grep "MEMORY" logs/tradingagents.log # Only errors cat logs/errors.log # API calls for specific provider grep "openai" logs/api_calls.log ``` ### Log Analysis ```bash # Count error types grep "ERROR" logs/tradingagents.log | cut -d'|' -f4 | sort | uniq -c # API call statistics grep "API call to" logs/api_calls.log | wc -l # Performance summary grep "Performance Summary" logs/performance.log -A 20 ``` --- ## Testing ### Test Logging System ```bash # Run logging system tests python -m tradingagents.utils.logging_config # Output: # Testing TradingAgents Logging System # ====================================================================== # 2025-01-15 10:30:00 | INFO | TEST | This is an info message # 2025-01-15 10:30:00 | WARNING | TEST | This is a warning message # 2025-01-15 10:30:00 | ERROR | TEST | This is an error message # ... # Logging test complete. Check the 'logs' directory for output files. ``` ### Verify Log Files ```bash # Check log directory ls -lh logs/ # Output: # -rw-r--r-- tradingagents.log # -rw-r--r-- api_calls.log # -rw-r--r-- errors.log # -rw-r--r-- performance.log ``` --- ## Configuration Reference ### Config Parameters ```python DEFAULT_CONFIG = { # Logging settings "log_level": "INFO", # DEBUG, INFO, WARNING, ERROR, CRITICAL "log_dir": "logs", # Directory for log files "log_to_console": True, # Enable console output "log_to_file": True, # Enable file output } ``` ### Environment Variables ```bash # Override log level export TRADINGAGENTS_LOG_LEVEL=DEBUG # Override log directory export TRADINGAGENTS_LOG_DIR=/var/log/tradingagents ``` --- ## API Reference ### get_logger() ```python def get_logger(name: str = "tradingagents", component: Optional[str] = None) -> logging.Logger ``` Get a configured logger instance. **Parameters**: - `name`: Logger name (default: "tradingagents") - `component`: Component name for context (optional) **Returns**: Configured logger instance ### get_api_logger() ```python def get_api_logger() -> APICallLogger ``` Get the API call tracking logger. **Returns**: APICallLogger instance ### get_performance_logger() ```python def get_performance_logger() -> PerformanceLogger ``` Get the performance tracking logger. **Returns**: PerformanceLogger instance ### configure_logging() ```python def configure_logging( level: str = "INFO", log_dir: Optional[str] = None, console: bool = True ) ``` Configure the logging system. **Parameters**: - `level`: Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) - `log_dir`: Directory for log files - `console`: Whether to log to console ### set_log_level() ```python def set_log_level(level: str) ``` Set the global log level. **Parameters**: - `level`: Log level string --- ## Migration from Print Statements ### Before ```python print(f"Memory enabled with provider: {provider}") print(f"Added {count} situations") print(f"ERROR: Failed to connect: {error}") ``` ### After ```python logger.info( f"Memory enabled with provider: {provider}", extra={"context": {"provider": provider}} ) logger.info( f"Added {count} situations", extra={"context": {"count": count}} ) logger.error( f"Failed to connect: {error}", extra={"context": {"error": str(error)}} ) ``` --- ## Future Enhancements Planned improvements: - [ ] Async logging for better performance - [ ] Cloud logging integration (CloudWatch, Stackdriver) - [ ] Real-time log streaming dashboard - [ ] Log aggregation and analytics - [ ] Structured JSON logging option - [ ] Log compression for archived files - [ ] Email alerts for critical errors - [ ] Slack/Discord notifications --- ## Support For questions or issues with the logging system: 1. Check this documentation 2. Review log files in `logs/` directory 3. Test with `python -m tradingagents.utils.logging_config` 4. Open GitHub issue with log samples --- **Version**: 1.0 **Last Updated**: 2025-01-15 **Status**: Production Ready ✅