Files
ReLibreHardwareMonitor/LibreHardwareMonitor.Windows.WinUI/Services/Tracing/StartupTracer.cs
T
JMR-devandCopilot 9b576ea633 Extract startup tracing behind IStartupTracer abstraction
Add Microsoft.Extensions.DependencyInjection package and introduce an
IStartupTracer abstraction with NoOpStartupTracer (zero-overhead default)
and FileStartupTracer (renamed from WinUiStartupTrace). A StartupTracer
factory selects the implementation from environment configuration.

Consumers (App, MainWindow, MainWindowViewModel, SensorColumnMeasurer) now
depend on the non-nullable interface, removing null-conditional trace calls
and decoupling startup instrumentation from construction logic. No behavior
change: tracing still writes the same log when enabled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-02 14:57:48 -05:00

57 lines
2.2 KiB
C#

// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Copyright (C) LibreHardwareMonitor and Contributors.
using System;
using System.IO;
namespace LibreHardwareMonitor.Windows.WinUI.Services.Tracing;
/// <summary>
/// Factory that selects the appropriate <see cref="IStartupTracer"/> based on environment
/// configuration. Returns a <see cref="FileStartupTracer"/> when timing is enabled, otherwise
/// the shared <see cref="NoOpStartupTracer"/>.
/// </summary>
internal static class StartupTracer
{
private const string EnabledEnvironmentVariable = "LHM_WINUI_STARTUP_TIMING";
private const string PathEnvironmentVariable = "LHM_WINUI_STARTUP_TIMING_PATH";
public static IStartupTracer Create()
{
return IsEnabled() ? new FileStartupTracer(GetLogFileName()) : NoOpStartupTracer.Instance;
}
private static string GetLogFileName()
{
string? configuredPath = Environment.GetEnvironmentVariable(PathEnvironmentVariable);
string fileName = $"LibreHardwareMonitor.WinUIStartupTiming-{DateTime.Now:yyyyMMdd-HHmmss-fff}.log";
if (string.IsNullOrWhiteSpace(configuredPath))
return Path.Combine(AppContext.BaseDirectory, fileName);
if (configuredPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)
|| configuredPath.EndsWith(Path.AltDirectorySeparatorChar.ToString(), StringComparison.Ordinal)
|| Directory.Exists(configuredPath))
{
return Path.Combine(configuredPath, fileName);
}
return configuredPath;
}
private static bool IsEnabled()
{
string environmentValue = Environment.GetEnvironmentVariable(EnabledEnvironmentVariable) ?? "";
return IsTruthy(environmentValue);
}
private static bool IsTruthy(string value)
{
return value.Equals("1", StringComparison.OrdinalIgnoreCase)
|| value.Equals("true", StringComparison.OrdinalIgnoreCase)
|| value.Equals("yes", StringComparison.OrdinalIgnoreCase)
|| value.Equals("on", StringComparison.OrdinalIgnoreCase);
}
}