Logging

codewithmukesh/dotnet-claude-kit/skills/logging

by codewithmukesh23300897f4d1No license754 starsListed Oct 8, 2026Updated Oct 8, 2026Repository updated 2 months ago

Observability overview and glue for .NET 10: how the pieces fit together, plus the cross-cutting parts owned here — ASP.NET health check endpoints (/health), correlation IDs, and log-level strategy. For deep Serilog setup load `serilog`; for traces and metrics load `opentelemetry`. Load this skill when setting up observability from scratch, wiring health check endpoints or correlation IDs, or when the user says "logging", "observability", "monitoring setup", "liveness", "readiness", or "ILogger".

Instructions only

Logging & Observability

Core Principles

  1. Structured logging with Serilog — Every log entry is a structured event with named properties, not a formatted string. This enables searching, filtering, and alerting. All setup (two-stage bootstrap, AddSerilog(), sinks, enrichers) lives in the serilog skill — that skill's AddSerilog()-over-UseSerilog() guidance is canonical.
  2. OpenTelemetry for distributed tracing — Traces connect requests across services; metrics track system health over time. Full setup lives in the opentelemetry skill.
  3. Health checks for operational readiness — Every service exposes /health endpoints for load balancers and orchestrators. Liveness and readiness are separate questions and separate endpoints.
  4. Correlation IDs for request tracing — Every request gets a unique ID that flows through all log entries and downstream service calls, so one user complaint maps to one filtered log stream.

Patterns

How the Pieces Fit Together

ConcernOwnerSkill
Structured application logsSerilog (AddSerilog())serilog
Request summary loggingUseSerilogRequestLogging()serilog
Traces + metrics + OTLP exportOpenTelemetry SDKopentelemetry
Health endpoints, correlation IDs, log-level strategyThis skilllogging

Wire logging first (you need logs to debug the rest), then health checks, then tracing.

Correlation IDs

csharp
// Middleware to set correlation IDpublic class CorrelationIdMiddleware(RequestDelegate next){    private const string CorrelationIdHeader = "X-Correlation-Id";
    public async Task InvokeAsync(HttpContext context)    {        var correlationId = context.Request.Headers[CorrelationIdHeader].FirstOrDefault()            ?? Guid.NewGuid().ToString();
        context.Items["CorrelationId"] = correlationId;        context.Response.Headers[CorrelationIdHeader] = correlationId;
        using (LogContext.PushProperty("CorrelationId", correlationId))        {            await next(context);        }    }}
// Program.cs — register early so every downstream log carries the IDapp.UseMiddleware<CorrelationIdMiddleware>();

Why middleware: pushing the property once at the pipeline edge attaches it to every log event in the request scope — no per-call-site plumbing. Propagate the same header on outgoing HttpClient calls via a DelegatingHandler (see the httpclient-factory skill).

Health Checks

csharp
// Program.csbuilder.Services.AddHealthChecks()    .AddNpgSql(builder.Configuration.GetConnectionString("Default")!,        name: "database", tags: ["ready"])    .AddRedis(builder.Configuration.GetConnectionString("Redis")!,        name: "redis", tags: ["ready"])    .AddRabbitMQ(builder.Configuration.GetConnectionString("RabbitMq")!,        name: "rabbitmq", tags: ["ready"]);
// Map endpointsapp.MapHealthChecks("/health/live", new HealthCheckOptions{    Predicate = _ => false // No dependency checks — just "am I running?"});
app.MapHealthChecks("/health/ready", new HealthCheckOptions{    Predicate = check => check.Tags.Contains("ready")});

Why two endpoints: liveness failing means "restart me"; readiness failing means "stop sending traffic". Conflating them makes a slow database restart your app in a loop.

Log-Level Strategy

LevelUse forEnvironment default
DebugDiagnostic detail, payload dumps (never PII in prod)Development only
InformationBusiness events: order placed, job completedDev + staging
WarningRecoverable anomalies: retry fired, fallback usedEverywhere — production default
ErrorFailed operations that need attentionEverywhere
Fatal/CriticalApp cannot continueEverywhere

