skills/analistadesarrollo4/skills/dotnet-elastic-apm

dotnet-elastic-apm

SKILL.md

Elasticsearch and Elastic APM Integration

Logging and Observability Standards

  • Logging Standard: All logging must be implemented using Serilog with structured logging.
  • Centralized Destination: All logs must be centralized in Elasticsearch, using Elastic APM authentication and Data Streams configuration.
  • Enriched Information: Logs must be enriched with context properties such as app-name and app-type.
  • Bootstrapping: Serilog initialization must be COMPLETELY OMITTED IN Program.cs and performed through an Extension Method from the Infrastructure layer.

Security and Data Privacy

  • Sensitive Information: PII (Personally Identifiable Information), credentials, and tokens must NEVER be logged.
  • Sanitize sensitive data before logging.
  • Use log filters to exclude sensitive endpoints or data.

Serilog Configuration Extension Method

Create an extension method in Infrastructure/Extensions/ExtensionLogging.cs:

using Serilog;
using Serilog.Events;
using Serilog.Sinks.Elasticsearch;
using Elastic.Ingest.Elasticsearch.DataStreams;
using Elastic.Ingest.Elasticsearch;
using Elastic.Transport;

namespace Infrastructure.Extensions
{
    /// <summary>
    /// Extension class for configuring Serilog with Elasticsearch and Elastic APM.
    /// </summary>
    public static class ExtensionLogging
    {
        /// <summary>
        /// Configures Serilog with Elasticsearch using Elastic APM.
        /// </summary>
        /// <param name="configuration">Application configuration.</param>
        public static void AddLog(IConfiguration configuration)
        {
            string? elasticUrl = configuration.GetValue<string>("Global:Elastic:Url");
            string? environment = configuration.GetValue<string>("Global:Elastic:Env");
            string? elasticUser = configuration.GetValue<string>("Global:Elastic:User");
            string? elasticPass = configuration.GetValue<string>("Global:Elastic:Pass");
            string? logLevelEnv = configuration.GetValue<string>("Global:Elastic:LogLevel");

            LogEventLevel logEventLevel = (LogEventLevel)int.Parse(logLevelEnv!);

            Log.Logger = new LoggerConfiguration()
                .Enrich.FromLogContext()
                .Enrich.WithProperty("app-name", configuration.GetSection("Elastic").GetValue<string>("app-name"))
                .Enrich.WithProperty("app-type", configuration.GetSection("Elastic").GetValue<string>("app-type"))
                .WriteTo.Console()
                .WriteTo.Elasticsearch([new Uri(elasticUrl!)], opts =>
                {
                    // Use DataStream for Elastic APM compatibility
                    opts.DataStream = new DataStreamName("app", environment!, "logs");
                    opts.BootstrapMethod = BootstrapMethod.None;
                    opts.MinimumLevel = logEventLevel;
                }, transport =>
                {
                    // Basic Authentication
                    transport.Authentication(new BasicAuthentication(elasticUser!, elasticPass!));
                    // Callback to accept certificates (e.g., in development)
                    transport.ServerCertificateValidationCallback((a, b, c, d) => true);
                })
                .CreateLogger();
        }
    }
}

Program.cs Configuration

Configure Serilog and Elastic APM in Program.cs only for development:

if (app.Environment.IsDevelopment())
{
    builder.Services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true));
    ExtensionLogging.AddLog(builder.Configuration);
    builder.Services.AddAllElasticApm();
}

Required NuGet Packages

  • Serilog.AspNetCore
  • Serilog.Sinks.Elasticsearch
  • Elastic.Apm.NetCoreAll
  • Elastic.Ingest.Elasticsearch
  • Elastic.Ingest.Elasticsearch.DataStreams
  • Elastic.Transport

Configuration Settings (appsettings.json)

{
  "Elastic": {
    "app-name": "your-app-name",
    "app-type": "api",
    "Url": "https://your-elastic-url:9200",
    "Env": "development",
    "User": "elastic_user",
    "Pass": "elastic_password",
    "LogLevel": "2"
  }
}

Log Level Values

  • 0 = Verbose
  • 1 = Debug
  • 2 = Information
  • 3 = Warning
  • 4 = Error
  • 5 = Fatal

Best Practices

  • Use structured logging with named properties: Log.Information("User {UserId} logged in", userId);
  • Avoid string interpolation in log messages.
  • Use log context to enrich logs with request-specific data.
  • Configure appropriate log levels for different environments.
  • Monitor APM metrics alongside logs for complete observability.
Weekly Installs
3
First Seen
Feb 6, 2026
Installed on
mcpjam3
claude-code3
replit3
junie3
windsurf3
zencoder3