Docs-Builder

# 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 file
  • mem - Store in ring buffer
  • output - Write to stdout/stderr
  • controlcenter - 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 operations
  • daemon.jsonl - Background daemon
  • server.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:

  1. Verify maxFileMB setting
  2. Check file permissions
  3. Ensure disk space available

Solution:

# Force rotation
logs.rotate_now()

High Memory Usage

Check:

  1. Ring buffer size (ring_buffer_size)
  2. TRACE rate limit (trace_rate_limit)
  3. 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:

  1. Dashboard is running (http://localhost:8765/health)
  2. controlcenter sink is enabled
  3. Firewall/network connectivity

Solution:

# Test Control Center endpoint
logs.test_controlcenter()


Source: Consolidated from docs/v1.1.0/Logging/ (README.md, BranchPy_Logging_Documentation.md)
Maintained by: BranchPy Core Team
License: Proprietary