TCIS.Logging
1.0.8-rc.2
See the version list below for details.
dotnet add package TCIS.Logging --version 1.0.8-rc.2
NuGet\Install-Package TCIS.Logging -Version 1.0.8-rc.2
<PackageReference Include="TCIS.Logging" Version="1.0.8-rc.2" />
<PackageVersion Include="TCIS.Logging" Version="1.0.8-rc.2" />
<PackageReference Include="TCIS.Logging" />
paket add TCIS.Logging --version 1.0.8-rc.2
#r "nuget: TCIS.Logging, 1.0.8-rc.2"
#:package TCIS.Logging@1.0.8-rc.2
#addin nuget:?package=TCIS.Logging&version=1.0.8-rc.2&prerelease
#tool nuget:?package=TCIS.Logging&version=1.0.8-rc.2&prerelease
TCIS.Logging
The core library providing foundational abstractions and infrastructure for the Logging system across all TCIS applications.
🌟 Overview
TCIS.Logging serves as the standard logging framework, integrated with IWorkContext to capture user and trace information, while utilizing a Channel mechanism for high-performance, asynchronous (non-blocking) logging.
📦 Installation
Install the package via NuGet or .NET CLI:
dotnet add package TCIS.Logging
⚙️ Configuration (appsettings.json)
You can configure the queue limit for the Background Logging Process:
{
"TLogSettings": {
"MaxQueueSize": 10000,
"SiteCode": "HP9"
}
}
SiteCode (tuỳ chọn) là nhãn application.site_code dự phòng cho bản ghi không có WorkContext —
consumer Kafka/Wolverine, hosted service, log của framework. Nó không nạp vào WorkContext và
không ảnh hưởng cách ly dữ liệu; WorkContext.Tenant.SiteCode luôn thắng khi có giá trị. Pod chạy
nhiều site thì không đặt. Biến môi trường tương ứng: TLogSettings__SiteCode.
Giới hạn dung lượng data.parameters / data.result
{
"TLogSettings": {
"ParameterSize": 2048,
"ResponseSize": 1000
}
}
| Khoá | Mặc định | Ý nghĩa |
|---|---|---|
ParameterSize |
2048 |
Trần byte (sau serialize JSON) của data.parameters, mỗi lời gọi. Vượt trần thì bỏ cả khối và ghi _warning kèm Limit: <n>, đồng thời bật custom.log.truncated. <= 0 được coi là 2048. |
ResponseSize |
1000 |
Trần byte của data.result (chỉ áp khi ResponseSummary.Enabled=false). <= 0 được coi là 2048. |
Hai ngưỡng này độc lập nhau; hạ ParameterSize không ảnh hưởng ResponseSize.
Chỉ ghi một số field của data.result (whitelist)
Mặc định data.result ghi cả đối tượng trả về. Muốn chỉ giữ vài field:
{
"TLogSettings": {
"ResultIncludeFields": ["id", "code", "cd"],
"ResultIncludeFieldsByMethod": {
"OrderService": ["id", "status"],
"OrderService.Get": ["id"],
"Repo`1.Get": ["*"]
},
"ResultFilterMaxItems": 1000
}
}
| Khoá | Mặc định | Ý nghĩa |
|---|---|---|
ResultIncludeFields |
[] |
Whitelist toàn cục. Rỗng hoặc chứa "*" = ghi hết (không lọc). Có khai báo nhưng toàn mục rỗng/gõ nhầm = không ghi result nào (fail-closed). |
ResultIncludeFieldsByMethod |
{} |
Ghi đè theo lớp hiện thực ("Class") hoặc "Class.Method" (generic viết Repo`1). Ưu tiên Class.Method > Class > ResultIncludeFields. Khoá không phân biệt hoa thường; giá trị ["*"] để riêng nơi đó ghi hết. |
ResultFilterMaxItems |
1000 |
Khi lọc đang áp và result là collection có Count vượt ngưỡng thì không serialize, ghi _warning "Filter skipped" (chốt chặn CPU/bộ nhớ). |
Quy tắc khớp:
- Duyệt vét cạn mọi tầng object/list lồng nhau tới tận lá (object → list → object → list…), với N phần tử bất kỳ; không dừng ở tầng 1 hay ở phần tử đầu.
- Tên field so qua chuẩn hoá:
user_id,userId,UserIdtương đương, không phân biệt hoa thường. - Field khớp được giữ nguyên cả giá trị: nếu nó là object/list thì giữ nguyên cả cây bên trong.
- Field không khớp mà chứa object/list thì đi sâu tiếp; nhánh không còn field nào bị bỏ. Phần tử list không có field nào khớp bị bỏ khỏi list; phần tử scalar trong list bị bỏ.
- Che dữ liệu nhạy cảm luôn thắng:
password/token… vẫn thành***kể cả khi nằm trong field được giữ. - Lọc chạy trước
ResponseSizevà trướcResponseSummary(whitelist chạy trước;ResponseSummary.ExcludedFieldslà blacklist chạy sau, áp trên phần đã giữ). Không còn field nào khớp thìdata.resultbỏ trống. - Chỉ áp cho
TLogInterceptor(AOP, packageTCIS.Logging.Autofac).TLogWriter,ControllerLoggingFilter,TGrpcClientInterceptor/TGrpcServerInterceptorchưa lọc. - Kết quả được cache theo phương thức của lớp hiện thực lúc gọi lần đầu; đổi cấu hình lúc đang chạy không có hiệu lực với phương thức đã gọi.
Chẩn đoán treo (LogInvocationStart, SlowCallThreshold)
Log AOP (TLogInterceptor) chỉ ghi khi Proceed() trả về (trong finally). Một lời gọi treo — chờ DB, lock,
HTTP không timeout — vì thế không để lại bản ghi nào. Hai tuỳ chọn trong TLogSettings bù chỗ này:
{
"TLogSettings": {
"LogInvocationStart": true,
"InvocationStartLevel": "INFO",
"SlowCallThreshold": "00:00:30"
}
}
| Khoá | Mặc định | Ý nghĩa |
|---|---|---|
LogInvocationStart |
false |
Ghi bản ghi "{Class}.{Method} started" trước Proceed(): không có data, event.outcome: "unknown", cùng event.id với bản ghi kết thúc. |
InvocationStartLevel |
"DEBUG" |
Mức của bản ghi started. Mặc định DEBUG sẽ bị admission loại khi min level là INFO (mặc định của lib) — hoặc hạ min level bằng Dynamic Log Level, hoặc đặt "INFO" khi cần điều tra mà không muốn hạ cả hệ thống. |
SlowCallThreshold |
null (tắt) |
Lời gọi chạy quá ngưỡng mà chưa kết thúc ⇒ một bản ghi WARN "{Class}.{Method} still running after {ms}ms", event.outcome: "unknown", event.duration = ms đã trôi, cùng event.id với bản ghi kết thúc. <= 0 cũng là tắt. |
Cơ chế và giới hạn:
- Một sweeper dùng chung (một
Timer, chu kỳ 1 giây, tạo lười) quét các lời gọi đang chạy — độ phân giải ~1 giây, không phải mili giây; không tạo Timer cho từng lời gọi. WARN bắn đúng một lần, không lặp theo bội số ngưỡng. - Ngữ cảnh (WorkContext, Activity) được chụp trên thread gọi lúc bắt đầu nên WARN vẫn mang đúng transaction/user dù sweeper chạy ở thread khác. WARN không bắn sau khi hàm đã hoàn tất; hàm xong trước ngưỡng thì không có WARN.
- Hàm chạy lâu một cách hợp lệ (job, export) sẽ sinh WARN: loại chúng bằng
ExcludeClasses/ExcludeMethods(đường bị loại không đăng ký sổ đang chạy). Khuyến nghị bậtSlowCallThresholdcho API đồng bộ, không bật toàn cục mù quáng. - Cách đọc log: thấy
WARN ... still runningmà chưa có bản ghi kết thúc cùngevent.id⇒ lời gọi đã vào hàm và đang treo. Phạm vi: cả ba đường — hàm đồng bộ,Task,Task<T>; chỉTLogInterceptor(controller/gRPC không có). - Giới hạn khi thread pool cạn: sweeper chạy trên thread pool. Đúng lúc thread pool bị bão hoà (thường đi kèm treo) callback có thể bị trễ hoặc không chạy, khi đó không có WARN — không có WARN chưa chứng minh là không treo.
event.iddùng chung cho started/WARN/kết thúc. Nếu pipeline phía sau (Filebeat/Logstash/ES ingest) đặt_idhoặc dedupe theoevent.id, bản ghi kết thúc sẽ đè bản ghi treo. Thư viện không dùngevent.idlàm khoá chống trùng (dùngRecordIdriêng cho spool/biên nhận). Đã kiểm trên Kibana UAT ngày 21/10/2026 (data viewtcis-logs*, gồm các service eBerth):_idkhácevent.idở mọi bản ghi lấy mẫu, nên ở đó không bị đè. Kết quả này phụ thuộc cấu hình pipeline của từng môi trường — môi trường khác (production, cụm khác) thì kiểm lại bằng cách so_idvớievent.idcủa một bản ghi trong Discover (tab JSON), hoặc bật thử một service rồi tìm theoevent.id: thấy 2 bản ghi (started + kết thúc) là không bị đè.
Điều tra nhanh một service nghi bị treo ở Proceed()
Cấu hình đọc lúc khởi động (IOptions): đổi xong phải restart service đó. Mỗi service có appsettings riêng nên chỉ bật
cho service đang nghi ngờ.
{
"TLogSettings": {
"SlowCallThreshold": "00:00:10"
}
}
- Bước 1 — chỉ cần
SlowCallThreshold(ghi WARN nên không phải hạ min level, chi phí thấp). ThấyWARN ... still runningmà chưa có bản ghi kết thúc cùngevent.id⇒ lời gọi đã vào hàm và đang treo; kết luận "API chưa được gọi" là sai. Hàm chạy lâu hợp lệ gây ồn thì thêm vàoExcludeMethods/ExcludeClasses. - Bước 2 — nếu cần biết mọi lời gọi có vào hàm hay không, thêm
"LogInvocationStart": truevà"InvocationStartLevel": "INFO"(hoặc giữ DEBUG và hạ min level bằng Dynamic Log Level). Nặng hơn: mỗi lời gọi được log thêm một bản ghi, chỉ bật trong lúc điều tra rồi tắt. - Điều tra xong: bỏ hai khoá trên và restart.
🚀 Usage
In Program.cs, add the Logging service to the DI container:
using TCIS.Logging.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Method 1: Read from IConfiguration (default section: "TLogSettings")
builder.Services.AddTLogging(builder.Configuration);
// Method 2: Configure via Action
builder.Services.AddTLogging(options =>
{
options.MaxQueueSize = 5000;
});
// (Optional) Add Console Sink to display formatted logs in Development
if (builder.Environment.IsDevelopment())
{
builder.Services.AddTCISConsoleSink();
}
💡 Basic Example
Use ILogWriter (do not use ILogger directly from Microsoft Logging to comply with TCIS rules) in your services:
using TCIS.Logging.Abstractions.Abstractions;
public class MyService
{
private readonly ILogWriter _logger;
private const string Provider = "my-service";
public MyService(ILogWriter logger)
{
_logger = logger;
}
public async Task DoWorkAsync()
{
_logger.LogInformation(
$"[{Provider}] DoWorkAsync: Processing data...",
nameof(DoWorkAsync),
new { Step = 1, Data = "Sample" }
);
}
}
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Elastic.CommonSchema (>= 8.11.0)
- Microsoft.Bcl.AsyncInterfaces (>= 9.0.0)
- Microsoft.Bcl.TimeProvider (>= 9.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 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.Diagnostics.DiagnosticSource (>= 9.0.0)
- System.Text.Encodings.Web (>= 9.0.0)
- System.Text.Json (>= 8.0.6)
- System.Threading.Channels (>= 8.0.0)
- TCIS.Core (>= 1.0.8-rc.2)
- TCIS.Logging.Abstractions (>= 1.0.8-rc.2)
- TCIS.Observability.Classification (>= 1.0.8-rc.2)
-
net8.0
- Elastic.CommonSchema (>= 8.11.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 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.Diagnostics.DiagnosticSource (>= 10.0.0)
- System.Text.Encodings.Web (>= 9.0.0)
- System.Text.Json (>= 9.0.0)
- System.Threading.Channels (>= 8.0.0)
- TCIS.Core (>= 1.0.8-rc.2)
- TCIS.Logging.Abstractions (>= 1.0.8-rc.2)
- TCIS.Observability.Classification (>= 1.0.8-rc.2)
NuGet packages (6)
Showing the top 5 NuGet packages that depend on TCIS.Logging:
| Package | Downloads |
|---|---|
|
TCIS.AspNetCore
TCIS Core Framework is an application framework for building modular, multi-tenant applications on ASP.NET Core. ASP.NET Core integration for TCIS Framework. |
|
|
TCIS.Http
TCIS Core Framework is an application framework for building modular, multi-tenant applications on ASP.NET Core. HTTP client extensions and utilities for TCIS Framework. |
|
|
TCIS.Http.Grpc
TCIS Core Framework is an application framework for building modular, multi-tenant applications on ASP.NET Core. gRPC client and server integration for TCIS Framework. |
|
|
TCIS.Logging.Autofac
TCIS Core Framework is an application framework for building modular, multi-tenant applications on ASP.NET Core. Autofac integration for TCIS Logging. |
|
|
TCIS.Logging.Serilog
TCIS Core Framework is an application framework for building modular, multi-tenant applications on ASP.NET Core. Serilog integration for TCIS Logging. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.8-rc.7 | 32 | 10/27/2026 |
| 1.0.8-rc.6 | 37 | 10/27/2026 |
| 1.0.8-rc.5 | 115 | 10/23/2026 |
| 1.0.8-rc.4 | 121 | 10/23/2026 |
| 1.0.8-rc.3 | 113 | 10/23/2026 |
| 1.0.8-rc.2 | 119 | 10/22/2026 |
| 1.0.8-rc.1 | 117 | 10/22/2026 |
| 1.0.7 | 161 | 10/22/2026 |
| 1.0.6 | 359 | 10/20/2026 |
| 1.0.6-rc.1 | 104 | 10/20/2026 |
| 1.0.5 | 371 | 10/19/2026 |
| 1.0.4 | 330 | 10/13/2026 |
| 1.0.3 | 335 | 10/13/2026 |
| 1.0.2 | 352 | 10/12/2026 |
| 1.0.2-rc.1 | 117 | 10/12/2026 |
| 1.0.1-rc.10 | 153 | 10/8/2026 |
| 1.0.1-rc.9 | 121 | 10/8/2026 |
| 1.0.1-rc.8 | 132 | 10/8/2026 |
| 1.0.1-rc.7 | 129 | 10/8/2026 |
| 1.0.1-rc.6 | 155 | 10/8/2026 |