diff --git a/Common.Web/Common.Web.csproj b/Common.Web/Common.Web.csproj index 2cc37ac1..af1ab085 100644 --- a/Common.Web/Common.Web.csproj +++ b/Common.Web/Common.Web.csproj @@ -9,6 +9,14 @@ + + + + + + + + diff --git a/Common.Web/ServiceConfiguration.cs b/Common.Web/ServiceConfiguration.cs index af186f43..ac6e919e 100644 --- a/Common.Web/ServiceConfiguration.cs +++ b/Common.Web/ServiceConfiguration.cs @@ -1,6 +1,4 @@ using Common.Web.Services; -using Microsoft.ApplicationInsights; -using Microsoft.ApplicationInsights.Extensibility; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -29,27 +27,5 @@ public static void ConfigurePlugins(IApplicationBuilder app, IEnumerable(); - if (telemetryConfig != null) - { - telemetryConfig.ConnectionString = aiConn; - var telemetry = new TelemetryClient(telemetryConfig); - telemetry.TrackEvent("Application start"); - telemetry.TrackTrace("Trace Application start"); - } - } - } - } + } } diff --git a/Common.Web/Setup.AppInsights.cs b/Common.Web/Setup.AppInsights.cs new file mode 100644 index 00000000..85c07398 --- /dev/null +++ b/Common.Web/Setup.AppInsights.cs @@ -0,0 +1,49 @@ +using Microsoft.ApplicationInsights; +using Microsoft.ApplicationInsights.Extensibility; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace Common.Web +{ + public class SetupAppInsights + { + public static void Add(IServiceCollection services, ConfigurationManager configurationManager) + { + //services.Configure(telemetryConfiguration => + //{ + // var builder = telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessorChainBuilder; + // telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessorChainBuilder + // .UseAdaptiveSampling(maxTelemetryItemsPerSecond: 5, excludedTypes: "Trace;Request;Exception"); + //}); + //services.AddApplicationInsightsTelemetry(new ApplicationInsightsServiceOptions + //{ + // EnableAdaptiveSampling = false, + //}); + + //services.AddSingleton(); + } + + public static void Configure(IApplicationBuilder app, IConfiguration config, bool isDevelopment) + { + var aiConn = config.GetValue("ApplicationInsights:ConnectionString", ""); + if (aiConn == "SECRET" || aiConn == string.Empty) + { + if (isDevelopment == false) + Console.WriteLine($"Warning: InstrumentationKey not set ({aiConn})"); + //throw new ArgumentException("InstrumentationKey not set"); + } + else + { + var telemetryConfig = app.ApplicationServices.GetService(); + if (telemetryConfig != null) + { + telemetryConfig.ConnectionString = aiConn; + var telemetry = new TelemetryClient(telemetryConfig); + telemetry.TrackEvent("Application start"); + telemetry.TrackTrace("Trace Application start"); + } + } + } + } +} diff --git a/Common.Web/Setup.OpenTelemetry.cs b/Common.Web/Setup.OpenTelemetry.cs new file mode 100644 index 00000000..51cbcc55 --- /dev/null +++ b/Common.Web/Setup.OpenTelemetry.cs @@ -0,0 +1,63 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; + +namespace Common.Web +{ + public class SetupOpenTelemetry + { + public static void Add(IServiceCollection services, IConfiguration config) + { + //config["Otel:"] + var endpointLoki = "http://localhost:4318"; + var endpointPrometheus = "/metrics"; + + services.AddOpenTelemetry() + //.ConfigureResource(builder => builder.AddDetector(sp => sp.GetRequiredService())) + //.ConfigureResource(builder => builder.AddService(serviceName: "MyService")) + .WithTracing(builder => + { + builder.AddAspNetCoreInstrumentation() + .AddConsoleExporter(); + if (endpointLoki?.Any() == true) + builder.AddOtlpExporter(opts => { opts.Endpoint = new Uri(endpointLoki); }); + }) + .WithMetrics(builder => + { + builder.AddAspNetCoreInstrumentation() + .AddRuntimeInstrumentation() + .AddHttpClientInstrumentation() + .AddConsoleExporter() + .AddPrometheusExporter(c => c.ScrapeEndpointPath = endpointPrometheus); + //.AddOtlpExporter(opts => { opts.Endpoint = new Uri(endpoint); }); + }); + } + + public static void Configure(IApplicationBuilder app) + { + app.UseOpenTelemetryPrometheusScrapingEndpoint(); + } + + public class MyResourceDetector : IResourceDetector + { + private readonly IWebHostEnvironment webHostEnvironment; + + public MyResourceDetector(IWebHostEnvironment webHostEnvironment) + { + this.webHostEnvironment = webHostEnvironment; + } + + public Resource Detect() + { + return ResourceBuilder.CreateEmpty() + .AddService(serviceName: webHostEnvironment.ApplicationName) + .AddAttributes(new Dictionary { ["host.environment"] = webHostEnvironment.EnvironmentName }) + .Build(); + } + } + } +} diff --git a/Directory.Packages.props b/Directory.Packages.props index e5081c63..8b74cfd7 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -61,6 +61,14 @@ + + + + + + + + diff --git a/ProblemSource/TrainingApi/Startup.cs b/ProblemSource/TrainingApi/Startup.cs index 7c8e9a20..e228dfe7 100644 --- a/ProblemSource/TrainingApi/Startup.cs +++ b/ProblemSource/TrainingApi/Startup.cs @@ -1,7 +1,5 @@ using Common.Web; using Common.Web.Services; -using Microsoft.ApplicationInsights.AspNetCore.Extensions; -using Microsoft.ApplicationInsights.Extensibility; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.FileProviders; @@ -33,6 +31,8 @@ public void ConfigureServices(IServiceCollection services, ConfigurationManager services.AddTransient(); services.AddSingleton(); + services.AddHttpClient(); + services.AddHttpContextAccessor(); var apiKeyUsers = new List(); configurationManager.GetSection("AppSettings:ApiKeyUsers").Bind(apiKeyUsers); @@ -85,29 +85,21 @@ public void ConfigureServices(IServiceCollection services, ConfigurationManager services.AddLogging(builder => { - builder.AddApplicationInsights(); // AddAzureWebAppDiagnostics + //builder.AddApplicationInsights(); // AddAzureWebAppDiagnostics }); - services.Configure(telemetryConfiguration => - { - var builder = telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessorChainBuilder; - telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessorChainBuilder - .UseAdaptiveSampling(maxTelemetryItemsPerSecond:5, excludedTypes: "Trace;Request;Exception"); - }); - services.AddApplicationInsightsTelemetry(new ApplicationInsightsServiceOptions - { - EnableAdaptiveSampling = false, - }); - - services.AddSingleton(); + SetupOpenTelemetry.Add(services, configurationManager); + //SetupAppInsights.Add(services, configurationManager); } - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ServiceConfiguration.ConfigurePlugins(app, plugins); - // Configure the HTTP request pipeline. - if (env.HasDevelopmentEnvironment()) + SetupOpenTelemetry.Configure(app); + + // Configure the HTTP request pipeline. + if (env.HasDevelopmentEnvironment()) { //app.UseSwagger(); //app.UseSwaggerUI(); @@ -219,13 +211,13 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) MinimumSameSitePolicy = env.IsDevelopment() ? Microsoft.AspNetCore.Http.SameSiteMode.None : Microsoft.AspNetCore.Http.SameSiteMode.Lax }); - ServiceConfiguration.ConfigureApplicationInsights(app, config, env.IsDevelopment()); + //SetupAppInsights.Configure(app, config, env.IsDevelopment()); //if (oldDbStartup != null) // oldDbStartup.Configure(app); } - private IPluginModule[] ConfigureProblemSource(IServiceCollection services, IConfiguration config, IHostEnvironment env) + private IPluginModule[] ConfigureProblemSource(IServiceCollection services, IConfiguration config, IHostEnvironment env) { //TypedConfiguration.ConfigureTypedConfiguration(services, config, "AppSettings"); ConfigureAuthentication(services, config, env);