From 96ae604ea27276ed5526c4b4c1b9a76256ed0f9d Mon Sep 17 00:00:00 2001 From: ichumakov Date: Thu, 19 Mar 2026 15:42:52 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BF?= =?UTF-8?q?=D0=BE=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AppHost/AppHost.csproj | 1 + AppHost/Program.cs | 4 +- Client.Wasm/Properties/launchSettings.json | 6 +- CloudDevelopment.sln | 8 ++- GeneratorService/GeneratorService.csproj | 3 + GeneratorService/Program.cs | 5 ++ ServiceDefaults/Extensions.cs | 80 ++++++++++++++++++++++ ServiceDefaults/ServiceDefaults.csproj | 21 ++++++ 8 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 ServiceDefaults/Extensions.cs create mode 100644 ServiceDefaults/ServiceDefaults.csproj diff --git a/AppHost/AppHost.csproj b/AppHost/AppHost.csproj index 4b870754..22b84afa 100644 --- a/AppHost/AppHost.csproj +++ b/AppHost/AppHost.csproj @@ -17,6 +17,7 @@ + \ No newline at end of file diff --git a/AppHost/Program.cs b/AppHost/Program.cs index ab52e867..08a8fe6b 100644 --- a/AppHost/Program.cs +++ b/AppHost/Program.cs @@ -9,6 +9,8 @@ .WithReference(redis) .WaitFor(redis) .WithEnvironment("Cors__AllowedOrigin", client.GetEndpoint("http")) - .WaitFor(client); + .WaitFor(client) + .WithUrlForEndpoint("http", url => url.Url += "/swagger") + .WithUrlForEndpoint("https", url => url.Url += "/swagger"); builder.Build().Run(); \ No newline at end of file diff --git a/Client.Wasm/Properties/launchSettings.json b/Client.Wasm/Properties/launchSettings.json index 0d824ea7..60120ec3 100644 --- a/Client.Wasm/Properties/launchSettings.json +++ b/Client.Wasm/Properties/launchSettings.json @@ -12,7 +12,7 @@ "http": { "commandName": "Project", "dotnetRunMessages": true, - "launchBrowser": true, + "launchBrowser": false, "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", "applicationUrl": "http://localhost:5127", "environmentVariables": { @@ -22,7 +22,7 @@ "https": { "commandName": "Project", "dotnetRunMessages": true, - "launchBrowser": true, + "launchBrowser": false, "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", "applicationUrl": "https://localhost:7282;http://localhost:5127", "environmentVariables": { @@ -31,7 +31,7 @@ }, "IIS Express": { "commandName": "IISExpress", - "launchBrowser": true, + "launchBrowser": false, "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" diff --git a/CloudDevelopment.sln b/CloudDevelopment.sln index ba4012e3..e7b068d0 100644 --- a/CloudDevelopment.sln +++ b/CloudDevelopment.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.14.36811.4 @@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeneratorService", "Generat EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeneratorService.Tests", "GeneratorService.Tests\GeneratorService.Tests.csproj", "{EBCA1829-1CB1-773B-8241-CE00EBFBCF9C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceDefaults", "ServiceDefaults\ServiceDefaults.csproj", "{9F0B1437-6E39-4706-8A9D-89BCE4B31AA0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -33,6 +35,10 @@ Global {EBCA1829-1CB1-773B-8241-CE00EBFBCF9C}.Debug|Any CPU.Build.0 = Debug|Any CPU {EBCA1829-1CB1-773B-8241-CE00EBFBCF9C}.Release|Any CPU.ActiveCfg = Release|Any CPU {EBCA1829-1CB1-773B-8241-CE00EBFBCF9C}.Release|Any CPU.Build.0 = Release|Any CPU + {9F0B1437-6E39-4706-8A9D-89BCE4B31AA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9F0B1437-6E39-4706-8A9D-89BCE4B31AA0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9F0B1437-6E39-4706-8A9D-89BCE4B31AA0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9F0B1437-6E39-4706-8A9D-89BCE4B31AA0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/GeneratorService/GeneratorService.csproj b/GeneratorService/GeneratorService.csproj index 785b4965..676109b5 100644 --- a/GeneratorService/GeneratorService.csproj +++ b/GeneratorService/GeneratorService.csproj @@ -18,4 +18,7 @@ + + + \ No newline at end of file diff --git a/GeneratorService/Program.cs b/GeneratorService/Program.cs index c736f927..9940f24c 100644 --- a/GeneratorService/Program.cs +++ b/GeneratorService/Program.cs @@ -46,8 +46,12 @@ }); builder.Services.AddCors(); + builder.AddServiceDefaults(); + var app = builder.Build(); + app.MapDefaultEndpoints(); + var allowedOrigin = builder.Configuration["Cors:AllowedOrigin"] ?? throw new InvalidOperationException("Cors:AllowedOrigin is not configured"); @@ -64,6 +68,7 @@ ? Results.BadRequest("id must be > 0") : Results.Ok(await svc.GetAsync(id, ct))) .WithName("GetPatient") + .WithSummary("Возвращает медицинскую карту пациента по идентификатору") .Produces() .ProducesProblem(400); diff --git a/ServiceDefaults/Extensions.cs b/ServiceDefaults/Extensions.cs new file mode 100644 index 00000000..c497d055 --- /dev/null +++ b/ServiceDefaults/Extensions.cs @@ -0,0 +1,80 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using OpenTelemetry; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +namespace Microsoft.Extensions.Hosting; + +public static class Extensions +{ + public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBuilder builder) + { + builder.ConfigureOpenTelemetry(); + builder.AddDefaultHealthChecks(); + builder.Services.AddServiceDiscovery(); + builder.Services.ConfigureHttpClientDefaults(http => + { + http.AddStandardResilienceHandler(); + http.AddServiceDiscovery(); + }); + return builder; + } + + public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder) + { + builder.Logging.AddOpenTelemetry(logging => + { + logging.IncludeFormattedMessage = true; + logging.IncludeScopes = true; + }); + + builder.Services.AddOpenTelemetry() + .WithMetrics(metrics => + { + metrics.AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + .AddRuntimeInstrumentation(); + }) + .WithTracing(tracing => + { + tracing.AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation(); + }); + + builder.AddOpenTelemetryExporters(); + return builder; + } + + private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder) + { + var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]); + if (useOtlpExporter) + builder.Services.AddOpenTelemetry().UseOtlpExporter(); + return builder; + } + + public static IHostApplicationBuilder AddDefaultHealthChecks(this IHostApplicationBuilder builder) + { + builder.Services.AddHealthChecks() + .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]); + return builder; + } + + public static WebApplication MapDefaultEndpoints(this WebApplication app) + { + if (app.Environment.IsDevelopment()) + { + app.MapHealthChecks("/health"); + app.MapHealthChecks("/alive", new HealthCheckOptions + { + Predicate = r => r.Tags.Contains("live") + }); + } + return app; + } +} \ No newline at end of file diff --git a/ServiceDefaults/ServiceDefaults.csproj b/ServiceDefaults/ServiceDefaults.csproj new file mode 100644 index 00000000..6cb5f230 --- /dev/null +++ b/ServiceDefaults/ServiceDefaults.csproj @@ -0,0 +1,21 @@ + + + + net8.0 + enable + enable + true + + + + + + + + + + + + + + \ No newline at end of file