Browse Source

Merge pull request #24871 from abpframework/auto-merge/rel-10-0/4354

Merge branch rel-10.1 with rel-10.0
pull/24872/head
Volosoft Agent 1 month ago
committed by GitHub
parent
commit
27ff4916b5
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      docs/en/docs-nav.json
  2. 177
      docs/en/framework/infrastructure/correlation-id.md

4
docs/en/docs-nav.json

@ -701,6 +701,10 @@
"text": "Concurrency Check",
"path": "framework/infrastructure/concurrency-check.md"
},
{
"text": "Correlation ID",
"path": "framework/infrastructure/correlation-id.md"
},
{
"text": "Current User",
"path": "framework/infrastructure/current-user.md"

177
docs/en/framework/infrastructure/correlation-id.md

@ -1,3 +1,178 @@
```json
//[doc-seo]
{
"Description": "Learn how the ABP Framework uses Correlation IDs to trace and correlate operations across HTTP requests, distributed events, audit logs, and microservices."
}
```
# Correlation ID
This document is planned to be written later.
A **Correlation ID** is a unique identifier that is assigned to a request or operation and propagated across all related processing steps. It allows you to **trace** and **correlate** logs, events, and operations that belong to the same logical transaction, even when they span multiple services or components.
ABP provides a built-in correlation ID infrastructure that:
- **Automatically assigns** a unique correlation ID to each incoming HTTP request (or uses the one provided by the caller).
- **Propagates** the correlation ID through distributed event bus messages, HTTP client calls, audit logs, security logs, and Serilog log entries.
- **Provides a simple API** (`ICorrelationIdProvider`) to get or change the current correlation ID in your application code.
## `AbpCorrelationIdMiddleware`
`AbpCorrelationIdMiddleware` is an ASP.NET Core middleware that handles correlation ID management for HTTP requests. It is automatically added to the request pipeline when you use ABP's application builder.
The middleware performs the following steps for each incoming HTTP request:
1. **Reads** the correlation ID from the incoming request's `X-Correlation-Id` header (configurable via `AbpCorrelationIdOptions` as explained below).
2. **Generates** a new correlation ID (`Guid.NewGuid().ToString("N")`) if the request does not contain one.
3. **Sets** the correlation ID in the current async context using `ICorrelationIdProvider`, making it available throughout the request pipeline.
4. **Writes** the correlation ID to the response header (if `SetResponseHeader` option is enabled).
You can add the middleware to your request pipeline by calling the `UseCorrelationId` extension method:
```csharp
app.UseCorrelationId();
```
> This is already configured in the application startup template. You typically don't need to add it manually.
## `ICorrelationIdProvider`
`ICorrelationIdProvider` is the core service for working with correlation IDs. It allows you to retrieve the current correlation ID or temporarily change it.
```csharp
public interface ICorrelationIdProvider
{
string? Get();
IDisposable Change(string? correlationId);
}
```
- `Get()`: Returns the current correlation ID for the executing context. Returns `null` if no correlation ID has been set.
- `Change(string? correlationId)`: Changes the correlation ID for the current context and returns an `IDisposable` object. When the returned object is disposed, the correlation ID is restored to its previous value.
### Using `ICorrelationIdProvider`
You can inject `ICorrelationIdProvider` into any service to access the current correlation ID:
```csharp
public class MyService : ITransientDependency
{
public ILogger<MyService> Logger { get; set; }
private readonly ICorrelationIdProvider _correlationIdProvider;
public MyService(ICorrelationIdProvider correlationIdProvider)
{
Logger = NullLogger<MyService>.Instance;
_correlationIdProvider = correlationIdProvider;
}
public async Task DoSomethingAsync()
{
// Get the current correlation ID
var correlationId = _correlationIdProvider.Get();
// Use it for logging, tracing, etc.
Logger.LogInformation("Processing with Correlation ID: {CorrelationId}", correlationId);
await SomeOperationAsync();
}
}
```
### Changing the Correlation ID
You can temporarily change the correlation ID using the `Change` method. This is useful when you want to create a new scope with a different correlation ID:
```csharp
public async Task ProcessAsync()
{
var currentCorrelationId = _correlationIdProvider.Get();
// currentCorrelationId = "abc123"
using (_correlationIdProvider.Change("new-correlation-id"))
{
var innerCorrelationId = _correlationIdProvider.Get();
// innerCorrelationId = "new-correlation-id"
}
var restoredCorrelationId = _correlationIdProvider.Get();
// restoredCorrelationId = "abc123" (restored to original)
}
```
The `Change` method returns an `IDisposable`. When disposed, the correlation ID is automatically restored to its previous value. This pattern supports nested scopes safely.
### Default Implementation
The default implementation (`DefaultCorrelationIdProvider`) uses `AsyncLocal<string?>` to store the correlation ID. This ensures that the correlation ID is isolated per async execution flow and is thread-safe.
## `AbpCorrelationIdOptions`
You can configure the correlation ID behavior using `AbpCorrelationIdOptions`:
```csharp
Configure<AbpCorrelationIdOptions>(options =>
{
options.HttpHeaderName = "X-Correlation-Id";
options.SetResponseHeader = true;
});
```
- `HttpHeaderName` (default: `"X-Correlation-Id"`): The HTTP header name used to read/write the correlation ID. You can change this if your infrastructure uses a different header name.
- `SetResponseHeader` (default: `true`): If `true`, the middleware automatically adds the correlation ID to the HTTP response headers. Set it to `false` if you don't want to expose the correlation ID in response headers.
## Correlation ID Across ABP Services
One of the most valuable aspects of ABP's correlation ID infrastructure is that it **automatically propagates** the correlation ID across various system boundaries. This allows you to trace a single user action as it flows through multiple services and components.
### HTTP Client Calls
When you use ABP's [dynamic client proxies](../api-development/dynamic-csharp-clients.md) to call remote services, the correlation ID is automatically added to the outgoing HTTP request headers. This means downstream services will receive the same correlation ID, enabling end-to-end tracing across microservices.
```
Client Request (X-Correlation-Id: abc123)
→ Service A (receives abc123, sets in context)
→ Service B via HTTP Client Proxy (forwards abc123 in header)
→ Service C via HTTP Client Proxy (forwards abc123 in header)
```
No manual configuration is required. ABP's `ClientProxyBase` automatically reads the current correlation ID from `ICorrelationIdProvider` and adds it as a request header.
### Distributed Event Bus
When you publish a [distributed event](./event-bus/distributed/index.md), ABP automatically attaches the current correlation ID to the outgoing event message. When the event is consumed (potentially by a different service), the correlation ID is extracted from the message and set in the consumer's context.
> This works with all supported event bus providers, including [RabbitMQ](./event-bus/distributed/rabbitmq.md), [Kafka](./event-bus/distributed/kafka.md), [Azure Service Bus](./event-bus/distributed/azure.md) and [Rebus](./event-bus/distributed/rebus.md).
```
Service A publishes event (CorrelationId: abc123)
→ Event Bus (carries abc123 in message metadata)
→ Service B receives event (CorrelationId restored to abc123)
```
### Audit Logging
ABP's [audit logging](./audit-logging.md) system automatically captures the current correlation ID when creating audit log entries. This is stored in the `CorrelationId` property of `AuditLogInfo`, allowing you to query and filter audit logs by correlation ID.
This is particularly useful for:
- Tracing all database changes made during a single request.
- Correlating audit log entries across multiple services for the same user action.
- Debugging and investigating issues by filtering logs with a specific correlation ID.
### Security Logging
Similar to audit logging, ABP's security log system also captures the current correlation ID. When security-related events are logged (such as login attempts, permission checks, etc.), the correlation ID is included in the `SecurityLogInfo.CorrelationId` property.
### Serilog Integration
If you use the **ABP Serilog integration**, the correlation ID is automatically added to the Serilog log context as a property. This means every log entry within a request will include the correlation ID, making it easy to filter and search logs.
The correlation ID is enriched as a log property named `CorrelationId` by default. You can use it in your Serilog output template or structured log queries.
## See Also
- [Audit Logging](./audit-logging.md)
- [Distributed Event Bus](./event-bus/distributed/index.md)
- [Dynamic Client Proxies](../api-development/dynamic-csharp-clients.md)

Loading…
Cancel
Save