diff --git a/backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs b/backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs index 5f9ab21dc..b400aa999 100644 --- a/backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs +++ b/backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs @@ -7,6 +7,8 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Logs; +using OpenTelemetry.Metrics; using OpenTelemetry.Trace; using Squidex.Infrastructure; using Squidex.Infrastructure.Plugins; @@ -26,9 +28,14 @@ public sealed class OtlpPlugin : IPlugin 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); + }); + } + public void Configure(MeterProviderBuilder builder) + { builder.AddOtlpExporter(options => { config.GetSection("logging:otlp").Bind(options); @@ -40,8 +47,7 @@ public sealed class OtlpPlugin : IPlugin { if (config.GetValue("logging:otlp:enabled")) { - services.AddSingleton(); + services.AddSingleton(); } } } diff --git a/backend/src/Squidex.Infrastructure/ITelemetryConfigurator.cs b/backend/src/Squidex.Infrastructure/ITelemetryConfigurator.cs index 7a8cfe005..cce68d3d0 100644 --- a/backend/src/Squidex.Infrastructure/ITelemetryConfigurator.cs +++ b/backend/src/Squidex.Infrastructure/ITelemetryConfigurator.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using OpenTelemetry.Metrics; using OpenTelemetry.Trace; namespace Squidex.Infrastructure; @@ -14,4 +15,8 @@ public interface ITelemetryConfigurator void Configure(TracerProviderBuilder builder) { } + + void Configure(MeterProviderBuilder builder) + { + } } diff --git a/backend/src/Squidex/Config/Domain/TelemetryServices.cs b/backend/src/Squidex/Config/Domain/TelemetryServices.cs index dcd9837cb..5e84a37ef 100644 --- a/backend/src/Squidex/Config/Domain/TelemetryServices.cs +++ b/backend/src/Squidex/Config/Domain/TelemetryServices.cs @@ -6,6 +6,8 @@ // ========================================================================== using OpenTelemetry; +using OpenTelemetry.Logs; +using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using OpenTelemetry.Trace; using Squidex.Infrastructure; @@ -16,21 +18,42 @@ public static class TelemetryServices { public static void AddSquidexTelemetry(this IServiceCollection services, IConfiguration config) { + var serviceName = config.GetValue("logging:name") ?? "Squidex"; + var resourceBuilder = ResourceBuilder.CreateDefault() + .AddService(serviceName, "Squidex", + typeof(TelemetryServices).Assembly.GetName().Version!.ToString()); + services.AddOpenTelemetry(); - services.AddSingleton(serviceProvider => + // Configure logging + services.AddLogging(builder => { - var builder = Sdk.CreateTracerProviderBuilder(); + builder.AddOpenTelemetry(options => + { + options.SetResourceBuilder(resourceBuilder); + options.IncludeFormattedMessage = true; - var serviceName = config.GetValue("logging:name") ?? "Squidex"; + // Add OTLP exporter and bind options directly. Sadly not possible + // to do it through ITelemetryConfigurator as it is not possible to + // get IServiceProvider here. Later when OpenTelemetry.Sdk.CreateLoggerProviderBuilder() + // is available and no longer expermential, we can do it the same way as with tracing and metrics... + if (config.GetValue("logging:otlp:enabled")) + { + options.AddOtlpExporter(options => + { + config.GetSection("logging:otlp").Bind(options); + }); + } + }); + }); - builder.SetResourceBuilder( - ResourceBuilder.CreateDefault() - .AddService(serviceName, "Squidex", - typeof(TelemetryServices).Assembly.GetName().Version!.ToString())); + // Configure tracing + services.AddSingleton(serviceProvider => + { + var builder = Sdk.CreateTracerProviderBuilder(); + builder.SetResourceBuilder(resourceBuilder); builder.AddSource("Squidex"); - builder.AddAspNetCoreInstrumentation(); builder.AddHttpClientInstrumentation(); @@ -50,5 +73,23 @@ public static class TelemetryServices return builder.Build()!; }); + + // Configure metrics + services.AddSingleton(serviceProvider => + { + var builder = Sdk.CreateMeterProviderBuilder(); + + builder.SetResourceBuilder(resourceBuilder); + builder.AddAspNetCoreInstrumentation(); + builder.AddHttpClientInstrumentation(); + builder.AddRuntimeInstrumentation(); + + foreach (var configurator in serviceProvider.GetRequiredService>()) + { + configurator.Configure(builder); + } + + return builder.Build()!; + }); } } diff --git a/backend/src/Squidex/Squidex.csproj b/backend/src/Squidex/Squidex.csproj index 307a8cf02..56d09cbad 100644 --- a/backend/src/Squidex/Squidex.csproj +++ b/backend/src/Squidex/Squidex.csproj @@ -63,6 +63,7 @@ +