CasCap.Common.Hosting.AspNetCore 5.2.0

Prefix Reserved
dotnet add package CasCap.Common.Hosting.AspNetCore --version 5.2.0
                    
NuGet\Install-Package CasCap.Common.Hosting.AspNetCore -Version 5.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CasCap.Common.Hosting.AspNetCore" Version="5.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CasCap.Common.Hosting.AspNetCore" Version="5.2.0" />
                    
Directory.Packages.props
<PackageReference Include="CasCap.Common.Hosting.AspNetCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CasCap.Common.Hosting.AspNetCore --version 5.2.0
                    
#r "nuget: CasCap.Common.Hosting.AspNetCore, 5.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CasCap.Common.Hosting.AspNetCore@5.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CasCap.Common.Hosting.AspNetCore&version=5.2.0
                    
Install as a Cake Addin
#tool nuget:?package=CasCap.Common.Hosting.AspNetCore&version=5.2.0
                    
Install as a Cake Tool

CasCap.Common.Hosting.AspNetCore

ASP.NET Core hosting defaults for feature-gated controllers, Serilog logging, and OpenTelemetry metrics, traces, and logs.

Installation

dotnet add package CasCap.Common.Hosting.AspNetCore

Target frameworks: net10.0, net11.0

Usage

In an ASP.NET Core application, enable the controller features this host can serve:

using System;
using System.Collections.Generic;
using CasCap.Common.Abstractions;
using CasCap.Common.Extensions;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);
var enabledFeatures = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Reports" };
builder.Services.AddControllers().AddFeatureGatedControllers(enabledFeatures);

var app = builder.Build();
app.MapControllers();
app.Run();

[ApiController]
[FeatureController("Reports")]
[Route("api/reports")]
public sealed class ReportsController : ControllerBase
{
    [HttpGet]
    public IActionResult Get() => Ok(new { Status = "ready" });
}

Feature-Gated Controllers

[FeatureController(...)] accepts one or more names. A marked controller is discoverable when any name overlaps the supplied enabled set; unmarked controllers remain available. Use a case-insensitive set consistently with the feature launcher. Register dependencies for every controller retained on the host. Gating controls discovery; it is not authentication or authorization.

Use the same set with CasCap.Common.Services when background features share those names. If controllers live in separate assemblies, application part selection can gate entire assemblies instead.

Controller Discovery Activity

flowchart TD
    DISCOVER["MVC controller discovery"] --> MARKED{"FeatureController attribute?"}
    MARKED -->|No| KEEP["Retain controller"]
    MARKED -->|Yes| ENABLED{"Any marked feature enabled?"}
    ENABLED -->|Yes| KEEP
    ENABLED -->|No| REMOVE["Remove controller from discovery"]
    KEEP --> ROUTES["Controller routes and API discovery"]

Serilog

SerilogExtensions.GetBootstrapLogger() provides early startup logging. Call builder.InitializeSerilog() to configure the host pipeline, then initialize OpenTelemetry if needed. This ordering matters: Serilog initialization clears existing logging providers. Serilog reads the Serilog section and forwards events to Microsoft logging providers, including the OpenTelemetry exporter.

The API also accepts an optional configureLogger callback, applied after the standard defaults and configuration binding. A deliberately reloadable application can use it to attach a per-host LoggingLevelSwitch to MinimumLevel.ControlledBy. This controls the actual pipeline, including forwarding, rather than only console output. The application owns validation, monitor subscription/disposal and its immutable startup baseline; existing calls retain their behavior.

Extension Description
SerilogExtensions.GetBootstrapLogger() Creates a bootstrap console logger and wires ApplicationLogging.LoggerFactory
SerilogWebApplicationBuilderExtensions.InitializeSerilog(builder, categoryName) Configures Serilog as the host pipeline and forwards events to registered logging providers
LoggerConfiguration.AddCasCapDefaults(IConfiguration) Applies standard enrichers, console output, health-check filtering, RequestPath removal and configuration binding
SerilogWebApplicationExtensions.UseCasCapRequestLogging(app, slowRequestThreshold) Emits one privacy-safe summary event per HTTP request

SerilogExtensions.ConsoleLevelSwitch controls console verbosity independently from other sinks. It defaults to Verbose; interactive applications can temporarily raise it to Warning to prevent rendered output from interleaving with logs.

Level Layers

