diff --git a/backend/extensions/Squidex.Extensions/APM/ApplicationInsights/ApplicationInsightsPlugin.cs b/backend/extensions/Squidex.Extensions/APM/ApplicationInsights/ApplicationInsightsPlugin.cs index 0aa0dac45..f654665ea 100644 --- a/backend/extensions/Squidex.Extensions/APM/ApplicationInsights/ApplicationInsightsPlugin.cs +++ b/backend/extensions/Squidex.Extensions/APM/ApplicationInsights/ApplicationInsightsPlugin.cs @@ -8,24 +8,39 @@ using Azure.Monitor.OpenTelemetry.Exporter; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Trace; +using Squidex.Infrastructure; using Squidex.Infrastructure.Plugins; namespace Squidex.Extensions.APM.ApplicationInsights { public sealed class ApplicationInsightsPlugin : IPlugin { - public void ConfigureServices(IServiceCollection services, IConfiguration config) + private class Configurator : ITelemetryConfigurator { - if (config.GetValue("logging:applicationInsights:enabled")) + private readonly IConfiguration config; + + public Configurator(IConfiguration config) { - services.AddOpenTelemetryTracing(builder => + this.config = config; + } + + public void Configure(TracerProviderBuilder builder) + { + builder.AddAzureMonitorTraceExporter(options => { - builder.AddAzureMonitorTraceExporter(options => - { - config.GetSection("logging:applicationInsights").Bind(options); - }); + config.GetSection("logging:applicationInsights").Bind(options); }); } } + + public void ConfigureServices(IServiceCollection services, IConfiguration config) + { + if (config.GetValue("logging:applicationInsights:enabled")) + { + services.AddSingleton(); + } + } } } diff --git a/backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs b/backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs index 64584dd1b..88113bc38 100644 --- a/backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs +++ b/backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs @@ -9,27 +9,41 @@ using System; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Trace; +using Squidex.Infrastructure; using Squidex.Infrastructure.Plugins; namespace Squidex.Extensions.APM.Datadog { public sealed class OtlpPlugin : IPlugin { - public void ConfigureServices(IServiceCollection services, IConfiguration config) + private class Configurator : ITelemetryConfigurator { - if (config.GetValue("logging:otlp:enabled")) + private readonly IConfiguration config; + + public Configurator(IConfiguration config) { - services.AddOpenTelemetryTracing(builder => - { - // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client - AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); + this.config = config; + } + + public void Configure(TracerProviderBuilder builder) + { + // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); - builder.AddOtlpExporter(options => - { - config.GetSection("logging:otlp").Bind(options); - }); + builder.AddOtlpExporter(options => + { + config.GetSection("logging:otlp").Bind(options); }); } } + + public void ConfigureServices(IServiceCollection services, IConfiguration config) + { + if (config.GetValue("logging:otlp:enabled")) + { + services.AddSingleton(); + } + } } } diff --git a/backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverPlugin.cs b/backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverPlugin.cs index ba11b2a53..6769e934e 100644 --- a/backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverPlugin.cs +++ b/backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverPlugin.cs @@ -10,6 +10,7 @@ using Google.Cloud.Diagnostics.Common; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Trace; +using Squidex.Infrastructure; using Squidex.Infrastructure.Plugins; using Squidex.Log; @@ -17,29 +18,45 @@ namespace Squidex.Extensions.APM.Stackdriver { public sealed class StackdriverPlugin : IPlugin { - public void ConfigureServices(IServiceCollection services, IConfiguration config) + private class Configurator : ITelemetryConfigurator { - var projectId = config.GetValue("logging:stackdriver:projectId"); - var projectName = config.GetValue("logging:stackdriver:projectName") ?? "Squidex"; + private readonly string projectId; + + public Configurator(string projectId) + { + this.projectId = projectId; + } + public void Configure(TracerProviderBuilder builder) + { + builder.UseStackdriverExporter(projectId); + } + } + + public void ConfigureServices(IServiceCollection services, IConfiguration config) + { var isEnabled = config.GetValue("logging:stackdriver:enabled"); - if (isEnabled && !string.IsNullOrWhiteSpace(projectId)) + if (isEnabled) { - services.AddOpenTelemetryTracing(builder => + var projectId = config.GetValue("logging:stackdriver:projectId"); + + if (!string.IsNullOrWhiteSpace(projectId)) { - builder.UseStackdriverExporter(projectId); - }); + services.AddSingleton( + new Configurator(projectId)); - services.AddSingleton(); + services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); - var version = Assembly.GetEntryAssembly().GetName().Version?.ToString(); + var serviceName = config.GetValue("logging:name") ?? "Squidex"; + var serviceVersion = Assembly.GetEntryAssembly().GetName().Version?.ToString(); - services.AddSingleton(c => ContextExceptionLogger.Create(projectId, projectName, version, null)); + services.AddSingleton(c => ContextExceptionLogger.Create(projectId, serviceVersion, serviceVersion, null)); + } } } } diff --git a/backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj b/backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj index b38c43a62..2485ca0ee 100644 --- a/backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj +++ b/backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj @@ -23,6 +23,7 @@ + diff --git a/backend/src/Squidex.Infrastructure/ITelemetryConfigurator.cs b/backend/src/Squidex.Infrastructure/ITelemetryConfigurator.cs new file mode 100644 index 000000000..13e6e6a2f --- /dev/null +++ b/backend/src/Squidex.Infrastructure/ITelemetryConfigurator.cs @@ -0,0 +1,18 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using OpenTelemetry.Trace; + +namespace Squidex.Infrastructure +{ + public interface ITelemetryConfigurator + { + void Configure(TracerProviderBuilder builder) + { + } + } +} diff --git a/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj b/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj index 5f6afd114..580bfd80f 100644 --- a/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj +++ b/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj @@ -24,6 +24,7 @@ + diff --git a/backend/src/Squidex.Infrastructure/Telemetry.cs b/backend/src/Squidex.Infrastructure/Telemetry.cs index 59cd58489..36287808b 100644 --- a/backend/src/Squidex.Infrastructure/Telemetry.cs +++ b/backend/src/Squidex.Infrastructure/Telemetry.cs @@ -13,7 +13,7 @@ namespace Squidex.Infrastructure { public static class Telemetry { - public static readonly ActivitySource Activities = new ActivitySource("Notifo"); + public static readonly ActivitySource Activities = new ActivitySource("Squidex"); public static Activity? StartMethod(this ActivitySource activity, Type type, [CallerMemberName] string? memberName = null) { diff --git a/backend/src/Squidex/Config/Domain/TelemetryServices.cs b/backend/src/Squidex/Config/Domain/TelemetryServices.cs index da524a005..0cab16676 100644 --- a/backend/src/Squidex/Config/Domain/TelemetryServices.cs +++ b/backend/src/Squidex/Config/Domain/TelemetryServices.cs @@ -5,27 +5,44 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System.Collections.Generic; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry; using OpenTelemetry.Resources; using OpenTelemetry.Trace; +using Squidex.Infrastructure; namespace Squidex.Config.Domain { public static class TelemetryServices { - public static void AddSquidexTelemetry(this IServiceCollection services) + public static void AddSquidexTelemetry(this IServiceCollection services, IConfiguration config) { - services.AddOpenTelemetryTracing(builder => + services.AddOpenTelemetryTracing(); + + services.AddSingleton(serviceProvider => { + var builder = Sdk.CreateTracerProviderBuilder(); + + var serviceName = config.GetValue("logging:name") ?? "Squidex"; + builder.SetResourceBuilder( ResourceBuilder.CreateDefault() - .AddService("Squidex", "Squidex", + .AddService(serviceName, "Squidex", typeof(TelemetryServices).Assembly.GetName().Version!.ToString())); builder.AddSource("Squidex"); builder.AddAspNetCoreInstrumentation(); builder.AddHttpClientInstrumentation(); + + foreach (var configurator in serviceProvider.GetRequiredService>()) + { + configurator.Configure(builder); + } + + return builder.Build(); }); } } diff --git a/backend/src/Squidex/Startup.cs b/backend/src/Squidex/Startup.cs index 7748339b0..3c34e1c91 100644 --- a/backend/src/Squidex/Startup.cs +++ b/backend/src/Squidex/Startup.cs @@ -68,7 +68,7 @@ namespace Squidex services.AddSquidexSerializers(); services.AddSquidexStoreServices(config); services.AddSquidexSubscriptions(config); - services.AddSquidexTelemetry(); + services.AddSquidexTelemetry(config); services.AddSquidexTranslation(config); services.AddSquidexUsageTracking(config); }