Quilt4Net.Toolkit.Api
0.7.17
dotnet add package Quilt4Net.Toolkit.Api --version 0.7.17
NuGet\Install-Package Quilt4Net.Toolkit.Api -Version 0.7.17
<PackageReference Include="Quilt4Net.Toolkit.Api" Version="0.7.17" />
<PackageVersion Include="Quilt4Net.Toolkit.Api" Version="0.7.17" />
<PackageReference Include="Quilt4Net.Toolkit.Api" />
paket add Quilt4Net.Toolkit.Api --version 0.7.17
#r "nuget: Quilt4Net.Toolkit.Api, 0.7.17"
#:package Quilt4Net.Toolkit.Api@0.7.17
#addin nuget:?package=Quilt4Net.Toolkit.Api&version=0.7.17
#tool nuget:?package=Quilt4Net.Toolkit.Api&version=0.7.17
Quilt4Net.Toolkit.Api
HTTP request/response logging and correlation tracking middleware for .NET Web Applications.
Captures method, path, headers, query parameters, request/response bodies, client IP, and execution time. Logs to Application Insights and/or standard ILogger.
Get started
Install the NuGet package Quilt4Net.Toolkit.Api and register the service in Program.cs.
var builder = WebApplication.CreateBuilder(args);
builder.AddQuilt4NetLogging()
.AddHttpRequestLogging();
var app = builder.Build();
app.UseQuilt4NetLogging();
app.Run();
AddQuilt4NetLogging() configures OpenTelemetry resource attributes and registers per-record processors that tag every AppTrace / AppException / AppRequest with service.name, service.version, host.name, deployment.environment, and quilt4net.monitor (see the core Quilt4Net.Toolkit README for details). AddHttpRequestLogging() opts in to HTTP request/response middleware on top of that. By default, all requests to paths starting with /Api are logged.
The old
AddQuilt4NetApiLogging()andUseQuilt4NetApiLogging()methods still work but are deprecated.
Correlation ID
CorrelationIdMiddleware reads the X-Correlation-ID header from incoming requests; if no header is present, a new GUID is generated. The id is:
- Stored in
HttpContext.Items["CorrelationId"]for inspection by downstream code. - Returned in the response's
X-Correlation-IDheader — clients can chain the same id to subsequent requests for distributed tracing. - Pushed into a logging scope (
Logger.BeginScope({ ["CorrelationId"] = id })) for the duration of the request, so everyILoggercall made while handling the request inherits the id as a structured property. The Azure Monitor exporter writes it tocustomDimensions["CorrelationId"]on every resultingAppTrace/AppException/AppRequestrow.
KQL pattern for "show me everything from one call chain":
union AppTraces, AppExceptions, AppRequests
| where Properties contains "<your-correlation-id>"
| order by TimeGenerated asc
Or, in the toolkit's LogView Search tab, paste the id into the search box (it filters on both Message and CorrelationId). The Search tab's CorrelationId column also has a click-to-self-search shortcut — click any row's correlation chip and the grid re-runs scoped to that id.
Forwarding the correlation id on outbound calls
The middleware gives the current request an id. To keep that id flowing when your app calls
other services over HTTP — so one id spans your app, the services it calls, and Quilt4Net.Server —
opt the relevant HttpClients into propagation:
// One-time registration (implied by AddQuilt4NetLogging().AddHttpRequestLogging(), but safe to call directly):
builder.Services.AddQuilt4NetCorrelationId();
// Opt in each client that calls a correlation-aware (typically your own internal) service:
builder.Services.AddHttpClient("internal-api")
.AddQuilt4NetCorrelationId();
Any request sent through that client carries the current request's X-Correlation-ID. If the
receiving service also runs CorrelationIdMiddleware, it continues the same id instead of minting a
new one — so a single id ties the whole chain together in Application Insights.
Notes:
- Opt-in per client by design. Don't attach it to clients calling third-party APIs (Fortnox, Stripe, Azure, …) — leaking an internal id to endpoints that don't read it is pointless and noisy.
- No ambient id → no header. Outside a request (background work, non-ASP.NET hosts) nothing is
added; an explicitly-set
X-Correlation-IDon the request is never overwritten. - Quilt4Net.Toolkit's own clients (
Content,RemoteConfiguration/feature toggles,ValueGroup) already forward the id to Quilt4Net.Server automatically onceAddHttpRequestLogging()is wired up.
Logging mode
Control where logs are sent using HttpRequestLogMode.
builder.AddQuilt4NetLogging()
.AddHttpRequestLogging(o =>
{
o.LogHttpRequest = HttpRequestLogMode.ApplicationInsights | HttpRequestLogMode.Logger;
});
| Value | Description |
|---|---|
None |
No logging. |
ApplicationInsights |
Append request/response data to Application Insights request telemetry. |
Logger |
Log via the standard ILogger pipeline. |
Values can be combined with | to log to multiple destinations.
Path filtering
By default, only paths matching ^/Api (case-insensitive) are logged. Override with regex patterns.
builder.AddQuilt4NetLogging()
.AddHttpRequestLogging(o =>
{
o.IncludePaths = [".*"]; // Log all paths
});
Per-endpoint control
Use [Logging] and [LoggingStream] attributes to override logging behavior on individual endpoints.
[Logging(RequestBody = true, ResponseBody = false)]
public async Task<IActionResult> StreamData() { ... }
[Logging(Enabled = false)]
public IActionResult InternalEndpoint() { ... }
[LoggingStream] // Shorthand for ResponseBody = false
public async Task<IActionResult> StreamEvents() { ... }
The [Logging] attribute can be applied to methods or classes.
| Property | Default | Description |
|---|---|---|
Enabled |
true |
Enable or disable all logging for the endpoint. |
RequestBody |
true |
Log the request body. |
ResponseBody |
true |
Log the response body. Set to false for streaming endpoints. |
Interceptor
The Interceptor modifies or filters the captured request/response before it is logged — the single
hook for removing secrets (headers, body, …).
By default it masks sensitive header values. Interceptor is pre-set to
MaskSensitiveHeadersInterceptor, which replaces the values of SensitiveHeaders with *** on both
request and response (case-insensitive name match), keeping the header key so its presence stays
visible without leaking the value. Default masked headers: Authorization, X-API-KEY,
Proxy-Authorization, Cookie, Set-Cookie.
Configure the masked set, log everything verbatim, or take full control:
builder.AddQuilt4NetLogging()
.AddHttpRequestLogging(o =>
{
// (a) tweak which headers the default interceptor masks:
o.SensitiveHeaders = ["Authorization", "X-API-KEY", "X-My-Secret"];
// (b) OR disable filtering entirely — log request/response verbatim:
o.Interceptor = null;
// (c) OR supply your own (optionally composing the built-in masking):
o.Interceptor = async (request, response, properties, serviceProvider) =>
{
request.Headers.Remove("X-Internal-Token");
return await o.MaskSensitiveHeadersInterceptor(request, response, properties, serviceProvider);
};
});
Configuration
All options can be set via code or appsettings.json. Code takes priority over appsettings.json, which takes priority over defaults.
Code configuration
builder.AddQuilt4NetLogging()
.AddHttpRequestLogging(o =>
{
o.LogHttpRequest = HttpRequestLogMode.ApplicationInsights;
o.UseCorrelationId = true;
o.MaxBodySize = 5_000_000;
o.IncludePaths = ["^/Api", "^/webhook"];
o.LogRequestBodyByDefault = true;
o.LogResponseBodyByDefault = false;
});
appsettings.json
{
"Quilt4Net": {
"ApiLogging": {
"LogHttpRequest": 1,
"UseCorrelationId": true,
"MonitorName": "Quilt4Net",
"MaxBodySize": 1000000,
"IncludePaths": ["^/Api"],
"LogRequestBodyByDefault": true,
"LogResponseBodyByDefault": false,
"SensitiveHeaders": ["Authorization", "X-API-KEY", "Proxy-Authorization", "Cookie", "Set-Cookie"]
}
}
}
Configuration path: Quilt4Net:ApiLogging
LoggingOptions
| Property | Default | Description |
|---|---|---|
LogHttpRequest |
ApplicationInsights |
Logging destination. Combine with \| for multiple. |
UseCorrelationId |
true |
Enable X-Correlation-ID header tracking. |
MonitorName |
"Quilt4Net" |
Monitor name for tracking log items. Set to empty to omit. |
MaxBodySize |
1 MB |
Maximum body size to log. Set to 0 to disable body logging. |
IncludePaths |
["^/Api"] |
Regex patterns (case-insensitive) for paths to include. |
LogRequestBodyByDefault |
true |
Log request body by default. Override per endpoint with [Logging]. |
LogResponseBodyByDefault |
false |
Log response body by default. Override per endpoint with [Logging]. |
SensitiveHeaders |
Authorization, X-API-KEY, Proxy-Authorization, Cookie, Set-Cookie |
Header names (case-insensitive) whose values the default interceptor masks. |
Interceptor |
masks SensitiveHeaders |
Callback to modify/filter logged data. Defaults to header masking; set to null to log verbatim. |
Logged data
Request
| Field | Description |
|---|---|
Method |
HTTP method (GET, POST, etc.). |
Path |
Request path. |
Headers |
Request headers (sensitive header values are masked by default — see Sensitive header masking). |
Query |
Query string parameters. |
Body |
Request body (respects MaxBodySize limit). |
ClientIp |
Client IP address. |
Response
| Field | Description |
|---|---|
StatusCode |
HTTP status code. |
Headers |
Response headers. |
Body |
Response body (respects MaxBodySize limit). |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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. |
-
net10.0
- Quilt4Net.Toolkit (>= 0.7.17)
-
net8.0
- Quilt4Net.Toolkit (>= 0.7.17)
-
net9.0
- Quilt4Net.Toolkit (>= 0.7.17)
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 |
|---|---|---|
| 0.7.17 | 0 | 5/31/2026 |
| 0.7.16 | 33 | 5/30/2026 |
| 0.7.15 | 90 | 5/27/2026 |
| 0.7.14 | 83 | 5/26/2026 |
| 0.7.13 | 115 | 5/20/2026 |
| 0.7.12 | 107 | 5/11/2026 |
| 0.7.11 | 150 | 5/11/2026 |
| 0.7.10 | 105 | 5/10/2026 |
| 0.7.9 | 101 | 5/10/2026 |
| 0.7.8 | 115 | 5/9/2026 |
| 0.7.7 | 101 | 5/9/2026 |
| 0.7.6 | 85 | 5/6/2026 |
| 0.7.5 | 87 | 5/6/2026 |
| 0.7.4 | 123 | 4/30/2026 |
| 0.7.3 | 128 | 4/22/2026 |
| 0.7.2 | 104 | 4/20/2026 |
| 0.7.1 | 99 | 4/20/2026 |
| 0.7.0 | 98 | 4/19/2026 |
| 0.6.18 | 95 | 4/19/2026 |
| 0.6.17 | 99 | 4/19/2026 |