Přeskočit na hlavní obsah

Telemetry

Overview​

Provide logging, tracing and metrics for ASP.NET Core.

For application-defined classifications on individual log entries, see Logging. The ASOL.Core.Logging package uses the host's existing logging providers and configuration.

Install​

  • ASOL.Core.Telemetry.Client.AspNetCore - Logs, tracing and metrics initialization and OTLP export configuration.
  • ASOL.Core.Telemetry.Client.Logger - ILogger initialization and configuration.

Usage of third party libraries (NuGets)​

  • OpenTelemetry.Extensions.Hosting
  • OpenTelemetry
  • OpenTelemetry.Instrumentation.AspNetCore
  • OpenTelemetry.Instrumentation.EntityFrameworkCore
  • OpenTelemetry.Instrumentation.Http
  • OpenTelemetry.Instrumentation.Runtime
  • OpenTelemetry.Exporter.Console
  • OpenTelemetry.Exporter.OpenTelemetryProtocol
  • Serilog.AspNetCore
  • Serilog.Enrichers.Environment
  • Serilog.Expressions
  • Serilog.Enrichers.Process
  • Serilog.Enrichers.Span
  • Serilog.Exceptions
  • Serilog.Sinks.File
  • Elastic.CommonSchema.Serilog

Changelog​

  • 0.0.1.52330-dev
    • fixed incorrect Tenant ID logging
  • 0.0.1.48598-dev
    • fix application code mapping
  • 0.0.1.48471-dev
    • Fix filtering unnecessary tracing data while reverse proxy is used
  • 0.0.1.45792-dev
    • Support for Application Insights has been removed; OpenTelemetry is now used instead. For proper functioning, the minimum required versions are:
      • ASOL.Core.Messaging* - 0.0.1.45790-dev
      • ASOL.Core.Persistence* - 0.0.1.45789-dev
      • ASOL.Core.Processing - 0.0.1.45802-dev
    • AddTelemetry method requires IConfiguration parameter.

Logger​

Call ClearProviders() before AddTelemetry() and AddTelemetryLogger() to remove the default logging providers and avoid duplicate console output. Calling it after AddTelemetry() removes the OpenTelemetry logging provider and prevents OTLP log export.

using ASOL.Core.Telemetry.Client.AspNetCore;
using ASOL.Core.Telemetry.Client.Logger;
using Microsoft.Extensions.Logging;

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging => logging.ClearProviders())
.ConfigureServices((context, services) => services.AddTelemetry(context.Configuration))
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.AddTelemetryLogger();

or

using ASOL.Core.Telemetry.Client.AspNetCore;
using ASOL.Core.Telemetry.Client.Logger;
using Microsoft.Extensions.Logging;

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Services.AddTelemetry(builder.Configuration);
builder.Host.AddTelemetryLogger();

Logs, traces and metrics​

using ASOL.Core.Telemetry.Client.AspNetCore;

public class Startup(IConfiguration configuration)
{
public virtual void ConfigureServices(IServiceCollection services)
{
// ..
services.AddTelemetry(Configuration);
// ..
}
}

Configuration​

Set Telemetry:ServiceName in appsettings.json.

OTLP export​

Select the transport explicitly with Telemetry:OtlpProtocol: Grpc (the default, preserving existing behavior) or HttpProtobuf.

OtlpEndpoint is the shared base endpoint. If a per-signal endpoint is unset, gRPC uses this URL as-is. HTTP/protobuf appends /v1/logs, /v1/traces, or /v1/metrics to the base URL, preserving any configured base path.

A per-signal endpoint overrides the shared endpoint and is used exactly as configured. For HTTP/protobuf, include the complete signal path:

{
"Telemetry": {
"ServiceName": "ASOL.MyOwnProject",
"OtlpProtocol": "HttpProtobuf",
"OtlpEndpoint": "http://collector:4318/otel/",
"EnableOtlpLogging": true,
"OtlpLogsEndpoint": "http://collector:4318/custom/logs",
"OtlpTracesEndpoint": "http://collector:4318/custom/traces",
"OtlpMetricsEndpoint": "http://collector:4318/custom/metrics"
}
}