Why Warning as the production default: Information-level request noise at scale costs real money in log storage and drowns the signals. Keep Information for genuine business events via namespace overrides (see the serilog skill's MinimumLevel.Override pattern).

Anti-patterns

Don't Log Sensitive Data

csharp
// BAD — logging credentialslogger.LogInformation("User logged in: {Email} with password {Password}", email, password);
// GOOD — log identifiers, never secrets or PII at Information levellogger.LogInformation("User {UserId} logged in", userId);

Don't Skip Health Check Tags

csharp
// BAD — all checks run for liveness AND readinessapp.MapHealthChecks("/health");
// GOOD — separate liveness (am I running?) from readiness (can I serve traffic?)app.MapHealthChecks("/health/live", new() { Predicate = _ => false });app.MapHealthChecks("/health/ready", new() { Predicate = c => c.Tags.Contains("ready") });

Don't Re-Implement What the Owning Skill Provides

csharp
// BAD — hand-rolling Serilog bootstrap here from memorybuilder.Host.UseSerilog(...);  // legacy API — the serilog skill forbids this
// GOOD — load the serilog skill and use its two-stage AddSerilog() bootstrapbuilder.Services.AddSerilog((services, lc) => lc.ReadFrom.Configuration(builder.Configuration)...);

Decision Guide

ScenarioRecommendation
Application logging setupLoad serilog — AddSerilog() two-stage bootstrap
Distributed tracing / metricsLoad opentelemetry — OTLP exporter
Custom business metricsIMeterFactory + counters/histograms (opentelemetry skill)
Request tracingCorrelation ID middleware (this skill)
Container health/health/live and /health/ready endpoints (this skill)
Log storageSeq (development), Elastic/Grafana/OTLP backend (production)
Log levelsDebug in dev, Information in staging, Warning default in production

Source and attribution

Source:codewithmukesh/dotnet-claude-kitinskills/loggingat commit2330089

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal

More from codewithmukesh/dotnet-claude-kit

Wrap Up

codewithmukesh

Captures end-of-session work, pending tasks and learnings into a handoff file, and reloads it at session start.

Productivity & Workflow754updated 2 months ago

Workflow Mastery

codewithmukesh

Claude Code workflow mastery for .NET developers. Covers parallel execution with git worktrees, plan mode strategy, verification loops, auto-formatting hooks, permission setup for dotnet CLI, prompting techniques, subagent patterns, and context discipline — token budget management, MCP-first navigation, lazy loading, and subagent isolation — all adapted for the .NET ecosystem. Load this skill when setting up Claude Code for a .NET project, optimizing workflows, running parallel sessions, when context is running low or sessions feel sluggish, when exploring a large codebase efficiently, or when the user mentions "productivity", "workflow", "parallel", "worktree", "plan mode", "permissions", "hooks", "10x", "setup Claude Code", "speed up development", "context", "tokens", "budget", "running out of context", "too many files", or "large codebase". Inspired by tips from Boris Cherny (creator of Claude Code) and the Anthropic team.

Awaiting classification754updated 2 months ago

Vertical Slice

codewithmukesh

Guides .NET developers in structuring applications with Vertical Slice Architecture, covering feature folders, endpoint grouping and handler patterns.

Software Development754updated 2 months ago

Testing

codewithmukesh

Testing strategy for .NET 10 applications. Covers xUnit v3, WebApplicationFactory for integration tests, Testcontainers for real database testing, Verify for snapshot testing, and the AAA pattern. Load this skill when writing tests, setting up test infrastructure, reviewing test coverage, or when the user mentions "test", "xUnit", "WebApplicationFactory", "Testcontainers", "integration test", "unit test", "bUnit", "snapshot test", "Verify", "test coverage", "AAA pattern", "WireMock", or "FakeTimeProvider".

Awaiting classification754updated 2 months ago

Tdd

codewithmukesh

Guided test-driven development workflow for .NET 10 using xUnit v3, WebApplicationFactory, Testcontainers, and Verify snapshots. Follows the strict red-green-refactor cycle. Use when: "TDD", "test-driven", "let's TDD this", "red green refactor", "write the test first", or when building a feature with clear acceptance criteria.

Awaiting classification754updated 2 months ago

Spec

codewithmukesh

Turns a vague feature idea into an agreed, persisted specification file through structured questioning rounds.

Productivity & Workflow754updated 2 months ago