TCIS.Logging.Wolverine
1.0.0
dotnet add package TCIS.Logging.Wolverine --version 1.0.0
NuGet\Install-Package TCIS.Logging.Wolverine -Version 1.0.0
<PackageReference Include="TCIS.Logging.Wolverine" Version="1.0.0" />
<PackageVersion Include="TCIS.Logging.Wolverine" Version="1.0.0" />
<PackageReference Include="TCIS.Logging.Wolverine" />
paket add TCIS.Logging.Wolverine --version 1.0.0
#r "nuget: TCIS.Logging.Wolverine, 1.0.0"
#:package TCIS.Logging.Wolverine@1.0.0
#addin nuget:?package=TCIS.Logging.Wolverine&version=1.0.0
#tool nuget:?package=TCIS.Logging.Wolverine&version=1.0.0
TCIS.Logging.Wolverine
Middleware tự động ghi log chuẩn Elastic Common Schema (ECS v1.3) cho message handler trong pipeline
Wolverine (WolverineFx).
Wolverine sinh mã bằng Roslyn lúc khởi động chứ không dùng runtime proxy, nên TCIS.Logging.Autofac
(Castle DynamicProxy) không bắt được handler của Wolverine. Gói này dệt trực tiếp vào pipeline
của Wolverine theo cơ chế convention-based middleware.
Tính năng
- Đo thời gian thực thi handler →
event.duration. - Trích
CorrelationId,TenantIdtừEnvelope;TraceId/SpanIdtừActivity.Current; phần còn lại (user, client, site) từIWorkContext. - Che dữ liệu nhạy cảm trong payload qua
LogArgumentResolver(dùng chung cấu hìnhTLogSettings:SensitiveProps). - Phân loại lỗi theo tiền tố taxonomy của
TBaseException.StatusCode:VALIDATION_/GUARD_/NOT_FOUND_/SEC_→WARN+event.kind = "event"; còn lại →ERROR+event.kind = "error". - Gọi
exception.MarkLogged()đểTExceptionMiddlewaretầng ngoài không ghi đúp bản ghi 4xx. - Loại trừ message ồn qua
ExcludeMessages/ExcludeAssemblies.
Cài đặt
using TCIS.Logging.Extensions;
using TCIS.Logging.Wolverine.Extensions;
var builder = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
services.AddTLogging(context.Configuration);
services.AddTWolverineLogging(context.Configuration); // bind TLogSettings:WolverineSettings
})
.UseWolverine(opts =>
{
opts.UseTWolverineLogging(); // gắn middleware vào mọi handler chain
});
Cấu hình bằng code thay cho appsettings.json:
opts.UseTWolverineLogging(o =>
{
o.IncludeMessagePayload = false;
o.ExcludeMessages.Add("HeartbeatCommand");
});
Cấu hình
Section: TLogSettings:WolverineSettings (cùng gốc TLogSettings với AddTLogging).
{
"TLogSettings": {
"WolverineSettings": {
"IncludeMessagePayload": true,
"ExcludeMessages": [ "PingMessage", "HeartbeatCommand" ],
"ExcludeAssemblies": [ "TCIS.Monitoring" ]
}
}
}
| Khoá | Kiểu | Mặc định | Ý nghĩa |
|---|---|---|---|
IncludeMessagePayload |
bool |
true |
Chụp và che payload của message vào data.parameters |
ExcludeMessages |
HashSet<string> |
rỗng | Tên class message bỏ qua, không phân biệt hoa thường |
ExcludeAssemblies |
HashSet<string> |
rỗng | Tên assembly bỏ qua; nhận cả "Acme.Ops" lẫn "Acme.Ops.dll" |
⚠️ Bắt buộc: sink Serilog phải khai formatter
Gói này chỉ dựng LogDetail rồi đẩy vào IInterceptedLogWriter. Phía render, mọi sink Serilog
phải khai TCISEcsJsonFormatter và host phải gọi .Destructure.AsScalar<TcisEcsDocument>(). Thiếu
một trong hai thì mỗi dòng log ra đúng chuỗi TCIS.Logging.TcisEcsDocument — mất sạch message,
exception và stack trace. Xem src/samples/TCIS.Logging.Wolverine.Sample.
⛔ Phiên bản WolverineFx tối thiểu: 5.28.0
Middleware dựa vào convention OnException/OnExceptionAsync. Convention này chỉ xuất hiện từ
WolverineFx 5.28.0 — đo bằng cách đọc Wolverine.Middleware.MiddlewarePolicy của từng bản:
| Bản | OnExceptionMethodNames |
|---|---|
| 3.13.5 → 5.27.0 | ❌ không có |
| 5.28.0 trở lên | ✅ có |
Gói hiện ghim 5.41.0 (bản 5.x mới nhất). Không nâng lên 6.x: WolverineFx 6 đã bỏ net8.0,
trong khi toàn bộ TCIS.* target net8.0.
⚠️ Đây là loại hỏng im lặng: Wolverine bỏ qua method không đúng convention mà không báo lỗi,
không cảnh báo. Chạy trên bản < 5.28.0 thì đường thành công vẫn ghi log bình thường, chỉ đường lỗi
biến mất. TWolverineLogPipelineTests là thứ duy nhất bắt được điều này — nó chạy message qua
pipeline thật.
Hai lối thoát trông hợp lý nhưng đã đo là sai, đừng dùng nếu buộc phải ở lại bản cũ:
Finally(..., Exception? ex)— Wolverine tựnew Exception()truyền vào, ở cả đường thành công lẫn thất bại. Chép logic sang đó thì mọi message thành công đều bị ghiERROR.Envelope.Failure— vẫnnullkhiFinallychạy trên đườngIMessageBus.InvokeAsync.
Hình dạng bản ghi so với phần còn lại của TCIS.Logging
Bản ghi đi qua đúng IInterceptedLogWriter → hàng đợi ưu tiên → sink như mọi đường log khác, nên có
đủ bộ field ECS chuẩn: @timestamp, log.level, message, error.*, event.*, host, service,
user, custom.{log_type,event_class,schema,error,application,data,code}. Ngoại lệ thô
(new Exception(...), không phải TBaseException) cũng ra bản ghi đầy đủ: ERROR, event.kind = error, error.code = SYS-UNK-9999, có error.stack_trace, payload vẫn được mask.
Ba khác biệt có chủ đích so với TLogInterceptor (đường AOP):
| Trường | AOP (TLogInterceptor) |
Gói này |
|---|---|---|
custom.code.class |
Lớp hiện thực | Kiểu message |
log.origin.function |
Tên method thật | Để trống — Wolverine không phơi tên method handler ra Envelope; hardcode "Handle" sẽ ghi sai với handler tên Consume |
error.code với TBaseException |
Lấy classification.ErrorCode trước |
Lấy StatusCode trước — khớp với mã mà TExceptionMiddleware trả về client |
event.duration chỉ xuất hiện khi thời gian thực thi > 0 ms (MicrosoftLoggingSink bỏ giá trị 0).
⚠️ Tác dụng phụ: gói này ĐĂNG KÝ IExceptionClassifier cho cả app
UseTWolverineLogging() và AddTWolverineLogging() đều gọi AddExceptionClassification(), vì
middleware của Wolverine nhận dependency qua tham số — Wolverine phân giải chúng lúc sinh mã nên
dịch vụ bắt buộc phải có mặt, không thể để tuỳ chọn. Các gói logging khác không làm vậy; chúng
tra IExceptionClassifier bằng service location và bỏ qua nếu không có.
Hệ quả trong app đã dùng AOP logging mà chưa từng gọi AddExceptionClassification(): bật
Wolverine logging sẽ làm TLogInterceptor bắt đầu thấy classifier, và vì nó lấy
classification.ErrorCode trước StatusCode, error.code của một TValidationException đổi từ
mã nghiệp vụ (GATE_IN_REJECTED) sang mã chung SYS-VAL-0001.
Ảnh hưởng chỉ ở log, không chạm response trả về client — TExceptionMiddleware vốn đã dùng
StatusCode trước. Dashboard/alert nào đang lọc theo error.code của log AOP thì cần rà lại.
Hai điều cần biết khi đọc log
- Wolverine ghi log lỗi của riêng nó. Ngoài bản ghi ECS của gói này, Wolverine còn ghi
"Invocation of ... failed!"quaILogger, mức ERROR vàerror.code = SYS-UNK-9999, kể cả với lỗi 4xx.MarkLogged()không chặn được nó (cờ đó chỉ dành choTExceptionMiddleware). Muốn hạ ồn thì đặtMinimumLevel.OverridetheoSourceContextlà tên kiểu message. - Phân biệt hai nguồn: bản ghi của gói này có
custom.code.classvàcustom.data.parameters; bản ghi của Wolverine đi qua nhánh fallback nên chỉ cólog.logger.
Tham chiếu
- Tài liệu kỹ thuật:
docs/TCIS.Logging.Wolverine.md - Sample chạy được:
src/samples/TCIS.Logging.Wolverine.Sample - Bộ test:
src/tests/TCIS.Logging.Wolverine.Tests
| 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 was computed. 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 was computed. 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. |
-
net8.0
- Elastic.CommonSchema (>= 8.11.0)
- Microsoft.Bcl.AsyncInterfaces (>= 9.0.0)
- Microsoft.CodeAnalysis.Analyzers (>= 4.14.0)
- Microsoft.CodeAnalysis.CSharp (>= 4.14.0)
- Microsoft.CodeAnalysis.Workspaces.Common (>= 4.14.0)
- Microsoft.Extensions.Caching.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Caching.Memory (>= 8.0.1)
- Microsoft.Extensions.Configuration (>= 9.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.0)
- Microsoft.Extensions.Configuration.Json (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Hosting (>= 9.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Logging (>= 9.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Options (>= 9.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 9.0.0)
- System.Text.Encodings.Web (>= 9.0.0)
- System.Text.Json (>= 9.0.0)
- TCIS.Logging (>= 1.0.0)
- WolverineFx (>= 5.41.0)
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 |
|---|---|---|
| 1.0.0 | 33 | 10/1/2026 |
| 1.0.0-rc.52 | 35 | 9/29/2026 |
| 1.0.0-rc.51 | 57 | 9/23/2026 |
| 1.0.0-rc.50 | 56 | 9/21/2026 |
| 1.0.0-rc.49 | 62 | 9/18/2026 |
| 1.0.0-rc.47 | 63 | 9/17/2026 |
| 1.0.0-rc.46 | 52 | 9/17/2026 |
| 1.0.0-rc.45 | 109 | 9/11/2026 |