YtSoft.Gmc.Core.Logging.Contracts 1.0.2

dotnet add package YtSoft.Gmc.Core.Logging.Contracts --version 1.0.2
                    
NuGet\Install-Package YtSoft.Gmc.Core.Logging.Contracts -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="YtSoft.Gmc.Core.Logging.Contracts" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="YtSoft.Gmc.Core.Logging.Contracts" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="YtSoft.Gmc.Core.Logging.Contracts" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add YtSoft.Gmc.Core.Logging.Contracts --version 1.0.2
                    
#r "nuget: YtSoft.Gmc.Core.Logging.Contracts, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package YtSoft.Gmc.Core.Logging.Contracts@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=YtSoft.Gmc.Core.Logging.Contracts&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=YtSoft.Gmc.Core.Logging.Contracts&version=1.0.2
                    
Install as a Cake Tool

YtSoft.Gmc.Core.Logging.Contracts 1.0.2

YtSoft.Gmc.Core.Logging.Contracts 是日志生产端、统一消费端和业务自定义消费者共用的纯消息契约包。它只包含 DTO、枚举、JSON 序列化和消息校验,不读取 Nacos,不引用 YtSoft.Gmc.Core.Config、RabbitMQ 或 MongoDB。

引用方式和职责

生产业务系统只需引用 YtSoft.Gmc.Core.Logging;Logging 会传递引入 Config 1.0.3 和本契约包,业务代码不需要重复声明 Contracts。

只消费业务自有队列的系统可以直接引用 Config 和 Contracts:

<PackageReference Include="YtSoft.Gmc.Core.Config" Version="1.0.3" />
<PackageReference Include="YtSoft.Gmc.Core.Logging.Contracts" Version="1.0.2" />

Config 1.0.3 和 Contracts 1.0.2 的可还原状态以实际使用的 NuGet 源为准。消费者仍应通过 Config 获取 MQ 连接信息,不要自行读取 Nacos 连接环境变量或拼接 DataId。

主要模型和枚举

  • LogRequestContext:请求关联和公共上下文,包括 TradeId、Service、Instance、Environment、Module、用户信息、客户端 IP、主机名、路由、方法、URL、Trace/Span、状态码、请求头和扩展属性。
  • LogWriteRequest:继承请求上下文,增加 Kind、Level、ContentFormat、字符串 Content、业务侧 Timestamp(Unix 毫秒)、结构化 Exception、可选 Destination、MessageTtl(分钟)和 IsTerminal。
  • LogEvent:生产端最终发送的事件,增加 SchemaVersion、EventId、OccurredAt、ConfigRevision 和可选 EventSequence;Timestamp 原样保留,不由生产端补值。
  • LogDestination:交换机、队列和路由键;生产请求中可以为空字段表示继承默认目标,真正发送的 LogEvent 必须包含完整目标。
  • LogExceptionInfo:异常类型、消息、堆栈和内部异常链。
  • LogWriteResult:生产入口的本地接受结果,包括 Accepted、TradeId、EventId 和失败原因。

三个枚举分别是:

枚举 值
LogKind Request、Response、Error、Sql、Other
LogSeverity Trace、Debug、Information、Warning、Error、Critical
LogContentFormat Text、Json、Xml、Query、Sql

业务生产端调用 ILogWriter.Write(LogWriteRequest),不手工创建 LogEvent。Logging 会补齐 schemaVersion=2、eventId、occurredAt、配置版本和解析后的 MQ 目标;eventId 在重试和消息重投时保持不变,tradeId 用于串联同一次请求的多条事件。Timestamp 必须由业务系统采集并原样传递,Request 表示开始、Response 或终结 Error 表示结束;Logging 和消费端都不能用 MQ 到达时间代替它。

Timestamp 使用 Unix 毫秒数,合法范围为 0 到 253402300799999,不携带时区。业务系统按照北京时间采集后直接传入即可;它用于计算接口耗时。生产端自动生成的 OccurredAt 是消息产生时间,序列化时带 +08:00 偏移,不能替代业务开始或结束时间。

