| File: Interaction\SpectreConsoleLoggerProvider.cs | Web Access |
| Project: src\src\Aspire.Cli\Aspire.Cli.csproj (aspire) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Extensions.Logging; using System.Globalization; namespace Aspire.Cli.Interaction; internal class SpectreConsoleLoggerProvider : ILoggerProvider { private readonly TextWriter _output; /// <summary> /// Creates a logger provider that writes to the specified output. /// </summary> /// <param name="output">The text writer to write log messages to.</param> public SpectreConsoleLoggerProvider(TextWriter output) { _output = output; } public ILogger CreateLogger(string categoryName) { return new SpectreConsoleLogger(_output, categoryName); } public void Dispose() { } } internal class SpectreConsoleLogger(TextWriter output, string categoryName) : ILogger { public bool IsEnabled(LogLevel logLevel) => logLevel >= LogLevel.Debug && (categoryName.StartsWith("Aspire.Cli", StringComparison.Ordinal) || logLevel >= LogLevel.Warning); public IDisposable? BeginScope<TState>(TState state) where TState : notnull => null; public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter) { if (!IsEnabled(logLevel)) { return; } var message = formatter(state, exception); if (string.IsNullOrEmpty(message) && exception is null) { return; } var formattedMessage = exception is not null ? $"{message} {exception}" : message; // Extract the last token from the category name to reduce noise var shortCategoryName = GetShortCategoryName(categoryName); // Format timestamp to show only time (HH:mm:ss) for debugging purposes var timestamp = DateTime.Now.ToString("HH:mm:ss", CultureInfo.InvariantCulture); var logMessage = $"[{timestamp}] [{GetLogLevelString(logLevel)}] {shortCategoryName}: {formattedMessage}"; // Write to the configured output (stderr by default) output.WriteLine(logMessage); } private static string GetLogLevelString(LogLevel logLevel) => logLevel switch { LogLevel.Debug => "dbug", LogLevel.Information => "info", LogLevel.Warning => "warn", LogLevel.Error => "fail", LogLevel.Critical => "crit", _ => logLevel.ToString().ToLower() }; private static string GetShortCategoryName(string categoryName) { var lastDotIndex = categoryName.LastIndexOf('.'); return lastDotIndex >= 0 ? categoryName.Substring(lastDotIndex + 1) : categoryName; } }