This document explains the conditional compilation-based logging system implemented for performance optimization.
The logging system uses C# conditional compilation attributes to completely eliminate logging code at compile time when it's not needed. This provides zero-performance overhead for disabled logging levels.
The logging levels are hierarchical and inclusive - enabling a level also enables all levels below it:
-
TRACE_LOGGING - Most verbose, includes performance tracing
- Includes: Trace, Verbose, Debug, Info, Warning, Error
- Use for: Beta releases, development builds with maximum detail
-
VERBOSE_LOGGING - Detailed operational information
- Includes: Verbose, Debug, Info, Warning, Error
- Use for: Production releases that need detailed troubleshooting
-
DEBUG_LOGGING - Debug information useful for development
- Includes: Debug, Info, Warning, Error
- Use for: Development builds with moderate detail
-
INFO_LOGGING - General information messages (default)
- Includes: Info, Warning, Error
- Use for: Standard production releases
-
WARNING_LOGGING - Warning messages only
- Includes: Warning, Error
- Use for: Minimal production builds
-
ERROR_LOGGING - Error messages only (always enabled)
- Includes: Error only
- Use for: Ultra-minimal builds
Edit src/HomeAssistantPlugin.csproj and uncomment the desired logging level:
<!-- For Beta/Development builds: Enable all verbose logging -->
<DefineConstants>$(DefineConstants);TRACE_LOGGING</DefineConstants>
<!-- For Production with detailed logs -->
<!-- <DefineConstants>$(DefineConstants);VERBOSE_LOGGING</DefineConstants> -->
<!-- For Standard Production (recommended) -->
<!-- <DefineConstants>$(DefineConstants);INFO_LOGGING</DefineConstants> -->// This string interpolation always executes, even if logging is disabled
PluginLog.Verbose($"Complex operation: {expensive.Calculate()} with {data.Count} items");// This entire method call is removed at compile time if VERBOSE_LOGGING is not defined
PluginLog.Verbose(() => $"Complex operation: {expensive.Calculate()} with {data.Count} items");- Zero Runtime Overhead - Disabled logs are completely removed from compiled code
- Lambda-Based Deferred Execution - Complex string operations only execute when logging is enabled
- Aggressive Inlining - Logging methods are optimized for performance
- Hierarchical Levels - Enable one level, get all lower levels automatically
// Use Trace for very frequent operations that would spam logs
PluginLog.Trace(() => $"Mouse position: {x}, {y}");// Use Verbose for detailed state that helps with troubleshooting
PluginLog.Verbose(() => $"Light state: entity={id}, brightness={bri}, color=({h},{s})");// Use Debug for information useful during development
PluginLog.Debug(() => $"Cache hit ratio: {hits}/{total} ({ratio:P})");// Use Info for important operational information
PluginLog.Info("Home Assistant connection established");<DefineConstants>$(DefineConstants);TRACE_LOGGING</DefineConstants><DefineConstants>$(DefineConstants);INFO_LOGGING</DefineConstants><DefineConstants>$(DefineConstants);WARNING_LOGGING</DefineConstants>When updating existing logs:
- Complex string interpolations → Use lambda syntax:
PluginLog.Level(() => $"message") - Frequent trace logs → Change from
VerbosetoTrace - Performance-critical logs → Change from
InfotoDebugorVerbose - Production-important logs → Keep as
InfoorWarning
The problematic log identified in the original issue:
// Before: Always executed, caused performance issues
PluginLog.Info($"[Light] {entityId} | name='{friendly}' | state={state} | dev='{deviceName}' mf='{mf}' model='{model}' bri={bri} tempMired={curM} range=[{minM},{maxM}] area='{areaId}'");
// After: Only executed when VERBOSE_LOGGING is enabled, zero cost otherwise
PluginLog.Verbose(() => $"[Light] {entityId} | name='{friendly}' | state={state} | dev='{deviceName}' mf='{mf}' model='{model}' bri={bri} tempMired={curM} range=[{minM},{maxM}] area='{areaId}'");This change eliminates the expensive string interpolation completely when verbose logging is disabled, providing significant performance improvements in production builds.