JSON 规则和校验

LogJson.CreateOptions() 使用 camelCase 属性名、camelCase 字符串枚举、禁止整数枚举值、忽略 null 属性,并保留中文字符。LogJson.Deserialize 只接受根对象显式包含 schemaVersion: 2 的新消息,不兼容旧消息结构。

LogEventValidator.TryValidate 会检查:

  • schemaVersion 必须为 2,eventId 和 tradeId 必须非空、无控制字符且不超过 128 个字符;
  • 三个枚举必须是已定义值,occurredAt 不能为默认值,content 不能为 null;
  • timestamp 如果提供,必须是 0 到 253402300799999 范围内的 Unix 毫秒时间戳;非法值会被拒绝,不会阻断业务宿主;
  • Destination 必须存在,交换机、队列和路由键必须非空、无控制字符且 UTF-8 长度不超过 255 字节;队列名不能含中英文逗号;
  • MessageTtl 如果提供,必须是非负整数;零表示消息立即过期,空值表示由生产端继承配置默认值。

契约版本仍为 schemaVersion=2。新增的 timestamp 和 messageTtl 都是可选字段:旧消息缺少它们时按空值读取,旧版消费者遇到未知字段时仍可按 JSON 规则忽略,不影响其他字段解析。DurationMs 不再属于生产端写入模型,业务应改为传入 Request/Response 的 Timestamp,由消费端计算 durationMs;历史 JSON 中若仍有 durationMs,反序列化时会按未知字段忽略。

下面的完整示例适合消费者或契约测试,展示序列化、反序列化和校验:

using YtSoft.Gmc.Core.Logging.Contracts;

var value = new LogEvent
{
    SchemaVersion = 2,
    EventId = "event-001",
    TradeId = "trade-001",
    OccurredAt = DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(8)),
    Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
    ConfigRevision = 7,
    Kind = LogKind.Response,
    Level = LogSeverity.Information,
    ContentFormat = LogContentFormat.Json,
    Content = "{\"message\":\"处理成功\"}",
    Destination = new LogDestination
    {
        ExchangeName = "gmc-logs",
        QueueName = "gateway-logs",
        RoutingKey = "gateway-logs"
    }
};

if (!LogEventValidator.TryValidate(value, out var error))
{
    throw new InvalidOperationException(error);
}

var body = LogJson.Serialize(value);
var restored = LogJson.Deserialize(body)
    ?? throw new InvalidOperationException("日志消息不是 schemaVersion=2 的有效 JSON。");

if (!LogEventValidator.TryValidate(restored, out var restoredError))
{
    throw new InvalidOperationException(restoredError);
}

Console.WriteLine($"{restored.TradeId}/{restored.EventId}");

这个示例直接构造 LogEvent 只是为了说明纯契约的序列化边界;生产业务仍应调用 Logging 的 Write,不应自己生成事件标识或目标。

消费端约定

统一消费端和业务自有消费者都应先复制消息正文,再调用 LogJson.Deserialize 和 LogEventValidator.TryValidate。消费端以 (tradeId,eventId) 事件标识做幂等判断,以 tradeId 聚合同一次请求的 Request、Response、Error、Sql 和 Other 内容;同一个 tradeId 的事件可能乱序或分次到达。

只有在幂等判断完成且数据已经持久化后才能 ACK。RabbitMQ 的 ACK、重试、死信、MongoDB 聚合和 QueueNames 过滤由具体消费者实现,本契约包不创建客户端,也不提供 ACK 实现。业务自有队列可以继续使用同一消息契约;不在 Middleware.MqConnections.QueueNames 名单中的队列不会由统一 Mqlog 消费,应由业务系统自行订阅处理。

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  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 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on YtSoft.Gmc.Core.Logging.Contracts:

Package Downloads
YtSoft.Gmc.Core.Logging

统一日志生产 SDK。业务服务通过 ILogWriter 写入带 tradeId 的日志事件,经 RabbitMQ 投递到日志平台。

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 39 10/21/2026
1.0.1 65 10/20/2026
1.0.0 68 10/20/2026