With the example above, any unset signal endpoint resolves under http://collector:4318/otel/v1/. Traces and metrics are not exported when neither the per-signal endpoint nor the shared endpoint is configured. AddTelemetry(configuration) configures OTLP export for all three signals and registers the OpenTelemetry logging provider for Microsoft.Extensions.Logging.ILogger. When using Serilog, also call AddTelemetryLogger() to configure enrichment and file/console sinks and forward log events to the registered logging providers.

EnableOtlpLogging defaults to false, preserving the existing Filebeat workflow. Set it to true to export logs through the OpenTelemetry logging provider using the OTLP exporter. It requires either OtlpLogsEndpoint or OtlpEndpoint; enabling it without either throws an InvalidOperationException during AddTelemetry(configuration) registration. The logs exporter uses the same endpoint resolution and protocol configuration as traces and metrics. Existing Serilog file and console sinks remain active; disable Filebeat ingestion for the same logs if duplicate delivery is unwanted. AddTelemetryLogger() forwards events to all registered logging providers. Call ClearProviders() first, as shown above, so the default Microsoft console provider does not duplicate Serilog console output. Register any additional providers after clearing the defaults.

Logs share the resource configuration used by traces and metrics, including the service name, instance ID, build version (when configured), application code, and deployment.environment. The environment is read from ASPNETCORE_ENVIRONMENT, with unknown as the fallback. Formatted messages and logging scopes are included.

appsettings.json​

{
"Logging": {
"LogLevel": {
"Default": "Information",
"ASOL.Core": "Warning",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Warning",
"Microsoft.AspNetCore.Hosting": "Warning",
"Microsoft.AspNetCore.Mvc.Internal": "Warning",
"Microsoft.AspNetCore.Authentication": "Warning"
}
},
"Telemetry": {
"ServiceName": "ASOL.MyOwnProject"
}
}

ProblemDetails setup​

public class ProblemDetailsOptionsCustomSetup(
IWebHostEnvironment environment,
IHttpContextAccessor httpContextAccessor,
IOptions<ApiBehaviorOptions> apiOptions)
: ProblemDetailsOptionsDefaultSetup(environment, httpContextAccessor, apiOptions)
{

public override void Configure(Hellang.Middleware.ProblemDetails.ProblemDetailsOptions options)
{
...
options.Map<ValidationException>(ex =>
{
Activity.Current?.AddException(ex);
...
});

options.Map<ProcessingCoreException>(ex =>
{
Activity.Current?.AddException(ex);
...
});
}
}

Example of custom trace and metrics​

public sealed class InstrumentationSource : IDisposable
{
internal const string ActivitySourceName = "MyOwnProject";
internal const string MeterName = "MyOwnProject";
private readonly Meter meter;

public InstrumentationSource()
{
ActivitySource = new ActivitySource(ActivitySourceName);
meter = new Meter(MeterName);
HighPriceCounter = meter.CreateCounter<long>("myownproject.highprice", description: "The number item with high price");
}

public ActivitySource ActivitySource { get; }

public Counter<long> HighPriceCounter { get; }

public void Dispose()
{
ActivitySource.Dispose();
meter.Dispose();
}
}

Register sources in Startup.cs:

using ASOL.Core.Telemetry.Client.AspNetCore;

public class Startup(IConfiguration configuration)
{
public virtual void ConfigureServices(IServiceCollection services)
{
// ..
services.AddSingleton<InstrumentationSource>();
services.AddTelemetry(configuration, builder => builder
.AddTracingSource(InstrumentationSource.ActivitySourceName)
.AddMeterSource(InstrumentationSource.MeterName)
);
// ..
}
}

Usage:

using var activity = instrumentationSource.ActivitySource.StartActivity("process item");
if (command.Price > 1)
{
instrumentationSource.HighPriceCounter.Add(1);
}

DevOps Monitoring​

You can view your application logs in the monitoring section.

Authorization

  • The user must be assigned the ASOLEU-Product-AP-.Developer role
  • For a concrete application and non-production stages the user must be assigned the {applicationCode}.User role or the {applicationCode}.Owner role
  • For a concrete application and production stages the user must be assigned the {applicationCode}.Owner role