# Logging Configuration
Version: 1.1.1
Last Updated: January 23, 2026
Status: Production
Overview
This document describes the configuration options for BranchPy’s logging system across all components (Python, TypeScript, Dashboard).
Python Configuration
Basic Setup
import branchpy.logs as logs
# Configure logging context
logs.set_context(
component="cli", # Component name
session="abc123", # Optional session ID
project="/path/to/game" # Optional project path
)
Configuration Dictionary
_config = {
"level": "INFO", # Minimum log level
"component": "cli", # Component identifier
"sinks": ["file", "mem", "controlcenter"], # Output targets
"maxFileMB": 10, # Max file size before rotation
"rotation_count": 5, # Number of backup files
"redaction": "standard", # Redaction mode
"ring_buffer_size": 5000, # In-memory buffer capacity
"controlcenter_url": "http://localhost:8765", # Control Center endpoint
"trace_rate_limit": 500 # TRACE events per second
}
Log Levels
# Set minimum log level
logs.set_level("DEBUG") # TRACE, DEBUG, INFO, WARN, ERROR, FATAL
# Temporary TRACE elevation (for debugging)
logs.enable_trace(duration_minutes=5) # Auto-reverts after 5 minutes
Sinks
Available Sinks:
file- Write to rotating log filemem- Store in ring bufferoutput- Write to stdout/stderrcontrolcenter- Send to VS Code Control Center
# Enable/disable sinks dynamically
logs.enable_sink("controlcenter")
logs.disable_sink("output")
File Rotation
# Configure rotation policy
logs.configure_rotation(
max_file_mb=10, # Rotate after 10MB
rotation_count=5 # Keep 5 backup files
)
# Result:
# .branchpy/logs/cli.jsonl (current)
# .branchpy/logs/cli.jsonl.1 (most recent backup)
# .branchpy/logs/cli.jsonl.2
# .branchpy/logs/cli.jsonl.3
# .branchpy/logs/cli.jsonl.4
# .branchpy/logs/cli.jsonl.5 (oldest backup)
Redaction Modes
Purpose: Protect sensitive data in logs (emails, tokens, file paths)
logs.set_redaction_mode("standard") # standard, strict, off
| Mode | Behavior | Example |
|---|---|---|
off |
No redaction | user@example.com |
standard |
Partial redaction | u***@example.com |
strict |
Full redaction | [REDACTED] |
Redaction Rules:
- Email addresses: First char +
***+ domain - API tokens: First 4 chars +
*** - File paths: Home directory replaced with
~
Ring Buffer
# Configure ring buffer size
logs.set_ring_buffer_size(5000) # Default: 5000 entries
# Query buffer
recent = logs.get_recent_logs() # All entries
filtered = logs.find_events_range(
min_level="DEBUG",
max_level="ERROR",
component="cli",
limit=50
)
Buffer Behavior:
- Circular buffer (oldest entries overwritten)
- O(1) append operation
- Thread-safe with lock protection
- Survives until process termination
Rate Limiting
TRACE Rate Limiting
# Set TRACE events per second limit
logs.set_trace_rate_limit(500) # Default: 500/sec
# Behavior:
# - Within limit: Events logged normally
# - Over limit: Events dropped silently
# - End of window: WARN summary emitted
Summary Event:
{"level":"WARN","event":"logs.trace_rate_limited","msg":"TRACE rate limit exceeded","attrs":{"dropped":123,"window_sec":1,"limit":500}}
Control Center Integration
# Enable Control Center sink (automatic if dashboard running)
logs.enable_controlcenter(url="http://localhost:8765")
# Disable Control Center sink
logs.disable_controlcenter()
# Fallback behavior (automatic)
# If server rejects TRACE/FATAL, retry with DEBUG/ERROR
Retry Logic:
try:
# Attempt 1: Send with original level (TRACE/FATAL)
response = requests.post(url, json={"level": "TRACE", ...})
except:
# Attempt 2: Send with fallback level (DEBUG/ERROR)
response = requests.post(url, json={"level": "DEBUG", ...})
Metrics
# Get per-level counters
metrics = logs.get_metrics()
# Returns: {'TRACE': 1523, 'DEBUG': 42, 'INFO': 156, 'WARN': 8, 'ERROR': 2, 'FATAL': 0}
# Reset all counters
logs.reset_metrics()
# High-volume auto-reset (automatic)
# TRACE counters reset after telemetry export if > 10,000
Telemetry Export
# Enable telemetry integration (requires telemetry module)
logs.enable_telemetry()
# Periodic metrics export (every 60 seconds)
# Writes to: .branchpy/license/usage.jsonl
# Format: {"event":"logging.metrics","ts":"...","attrs":{...}}
TypeScript Configuration (VS Code Extension)
Basic Setup
import * as log from './log';
// Initialize logging
log.initLogging(outputChannel);
// Configure
log.configure({
level: "INFO",
component: "vscode",
sinks: ["file", "mem", "output"],
maxFileMB: 10,
rotation_count: 5,
redaction: "standard",
ring_buffer_size: 5000
});
Configuration Object
interface LogConfig {
level: Level; // Minimum log level
component: string; // Component name
sinks: Sink[]; // Output targets
maxFileMB: number; // Max file size (MB)
rotation_count: number; // Backup file count
redaction: RedactionMode; // Redaction policy
ring_buffer_size: number; // Buffer capacity
}
type Level = "TRACE" | "DEBUG" | "INFO" | "WARN" | "ERROR" | "FATAL";
type Sink = "file" | "mem" | "output";
type RedactionMode = "off" | "standard" | "strict";
File Locations
// Windows
%LOCALAPPDATA%\BranchPy\logs\vscode.jsonl
// macOS/Linux
~/.branchpy/logs/vscode.jsonl
Ring Buffer Operations
// Get all logs from ring buffer
const logs = log.getRecentLogs();
// Tail from file (persistent)
const recent = log.tailFile('vscode', 100); // Last 100 lines
// Query by level
const errors = logs.filter(l => l.level === 'ERROR');
SmartLogger Configuration
import { SmartLogger } from './smartLogger';
const logger = new SmartLogger(
'Preflight', // Context name
'preflight', // Event prefix
{
firstNOccurrences: 3, // Show first 3 occurrences
aggregateInterval: 5000, // Aggregate every 5 seconds
maxAge: 60000 // Auto-clean after 60 seconds
}
);
// Usage
logger.log('Health check completed');
logger.warn('Connection timeout');
logger.error('Service unavailable');
SmartLogger Features:
- Intelligent hash normalization (detects duplicates)
- Rate limiting (shows first N, then counts)
- Periodic aggregation summaries
- Auto-cleanup to prevent memory leaks
Dashboard Configuration (React)
Logger Setup
import { Logger } from '../utils/logger';
// Initialize logger
const logger = new Logger(
window.location.origin, // Server URL
{
enabled: true, // Enable/disable logging
console: true, // Echo to console
level: 'INFO' // Minimum level
}
);
// Usage
logger.info('message', { key: 'value' });
logger.warn('message', { key: 'value' });
logger.error('message', { key: 'value' });
Production Mode
// Disable logging in production
if (process.env.NODE_ENV === 'production') {
logger.setEnabled(false);
}
Server Configuration (Node.js Backend)
Environment Variables
# .env file
LOG_LEVEL=INFO # Minimum log level
LOG_FILE_PATH=/var/log/branchpy/ # Log directory
LOG_MAX_FILES=5 # Rotation count
LOG_MAX_SIZE=10M # Max file size
Programmatic Configuration
// server.js
const logConfig = {
level: process.env.LOG_LEVEL || 'INFO',
maxFiles: parseInt(process.env.LOG_MAX_FILES) || 5,
maxSize: process.env.LOG_MAX_SIZE || '10M'
};
Log File Locations
Python
| OS | Path |
|---|---|
| Windows | %LOCALAPPDATA%\BranchPy\logs\ |
| macOS | ~/.branchpy/logs/ |
| Linux | ~/.branchpy/logs/ |
Files:
cli.jsonl- CLI operationsdaemon.jsonl- Background daemonserver.jsonl- FastAPI server
TypeScript (VS Code)
| OS | Path |
|---|---|
| Windows | %LOCALAPPDATA%\BranchPy\logs\vscode.jsonl |
| macOS | ~/Library/Application Support/BranchPy/logs/vscode.jsonl |
| Linux | ~/.local/share/BranchPy/logs/vscode.jsonl |
Dashboard (Node.js)
| OS | Path |
|---|---|
| Windows | %LOCALAPPDATA%\BranchPy\logs\dashboard.jsonl |
| macOS | ~/Library/Application Support/BranchPy/logs/dashboard.jsonl |
| Linux | ~/.local/share/BranchPy/logs/dashboard.jsonl |
Advanced Configuration
Custom Sinks
# Python: Implement custom sink
def custom_sink(record: LogRecord):
"""Send logs to custom destination"""
send_to_splunk(record)
logs.register_sink("splunk", custom_sink)
logs.enable_sink("splunk")
Correlation IDs
# Python: Add correlation IDs for distributed tracing
logs.set_context(
session="abc123",
run="xyz789",
project="my-game"
)
# All subsequent logs include these IDs
logs.info("event", "message")
# → {"ids":{"session":"abc123","run":"xyz789","project":"my-game"},...}
// TypeScript: Add correlation IDs
log.setContext({
sessionId: 'abc123',
runId: 'xyz789',
projectId: 'my-game'
});
Dynamic Level Changes
# Python: Change level at runtime
import signal
def handle_sigusr1(signum, frame):
logs.enable_trace(duration_minutes=5)
signal.signal(signal.SIGUSR1, handle_sigusr1)
# Send signal to enable TRACE for 5 minutes:
# kill -USR1 <pid>
Structured Attributes
# Python: Rich structured data
logs.info(
"analysis.complete",
msg="Deep analysis finished",
attrs={
"findings": {
"total": 42,
"by_severity": {
"high": 3,
"medium": 15,
"low": 24
}
},
"duration_ms": 1523,
"engine": "renpy"
}
)
Performance Tuning
High-Volume Scenarios
# Reduce overhead for high-volume logging
logs.set_ring_buffer_size(1000) # Smaller buffer
logs.set_trace_rate_limit(100) # Tighter rate limit
logs.disable_sink("controlcenter") # Skip remote sink
logs.set_redaction_mode("off") # Skip redaction
Low-Latency Scenarios
# Minimize latency (trade durability for speed)
logs.disable_sink("file") # Skip disk I/O
logs.set_ring_buffer_size(10000) # Larger in-memory buffer
Debug Mode
# Maximum verbosity for troubleshooting
logs.set_level("TRACE")
logs.enable_trace(duration_minutes=0) # Permanent TRACE
logs.set_trace_rate_limit(0) # No rate limit
logs.enable_sink("output") # Echo to console
Configuration Examples
Development Environment
# config/dev.py
import branchpy.logs as logs
logs.configure({
"level": "DEBUG",
"sinks": ["file", "mem", "output", "controlcenter"],
"redaction": "off",
"ring_buffer_size": 5000,
"trace_rate_limit": 500
})
Production Environment
# config/prod.py
import branchpy.logs as logs
logs.configure({
"level": "INFO",
"sinks": ["file", "mem"], # No console output
"redaction": "strict", # Full redaction
"ring_buffer_size": 1000, # Smaller buffer
"trace_rate_limit": 100, # Tighter limit
"maxFileMB": 50, # Larger files
"rotation_count": 10 # More backups
})
Testing Environment
# config/test.py
import branchpy.logs as logs
logs.configure({
"level": "WARN", # Only warnings and errors
"sinks": ["mem"], # In-memory only
"redaction": "off", # No redaction
"ring_buffer_size": 100 # Minimal buffer
})
Environment-Specific Settings
VS Code Extension
settings.json:
{
"branchpy.logging.level": "INFO",
"branchpy.logging.maxFileMB": 10,
"branchpy.logging.rotationCount": 5,
"branchpy.dashboard.url": "http://localhost:8765"
}
Access in code:
const config = vscode.workspace.getConfiguration('branchpy.logging');
const level = config.get('level', 'INFO');
Dashboard (React)
.env file:
REACT_APP_LOG_LEVEL=INFO
REACT_APP_LOG_ENABLED=true
REACT_APP_SERVER_URL=http://localhost:8765
Access in code:
const logLevel = process.env.REACT_APP_LOG_LEVEL || 'INFO';
const logEnabled = process.env.REACT_APP_LOG_ENABLED === 'true';
Troubleshooting
Logs Not Rotating
Check:
- Verify
maxFileMBsetting - Check file permissions
- Ensure disk space available
Solution:
# Force rotation
logs.rotate_now()
High Memory Usage
Check:
- Ring buffer size (
ring_buffer_size) - TRACE rate limit (
trace_rate_limit) - Sink configuration
Solution:
# Reduce memory footprint
logs.set_ring_buffer_size(1000)
logs.set_trace_rate_limit(100)
logs.clear_buffer()
Control Center Not Receiving Logs
Check:
- Dashboard is running (
http://localhost:8765/health) controlcentersink is enabled- Firewall/network connectivity
Solution:
# Test Control Center endpoint
logs.test_controlcenter()
Related Documentation
- Logging Overview - Main logging documentation
- Backend Observability - Health checks, monitoring
- API Reference - Server logging endpoints
Source: Consolidated from
docs/v1.1.0/Logging/(README.md, BranchPy_Logging_Documentation.md)
Maintained by: BranchPy Core Team
License: Proprietary