添加协议层数据统计结构,日志文件保存在 Logs 下

This commit is contained in:
2026-03-27 17:39:25 +08:00
parent ca26ab8e38
commit e361510100
13 changed files with 866 additions and 12 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-03-27
@@ -0,0 +1,49 @@
## Context
`KcpTransport` currently exposes send/receive behavior and session isolation, but transport-level diagnostics are limited to ad-hoc console logging. Weak-network verification, multi-session troubleshooting, and resume-facing statistics all need structured counters and end-of-run summaries that do not depend on Unity and do not force changes onto `ITransport`.
## Goals / Non-Goals
**Goals:**
- Add a transport-agnostic metrics module interface and snapshot model in shared networking code.
- Let `KcpTransport` publish lifecycle, session, payload, datagram, and error events into that module with minimal intrusion.
- Produce one JSON report plus one console summary when a transport run ends at `Stop()`.
- Allow tests and diagnostics code to query the current metrics snapshot without reading the exported file.
**Non-Goals:**
- Add gameplay, UI, or session-state business metrics above the transport layer.
- Change `ITransport` or require all future transports to implement metrics immediately.
- Persist per-event trace logs or high-volume packet histories in v1.
- Add Unity-specific visualization or editor tooling for the exported metrics.
## Decisions
### Use a standalone diagnostics interface instead of nesting metrics types under `KcpTransport`
The metrics contract will live in shared networking code as a transport-agnostic module interface with snapshot DTOs. `KcpTransport` will only hold a private reference and call interface methods at integration points. This keeps the module reusable and avoids making other callers depend on a concrete transport type.
### Keep `ITransport` unchanged and extend only `KcpTransport`
`ITransport` remains the transport contract for runtime networking. `KcpTransport` constructors gain an optional metrics-module parameter and a snapshot query method. This scopes the feature to the only reliable runtime transport without imposing a cross-cutting interface change.
### Treat each `StartAsync` to `Stop()` window as one metrics run
The module resets when the transport starts, accumulates counters for the active run, and finalizes exactly once at shutdown. Repeated `Stop()` calls must be idempotent so the same run does not emit duplicate reports.
### Export global and per-peer summaries, not event streams
The module aggregates totals for payloads, UDP datagrams, sessions, and errors globally and by remote endpoint. This is sufficient for Clumsy validation and multi-session diagnosis while avoiding heavy trace storage and output noise.
### Default reporting is JSON to `Logs/transport-metrics/` plus a compact console summary
The built-in module writes a timestamped JSON file on finalization and prints a one-line summary to the console. JSON preserves data for later scripting, while the console line gives an immediate close-out signal during local runs.
## Risks / Trade-offs
- [Extra synchronization overhead in hot transport paths] -> Mitigation: keep module callbacks coarse-grained, aggregate with counters/snapshots, and avoid per-packet file I/O.
- [Shutdown reporting can fail because of file-system issues] -> Mitigation: make file export best-effort, keep the in-memory snapshot available, and still print a console summary/error.
- [Transport metrics can be misread as business-layer truth] -> Mitigation: keep field names explicitly transport-scoped and exclude gameplay/session outcome claims from the module.
- [Dirty worktree around `KcpTransport` can cause merge pressure] -> Mitigation: constrain edits to additive hooks, new diagnostics types, and focused tests without rewriting existing KCP logic.
## Migration Plan
Add the diagnostics types, wire `KcpTransport`, update transport tests, and keep default behavior backward compatible by making metrics injection optional. No data migration or host adapter changes are required.
## Open Questions
None for v1; output mode and aggregation scope are fixed to JSON plus console and global plus per-peer summaries.
@@ -0,0 +1,24 @@
## Why
The transport layer can already move payloads and manage KCP sessions, but it does not expose structured runtime metrics for weak-network verification or resume-ready project data. We need a transport-agnostic metrics module now so each run can produce a durable summary without introducing Unity dependencies or bloating `ITransport`.
## What Changes
- Add an independent transport metrics module interface and snapshot model that aggregate transport-level statistics without depending on Unity or a concrete transport implementation.
- Wire `KcpTransport` to emit transport lifecycle, session, logical payload, UDP datagram, and error events into the metrics module through that interface.
- Add final-run reporting so `KcpTransport.Stop()` writes one JSON summary per run and prints a compact console summary.
- Expose a runtime snapshot query API on `KcpTransport` for tests and diagnostic tooling without changing `ITransport`.
## Capabilities
### New Capabilities
- `transport-metrics-reporting`: Structured transport metrics aggregation, peer-level summaries, and final report export for a single transport run.
### Modified Capabilities
- `kcp-transport`: KCP transport instances can publish lifecycle, traffic, session, and error statistics to an injected metrics module and emit a final report on shutdown.
## Impact
- Affected code: `Assets/Scripts/Network/NetworkTransport/` transport implementation and new diagnostics module types.
- Affected APIs: `KcpTransport` constructors gain an optional metrics-module dependency and expose a snapshot query method; `ITransport` remains unchanged.
- Affected tests: edit-mode transport tests gain coverage for metrics aggregation, multi-session peer summaries, and single-report shutdown behavior.
@@ -0,0 +1,14 @@
## ADDED Requirements
### Requirement: KCP transport can emit structured metrics through an optional module
`KcpTransport` SHALL allow callers to provide an optional transport metrics module without changing the shared `ITransport` contract. While running, `KcpTransport` MUST publish transport lifecycle, session creation and disposal, logical payload traffic, UDP datagram traffic, and transport-stage errors into that module, and it MUST expose a current metrics snapshot query for diagnostics and tests.
#### Scenario: Injected metrics module receives KCP traffic statistics
- **WHEN** a caller starts a `KcpTransport`, sends and receives payloads, and then stops the transport
- **THEN** the injected metrics module receives enough events to aggregate the run's payload, datagram, session, and error statistics
- **THEN** diagnostics code can query the current snapshot without reading the exported report file
#### Scenario: Default metrics module exports on KCP transport shutdown
- **WHEN** a caller uses `KcpTransport` without providing a custom metrics module and later calls `Stop()`
- **THEN** the transport uses its built-in metrics module to finalize the run summary during shutdown
- **THEN** the transport emits the final JSON report and compact console summary exactly once for that run
@@ -0,0 +1,25 @@
## ADDED Requirements
### Requirement: Transport metrics module is transport-agnostic and host-agnostic
The project SHALL provide a transport metrics module contract and snapshot model that do not depend on Unity runtime types or a specific `ITransport` implementation. Transport implementations MUST be able to publish lifecycle, traffic, session, and error events through that contract without exposing Unity-specific dependencies.
#### Scenario: KCP transport can publish into a shared metrics contract
- **WHEN** `KcpTransport` is constructed with a metrics module implementation
- **THEN** it can report start, shutdown, payload, datagram, session, and error events through that contract
- **THEN** the metrics module remains reusable outside Unity-specific hosts
### Requirement: Metrics summaries include global and per-peer transport statistics
The metrics module SHALL aggregate one run summary from transport start to transport stop, including global totals and per-peer totals keyed by remote endpoint. The summary MUST include at least payload counts and bytes, datagram counts and bytes, session lifecycle totals, and error counts.
#### Scenario: Multi-session traffic is preserved per remote endpoint
- **WHEN** a server transport communicates with multiple remote endpoints during one run
- **THEN** the final summary contains transport totals for the whole run
- **THEN** it also contains separate per-peer summaries so one endpoint's traffic and errors do not overwrite another's
### Requirement: Metrics module can finalize and export one run summary
The metrics module SHALL support end-of-run finalization that produces one durable summary per run and MUST make repeated finalization idempotent. The default reporting path MUST write a JSON report and emit a compact console summary when finalization occurs.
#### Scenario: Transport stop exports a single final summary
- **WHEN** a transport run reaches shutdown and triggers metrics finalization
- **THEN** one JSON summary is written for that run and one compact console summary is printed
- **THEN** a repeated shutdown call does not create a duplicate report for the same run
@@ -0,0 +1,14 @@
## 1. Metrics module
- [x] 1.1 Add transport metrics contracts, snapshot models, and default JSON-plus-console reporting implementation in shared networking code.
- [x] 1.2 Ensure the metrics module aggregates one run of global and per-peer counters and finalizes idempotently.
## 2. KCP transport integration
- [x] 2.1 Extend `KcpTransport` with optional metrics-module injection and current-snapshot access without changing `ITransport`.
- [x] 2.2 Publish start, shutdown, session, payload, datagram, and error events from `KcpTransport` into the metrics module and finalize reports on `Stop()`.
## 3. Verification
- [x] 3.1 Add edit-mode tests for metrics aggregation, peer isolation, and single-report shutdown behavior.
- [x] 3.2 Run the relevant network edit-mode test suite and confirm the new metrics behavior passes.
+13 -1
View File
@@ -1,4 +1,4 @@
# kcp-transport Specification
# kcp-transport Specification
## Purpose
TBD - created by archiving change introduce-kcp-transport. Update Purpose after archive.
@@ -61,3 +61,15 @@ The codebase SHALL NOT keep a directly instantiable `ReliableUdpTransport` entry
- **WHEN** developers inspect the transport implementations available to runtime code
- **THEN** they do not find a usable `ReliableUdpTransport` class representing reliable delivery
- **THEN** the remaining transport naming makes the reliable-versus-unreliable boundary explicit
### Requirement: KCP transport can emit structured metrics through an optional module
`KcpTransport` SHALL allow callers to provide an optional transport metrics module without changing the shared `ITransport` contract. While running, `KcpTransport` MUST publish transport lifecycle, session creation and disposal, logical payload traffic, UDP datagram traffic, and transport-stage errors into that module, and it MUST expose a current metrics snapshot query for diagnostics and tests.
#### Scenario: Injected metrics module receives KCP traffic statistics
- **WHEN** a caller starts a `KcpTransport`, sends and receives payloads, and then stops the transport
- **THEN** the injected metrics module receives enough events to aggregate the run's payload, datagram, session, and error statistics
- **THEN** diagnostics code can query the current snapshot without reading the exported report file
#### Scenario: Default metrics module exports on KCP transport shutdown
- **WHEN** a caller uses `KcpTransport` without providing a custom metrics module and later calls `Stop()`
- **THEN** the transport uses its built-in metrics module to finalize the run summary during shutdown
- **THEN** the transport emits the final JSON report and compact console summary exactly once for that run
@@ -0,0 +1,29 @@
# transport-metrics-reporting Specification
## Purpose
Define the shared transport metrics contract and final-run reporting behavior that transport implementations can use without depending on Unity or a concrete transport implementation.
## Requirements
### Requirement: Transport metrics module is transport-agnostic and host-agnostic
The project SHALL provide a transport metrics module contract and snapshot model that do not depend on Unity runtime types or a specific `ITransport` implementation. Transport implementations MUST be able to publish lifecycle, traffic, session, and error events through that contract without exposing Unity-specific dependencies.
#### Scenario: KCP transport can publish into a shared metrics contract
- **WHEN** `KcpTransport` is constructed with a metrics module implementation
- **THEN** it can report start, shutdown, payload, datagram, session, and error events through that contract
- **THEN** the metrics module remains reusable outside Unity-specific hosts
### Requirement: Metrics summaries include global and per-peer transport statistics
The metrics module SHALL aggregate one run summary from transport start to transport stop, including global totals and per-peer totals keyed by remote endpoint. The summary MUST include at least payload counts and bytes, datagram counts and bytes, session lifecycle totals, and error counts.
#### Scenario: Multi-session traffic is preserved per remote endpoint
- **WHEN** a server transport communicates with multiple remote endpoints during one run
- **THEN** the final summary contains transport totals for the whole run
- **THEN** it also contains separate per-peer summaries so one endpoint's traffic and errors do not overwrite another's
### Requirement: Metrics module can finalize and export one run summary
The metrics module SHALL support end-of-run finalization that produces one durable summary per run and MUST make repeated finalization idempotent. The default reporting path MUST write a JSON report and emit a compact console summary when finalization occurs.
#### Scenario: Transport stop exports a single final summary
- **WHEN** a transport run reaches shutdown and triggers metrics finalization
- **THEN** one JSON summary is written for that run and one compact console summary is printed
- **THEN** a repeated shutdown call does not create a duplicate report for the same run