Table of Contents

Telemetry identity & correlation

AddQuilt4NetLogging():

  1. Configures OpenTelemetry resource attributes so the Azure Monitor exporter populates the AI columns cloud_RoleName, application_Version, and cloud_RoleInstance.
  2. Registers BaseProcessors — one for LogRecord, one for Activity — that copy a five-attribute identity onto every per-record Properties bag at export time. The Azure Monitor exporter does not forward arbitrary OTel resource attributes to per-row Properties for log records, so without this step customDimensions["deployment.environment"] would always be empty.
  3. Optionally enriches records with exception data and log scopes (see below) so a correlation id reaches customDimensions.
var builder = WebApplication.CreateBuilder(args);

builder.AddQuilt4NetLogging();

What lands on every record

Five attributes attached to every AppTrace, AppException, AppRequest, and outbound AppDependency:

Key Default Notes
service.name IHostEnvironment.ApplicationName Also surfaces as cloud_RoleName.
service.version Entry assembly version Also surfaces as application_Version.
host.name Environment.MachineName Also surfaces as cloud_RoleInstance.
deployment.environment IHostEnvironment.EnvironmentNameDOTNET_ENVIRONMENTASPNETCORE_ENVIRONMENT"Production" Per-record copy. Read-side queries use a centralised KQL projection that coalesces this with the legacy AspNetCoreEnvironment scope tag.
quilt4net.monitor "Quilt4Net" (configurable via MonitorName) Identifies the instrumentation source — distinguishes telemetry from multiple Quilt4Net-instrumented services shipping to the same workspace.

Override

builder.AddQuilt4NetLogging(o =>
{
    o.ApplicationName = "florida-server";
    o.Version = "2.0.0";
    o.Environment = "Production";
    o.MonitorName = "florida";
});
{
  "Quilt4Net": {
    "Logging": {
      "ApplicationName": "florida-server",
      "Version": "2.0.0",
      "Environment": "Production",
      "MonitorName": "florida"
    }
  }
}

Correlation across requests + handlers

Pair AddQuilt4NetLogging() with Quilt4Net.Toolkit.Api:

builder.AddQuilt4NetLogging()
    .AddHttpRequestLogging();

var app = builder.Build();
app.UseQuilt4NetLogging();

CorrelationIdMiddleware:

  1. Reads X-Correlation-ID from the request, or generates a new GUID.
  2. Echoes it back as a response header.
  3. Pushes it into a logging scope (Logger.BeginScope({ ["CorrelationId"] = id })) for the duration of the request.

Every ILogger call made while handling the request inherits the id as a structured property. For that scoped id to reach customDimensions["CorrelationId"], enable scope capture (scope values are not exported by default):

builder.AddQuilt4NetLogging(o => o.IncludeScopes = true)
    .AddHttpRequestLogging();

Then, on every resulting AppTrace / AppException / AppRequest:

union AppTraces, AppExceptions, AppRequests
| where Properties contains "<the-correlation-id>"
| order by TimeGenerated asc

A client that wants to chain calls just sends the same header to every server. Server code that wants to start a new chain can read HttpContext.Items["CorrelationId"] and forward it to outbound HttpClient calls (see the Api README → AddQuilt4NetCorrelationId).

Exception data → customDimensions

EnrichExceptionData (on by default) copies a logged exception's Exception.Data entries onto the exception telemetry, so an id attached to the exception is findable in AI:

catch (Exception e)
{
    e.AddData("CorrelationId", correlationId);   // Quilt4Net.Toolkit.Features.Measure
    logger.LogError(e, e.Message);
}
AppExceptions | where tostring(customDimensions.CorrelationId) == "<guid>"

Both enrichers run on the OpenTelemetry logging pipeline. Apps ingesting via the classic Application Insights SDK on AI 3.x must export logs through Azure.Monitor.OpenTelemetry to benefit — AI 3.x does not ingest ILogger telemetry through the classic pipeline.

This cross-hop CorrelationId is distinct from the user-facing 6-character IncidentId rendered in Log-view error messages.

Demo endpoint

Quilt4Net.Toolkit.Blazor.Server.Sample ships a working endpoint:

curl -i -H "X-Correlation-ID: my-test-1" https://localhost:7187/api/correlation-demo

→ three AppTrace rows in AI, all sharing customDimensions["CorrelationId"] == "my-test-1".

Host and runtime metrics

AddQuilt4NetLogging() sets up telemetry identity, logs, and traces — it deliberately does not emit host or process metrics. Two reasons:

  • Host metrics (CPU, memory, disk space, disk/network I/O, load average) belong to an OpenTelemetry Collector (hostmetrics receiver) or your platform's node monitoring — not an application library. An app reporting node-level disk space is both duplicative and misleading on a multi-tenant host.
  • .NET runtime / process metrics are already provided by standard OpenTelemetry instrumentation — no custom code in the toolkit is needed.

If you want your app's runtime/process metrics in Application Insights, add the standard instrumentation to the metrics pipeline yourself:

builder.Services.AddOpenTelemetry().WithMetrics(m => m
    .AddRuntimeInstrumentation()      // GC, heap, thread-pool, JIT  (OpenTelemetry.Instrumentation.Runtime)
    .AddProcessInstrumentation());    // process CPU + memory        (OpenTelemetry.Instrumentation.Process)

These land in the AppMetrics table (customMetrics). This requires exporting metrics via Azure.Monitor.OpenTelemetry — the classic Application Insights SDK on AI 3.x does not ingest them.

For host-level metrics, run the OpenTelemetry Collector (hostmetrics + kubeletstats) into the same workspace. Its system.* metrics and the toolkit's identity attributes coexist in AI under the standard OpenTelemetry names, so a single query spans both.

Where next

  • Log views — render and query the resulting telemetry.
  • API reference: xref:Quilt4Net.Toolkit.Quilt4NetLoggingOptions, xref:Quilt4Net.Toolkit.Features.Logging.TelemetryIdentityLogProcessor.