Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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 @@ -15,6 +15,6 @@
// to test end developer dashboard launch experience. Refer to Directory.Build.props
// for the path to the dashboard binary (defaults to the Aspire.Dashboard bin output
// in the artifacts dir).
builder.AddProject<Projects.Aspire_Dashboard>(KnownResourceNames.AspireDashboard);
builder.AddProject<Projects.Aspire_Dashboard>(KnownResourceNames.AspireDashboard).ExcludeFromManifest();

builder.Build().Run();
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175",
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" // Display dashboard resource in console for local development
}
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true"
},
"generate-manifest": {
"commandName": "Project",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
// to test end developer dashboard launch experience. Refer to Directory.Build.props
// for the path to the dashboard binary (defaults to the Aspire.Dashboard bin output
// in the artifacts dir).
//builder.AddProject<Projects.Aspire_Dashboard>(KnownResourceNames.AspireDashboard);
builder.AddProject<Projects.Aspire_Dashboard>(KnownResourceNames.AspireDashboard).ExcludeFromManifest();

builder.Build().Run();
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175",
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" // Display dashboard resource in console for local development
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true"
}
},
"generate-manifest": {
Expand Down
2 changes: 1 addition & 1 deletion playground/dapr/AppHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// to test end developer dashboard launch experience. Refer to Directory.Build.props
// for the path to the dashboard binary (defaults to the Aspire.Dashboard bin output
// in the artifacts dir).
builder.AddProject<Projects.Aspire_Dashboard>(KnownResourceNames.AspireDashboard);
builder.AddProject<Projects.Aspire_Dashboard>(KnownResourceNames.AspireDashboard).ExcludeFromManifest();

using var app = builder.Build();

Expand Down
2 changes: 1 addition & 1 deletion playground/dapr/AppHost/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031",
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" // Display dashboard resource in console for local development
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true"
}
},
"generate-manifest": {
Expand Down
2 changes: 1 addition & 1 deletion playground/eShopLite/AppHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@
// to test end developer dashboard launch experience. Refer to Directory.Build.props
// for the path to the dashboard binary (defaults to the Aspire.Dashboard bin output
// in the artifacts dir).
builder.AddProject<Projects.Aspire_Dashboard>(KnownResourceNames.AspireDashboard);
builder.AddProject<Projects.Aspire_Dashboard>(KnownResourceNames.AspireDashboard).ExcludeFromManifest();

builder.Build().Run();
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031",
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" // Display dashboard resource in console for local development
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true"
}
},
"generate-manifest": {
Expand Down
3 changes: 2 additions & 1 deletion playground/eShopLite/AppHost/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
"Microsoft.AspNetCore": "Warning",
"Aspire.Hosting.Dcp": "Warning"
}
}
}
4 changes: 2 additions & 2 deletions playground/mongo/Mongo.AppHost/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:15888",
"applicationUrl": "http://localhost:15888/",
Comment thread
mitchdenny marked this conversation as resolved.
Outdated
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16175",
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" // Display dashboard resource in console for local development
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true"
}
},
"generate-manifest": {
Expand Down
2 changes: 1 addition & 1 deletion playground/orleans/OrleansAppHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
// to test end developer dashboard launch experience. Refer to Directory.Build.props
// for the path to the dashboard binary (defaults to the Aspire.Dashboard bin output
// in the artifacts dir).
builder.AddProject<Projects.Aspire_Dashboard>(KnownResourceNames.AspireDashboard);
builder.AddProject<Projects.Aspire_Dashboard>(KnownResourceNames.AspireDashboard).ExcludeFromManifest();
Comment thread
mitchdenny marked this conversation as resolved.
Outdated

using var app = builder.Build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16031",
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true" // Display dashboard resource in console for local development
"DOTNET_ASPIRE_SHOW_DASHBOARD_RESOURCES": "true"
}
},
"generate-manifest": {
Expand Down
23 changes: 4 additions & 19 deletions src/Aspire.Hosting/Dcp/ApplicationExecutor.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics.CodeAnalysis;
using System.Net.Sockets;
using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.Dashboard;
using Aspire.Hosting.Dcp.Model;
using Aspire.Hosting.Lifecycle;
using Aspire.Hosting.Utils;
using k8s;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
Expand Down Expand Up @@ -138,12 +138,12 @@ private async Task ConfigureAspireDashboardResource(IResource dashboardResource,
{
if (Environment.GetEnvironmentVariable("ASPNETCORE_URLS") is not { } appHostApplicationUrl)
{
throw new DistributedApplicationException("Dashboard inner loop hook failed to configure resource because ASPNETCORE_URLS environment variable was not set.");
throw new DistributedApplicationException("Failed to configure dashboard resource because ASPNETCORE_URLS environment variable was not set.");
}

if (Environment.GetEnvironmentVariable("DOTNET_DASHBOARD_OTLP_ENDPOINT_URL") is not { } otlpEndpointUrl)
{
throw new DistributedApplicationException("Dashboard inner loop hook failed to configure resource because DOTNET_DASHBOARD_OTLP_ENDPOINT_URL environment variable was not set.");
throw new DistributedApplicationException("Failed to configure dashboard resource because DOTNET_DASHBOARD_OTLP_ENDPOINT_URL environment variable was not set.");
}

// Grab the resource service URL. We need to inject this into the resource.
Expand Down Expand Up @@ -254,7 +254,7 @@ private static TimeSpan DashboardAvailabilityTimeoutDuration

private async Task CheckDashboardAvailabilityAsync(string delimitedUrlList, CancellationToken cancellationToken)
{
if (TryGetUriFromDelimitedString(delimitedUrlList, ";", out var firstDashboardUrl))
if (StringUtils.TryGetUriFromDelimitedString(delimitedUrlList, ";", out var firstDashboardUrl))
{
await WaitForHttpSuccessOrThrow(firstDashboardUrl, DashboardAvailabilityTimeoutDuration, cancellationToken).ConfigureAwait(false);
}
Expand Down Expand Up @@ -669,21 +669,6 @@ private async Task CreateExecutablesAsync(IEnumerable<AppResource> executableRes
}
}

private static bool TryGetUriFromDelimitedString(string input, string delimiter, [NotNullWhen(true)]out Uri? uri)
{
if (!string.IsNullOrEmpty(input)
&& input.Split(delimiter) is { Length: > 0} splitInput
&& Uri.TryCreate(splitInput[0], UriKind.Absolute, out uri))
{
return true;
}
else
{
uri = null;
return false;
}
}

private static void ApplyLaunchProfile(AppResource executableResource, Dictionary<string, string> config, string launchProfileName, LaunchSettings launchSettings)
{
// Populate DOTNET_LAUNCH_PROFILE environment variable for consistency with "dotnet run" and "dotnet watch".
Expand Down
61 changes: 50 additions & 11 deletions src/Aspire.Hosting/DistributedApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.Lifecycle;
using Aspire.Hosting.Publishing;
using Aspire.Hosting.Utils;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Aspire.Hosting;
Expand Down Expand Up @@ -46,6 +48,7 @@ public class DistributedApplication : IHost, IAsyncDisposable
{
private readonly IHost _host;
private readonly string[] _args;
private readonly ILogger<DistributedApplication> _logger;

/// <summary>
/// Initializes a new instance of the <see cref="DistributedApplication"/> class.
Expand All @@ -55,6 +58,7 @@ public class DistributedApplication : IHost, IAsyncDisposable
public DistributedApplication(IHost host, string[] args)
{
_host = host;
_logger = host.Services.GetRequiredService<ILogger<DistributedApplication>>();
_args = args;
}

Expand Down Expand Up @@ -111,8 +115,38 @@ public ValueTask DisposeAsync()
/// <inheritdoc cref="IHost.StartAsync" />
public async Task StartAsync(CancellationToken cancellationToken = default)
{
await ExecuteBeforeStartHooksAsync(cancellationToken).ConfigureAwait(false);
SuppressLogs();
WriteStartupMessages();
await _host.StartAsync(cancellationToken).ConfigureAwait(false);
await ExecuteBeforeStartHooksAsync(cancellationToken).ConfigureAwait(false);
}

private void WriteStartupMessages()
{
var options = _host.Services.GetRequiredService<IOptions<PublishingOptions>>();

if (options.Value?.Publisher == "manifest")
{
// If we are producing the manifest, don't write startup messages.
return;
}

if (Environment.GetEnvironmentVariable("ASPNETCORE_URLS") is { } dashboardUrls
&& StringUtils.TryGetUriFromDelimitedString(dashboardUrls, ";", out var dashboardUrl))
{
// dotnet watch appears to blindly append a training slash to the URI which present
// on this message. This results in an address that looks like http://host:port// which
// is a 404 on the dashboard. This is a quick workaround.
var dotnetWatchSafeDashboardUrl = dashboardUrl.ToString().TrimEnd('/');
_logger.LogInformation("Now listening on: {DashboardUrl}", dotnetWatchSafeDashboardUrl);
}

if (Environment.GetEnvironmentVariable("DOTNET_DASHBOARD_OTLP_ENDPOINT_URL") is { } otlpEndpointUrl)
{
_logger.LogInformation("OTLP endpoint listening on: {OtlpEndpointUrl}", otlpEndpointUrl);
}

_logger.LogInformation("Application started. Press Ctrl+C to shut down.");
}

/// <inheritdoc cref="IHost.StopAsync" />
Expand All @@ -121,29 +155,34 @@ public async Task StopAsync(CancellationToken cancellationToken = default)
await _host.StopAsync(cancellationToken).ConfigureAwait(false);
}

private void SuppressLifetimeLogsDuringManifestPublishing()
private void SuppressLogs()
Comment thread
mitchdenny marked this conversation as resolved.
Outdated
{
var config = (IConfigurationRoot)_host.Services.GetRequiredService<IConfiguration>();
var options = _host.Services.GetRequiredService<IOptions<PublishingOptions>>();

if (options.Value?.Publisher != "manifest")
{
// If we aren't doing manifest publishing we want the logs
// to be produced as normal.
return;
}

// Suppress excess logging from lifetime logger category. This blocks the "Now listening on"
// message. This is not a problem for VS usage, but it does confuse "dotnet watch" which looks
// at the stdout to figure out when it should launch the browser. Rather than relying on
// lifetime logger category for this special string we will emit it ourselves to make
// sure that it is correct.
var hostingLifetimeLoggingLevelSection = config.GetSection("Logging:LogLevel:Microsoft.Hosting.Lifetime");
hostingLifetimeLoggingLevelSection.Value = "Warning";

// Suppresses warning that we've overridden the default ASPNETCORE_URLS value. This is
// because the endpoints that we host in the AppHost is a randomly assinged resource
// endpoint that is used for the dashboard. The ASPNETCORE_URLS value is actually passed
// into the dashboard that is launched out of process.
var aspNetCoreServerKestrelLoggingLevelSection = config.GetSection("Logging:LogLevel:Microsoft.AspNetCore.Server.Kestrel");
aspNetCoreServerKestrelLoggingLevelSection.Value = "None";

Comment thread
mitchdenny marked this conversation as resolved.
Outdated
config.Reload();
}

/// <inheritdoc cref="HostingAbstractionsHostExtensions.RunAsync" />
public async Task RunAsync(CancellationToken cancellationToken = default)
{
SuppressLifetimeLogsDuringManifestPublishing();
SuppressLogs();
await ExecuteBeforeStartHooksAsync(cancellationToken).ConfigureAwait(false);
WriteStartupMessages();
await _host.RunAsync(cancellationToken).ConfigureAwait(false);
}

Expand Down
25 changes: 25 additions & 0 deletions src/Aspire.Hosting/Utils/StringUtils.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 System.Diagnostics.CodeAnalysis;

namespace Aspire.Hosting.Utils;

internal static class StringUtils
{
public static bool TryGetUriFromDelimitedString(string input, string delimiter, [NotNullWhen(true)] out Uri? uri)
{
if (!string.IsNullOrEmpty(input)
&& input.Split(delimiter) is { Length: > 0 } splitInput
&& Uri.TryCreate(splitInput[0], UriKind.Absolute, out uri))
{
return true;
}
else
{
uri = null;
return false;
}
}

}