mirror of
https://github.com/alex289/CleanArchitecture.git
synced 2025-06-30 02:31:08 +00:00
feat: Improve Aspire telemetry
This commit is contained in:
parent
27c8b6064c
commit
2f494932f8
@ -7,13 +7,14 @@ var rabbitPasswordParameter =
|
|||||||
builder.AddParameter("username", rabbitPasswordRessource.Value);
|
builder.AddParameter("username", rabbitPasswordRessource.Value);
|
||||||
|
|
||||||
var rabbitMq = builder
|
var rabbitMq = builder
|
||||||
.AddRabbitMQ("RabbitMq", null, rabbitPasswordParameter, 5672)
|
.AddRabbitMQ("RabbitMQ", null, rabbitPasswordParameter, 5672)
|
||||||
.WithManagementPlugin();
|
.WithManagementPlugin();
|
||||||
|
|
||||||
var sqlServer = builder.AddSqlServer("SqlServer");
|
var sqlServer = builder.AddSqlServer("SqlServer");
|
||||||
var db = sqlServer.AddDatabase("Database", "clean-architecture");
|
var db = sqlServer.AddDatabase("Database", "clean-architecture");
|
||||||
|
|
||||||
builder.AddProject<Projects.CleanArchitecture_Api>("CleanArchitecture-Api")
|
builder.AddProject<Projects.CleanArchitecture_Api>("CleanArchitecture-Api")
|
||||||
|
.WithEnvironment("ASPIRE_ENABLED", "true")
|
||||||
.WithOtlpExporter()
|
.WithOtlpExporter()
|
||||||
.WithHttpHealthCheck("/health")
|
.WithHttpHealthCheck("/health")
|
||||||
.WithReference(redis)
|
.WithReference(redis)
|
||||||
|
@ -4,14 +4,13 @@
|
|||||||
"Aspire": {
|
"Aspire": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"dotnetRunMessages": true,
|
"dotnetRunMessages": true,
|
||||||
"launchBrowser": true,
|
"launchBrowser": false,
|
||||||
"applicationUrl": "https://localhost:17270;http://localhost:15188",
|
"applicationUrl": "https://localhost:17270;http://localhost:15188",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development",
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
"DOTNET_ENVIRONMENT": "Development",
|
"DOTNET_ENVIRONMENT": "Development",
|
||||||
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21200",
|
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21200",
|
||||||
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22111",
|
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22111"
|
||||||
"ASPIRE_ENABLED": "true"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,6 @@
|
|||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
"Microsoft.AspNetCore": "Warning"
|
"Microsoft.AspNetCore": "Warning"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"EnableHttpTraces": false
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
@ -39,6 +40,8 @@ public static class Extensions
|
|||||||
|
|
||||||
private static void ConfigureOpenTelemetry<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
|
private static void ConfigureOpenTelemetry<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
|
||||||
{
|
{
|
||||||
|
var enableHttpTraces = builder.Configuration.GetValue<bool?>("APP_ENABLE_HTTP_TRACES") ?? false;
|
||||||
|
|
||||||
builder.Logging.AddOpenTelemetry(logging =>
|
builder.Logging.AddOpenTelemetry(logging =>
|
||||||
{
|
{
|
||||||
logging.IncludeFormattedMessage = true;
|
logging.IncludeFormattedMessage = true;
|
||||||
@ -48,17 +51,44 @@ public static class Extensions
|
|||||||
builder.Services.AddOpenTelemetry()
|
builder.Services.AddOpenTelemetry()
|
||||||
.WithMetrics(metrics =>
|
.WithMetrics(metrics =>
|
||||||
{
|
{
|
||||||
metrics.AddAspNetCoreInstrumentation()
|
metrics
|
||||||
|
.AddAspNetCoreInstrumentation()
|
||||||
.AddHttpClientInstrumentation()
|
.AddHttpClientInstrumentation()
|
||||||
.AddRuntimeInstrumentation();
|
.AddRuntimeInstrumentation();
|
||||||
})
|
})
|
||||||
.WithTracing(tracing =>
|
.WithTracing(tracing =>
|
||||||
{
|
{
|
||||||
tracing.AddSource(builder.Environment.ApplicationName)
|
tracing
|
||||||
.AddAspNetCoreInstrumentation()
|
.AddSource(builder.Environment.ApplicationName)
|
||||||
.AddGrpcClientInstrumentation()
|
.AddSource("MassTransit")
|
||||||
.AddEntityFrameworkCoreInstrumentation()
|
.AddAspNetCoreInstrumentation(options =>
|
||||||
.AddHttpClientInstrumentation();
|
{
|
||||||
|
options.EnableAspNetCoreSignalRSupport = true;
|
||||||
|
options.EnrichWithHttpResponse = HttpEnricher.HttpRouteEnricher;
|
||||||
|
})
|
||||||
|
.AddGrpcClientInstrumentation(options =>
|
||||||
|
{
|
||||||
|
if (enableHttpTraces)
|
||||||
|
{
|
||||||
|
options.EnrichWithHttpRequestMessage = HttpEnricher.RequestEnricher;
|
||||||
|
options.EnrichWithHttpResponseMessage = HttpEnricher.ResponseEnricher;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.AddEntityFrameworkCoreInstrumentation(options =>
|
||||||
|
{
|
||||||
|
options.EnrichWithIDbCommand = (activity, dbCommand) =>
|
||||||
|
{
|
||||||
|
activity.SetTag("sql.statement", dbCommand.CommandText);
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.AddHttpClientInstrumentation(options =>
|
||||||
|
{
|
||||||
|
if (enableHttpTraces)
|
||||||
|
{
|
||||||
|
options.EnrichWithHttpRequestMessage = HttpEnricher.RequestEnricher;
|
||||||
|
options.EnrichWithHttpResponseMessage = HttpEnricher.ResponseEnricher;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.AddOpenTelemetryExporters();
|
builder.AddOpenTelemetryExporters();
|
||||||
|
80
CleanArchitecture.ServiceDefaults/HttpEnricher.cs
Normal file
80
CleanArchitecture.ServiceDefaults/HttpEnricher.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||||
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
|
||||||
|
namespace CleanArchitecture.ServiceDefaults;
|
||||||
|
|
||||||
|
public static class HttpEnricher
|
||||||
|
{
|
||||||
|
public static Action<System.Diagnostics.Activity, HttpRequestMessage>? RequestEnricher = static (activity, request) =>
|
||||||
|
{
|
||||||
|
if (request.Content is not null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var requestContent = request.Content.ReadAsStringAsync().Result;
|
||||||
|
activity.SetTag("http.request.body", requestContent);
|
||||||
|
}
|
||||||
|
catch (HttpRequestException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activity.SetTag("http.response.body", null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static Action<System.Diagnostics.Activity, HttpResponseMessage>? ResponseEnricher = static (activity, response) =>
|
||||||
|
{
|
||||||
|
if (response.Content is not null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var responseContent = response.Content.ReadAsStringAsync().Result;
|
||||||
|
activity.SetTag("http.response.body", responseContent);
|
||||||
|
}
|
||||||
|
catch (HttpRequestException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activity.SetTag("http.response.body", null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static Action<System.Diagnostics.Activity, HttpResponse>? HttpRouteEnricher = static (activity, request) =>
|
||||||
|
{
|
||||||
|
var endpoint = request.HttpContext.GetEndpoint();
|
||||||
|
|
||||||
|
if (endpoint is RouteEndpoint routeEndpoint)
|
||||||
|
{
|
||||||
|
var descriptor = routeEndpoint.Metadata.GetMetadata<ControllerActionDescriptor>();
|
||||||
|
|
||||||
|
if (descriptor is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var controller = descriptor.ControllerName;
|
||||||
|
var action = descriptor.ActionName;
|
||||||
|
|
||||||
|
var pathParameters = descriptor.Parameters
|
||||||
|
.Where(p => p.BindingInfo is null || p.BindingInfo.BindingSource?.Id == "Path")
|
||||||
|
.Select(p => $"{{{p.Name}}}");
|
||||||
|
|
||||||
|
var route = string.Join("/", [controller, action, .. pathParameters]);
|
||||||
|
|
||||||
|
activity.DisplayName = route;
|
||||||
|
activity.SetTag("http.route", route);
|
||||||
|
activity.SetTag("Name", route);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user