mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-13 08:37:07 +00:00
Add OpenTelemetry instrumentation
This commit is contained in:
parent
169745fddb
commit
95f84de20a
6 changed files with 224 additions and 0 deletions
|
|
@ -53,6 +53,12 @@
|
|||
<PackageVersion Include="Moq" Version="4.18.4" />
|
||||
<PackageVersion Include="NEbml" Version="1.1.0.5" />
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.3" />
|
||||
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.15.3" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.15.2" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.15.1-beta.1" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.15.1" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.15.1" />
|
||||
<PackageVersion Include="PlaylistsNET" Version="1.4.1" />
|
||||
<PackageVersion Include="prometheus-net.AspNetCore" Version="8.2.1" />
|
||||
<PackageVersion Include="prometheus-net.DotNetRuntime" Version="4.4.1" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OpenTelemetry.Exporter;
|
||||
using OpenTelemetry.Logs;
|
||||
using OpenTelemetry.Metrics;
|
||||
using OpenTelemetry.Resources;
|
||||
using OpenTelemetry.Trace;
|
||||
|
||||
namespace Jellyfin.Server.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for wiring up OpenTelemetry tracing, metrics and logging.
|
||||
/// </summary>
|
||||
public static class OpenTelemetryServiceCollectionExtensions
|
||||
{
|
||||
private const string DefaultServiceName = "jellyfin";
|
||||
|
||||
/// <summary>
|
||||
/// Registers OpenTelemetry pipelines based on the provided <see cref="OpenTelemetryOptions"/>.
|
||||
/// When <see cref="OpenTelemetryOptions.Enabled"/> is <c>false</c> this method is a no-op.
|
||||
/// </summary>
|
||||
/// <param name="services">The service collection.</param>
|
||||
/// <param name="options">Server-side OpenTelemetry options.</param>
|
||||
/// <returns>The service collection, for chaining.</returns>
|
||||
public static IServiceCollection AddJellyfinOpenTelemetry(this IServiceCollection services, OpenTelemetryOptions options)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(services);
|
||||
ArgumentNullException.ThrowIfNull(options);
|
||||
|
||||
if (!options.Enabled)
|
||||
{
|
||||
return services;
|
||||
}
|
||||
|
||||
var serviceName = string.IsNullOrWhiteSpace(options.ServiceName) ? DefaultServiceName : options.ServiceName;
|
||||
var serviceVersion = Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "unknown";
|
||||
|
||||
var otel = services.AddOpenTelemetry()
|
||||
.ConfigureResource(r => r.AddService(serviceName: serviceName, serviceVersion: serviceVersion));
|
||||
|
||||
if (options.EnableTraces)
|
||||
{
|
||||
otel.WithTracing(tracing =>
|
||||
{
|
||||
if (options.InstrumentAspNetCore)
|
||||
{
|
||||
tracing.AddAspNetCoreInstrumentation();
|
||||
}
|
||||
|
||||
if (options.InstrumentHttpClient)
|
||||
{
|
||||
tracing.AddHttpClientInstrumentation();
|
||||
}
|
||||
|
||||
if (options.InstrumentEntityFrameworkCore)
|
||||
{
|
||||
tracing.AddEntityFrameworkCoreInstrumentation();
|
||||
}
|
||||
|
||||
tracing.AddOtlpExporter(o => ConfigureOtlp(o, options));
|
||||
});
|
||||
}
|
||||
|
||||
if (options.EnableMetrics)
|
||||
{
|
||||
otel.WithMetrics(metrics =>
|
||||
{
|
||||
if (options.InstrumentAspNetCore)
|
||||
{
|
||||
metrics.AddAspNetCoreInstrumentation();
|
||||
}
|
||||
|
||||
if (options.InstrumentHttpClient)
|
||||
{
|
||||
metrics.AddHttpClientInstrumentation();
|
||||
}
|
||||
|
||||
if (options.InstrumentRuntime)
|
||||
{
|
||||
metrics.AddRuntimeInstrumentation();
|
||||
}
|
||||
|
||||
metrics.AddOtlpExporter(o => ConfigureOtlp(o, options));
|
||||
});
|
||||
}
|
||||
|
||||
if (options.EnableLogs)
|
||||
{
|
||||
services.AddLogging(b => b.AddOpenTelemetry(o =>
|
||||
{
|
||||
o.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(serviceName: serviceName, serviceVersion: serviceVersion));
|
||||
o.IncludeFormattedMessage = true;
|
||||
o.IncludeScopes = true;
|
||||
o.AddOtlpExporter(opt => ConfigureOtlp(opt, options));
|
||||
}));
|
||||
}
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
private static void ConfigureOtlp(OtlpExporterOptions exporter, OpenTelemetryOptions options)
|
||||
{
|
||||
exporter.Protocol = options.OtlpProtocol == OpenTelemetryOtlpProtocol.HttpProtobuf
|
||||
? OtlpExportProtocol.HttpProtobuf
|
||||
: OtlpExportProtocol.Grpc;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(options.OtlpEndpoint)
|
||||
&& Uri.TryCreate(options.OtlpEndpoint, UriKind.Absolute, out var endpoint))
|
||||
{
|
||||
exporter.Endpoint = endpoint;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(options.OtlpHeaders))
|
||||
{
|
||||
exporter.Headers = options.OtlpHeaders;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -46,6 +46,12 @@
|
|||
<PackageReference Include="CommandLineParser" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" />
|
||||
<PackageReference Include="Morestachio" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" />
|
||||
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Http" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" />
|
||||
<PackageReference Include="prometheus-net" />
|
||||
<PackageReference Include="prometheus-net.AspNetCore" />
|
||||
<PackageReference Include="Serilog.AspNetCore" />
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ namespace Jellyfin.Server
|
|||
services.AddJellyfinApi(_serverApplicationHost.GetApiPluginAssemblies(), _serverConfigurationManager.GetNetworkConfiguration());
|
||||
services.AddJellyfinDbContext(_serverApplicationHost.ConfigurationManager, _configuration);
|
||||
services.AddJellyfinApiSwagger();
|
||||
services.AddJellyfinOpenTelemetry(_serverConfigurationManager.Configuration.OpenTelemetry);
|
||||
|
||||
// configure custom legacy authentication
|
||||
services.AddCustomAuthentication();
|
||||
|
|
|
|||
84
MediaBrowser.Model/Configuration/OpenTelemetryOptions.cs
Normal file
84
MediaBrowser.Model/Configuration/OpenTelemetryOptions.cs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
namespace MediaBrowser.Model.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The OTLP transport protocol to use when exporting telemetry.
|
||||
/// </summary>
|
||||
public enum OpenTelemetryOtlpProtocol
|
||||
{
|
||||
/// <summary>
|
||||
/// gRPC over HTTP/2. Default OTLP endpoint is http://localhost:4317.
|
||||
/// </summary>
|
||||
Grpc = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Protobuf payloads over HTTP/1.1. Default OTLP endpoint is http://localhost:4318.
|
||||
/// </summary>
|
||||
HttpProtobuf = 1
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Settings controlling the OpenTelemetry pipeline. Disabled by default.
|
||||
/// </summary>
|
||||
public class OpenTelemetryOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether OpenTelemetry instrumentation and export are enabled.
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether traces are collected and exported.
|
||||
/// </summary>
|
||||
public bool EnableTraces { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether metrics are collected and exported.
|
||||
/// </summary>
|
||||
public bool EnableMetrics { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether logs are exported via OpenTelemetry.
|
||||
/// </summary>
|
||||
public bool EnableLogs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether ASP.NET Core requests are instrumented.
|
||||
/// </summary>
|
||||
public bool InstrumentAspNetCore { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether outgoing HTTP client calls are instrumented.
|
||||
/// </summary>
|
||||
public bool InstrumentHttpClient { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether Entity Framework Core database commands are instrumented.
|
||||
/// Backed by a prerelease OpenTelemetry instrumentation package.
|
||||
/// </summary>
|
||||
public bool InstrumentEntityFrameworkCore { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether .NET runtime metrics (GC, thread pool, exceptions, etc.) are collected.
|
||||
/// </summary>
|
||||
public bool InstrumentRuntime { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the service name reported in telemetry. Defaults to "jellyfin" when null or empty.
|
||||
/// </summary>
|
||||
public string? ServiceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the OTLP endpoint URL. When null or empty the SDK default for the configured protocol is used.
|
||||
/// </summary>
|
||||
public string? OtlpEndpoint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the OTLP protocol. The default is gRPC.
|
||||
/// </summary>
|
||||
public OpenTelemetryOtlpProtocol OtlpProtocol { get; set; } = OpenTelemetryOtlpProtocol.Grpc;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets optional OTLP headers in the form "key1=value1,key2=value2". Useful for vendor authentication tokens.
|
||||
/// </summary>
|
||||
public string? OtlpHeaders { get; set; }
|
||||
}
|
||||
|
|
@ -288,4 +288,9 @@ public class ServerConfiguration : BaseApplicationConfiguration
|
|||
/// Gets or sets a value indicating whether old authorization methods are allowed.
|
||||
/// </summary>
|
||||
public bool EnableLegacyAuthorization { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the OpenTelemetry options.
|
||||
/// </summary>
|
||||
public OpenTelemetryOptions OpenTelemetry { get; set; } = new OpenTelemetryOptions();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue