Cloudstrap.Observability 0.2.0-preview.83

Prefix Reserved
This is a prerelease version of Cloudstrap.Observability.
dotnet add package Cloudstrap.Observability --version 0.2.0-preview.83
                    
NuGet\Install-Package Cloudstrap.Observability -Version 0.2.0-preview.83
                    
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="Cloudstrap.Observability" Version="0.2.0-preview.83" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Cloudstrap.Observability" Version="0.2.0-preview.83" />
                    
Directory.Packages.props
<PackageReference Include="Cloudstrap.Observability" />
                    
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 Cloudstrap.Observability --version 0.2.0-preview.83
                    
#r "nuget: Cloudstrap.Observability, 0.2.0-preview.83"
                    
#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 Cloudstrap.Observability@0.2.0-preview.83
                    
#: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=Cloudstrap.Observability&version=0.2.0-preview.83&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Cloudstrap.Observability&version=0.2.0-preview.83&prerelease
                    
Install as a Cake Tool

Cloudstrap.Observability

Serilog logging, a vendor-neutral OpenTelemetry pipeline (traces, metrics, logs), correlation and business tracing for ASP.NET Core applications — one call, driven by the Cloudstrap: configuration section.

Runtime requirement: this package carries a Microsoft.AspNetCore.App framework reference. Every consumer requires the ASP.NET Core shared framework at run time — mcr.microsoft.com/dotnet/aspnet base images work; mcr.microsoft.com/dotnet/runtime-only base images are not supported.

Quick start

var builder = WebApplication.CreateBuilder(args);

builder.UseCloudstrapObservability();

var app = builder.Build();
app.UseRouting();
app.UseCloudstrapCorrelation();   // after routing, so endpoint metadata is visible
app.MapControllers();
app.Run();
{
  "Cloudstrap": {
    "Application": {
      "SystemName": "Contoso",
      "SubsystemName": "Orders",
      "SubsystemType": "Api"
    },
    "OpenTelemetry": {
      "Mode": "Otlp",
      "Endpoint": "https://collector.example.com"
    },
    "Logging": {
      "Level": "Information"
    }
  }
}

Misconfiguration fails at the UseCloudstrapObservability() call with a ConfigurationValidationException listing every violation — never at first use.

Telemetry modes (Cloudstrap:OpenTelemetry:Mode)

Mode Behavior
Disabled No tracer/meter/log providers are registered. IBusinessTrace and correlation still resolve and work as safe no-ops. The default.
Console Traces, metrics and logs export to the console — local development without a collector.
Otlp Exports over OTLP. See endpoint resolution below.
AzureMonitor Requires the Cloudstrap.Observability.AzureMonitor package to contribute the exporter. Without it, host startup fails with an actionable message — telemetry is never silently dropped. Sampler ownership moves to that exporter (see below).
Sampler ownership in AzureMonitor mode

The Azure Monitor exporter installs its own sampler, and OpenTelemetry's SetSampler is last-wins, so Cloudstrap installs none in this mode — the Application Insights sampler stamps the sample rate that lets the portal renormalize counts, which a replacement sampler would lose.

EnableBlazorHubTracing = false is still honored: hub spans are suppressed at export time instead of at sampling time, ahead of every exporter Cloudstrap and its exporter packages register, so no ComponentHub span is exported. Two consequences are worth knowing:

  • Under the exporter's rate-limited default, hub spans are sampled in and consume traces-per-second budget before they are scrubbed, so Blazor Server applications should prefer a fixed percentage (Cloudstrap:AzureMonitor:SamplingRatio) over a rate limit.
  • Only the hub span itself is suppressed. Work started inside a hub invocation — a downstream HTTP call, for example — is still exported, parented to the span that was scrubbed; in Console and Otlp mode the parent-based sampler drops those descendants along with the hub span.

In contribute mode Cloudstrap adds no scrub: it contributes its sampler chain as usual (subject to ApplySampler), and an Azure Monitor exporter registered afterwards replaces that sampler — so hub suppression is the host's to arrange there.

OTLP endpoint resolution

  • An explicit Cloudstrap:OpenTelemetry:Endpoint wins: Cloudstrap configures HTTP/protobuf with per-signal paths (/v1/traces, /v1/metrics, /v1/logs, preserving any base path) and formats Cloudstrap:OpenTelemetry:Headers into the exporter headers.
  • No explicit endpoint but OTEL_EXPORTER_OTLP_ENDPOINT present: Cloudstrap sets nothing — endpoint, protocol and headers are the OpenTelemetry SDK's to resolve from the standard variables.
  • Neither: startup fails validation, naming both Endpoint and OTEL_EXPORTER_OTLP_ENDPOINT.
  • ConfigureOtlpExporter (code-level option) runs last per signal and has the final say.

Owner vs. contribute (Aspire coexistence)

Cloudstrap coexists with platform defaults such as Aspire ServiceDefaults without depending on them:

  • Owner (default): Cloudstrap stands up the whole pipeline — resource identity (service.name from the workload name, deployment.environment.name, host.name, plus cloudstrap.system.name, cloudstrap.subsystem.name, cloudstrap.subsystem.type and optional cloudstrap.environment.tier), ASP.NET Core / HTTP client / runtime / optional SQL client instrumentation, exporter selection per mode.
  • Contribute (options.PipelineMode = ObservabilityPipelineMode.Contribute): the host owns the pipeline; Cloudstrap adds only its differentiated pieces — the cloudstrap.* resource attributes (no service.name takeover), the sampler chain and the trace noise filters. No instrumentation, no exporters, no duplicate spans, no Azure Monitor guard.
  • ApplySampler caveat: OpenTelemetry's SetSampler is last-wins. When the host must own the sampler, set ApplySampler = false and Cloudstrap steps aside entirely.

Trace noise defaults (every convention has an override)

Probe endpoints (from Cloudstrap:HealthChecks), /_blazor, /_framework/, /_content/, static-asset extensions and configured IgnoredPathSegments are dropped from traces; Blazor Server component-hub spans are sampled out unless EnableBlazorHubTracing. Filters compose with — never overwrite — a filter the host already set. Switch the whole default filter off with EnableDefaultTraceNoiseFilter = false; AlwaysOnSampler records every span for development diagnosis.

Logging

  • The Serilog provider is added to the host's logging — ClearProviders is never called, and providers you registered stay.
  • The minimum level comes from Cloudstrap:Logging:Level; framework categories (Microsoft.AspNetCore, Microsoft.AspNetCore.Hosting.Diagnostics, System.Net.Http.HttpClient, Microsoft.Hosting.Lifetime) are seeded at Warning; Cloudstrap:Logging:LevelOverrides entries are applied last, so your overrides win — including over the seeds. Level: None writes nothing.
  • File logging (Cloudstrap:Logging:File) writes daily-rolling log-.log files (10 MB size cap, 20 files retained, shared) directly under the configured Path — no subfolders, no machine-derived names.
  • ConfigureSerilog (code-level option) runs last over the Serilog configuration and has the final say.

Logging before the host exists

CloudstrapOptions options = configuration.GetCloudstrapOptions();
using ILoggerFactory bootstrapLoggers = CloudstrapBootstrapLogger.Create(options);
bootstrapLoggers.CreateLogger("Contoso.Orders.Startup").LogInformation("Configuration loaded");
// dispose after Build() — the host's own logging takes over from there

The factory is independent of the host pipeline and never sets the global Log.Logger.

Correlation

  • Header convention: X-Correlation-ID, overridable via Cloudstrap:Correlation:HeaderName.
  • app.UseCloudstrapCorrelation() (place it after routing) establishes the ambient id for every request: the inbound header value, or a generated one (the current trace id, else a GUID — override by registering your own ICorrelationSource).
  • Read or set the id anywhere — with or without an HttpContext — through ICorrelationContextAccessor.
  • The id is echoed back in a response header of the same name, so a caller who sent none still learns the generated one and can quote it. Turn it off with Cloudstrap:Correlation:Request:EchoInResponse = false; a value the application set itself is never overwritten.
  • Code holding the HttpContext but running outside the middleware's async scope — an exception handler placed ahead of it, for instance — reads the id with HttpContext.GetCloudstrapCorrelationId(). Ordinary application code should prefer ICorrelationContextAccessor, which also works where there is no request.
  • Require correlation globally (Cloudstrap:Correlation:Request:RequireForAllEndpoints) or per endpoint ([CorrelationRequired]); a missing header then yields 400 application/problem+json naming the header. Exemptions: configured HealthEndpoints/ExcludeEndpoints paths, health-check endpoint metadata, and [AllowNoCorrelation]. The 400 body is backed by the framework's problem-details services, which AddCloudstrapCorrelation registers additively.
  • Outbound propagation: .AddCloudstrapCorrelationHandler() on any IHttpClientBuilder adds a set-if-absent delegating handler carrying the same header — safe under retries and double registration.

Business tracing

public sealed class OrderService(IBusinessTrace businessTrace)
{
    public void Submit(Order order)
    {
        using IBusinessTraceScope scope = businessTrace.StartSpan("SubmitOrder", nameof(OrderService));
        // ... domain work ...
        scope.SetOutcome("succeeded");
    }
}

Keep operation, component and outcome low-cardinality — kinds of work, never user or document identifiers. Spans ride the pipeline in both owner and contribute modes (the Cloudstrap.Business source is pre-wired; consumers owning their own pipeline can AddSource(CloudstrapActivitySources.Business)), and a disabled pipeline makes every scope a safe no-op.

Health-check tag vocabulary

CloudstrapHealthCheckTags.Liveness ("live") and CloudstrapHealthCheckTags.Readiness ("ready") are the shared tags Cloudstrap hosting packages use to route checks to the liveness and readiness probes.

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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (6)

Showing the top 5 NuGet packages that depend on Cloudstrap.Observability:

Package Downloads
Cloudstrap.Extensions

KeyVault-backed configuration, Azure Blob data protection, a conventional blob container client, config-driven typed HTTP clients with correlation and access-token seams, and the standard health probe endpoints — one call and one Cloudstrap: configuration subsection each.

Cloudstrap.Observability.AzureMonitor

Application Insights exporter for the Cloudstrap observability pipeline — per-signal Azure Monitor export of traces, metrics and logs, sampling policy and Entra ID ingestion authentication, driven by the Cloudstrap:AzureMonitor configuration section.

Cloudstrap.Worker

Worker-service bootstrap for the .NET generic host: validated Cloudstrap configuration (fail-fast at the call), correlation, additive health-check registration, and a minimal Kestrel health listener serving /healthz + /ready from the host's registered checks on a configurable port. One call and one Cloudstrap:Worker section.

Cloudstrap.WebApi

Web API bootstrap for ASP.NET Core: API versioning, one OpenAPI document per version with a Scalar reference UI, RFC 9457 problem-details error handling, correlation, health probes, security headers, HSTS and CORS, plus optional hardened JWT bearer validation — two calls and one Cloudstrap: subsection each.

Cloudstrap.Mvc

Server-rendered MVC bootstrap for ASP.NET Core: controllers + views, hardened session state on stock Microsoft.AspNetCore.Session, content-negotiated error handling — an error page for browsers, RFC 9457 problem details for JSON clients — correlation, health probes, security headers, HSTS and CORS. Two calls and one Cloudstrap:Mvc section.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.0-preview.83 64 9/3/2026
0.2.0-preview.2 86 8/27/2026