Skip to content

Logging Overview

Truong Giang Vu edited this page Feb 13, 2026 · 4 revisions

Logging Module

Unified logging infrastructure with multi-sink output, Revit enrichers, and geometry visualization integration.

This module provides a centralized logging system that captures all trace, console, and debug output with real-time syntax highlighting, geometry interception, file logging, and flexible output sinks.


📚 Documentation

Core Features

Integration


⚡ Quick Start

C# Logging

See RevitDevTool.Test/Log.cs:

using System.Diagnostics;

// Simple trace logging
Trace.TraceInformation("Operation started");
Trace.TraceWarning("File not found, using default");
Trace.TraceError("Connection failed");

// Appears in RevitDevTool Trace panel with color coding

More examples:

  • Log.cs - Comprehensive logging tests (batch, formatting, keywords)

Python Integration

See logging_format_script.py:

# Python logging uses print() - automatically redirected to Trace panel

# Simple logging
print("Processing walls...")
print("Analysis complete ✓")
print("WARNING: Some elements skipped")
print("ERROR: Failed to load configuration")

# Geometry visualization - print geometry objects directly
from Autodesk.Revit.DB import Line, XYZ
line = Line.CreateBound(XYZ.Zero, XYZ(10, 0, 0))
print(line)  # Geometry appears in 3D view

More examples:


🎨 Features

1. Real-Time Capture

  • Captures System.Diagnostics.Trace output
  • Intercepts Console.WriteLine()
  • Python print() integration
  • WPF binding error capture
  • Custom trace listeners

2. Output Sinks

  • UI Sink: RichTextBox with syntax highlighting
  • File Sink: JSON or plain text formats
  • External File Only Mode: Log directly to file without UI overhead
  • Configurable rolling intervals (Infinite, Year, Month, Day, Hour, Minute)
  • Auto-clean old log files
  • Process ID in filenames for multi-instance scenarios

3. Revit Enrichers

Automatically add Revit context to every log entry:

  • RevitVersion: Revit version number (e.g., "2024")
  • RevitBuild: Build number (e.g., "20240101_0000")
  • RevitUserName: Current Revit user name
  • RevitLanguage: Revit UI language (e.g., "ENU", "CHT")
  • RevitDocumentTitle: Active document title
  • RevitDocumentPathName: Active document file path
  • RevitDocumentModelPath: Active document model path

4. Syntax Highlighting

  • Automatic keyword detection
  • Theme-aware colors (dark/light mode)
  • JSON pretty-printing
  • Custom color schemes
  • Filter keywords for log level detection

5. Geometry Visualization

  • Intercepts geometry objects in log messages
  • Displays in 3D view via DirectContext3D
  • Supports: Points, Curves, Faces, Solids, Meshes, BoundingBoxXYZ
  • See: Trace Geometry

6. Python Stack Traces

  • Beautiful Python error formatting
  • Syntax-highlighted tracebacks
  • File/line number clickable links
  • Configurable stack trace depth
  • See: Python Stack Traces

7. WPF Trace Support

  • Capture WPF binding errors and trace output
  • Configurable trace level (Off, Error, Warning, Information, Verbose)
  • Helps debug XAML binding issues

📊 Color Keywords

Automatic syntax highlighting for common patterns:

Pattern Color Example
Success Green , SUCCESS, PASS
Warning Orange WARNING, ⚠️, SKIP
Error Red ERROR, FAIL,
Info Blue INFO, ℹ️
Numbers Cyan 123, 45.67
Strings Yellow "text", 'value'
JSON Keys Purple "name":, "id":

See: Complete Color Keywords List


🔧 Configuration

Output Sinks

UI Sink (RichTextBox)

using RevitDevTool.Logging;

// Logs appear in Trace Panel with syntax highlighting
_loggingService.Initialize(isDarkTheme: true);

File Sink

var config = new LogConfig
{
    IsSaveLogEnabled = true,
    SaveFormat = LogSaveFormat.Json,  // or LogSaveFormat.Text
    LogFolder = @"C:\Logs",
    TimeInterval = RollingInterval.Day,  // Daily log files
    AutoClean = true  // Clean old logs automatically
};

External File Only Mode

var config = new LogConfig
{
    IsSaveLogEnabled = true,
    UseExternalFileOnly = true,  // Skip UI, log to file only
    SaveFormat = LogSaveFormat.Json
};

Log File Formats:

  • JSON: Structured JSON format for parsing log_<pid>_YYYYMMDD.json
  • Text: Human-readable with timestamps log_<pid>_YYYYMMDD.log

Rolling Intervals:

  • Infinite - Single log file
  • Year, Month, Day - Time-based rotation
  • Hour, Minute - Fine-grained rotation

Revit Enrichers

Add Revit context automatically to every log entry:

using RevitDevTool.Logging.Enums;

var config = new LogConfig
{
    RevitEnrichers = RevitEnricher.RevitVersion 
                   | RevitEnricher.RevitDocumentTitle
                   | RevitEnricher.RevitDocumentPathName
};

Available Enrichers:

Enricher Description Example Output
RevitVersion Revit version number "RevitVersion": "2024"
RevitBuild Build number "RevitBuild": "20240101_0000"
RevitUserName Current user name "RevitUserName": "JohnDoe"
RevitLanguage UI language code "RevitLanguage": "ENU"
RevitDocumentTitle Document title "RevitDocumentTitle": "Sample Project"
RevitDocumentPathName Document file path "RevitDocumentPathName": "C:\\Projects\\Sample.rvt"
RevitDocumentModelPath Model path "RevitDocumentModelPath": "C:\\Projects\\Sample.rvt"

Default Enrichers: RevitVersion | RevitDocumentTitle

Example JSON Output with Enrichers:

{
  "Timestamp": "2024-02-13 15:30:45.123",
  "Level": "Information",
  "Message": "Starting wall analysis",
  "RevitVersion": "2024",
  "RevitDocumentTitle": "Office Building",
  "RevitDocumentPathName": "C:\\Projects\\Office.rvt"
}

Filter Keywords

Automatically detect log levels from message content:

var config = new LogConfig
{
    FilterKeywords = new LogFilterKeywords
    {
        Information = "info,success,completed",
        Warning = "warning,warn,caution",
        Error = "error,failed,exception",
        Critical = "fatal,critical,crash"
    }
};

How it works:

Trace.WriteLine("Operation completed");  // → Information (matched "completed")
Trace.WriteLine("WARNING: File not found");  // → Warning (matched "WARNING")
Trace.WriteLine("ERROR: Connection failed");  // → Error (matched "ERROR", "failed")
Trace.WriteLine("FATAL: System crash");  // → Critical (matched "FATAL", "crash")

Prefix Detection: Automatically detects [INFO], [WARN], [ERROR], [FATAL], [DEBUG] prefixes.


Pretty JSON Output

Automatic JSON formatting for complex objects:

var config = new LogConfig
{
    EnablePrettyJson = true
};

// Objects are automatically serialized to formatted JSON
var data = new { Name = "Wall", Count = 42, Status = "Active" };
Trace.WriteLine(data);

Output:

{
  "Name": "Wall",
  "Count": 42,
  "Status": "Active"
}

WPF Trace Support

Capture WPF binding errors and trace output:

using System.Diagnostics;

var config = new LogConfig
{
    IncludeWpfTrace = true,
    WpfTraceLevel = SourceLevels.Warning  // Off, Error, Warning, Information, Verbose
};

Use case: Debug XAML binding issues without external tools.


Stack Trace Configuration

var config = new LogConfig
{
    IncludeStackTrace = true,  // Include stack trace in logs
    StackTraceDepth = 3        // Number of stack frames
};

Initialize Logging Service

using RevitDevTool.Logging;

public class AppInitializer
{
    private readonly ILoggingService _loggingService;

    public void Initialize(bool isDarkTheme)
    {
        // Initialize with theme
        _loggingService.Initialize(isDarkTheme);
        
        // Register built-in listeners
        _loggingService.RegisterTraceListeners();
    }
}

🎯 Common Use Cases

Basic Script Logging

# Use print() - redirected to Trace panel
print("Starting analysis...")
print(f"Processing {len(elements)} elements")
print("Analysis complete ✓")

Log Level Detection with Keywords

# Messages automatically get correct log level
print("INFO: Starting wall analysis")      # → Information
print("SUCCESS: Analysis completed")        # → Information
print("WARNING: Some elements skipped")     # → Warning 
print("ERROR: Failed to load configuration") # → Error
print("FATAL: System crash detected")       # → Critical

With Revit Enrichers

// Every log entry automatically includes Revit context
Trace.TraceInformation("Creating walls");
// Output includes: RevitVersion="2024", RevitDocumentTitle="Office Building"

Log to File Only (Performance Mode)

// Skip UI, log directly to file for better performance
var config = new LogConfig
{
    IsSaveLogEnabled = true,
    UseExternalFileOnly = true,  // No UI overhead
    SaveFormat = LogSaveFormat.Json,
    LogFolder = @"C:\RevitLogs"
};

Geometry Visualization

from Autodesk.Revit.DB import Line, XYZ

# Create geometry
start = XYZ(0, 0, 0)
end = XYZ(10, 10, 0)
line = Line.CreateBound(start, end)

# Print geometry object - appears in 3D view
print("Boundary line:")
print(line)

Pretty JSON Output

import json

data = {"walls": 42, "doors": 18, "windows": 36}
print(json.dumps(data, indent=2))
# Automatic syntax highlighting in Trace panel

Or from C#:

var data = new { Walls = 42, Doors = 18, Windows = 36 };
Trace.WriteLine(data);  // Automatically formatted as JSON

Multi-Instance Logging

// Process ID in filename prevents conflicts
// log_12345_20240213.log  ← Process 12345
// log_67890_20240213.log  ← Process 67890

WPF Binding Debug

// Capture WPF binding errors
var config = new LogConfig
{
    IncludeWpfTrace = true,
    WpfTraceLevel = SourceLevels.Error
};

// XAML binding errors now appear in Trace panel

Python Error Handling

try:
    result = risky_operation()
except Exception as e:
    print(f"ERROR: Operation failed: {e}")
    # Beautiful stack trace with syntax highlighting

🛠️ Technical Details

For developers extending the logging system:


📖 Related Modules


Supported Output: Trace, Console, Debug
Theme Support: Dark/Light mode
Integration: Python, C#, Any .NET language

Clone this wiki locally