Telemetry identity & correlation
AddQuilt4NetLogging():
- Configures OpenTelemetry resource attributes so the Azure Monitor exporter populates the AI columns
cloud_RoleName,application_Version, andcloud_RoleInstance. - Registers
BaseProcessors — one forLogRecord, one forActivity— that copy a five-attribute identity onto every per-recordPropertiesbag at export time. The Azure Monitor exporter does not forward arbitrary OTel resource attributes to per-row Properties for log records, so without this stepcustomDimensions["deployment.environment"]would always be empty. - 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.EnvironmentName → DOTNET_ENVIRONMENT → ASPNETCORE_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:
- Reads
X-Correlation-IDfrom the request, or generates a new GUID. - Echoes it back as a response header.
- 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
CorrelationIdis distinct from the user-facing 6-characterIncidentIdrendered 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 (
hostmetricsreceiver) 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.