Three independent settings decide whether an event is written:

  1. The pipeline minimum, Serilog:MinimumLevel:Default, or a LoggingLevelSwitch attached through configureLogger.
  2. Category overrides. The defaults set Microsoft.AspNetCore and System.Net.Http.HttpClient to Warning and Microsoft.Extensions.Http to Information; Serilog:MinimumLevel:Override entries replace them. An override applies whatever the pipeline minimum is, so lowering the minimum to Debug does not reveal framework categories.
  3. Sink thresholds, such as ConsoleLevelSwitch, which can only drop events further.

The defaults also exclude events below Warning whose SourceContext starts with Microsoft.Extensions.Diagnostics.HealthChecks, so the framework's routine health-check processing stays out of a Debug log while failed checks remain visible. The filter reads only SourceContext; application events that merely mention health checks are kept. SerilogExtensions.IsHealthCheckNoise exposes the predicate for custom pipelines.

ASP.NET Core's hosting scope attaches the raw request path to every event logged during a request. Raw paths can carry record or user identifiers, so the defaults remove RequestPath; RequestId, TraceId and SpanId still correlate events with their request summary.

Request Summary

app.UseCasCapRequestLogging() logs one event per request with the method, the matched route template, the status code and the elapsed time:

HTTP GET /api/widgets/{id} responded 200 in 4.2 ms

It never logs the raw path, query string, headers or bodies. A request that matches no endpoint logs (unmatched) as its route.

Outcome Level
Unhandled exception or 5xx response Error
Failed /healthz probe; non-streaming request slower than the threshold (default five seconds) Warning
Other 1xx-4xx responses Information
Client cancellation; 404 with no matching endpoint Debug
Successful /healthz probe; successful static file Verbose

Register it first, before UseExceptionHandler, so it times the whole pipeline, records authentication and authorization rejections and leaves the exception itself to the exception handler, which logs it once:

var app = builder.Build();
app.UseCasCapRequestLogging();
app.UseExceptionHandler();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

OpenTelemetry

InitializeOpenTelemetry registers metrics, traces and logs with OTLP gRPC export. It takes an IMetricsConfig, ApplicationMetadata, and optional Redis connection, exporter authentication and metric/trace customization callbacks.

Extension Description
OpenTelemetryExtensions.InitializeOpenTelemetry(...) Registers OpenTelemetry metrics, traces, and logs with OTLP gRPC export
MeterProviderBuilderExtensions.AddHistogramView(...) Registers explicit histogram bucket boundaries for a prefixed instrument
MetricBoundaries.Symmetric(...) Mirrors positive boundaries into a signed set around zero

Registration is skipped when OtlpExporterEndpoint is null. Development hosts register a Prometheus exporter; exposing its endpoint still requires application setup. Non-development hosts add ASP.NET Core, runtime and process metrics. HTTP client tracing is enabled in both environments; ASP.NET Core and optional Redis tracing are added outside Development.

Configuration Examples

The library consumes IMetricsConfig; it does not bind a fixed AppConfig section. The application chooses an options type and section. This example uses Telemetry:

using System;
using CasCap.Common.Abstractions;
using CasCap.Common.Extensions;
using CasCap.Common.Models;
using Microsoft.Extensions.Configuration;
using Serilog;

builder.InitializeSerilog();
var telemetry = builder.Configuration.GetSection("Telemetry").Get<TelemetryOptions>()
    ?? new TelemetryOptions();
builder.InitializeOpenTelemetry(telemetry, new ApplicationMetadata());

public sealed record TelemetryOptions : IMetricsConfig
{
    public string MetricNamePrefix { get; init; } = "example";
    public string OtelServiceName { get; init; } = "Example.App";
    public Uri? OtlpExporterEndpoint { get; init; }
}

Run these registrations before builder.Build() in the Usage example. Place the options type after the program's top-level statements.

No Telemetry Export

{
    "Telemetry": {
        "MetricNamePrefix": "example",
        "OtelServiceName": "Example.App"
    }
}

OTLP Export

{
    "Telemetry": {
        "MetricNamePrefix": "example",
        "OtelServiceName": "Example.App",
        "OtlpExporterEndpoint": "http://otel-collector.example.com:4317"
    }
}

Use a caller-controlled endpoint and protect exporter credentials with a secret provider. Telemetry can leave the application through the configured collector; review resource attributes and emitted events before enabling it.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed.  net11.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.2.0 90 11/14/2026
5.1.0 268 11/5/2026
5.0.0 116 11/1/2026
4.17.0 200 10/24/2026
4.16.0 168 10/21/2026
4.15.0 85 10/6/2026