Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ public virtual async Task<ProvisioningContext> CreateProvisioningContextAsync(Ca

var armClient = _armClientProvider.GetArmClient(credential, subscriptionId);

_logger.LogInformation("Getting default subscription and tenant...");

var (subscriptionResource, tenantResource) = await armClient.GetSubscriptionAndTenantAsync(cancellationToken).ConfigureAwait(false);

_logger.LogInformation("Default subscription: {name} ({subscriptionId})", subscriptionResource.DisplayName, subscriptionResource.Id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,6 @@ public DefaultTokenCredentialProvider(

internal void LogCredentialType()
{
if (_credential.GetType() == typeof(DefaultAzureCredential))
{
_logger.LogInformation(
"Using DefaultAzureCredential for provisioning. This may not work in all environments. " +
"See https://aka.ms/azsdk/net/identity/credential-chains#defaultazurecredential-overview for more information.");
}
else
{
_logger.LogInformation("Using {credentialType} for provisioning.", _credential.GetType().Name);
}
_logger.LogInformation("Using {credentialType} for provisioning.", _credential.GetType().Name);
}
}
16 changes: 10 additions & 6 deletions src/Aspire.Hosting/DistributedApplicationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -446,13 +446,11 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options)
_innerBuilder.Services.AddSingleton<PipelineActivityReporter>();
_innerBuilder.Services.AddSingleton<IPipelineActivityReporter, PipelineActivityReporter>(sp => sp.GetRequiredService<PipelineActivityReporter>());
_innerBuilder.Services.AddSingleton(Pipeline);
_innerBuilder.Services.AddSingleton<ILoggerProvider, PipelineLoggerProvider>();

// Read this once from configuration and use it to filter logs from the pipeline
LogLevel? minLevel = null;
_innerBuilder.Logging.AddFilter<PipelineLoggerProvider>((level) =>
// Configure pipeline logging options
_innerBuilder.Services.Configure<PipelineLoggingOptions>(o =>
{
minLevel ??= _innerBuilder.Configuration["Publishing:LogLevel"]?.ToLowerInvariant() switch
o.MinimumLogLevel = _innerBuilder.Configuration["Publishing:LogLevel"]?.ToLowerInvariant() switch
{
"trace" => LogLevel.Trace,
"debug" => LogLevel.Debug,
Expand All @@ -462,8 +460,14 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options)
"crit" or "critical" => LogLevel.Critical,
_ => LogLevel.Information
};
});

return level >= minLevel;
_innerBuilder.Services.AddSingleton<ILoggerProvider, PipelineLoggerProvider>();

// Configure logging filter using the PipelineLoggingOptions
_innerBuilder.Services.AddOptions<LoggerFilterOptions>().Configure<IOptions<PipelineLoggingOptions>>((filterLoggingOptions, pipelineLoggingOptions) =>
{
filterLoggingOptions.AddFilter<PipelineLoggerProvider>((level) => level >= pipelineLoggingOptions.Value.MinimumLogLevel);
});

// Register IDeploymentStateManager based on execution context
Expand Down
1 change: 1 addition & 0 deletions src/Aspire.Hosting/Pipelines/PipelineLoggerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ private sealed class StepLoggerHolder
/// <remarks>
/// This logger acts as a proxy and dynamically resolves the current logger on each operation,
/// allowing the target logger to change between calls.
/// When logging exceptions, stack traces are only included when the configured minimum log level is Debug or Trace.
/// </remarks>
private sealed class PipelineLogger(Func<ILogger> currentLoggerAccessor) : ILogger
{
Expand Down
25 changes: 25 additions & 0 deletions src/Aspire.Hosting/Pipelines/PipelineLoggingOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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;

namespace Aspire.Hosting.Pipelines;

/// <summary>
/// Options for controlling logging behavior in the pipeline.
/// </summary>
internal sealed class PipelineLoggingOptions
{
/// <summary>
/// Gets or sets the minimum log level for pipeline logging.
/// </summary>
public LogLevel MinimumLogLevel { get; set; } = LogLevel.Information;

/// <summary>
/// Gets a value indicating whether exception details (stack traces) should be included in logs.
/// </summary>
/// <remarks>
/// Exception details are included when the minimum log level is Debug or Trace.
/// </remarks>
public bool IncludeExceptionDetails => MinimumLogLevel <= LogLevel.Debug;
}
12 changes: 9 additions & 3 deletions src/Aspire.Hosting/Pipelines/PipelineStepContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

using System.Diagnostics.CodeAnalysis;
using Aspire.Hosting.ApplicationModel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Aspire.Hosting.Pipelines;

Expand Down Expand Up @@ -45,10 +47,12 @@ public sealed class PipelineStepContext
/// </summary>
public IServiceProvider Services => PipelineContext.Services;

internal PipelineLoggingOptions PipelineLoggingOptions => Services.GetRequiredService<IOptions<PipelineLoggingOptions>>().Value;

/// <summary>
/// Gets the logger for pipeline operations that writes to both the pipeline logger and the step logger.
/// </summary>
public ILogger Logger => field ??= new StepLogger(ReportingStep);
public ILogger Logger => field ??= new StepLogger(ReportingStep, PipelineLoggingOptions);

/// <summary>
/// Gets the cancellation token for the pipeline operation.
Expand All @@ -65,9 +69,10 @@ public sealed class PipelineStepContext
/// A logger that writes to the step logger.
/// </summary>
[Experimental("ASPIREPUBLISHERS001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
internal sealed class StepLogger(IReportingStep step) : ILogger
internal sealed class StepLogger(IReportingStep step, PipelineLoggingOptions options) : ILogger
{
private readonly IReportingStep _step = step;
private readonly PipelineLoggingOptions _options = options;

public IDisposable? BeginScope<TState>(TState state) where TState : notnull
{
Expand All @@ -83,7 +88,8 @@ public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Except
{
// Also log to the step logger (for publishing output display)
var message = formatter(state, exception);
if (exception != null)

if (_options.IncludeExceptionDetails && exception != null)
{
message = $"{message} {exception}";
}
Expand Down
4 changes: 2 additions & 2 deletions src/Aspire.Hosting/Publishing/ContainerRuntimeBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private async Task ExecuteContainerCommandAsync(
{
var spec = CreateProcessSpec(arguments);

_logger.LogInformation("Running {RuntimeName} with arguments: {ArgumentList}", Name, spec.Arguments);
_logger.LogDebug("Running {RuntimeName} with arguments: {ArgumentList}", Name, spec.Arguments);
var (pendingProcessResult, processDisposable) = ProcessUtil.Run(spec);

await using (processDisposable)
Expand Down Expand Up @@ -131,7 +131,7 @@ protected async Task<int> ExecuteContainerCommandWithExitCodeAsync(
}
}

_logger.LogInformation("Running {RuntimeName} with arguments: {ArgumentList}", Name, spec.Arguments);
_logger.LogDebug("Running {RuntimeName} with arguments: {ArgumentList}", Name, spec.Arguments);
var (pendingProcessResult, processDisposable) = ProcessUtil.Run(spec);

await using (processDisposable)
Expand Down
2 changes: 1 addition & 1 deletion src/Aspire.Hosting/Publishing/DockerContainerRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private async Task<int> RunDockerBuildAsync(string contextPath, string dockerfil
}
}

Logger.LogInformation("Running Docker CLI with arguments: {ArgumentList}", spec.Arguments);
Logger.LogDebug("Running Docker CLI with arguments: {ArgumentList}", spec.Arguments);
var (pendingProcessResult, processDisposable) = ProcessUtil.Run(spec);

await using (processDisposable)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ await File.WriteAllTextAsync(
flattenedSecrets.ToJsonString(s_jsonSerializerOptions),
cancellationToken).ConfigureAwait(false);

logger.LogInformation("Deployment state saved to {Path}", deploymentStatePath);
logger.LogDebug("Deployment state saved to {Path}", deploymentStatePath);
}
catch (Exception ex)
{
Expand Down