Problem
During debugging of issue #70, we added extensive Console.Error.WriteLine statements throughout the codebase to trace execution flow, focus management, layout lifecycle, and observable emissions. This manual logging proved invaluable for diagnosing complex issues but had to be removed afterward.
Key areas where trace logging was helpful:
- Focus management (FocusManager: PushFocus, PopFocus, RouteInput)
- Layout node lifecycle (OnActivate, OnDeactivate, Dispose)
- Reactive subscriptions and emissions (Observable hash codes, emission values)
- Input routing and handling
- Page lifecycle (OnBound, OnNavigatedTo, BuildLayout)
Proposed Solution
Add a first-party trace logging system that:
-
Uses a custom abstraction rather than directly depending on Microsoft.Extensions.Logging
- Avoids requiring injection into all components
- Keeps the API surface clean and doesn't force external dependencies
- Can be implemented as a static or ambient context logger
-
Can integrate with Microsoft.Extensions.Logging when desired
- Provide an adapter/bridge for apps that use MEL
- Allow developers to route Termina's trace output to their logging infrastructure
-
Supports structured logging with context
- Component name/type
- Instance hashes for tracking specific objects
- Hierarchical categories (e.g., "Termina.Layout.TextInputNode", "Termina.Focus")
- Log levels (Trace, Debug, Info, Warning, Error)
-
Zero-cost when disabled
- Should compile out or have minimal overhead when not active
- Consider using conditional compilation or source generators
-
Key scenarios to support:
- Focus flow debugging
- Layout lifecycle tracing
- Observable subscription tracking
- Input routing visualization
- Performance diagnostics
Benefits
- Easier debugging of complex TUI applications
- Better diagnostics for users encountering issues
- Ability to capture logs in production scenarios
- Consistent logging patterns across the framework
Implementation Considerations
- Could use a static class with category-specific methods
- Consider source generator for adding trace points
- Should work well with both development and production scenarios
- Needs to handle high-frequency events efficiently (e.g., cursor blink, render cycles)
Example API
// Option 1: Static API
TerminaTrace.Focus.PushFocus(focusable, depth);
TerminaTrace.Layout.Activated(node);
TerminaTrace.Observable.Emitted(observable, value);
// Option 2: Scoped API
using var scope = TerminaTrace.BeginScope("TodoListPage", instance);
scope.Debug("BuildLayout called");
scope.Trace("Created TextInputNode: {0}", hash);
Related Issues
Problem
During debugging of issue #70, we added extensive Console.Error.WriteLine statements throughout the codebase to trace execution flow, focus management, layout lifecycle, and observable emissions. This manual logging proved invaluable for diagnosing complex issues but had to be removed afterward.
Key areas where trace logging was helpful:
Proposed Solution
Add a first-party trace logging system that:
Uses a custom abstraction rather than directly depending on Microsoft.Extensions.Logging
Can integrate with Microsoft.Extensions.Logging when desired
Supports structured logging with context
Zero-cost when disabled
Key scenarios to support:
Benefits
Implementation Considerations
Example API
Related Issues