You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/Libraries/Microsoft.AspNetCore.Diagnostics.Middleware/README.md
+54Lines changed: 54 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,6 +20,60 @@ Or directly in the C# project file:
20
20
21
21
## Usage Example
22
22
23
+
### Log Buffering
24
+
25
+
Provides a buffering mechanism for logs, allowing you to store logs in temporary circular buffers in memory. If the buffer is full, the oldest logs will be dropped. If you want to emit the buffered logs, you can call `Flush()` on the buffer. That way, if you don't flush buffers, all buffered logs will eventually be dropped and that makes sense - if you don't flush buffers, chances are
26
+
those logs are not important. At the same time, you can trigger a flush on the buffer when certain conditions are met, such as when an exception occurs.
27
+
28
+
#### Per-request Buffering
29
+
30
+
Provides HTTP request-scoped buffering for web applications:
31
+
32
+
```csharp
33
+
// Simple configuration with log level
34
+
builder.Logging.AddPerIncomingRequestBuffer(LogLevel.Warning); // Buffer Warning and lower level logs per request
Per-request buffering is especially useful for capturing all logs related to a specific HTTP request and making decisions about them collectively based on request outcomes.
75
+
Per-request buffering is tightly coupled with [Global Buffering](https://github.com/dotnet/extensions/blob/main/src/Libraries/Microsoft.Extensions.Telemetry/README.md#log-buffering). If a log entry is supposed to be buffered to a per-request buffer, but there is no active HTTP context, it will be buffered to the global buffer instead. If buffer flush is triggered, the per-request buffer will be flushed first, followed by the global buffer.
76
+
23
77
### Tracking HTTP Request Latency
24
78
25
79
These components enable tracking and reporting the latency of HTTP request processing.
The Random Probabilistic Sampler supports the `IOptionsMonitor<T>` pattern, allowing for dynamic configuration updates. This means you can change the sampling rules at runtime without needing to restart your application.
48
48
49
+
### Log Buffering
50
+
51
+
Provides a buffering mechanism for logs, allowing you to store logs in temporary circular buffers in memory. If the buffer is full, the oldest logs will be dropped. If you want to emit the buffered logs, you can call `Flush()` on the buffer. That way, if you don't flush buffers, all buffered logs will eventually be dropped and that makes sense - if you don't flush buffers, chances are
52
+
those logs are not important. At the same time, you can trigger a flush on the buffer when certain conditions are met, such as when an exception occurs.
53
+
54
+
This library works with all logger providers, even if they do not implement the `Microsoft.Extensions.Logging.Abstractions.IBufferedLogger` interface. In that case, the library will
55
+
be calling `ILogger.Log()` method directly on every single buffered log record when flushing the buffer.
56
+
57
+
#### Global Buffering
58
+
59
+
Provides application-wide log buffering with configurable rules:
60
+
61
+
```csharp
62
+
// Simple configuration with log level
63
+
builder.Logging.AddGlobalBuffer(LogLevel.Warning); // Buffer Warning and lower level logs
64
+
65
+
// Configuration using options
66
+
builder.Logging.AddGlobalBuffer(options=>
67
+
{
68
+
options.Rules.Add(newLogBufferingFilterRule(logLevel: LogLevel.Information)); // Buffer Information and lower level logs
69
+
options.Rules.Add(newLogBufferingFilterRule(categoryName: "Microsoft.*")); // Buffer logs from Microsoft namespaces
Then, to flush the global buffer when a bad thing happens, call the `Flush()` method on the injected GlobalLogBuffer instance:
77
+
78
+
```csharp
79
+
publicclassMyService
80
+
{
81
+
privatereadonlyGlobalLogBuffer_globalLogBuffer;
82
+
83
+
publicMyService(GlobalLogBufferglobalLogBuffer)
84
+
{
85
+
_globalLogBuffer=globalLogBuffer;
86
+
}
87
+
88
+
publicvoidDoSomething()
89
+
{
90
+
try
91
+
{
92
+
// ...
93
+
}
94
+
catch (Exceptionex)
95
+
{
96
+
// Flush the global buffer when an exception occurs
97
+
_globalLogBuffer.Flush();
98
+
}
99
+
}
100
+
}
101
+
```
102
+
103
+
The Global Log Buffer supports the `IOptionsMonitor<T>` pattern, allowing for dynamic configuration updates. This means you can change the buffering rules at runtime without needing to restart your application.
104
+
105
+
##### Limitations
106
+
107
+
1. This library does not preserve the order of log records. However, original timestamps are preserved.
108
+
1. The library does not support custom configuration per each logger provider. Same configuration is applied to all logger providers.
109
+
1. When buffering and then flushing buffers, not all information of the original log record is preserved. This is due to serialing/deserialing limitation, but can be
110
+
revisited in future. Namely, this library uses `Microsoft.Extensions.Logging.Abstractions.BufferedLogRecord` class when converting buffered log records to actual log records, but omits following properties:
Matches logging sampling decisions with the underlying [Distributed Tracing sampling decisions](https://learn.microsoft.com/dotnet/core/diagnostics/distributed-tracing-concepts#sampling):
@@ -54,6 +122,7 @@ Matches logging sampling decisions with the underlying [Distributed Tracing samp
54
122
// Add trace-based sampler
55
123
builder.Logging.AddTraceBasedSampler();
56
124
```
125
+
57
126
This comes in handy when you already use OpenTelemetry .NET Tracing and would like to see sampling decisions being consistent across both logs and their underlying [`Activity`](https://learn.microsoft.com/dotnet/core/diagnostics/distributed-tracing-concepts#sampling).
0 commit comments