# Monitoring — Gap Analysis > This file tracks what has and hasn't been ported from Go to .NET for the **Monitoring** module. > See [stillmissing.md](stillmissing.md) for the full LOC comparison across all modules. ## LLM Instructions: How to Analyze This Category ### Step 1: Read the Go Reference Files Read each Go source file listed below. For every file: 1. Extract all **exported types** (structs, interfaces, type aliases) 2. Extract all **exported methods** on those types (receiver functions) 3. Extract all **exported standalone functions** 4. Note **key constants, enums, and protocol states** 5. Note **important unexported helpers** that implement core logic (functions >20 lines) 6. Pay attention to **concurrency patterns** (goroutines, mutexes, channels) — these map to different .NET patterns ### Step 2: Read the .NET Implementation Files Read all `.cs` files in the .NET directories listed below. For each Go symbol found in Step 1: 1. Search for a matching type, method, or function in .NET 2. If found, compare the behavior: does it handle the same edge cases? Same error paths? 3. If partially implemented, note what's missing 4. If not found, note it as MISSING ### Step 3: Cross-Reference Tests Compare Go test functions against .NET test methods: 1. For each Go `Test*` function, check if a corresponding .NET `[Fact]` or `[Theory]` exists 2. Note which test scenarios are covered and which are missing 3. Check the parity DB (`docs/test_parity.db`) for existing mappings: ```bash sqlite3 docs/test_parity.db "SELECT go_test, dotnet_test, confidence FROM test_mappings tm JOIN go_tests gt ON tm.go_test_id=gt.rowid JOIN dotnet_tests dt ON tm.dotnet_test_id=dt.rowid WHERE gt.go_file LIKE '%PATTERN%'" ``` ### Step 4: Classify Each Item Use these status values: | Status | Meaning | |--------|---------| | **PORTED** | Equivalent exists in .NET with matching behavior | | **PARTIAL** | .NET implementation exists but is incomplete (missing edge cases, error handling, or features) | | **MISSING** | No .NET equivalent found — needs to be ported | | **NOT_APPLICABLE** | Go-specific pattern that doesn't apply to .NET (build tags, platform-specific goroutine tricks, etc.) | | **DEFERRED** | Intentionally skipped for now (document why) | ### Step 5: Fill In the Gap Inventory Add rows to the Gap Inventory table below. Group by Go source file. Include the Go file and line number so a porting LLM can jump directly to the reference implementation. ### Key Porting Notes for Monitoring - The monitoring JSON response shapes must match the Go server for tooling compatibility (nats-top, Prometheus exporters, etc.). - Each endpoint has query parameters for filtering and sorting (e.g., `/connz?sort=bytes_to&limit=10`). - `/healthz` is used for Kubernetes liveness probes and has JetStream-aware health checks. - Port 8222 by default. --- ## Go Reference Files (Source) - `golang/nats-server/server/monitor.go` — HTTP monitoring endpoints (~4,200 lines): `/varz`, `/connz`, `/routez`, `/gatewayz`, `/leafz`, `/subsz`, `/jsz`, `/healthz`, `/accountz` - `golang/nats-server/server/monitor_sort_opts.go` — Sort options for monitoring endpoints ## Go Reference Files (Tests) - `golang/nats-server/server/monitor_test.go` - `golang/nats-server/test/monitor_test.go` (integration) ## .NET Implementation Files (Source) - `src/NATS.Server/Monitoring/MonitorServer.cs` - `src/NATS.Server/Monitoring/Varz.cs` - `src/NATS.Server/Monitoring/Subsz.cs` - `src/NATS.Server/Monitoring/VarzHandler.cs` - `src/NATS.Server/Monitoring/SubszHandler.cs` - `src/NATS.Server/Monitoring/JszHandler.cs` - `src/NATS.Server/Monitoring/AccountzHandler.cs` - `src/NATS.Server/Monitoring/GatewayzHandler.cs` - `src/NATS.Server/Monitoring/LeafzHandler.cs` - `src/NATS.Server/Monitoring/RoutezHandler.cs` - `src/NATS.Server/Monitoring/PprofHandler.cs` - `src/NATS.Server/Monitoring/ClosedClient.cs` - All other files in `src/NATS.Server/Monitoring/` ## .NET Implementation Files (Tests) - `tests/NATS.Server.Tests/Monitoring/` --- ## Gap Inventory ### monitor_sort_opts.go | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `ConnInfos` (type alias `[]*ConnInfo`) | golang/nats-server/server/monitor_sort_opts.go:21 | PORTED | src/NATS.Server/Monitoring/Connz.cs:30 | .NET uses `ConnInfo[]` arrays instead | | `ConnInfos.Len()` | golang/nats-server/server/monitor_sort_opts.go:25 | NOT_APPLICABLE | — | Go sort.Interface boilerplate; .NET LINQ handles sorting natively | | `ConnInfos.Swap()` | golang/nats-server/server/monitor_sort_opts.go:28 | NOT_APPLICABLE | — | Go sort.Interface boilerplate; .NET LINQ handles sorting natively | | `SortOpt` (string type) | golang/nats-server/server/monitor_sort_opts.go:31 | PORTED | src/NATS.Server/Monitoring/Connz.cs:595 | .NET has both `SortOpt` enum (internal) and `ConnzSortOption` enum (public API) | | `ByCid` constant | golang/nats-server/server/monitor_sort_opts.go:35 | PORTED | src/NATS.Server/Monitoring/Connz.cs:597 | `SortOpt.ByCid` | | `ByStart` constant | golang/nats-server/server/monitor_sort_opts.go:36 | PORTED | src/NATS.Server/Monitoring/Connz.cs:598 | `SortOpt.ByStart` | | `BySubs` constant | golang/nats-server/server/monitor_sort_opts.go:37 | PORTED | src/NATS.Server/Monitoring/Connz.cs:599 | `SortOpt.BySubs` | | `ByPending` constant | golang/nats-server/server/monitor_sort_opts.go:38 | PORTED | src/NATS.Server/Monitoring/Connz.cs:600 | `SortOpt.ByPending` | | `ByOutMsgs` constant | golang/nats-server/server/monitor_sort_opts.go:39 | PORTED | src/NATS.Server/Monitoring/Connz.cs:601 | `SortOpt.ByMsgsTo` | | `ByInMsgs` constant | golang/nats-server/server/monitor_sort_opts.go:40 | PORTED | src/NATS.Server/Monitoring/Connz.cs:602 | `SortOpt.ByMsgsFrom` | | `ByOutBytes` constant | golang/nats-server/server/monitor_sort_opts.go:41 | PORTED | src/NATS.Server/Monitoring/Connz.cs:603 | `SortOpt.ByBytesTo` | | `ByInBytes` constant | golang/nats-server/server/monitor_sort_opts.go:42 | PORTED | src/NATS.Server/Monitoring/Connz.cs:604 | `SortOpt.ByBytesFrom` | | `ByLast` constant | golang/nats-server/server/monitor_sort_opts.go:43 | PORTED | src/NATS.Server/Monitoring/Connz.cs:605 | `SortOpt.ByLast` | | `ByIdle` constant | golang/nats-server/server/monitor_sort_opts.go:44 | PORTED | src/NATS.Server/Monitoring/Connz.cs:606 | `SortOpt.ByIdle` | | `ByUptime` constant | golang/nats-server/server/monitor_sort_opts.go:45 | PORTED | src/NATS.Server/Monitoring/Connz.cs:607 | `SortOpt.ByUptime` | | `ByStop` constant | golang/nats-server/server/monitor_sort_opts.go:46 | PORTED | src/NATS.Server/Monitoring/Connz.cs:608 | `SortOpt.ByStop` | | `ByReason` constant | golang/nats-server/server/monitor_sort_opts.go:47 | PORTED | src/NATS.Server/Monitoring/Connz.cs:609 | `SortOpt.ByReason` | | `ByRTT` constant | golang/nats-server/server/monitor_sort_opts.go:48 | PORTED | src/NATS.Server/Monitoring/Connz.cs:610 | `SortOpt.ByRtt` | | `SortByCid` | golang/nats-server/server/monitor_sort_opts.go:53 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:59 | Implemented as LINQ OrderBy in the sort switch | | `SortBySubs` | golang/nats-server/server/monitor_sort_opts.go:58 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:61 | LINQ OrderByDescending | | `SortByPending` | golang/nats-server/server/monitor_sort_opts.go:63 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:62 | LINQ OrderByDescending | | `SortByOutMsgs` | golang/nats-server/server/monitor_sort_opts.go:68 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:63 | LINQ OrderByDescending | | `SortByInMsgs` | golang/nats-server/server/monitor_sort_opts.go:73 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:64 | LINQ OrderByDescending | | `SortByOutBytes` | golang/nats-server/server/monitor_sort_opts.go:78 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:65 | LINQ OrderByDescending | | `SortByInBytes` | golang/nats-server/server/monitor_sort_opts.go:83 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:66 | LINQ OrderByDescending | | `SortByLast` | golang/nats-server/server/monitor_sort_opts.go:88 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:67 | LINQ OrderByDescending | | `SortByIdle` | golang/nats-server/server/monitor_sort_opts.go:95 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:68 | LINQ OrderByDescending with now capture | | `SortByUptime` | golang/nats-server/server/monitor_sort_opts.go:105 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:69 | LINQ OrderByDescending | | `SortByStop` | golang/nats-server/server/monitor_sort_opts.go:128 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:70 | LINQ OrderByDescending | | `SortByReason` | golang/nats-server/server/monitor_sort_opts.go:137 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:71 | LINQ OrderBy | | `SortByRTT` | golang/nats-server/server/monitor_sort_opts.go:144 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:72 | LINQ OrderBy | | `SortOpt.IsValid()` | golang/nats-server/server/monitor_sort_opts.go:149 | PORTED | src/NATS.Server/Monitoring/Connz.cs:618 | Added explicit `SortOptExtensions.IsValid()` parity helper and wired query parsing to validate parsed sort keys | --- ### monitor.go — Types and Structs | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `Connz` struct | golang/nats-server/server/monitor.go:48 | PORTED | src/NATS.Server/Monitoring/Connz.cs:8 | All JSON fields match | | `ConnzOptions` struct | golang/nats-server/server/monitor.go:59 | PORTED | src/NATS.Server/Monitoring/Connz.cs:628 | All options ported | | `ConnState` type | golang/nats-server/server/monitor.go:102 | PORTED | src/NATS.Server/Monitoring/Connz.cs:617 | `ConnState` enum with Open/Closed/All | | `ConnOpen` constant | golang/nats-server/server/monitor.go:105 | PORTED | src/NATS.Server/Monitoring/Connz.cs:619 | `ConnState.Open` | | `ConnClosed` constant | golang/nats-server/server/monitor.go:107 | PORTED | src/NATS.Server/Monitoring/Connz.cs:620 | `ConnState.Closed` | | `ConnAll` constant | golang/nats-server/server/monitor.go:109 | PORTED | src/NATS.Server/Monitoring/Connz.cs:621 | `ConnState.All` | | `ConnInfo` struct | golang/nats-server/server/monitor.go:114 | PARTIAL | src/NATS.Server/Monitoring/Connz.cs:36 | Added `stalls`, `jwt`, `issuer_key`, `name_tag`, `tags`, and structured `proxy` fields with open/closed snapshot mapping in `ConnzHandler`. Remaining parity gap: `stalls` is currently reported as `0` and `name_tag` is currently empty (no account name-tag source wired). | | `ProxyInfo` struct | golang/nats-server/server/monitor.go:157 | PORTED | src/NATS.Server/Monitoring/Connz.cs:154 | Added `ProxyInfo` model with `key` field and wired `ConnInfo.proxy` as an object in connz output. | | `TLSPeerCert` struct | golang/nats-server/server/monitor.go:163 | PORTED | src/NATS.Server/Monitoring/Connz.cs:144 | Added `TLSPeerCert` with `subject`, `subject_pk_sha256`, and `cert_sha256` fields; wired into `ConnInfo.tls_peer_certs` | | `DefaultConnListSize` constant | golang/nats-server/server/monitor.go:169 | PORTED | src/NATS.Server/Monitoring/Connz.cs:660 | Default 1024 on `ConnzOptions.Limit` | | `DefaultSubListSize` constant | golang/nats-server/server/monitor.go:172 | PORTED | src/NATS.Server/Monitoring/Subsz.cs:41 | Default 1024 on `SubszOptions.Limit` | | `Routez` struct | golang/nats-server/server/monitor.go:782 | PARTIAL | src/NATS.Server/Monitoring/RoutezHandler.cs:12 | Go has full Routez struct with ID, Name, Now, Import, Export, NumRoutes, Routes; .NET returns anonymous object with only `routes` and `num_routes` counts | | `RoutezOptions` struct | golang/nats-server/server/monitor.go:793 | MISSING | — | No options struct; handler accepts no query params | | `RouteInfo` struct | golang/nats-server/server/monitor.go:801 | MISSING | — | Go has full per-route details (Rid, RemoteID, RTT, etc.); .NET returns just route count | | `Subsz` struct | golang/nats-server/server/monitor.go:928 | PARTIAL | src/NATS.Server/Monitoring/Subsz.cs:8 | Missing `SublistStats` embedded fields; .NET has `NumSubs` and `NumCache` instead of the full `SublistStats` type | | `SubszOptions` struct | golang/nats-server/server/monitor.go:940 | PORTED | src/NATS.Server/Monitoring/Subsz.cs:38 | All options present | | `SubDetail` struct | golang/nats-server/server/monitor.go:961 | PARTIAL | src/NATS.Server/Monitoring/Connz.cs:142 | Missing `AccountTag` field; present fields match | | `Varz` struct | golang/nats-server/server/monitor.go:1211 | PARTIAL | src/NATS.Server/Monitoring/Varz.cs:8 | Missing: `ConfigDigest`, `TrustedOperatorsJwt`, `TrustedOperatorsClaim`, `PinnedAccountFail` (present), `OCSPResponseCache`, `StaleConnectionStats` (present), `Proxies`, `WriteTimeout` string field; `StalledClients` field missing; `Metadata` field missing | | `JetStreamVarz` struct | golang/nats-server/server/monitor.go:1286 | PARTIAL | src/NATS.Server/Monitoring/Varz.cs:403 | Missing `Meta *MetaClusterInfo` and `Limits *JSLimitOpts` fields | | `ClusterOptsVarz` struct | golang/nats-server/server/monitor.go:1294 | PARTIAL | src/NATS.Server/Monitoring/Varz.cs:251 | Missing `WriteDeadline`, `WriteTimeout`, `TLSCertNotAfter` fields | | `GatewayOptsVarz` struct | golang/nats-server/server/monitor.go:1310 | PARTIAL | src/NATS.Server/Monitoring/Varz.cs:285 | Missing `Gateways []RemoteGatewayOptsVarz`, `WriteDeadline`, `WriteTimeout`, `TLSCertNotAfter` fields | | `RemoteGatewayOptsVarz` struct | golang/nats-server/server/monitor.go:1328 | MISSING | — | No .NET equivalent | | `LeafNodeOptsVarz` struct | golang/nats-server/server/monitor.go:1335 | PARTIAL | src/NATS.Server/Monitoring/Varz.cs:322 | Missing `Remotes []RemoteLeafOptsVarz`, `WriteDeadline`, `WriteTimeout`, `TLSCertNotAfter` fields | | `DenyRules` struct | golang/nats-server/server/monitor.go:1350 | MISSING | — | No .NET equivalent | | `RemoteLeafOptsVarz` struct | golang/nats-server/server/monitor.go:1356 | MISSING | — | No .NET equivalent | | `MQTTOptsVarz` struct | golang/nats-server/server/monitor.go:1365 | PARTIAL | src/NATS.Server/Monitoring/Varz.cs:350 | Missing `TLSOCSPPeerVerify`, `TLSCertNotAfter` fields | | `WebsocketOptsVarz` struct | golang/nats-server/server/monitor.go:1381 | PARTIAL | src/NATS.Server/Monitoring/Varz.cs:387 | Go has many more fields (Advertise, NoAuthUser, JWTCookie, HandshakeTimeout, AuthTimeout, NoTLS, TLSMap, TLSPinnedCerts, SameOrigin, AllowedOrigins, Compression, TLSOCSPPeerVerify, TLSCertNotAfter); .NET only has Host, Port, TlsTimeout | | `OCSPResponseCacheVarz` struct | golang/nats-server/server/monitor.go:1399 | MISSING | — | No .NET equivalent; OCSP cache monitoring not ported | | `ProxiesOptsVarz` struct | golang/nats-server/server/monitor.go:1411 | MISSING | — | No .NET equivalent | | `ProxyOptsVarz` struct | golang/nats-server/server/monitor.go:1416 | MISSING | — | No .NET equivalent | | `VarzOptions` struct | golang/nats-server/server/monitor.go:1422 | PORTED | — | Empty struct, not needed in .NET since handler takes no options | | `SlowConsumersStats` struct | golang/nats-server/server/monitor.go:1424 | PORTED | src/NATS.Server/Monitoring/Varz.cs:213 | All four fields present | | `StaleConnectionStats` struct | golang/nats-server/server/monitor.go:1432 | PORTED | src/NATS.Server/Monitoring/Varz.cs:232 | All four fields present | | `GatewayzOptions` struct | golang/nats-server/server/monitor.go:2004 | MISSING | — | .NET GatewayzHandler has no options; returns only counts | | `Gatewayz` struct | golang/nats-server/server/monitor.go:2024 | PARTIAL | src/NATS.Server/Monitoring/GatewayzHandler.cs:12 | Go has full struct with OutboundGateways/InboundGateways maps; .NET returns anonymous count object | | `RemoteGatewayz` struct | golang/nats-server/server/monitor.go:2036 | MISSING | — | No .NET equivalent | | `AccountGatewayz` struct | golang/nats-server/server/monitor.go:2043 | MISSING | — | No .NET equivalent | | `Leafz` struct | golang/nats-server/server/monitor.go:2348 | PARTIAL | src/NATS.Server/Monitoring/LeafzHandler.cs:12 | Go has full struct with NumLeafs and Leafs array; .NET returns anonymous count object | | `LeafzOptions` struct | golang/nats-server/server/monitor.go:2356 | MISSING | — | No options struct; handler accepts no query params | | `LeafInfo` struct | golang/nats-server/server/monitor.go:2364 | MISSING | — | No .NET equivalent for per-leafnode detail | | `AccountStatz` struct | golang/nats-server/server/monitor.go:2471 | PARTIAL | src/NATS.Server/Monitoring/AccountzHandler.cs:27 | Go has `ID`, `Now`, `Accounts []*AccountStat`; .NET returns anonymous object with total counts | | `AccountStatzOptions` struct | golang/nats-server/server/monitor.go:2478 | MISSING | — | No .NET equivalent; `?unused` query param not parsed | | `AccountzOptions` struct | golang/nats-server/server/monitor.go:2646 | MISSING | — | `?acc=` query param not parsed for account detail | | `ExtImport` struct | golang/nats-server/server/monitor.go:2662 | MISSING | — | JWT import monitoring detail not ported | | `ExtExport` struct | golang/nats-server/server/monitor.go:2672 | MISSING | — | JWT export monitoring detail not ported | | `ExtVrIssues` struct | golang/nats-server/server/monitor.go:2678 | MISSING | — | JWT validation result reporting not ported | | `ExtMap` type | golang/nats-server/server/monitor.go:2684 | MISSING | — | Account subject mapping detail not ported | | `AccountInfo` struct | golang/nats-server/server/monitor.go:2686 | MISSING | — | Detailed per-account monitoring not ported | | `Accountz` struct | golang/nats-server/server/monitor.go:2710 | PARTIAL | src/NATS.Server/Monitoring/AccountzHandler.cs:14 | Go has ID, Now, SystemAccount, Accounts list, and Account detail; .NET returns simplified anonymous object | | `JSzOptions` struct | golang/nats-server/server/monitor.go:2928 | PARTIAL | — | Most options not parsed from query string; handler builds static JSZ response | | `HealthzOptions` struct | golang/nats-server/server/monitor.go:2943 | MISSING | — | .NET /healthz endpoint does not parse any options; returns static "ok" | | `ProfilezOptions` struct | golang/nats-server/server/monitor.go:2956 | PARTIAL | src/NATS.Server/Monitoring/PprofHandler.cs:24 | Only `seconds` duration from CPU profile path; no `name` or `debug` level routing | | `IpqueueszOptions` struct | golang/nats-server/server/monitor.go:2963 | MISSING | — | /ipqueuesz endpoint not implemented | | `RaftzOptions` struct | golang/nats-server/server/monitor.go:2969 | MISSING | — | /raftz endpoint not implemented | | `StreamDetail` struct | golang/nats-server/server/monitor.go:2975 | MISSING | — | JSZ stream detail not ported | | `RaftGroupDetail` struct | golang/nats-server/server/monitor.go:2991 | MISSING | — | RAFT group detail not ported | | `AccountDetail` struct | golang/nats-server/server/monitor.go:2996 | MISSING | — | JSZ per-account detail not ported | | `MetaSnapshotStats` struct | golang/nats-server/server/monitor.go:3003 | MISSING | — | RAFT meta snapshot stats not ported | | `MetaClusterInfo` struct | golang/nats-server/server/monitor.go:3011 | MISSING | — | RAFT meta cluster info not ported (referenced in JetStreamVarz.Meta) | | `JSInfo` struct | golang/nats-server/server/monitor.go:3023 | PARTIAL | src/NATS.Server/Monitoring/JszHandler.cs:39 | Go JSInfo has JetStreamStats embedded, ID, Now, Disabled, Config, Limits, Streams, StreamsLeader, Consumers, ConsumersLeader, Messages, Bytes, Meta, AccountDetails, Total; .NET JszResponse has simplified fields with different JSON names (`api_total`/`api_errors` instead of nested `api`) | | `HealthStatus` struct | golang/nats-server/server/monitor.go:3408 | PORTED | src/NATS.Server/Monitoring/Healthz.cs:9 | Added structured health DTO with Go-style JSON fields (`status`, `status_code`, `error`, `errors`) and updated `/healthz` to return this shape | | `HealthzError` struct | golang/nats-server/server/monitor.go:3415 | PORTED | src/NATS.Server/Monitoring/Healthz.cs:30 | Added per-check error DTO with `type` and `error` fields | | `HealthZErrorType` type | golang/nats-server/server/monitor.go:3423 | PORTED | src/NATS.Server/Monitoring/Healthz.cs:44 | Added health error classification enum with JSON string serialization | | `ExpvarzStatus` struct | golang/nats-server/server/monitor.go:4019 | MISSING | — | /expvarz endpoint not implemented | | `ProfilezStatus` struct | golang/nats-server/server/monitor.go:4043 | MISSING | — | No structured response; CPU profile endpoint returns raw bytes | | `RaftzGroup` struct | golang/nats-server/server/monitor.go:4086 | MISSING | — | /raftz endpoint not implemented | | `RaftzGroupPeer` struct | golang/nats-server/server/monitor.go:4114 | MISSING | — | /raftz endpoint not implemented | | `RaftzStatus` type | golang/nats-server/server/monitor.go:4121 | MISSING | — | /raftz endpoint not implemented | | `IpqueueszStatusIPQ` struct | golang/nats-server/server/monitor.go:1162 | MISSING | — | /ipqueuesz endpoint not implemented | | `IpqueueszStatus` type | golang/nats-server/server/monitor.go:1167 | MISSING | — | /ipqueuesz endpoint not implemented | --- ### monitor.go — Methods and Functions | Go Symbol | Go File:Line | Status | .NET Equivalent | Notes | |-----------|:-------------|--------|:----------------|-------| | `newSubsDetailList()` | golang/nats-server/server/monitor.go:176 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:189 | Implemented inline in BuildConnInfo | | `newSubsList()` | golang/nats-server/server/monitor.go:184 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:180 | Implemented inline in BuildConnInfo | | `Server.Connz()` | golang/nats-server/server/monitor.go:193 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:12 | `ConnzHandler.HandleConnz()` | | `ConnInfo.fill()` | golang/nats-server/server/monitor.go:556 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:144 | `BuildConnInfo()` static method | | `createProxyInfo()` | golang/nats-server/server/monitor.go:609 | PARTIAL | src/NATS.Server/Monitoring/ConnzHandler.cs:378 | .NET now emits structured `ProxyInfo` (`proxy.key`) and snapshots it for closed clients, but key derivation is currently based on `proxy:` username prefix rather than Go's internal `client.proxyKey` source. | | `makePeerCerts()` | golang/nats-server/server/monitor.go:616 | PORTED | src/NATS.Server/Monitoring/TlsPeerCertMapper.cs:8 | Added peer-cert mapping helper computing subject + SHA256 hashes and wired for both open and closed connz snapshots | | `client.getRTT()` | golang/nats-server/server/monitor.go:629 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:321 | `FormatRtt()` formats from stored `client.Rtt` | | `decodeBool()` | golang/nats-server/server/monitor.go:647 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:267 | Inline query param parsing in ParseQueryParams | | `decodeUint64()` | golang/nats-server/server/monitor.go:661 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:291 | Inline query param parsing | | `decodeInt()` | golang/nats-server/server/monitor.go:675 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:285 | Inline query param parsing | | `decodeState()` | golang/nats-server/server/monitor.go:689 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:275 | State parsing in ParseQueryParams | | `decodeSubs()` | golang/nats-server/server/monitor.go:709 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:266 | Subs + subs-detail parsing | | `Server.HandleConnz()` | golang/nats-server/server/monitor.go:718 | PORTED | src/NATS.Server/Monitoring/MonitorServer.cs:70 | Mapped at `/connz` route | | `Server.Routez()` | golang/nats-server/server/monitor.go:830 | PARTIAL | src/NATS.Server/Monitoring/RoutezHandler.cs:13 | Go returns full Routez struct with per-route RouteInfo; .NET returns only count | | `Server.HandleRoutez()` | golang/nats-server/server/monitor.go:904 | PARTIAL | src/NATS.Server/Monitoring/MonitorServer.cs:76 | Endpoint mapped, but subs/subscriptions_detail query params not parsed | | `newSubDetail()` | golang/nats-server/server/monitor.go:973 | PORTED | src/NATS.Server/Monitoring/SubszHandler.cs:51 | Implemented inline | | `newClientSubDetail()` | golang/nats-server/server/monitor.go:981 | PORTED | src/NATS.Server/Monitoring/ConnzHandler.cs:189 | Implemented inline | | `Server.Subsz()` | golang/nats-server/server/monitor.go:992 | PORTED | src/NATS.Server/Monitoring/SubszHandler.cs:12 | `SubszHandler.HandleSubsz()` | | `Server.HandleSubsz()` | golang/nats-server/server/monitor.go:1095 | PORTED | src/NATS.Server/Monitoring/MonitorServer.cs:91 | Mapped at `/subz` and `/subscriptionsz` | | `Server.HandleStacksz()` | golang/nats-server/server/monitor.go:1142 | MISSING | — | No .NET /stacksz endpoint | | `Server.Ipqueuesz()` | golang/nats-server/server/monitor.go:1169 | MISSING | — | No .NET /ipqueuesz endpoint | | `Server.HandleIPQueuesz()` | golang/nats-server/server/monitor.go:1194 | MISSING | — | No .NET /ipqueuesz endpoint | | `Server.updateJszVarz()` | golang/nats-server/server/monitor.go:1555 | PARTIAL | src/NATS.Server/Monitoring/VarzHandler.cs:125 | Partially in VarzHandler; missing Meta/Limits/Config update logic | | `Server.Varz()` | golang/nats-server/server/monitor.go:1580 | PORTED | src/NATS.Server/Monitoring/VarzHandler.cs:30 | `VarzHandler.HandleVarzAsync()` | | `Server.createVarz()` | golang/nats-server/server/monitor.go:1603 | PORTED | src/NATS.Server/Monitoring/VarzHandler.cs:67 | Logic inline in HandleVarzAsync | | `urlsToStrings()` | golang/nats-server/server/monitor.go:1756 | NOT_APPLICABLE | — | Helper for URL slice conversion; .NET uses LINQ Select | | `Server.updateVarzConfigReloadableFields()` | golang/nats-server/server/monitor.go:1768 | PARTIAL | src/NATS.Server/Monitoring/VarzHandler.cs:67 | Config fields set at construction; no reload tracking; missing TLSCertNotAfter for cluster/gateway/leafnode/mqtt/websocket | | `Server.updateVarzRuntimeFields()` | golang/nats-server/server/monitor.go:1840 | PORTED | src/NATS.Server/Monitoring/VarzHandler.cs:67 | Runtime fields computed each request | | `getPinnedCertsAsSlice()` | golang/nats-server/server/monitor.go:1825 | PORTED | src/NATS.Server/Monitoring/VarzHandler.cs:173 | Present for MQTT; no websocket equivalent | | `Server.HandleVarz()` | golang/nats-server/server/monitor.go:1946 | PORTED | src/NATS.Server/Monitoring/MonitorServer.cs:64 | Mapped at `/varz` | | `Server.HandleRoot()` | golang/nats-server/server/monitor.go:1480 | PARTIAL | src/NATS.Server/Monitoring/MonitorServer.cs:47 | .NET returns JSON array of endpoint names; Go returns HTML page with links and NATS logo | | `myUptime()` | golang/nats-server/server/monitor.go:1440 | PORTED | src/NATS.Server/Monitoring/VarzHandler.cs:183 | `FormatUptime()` and `FormatDuration()` — same format logic | | `tlsCertNotAfter()` | golang/nats-server/server/monitor.go:1463 | PARTIAL | src/NATS.Server/Monitoring/VarzHandler.cs:53 | .NET only reads cert for client TLS; Go reads for all subsystem TLS configs | | `Server.Gatewayz()` | golang/nats-server/server/monitor.go:2054 | PARTIAL | src/NATS.Server/Monitoring/GatewayzHandler.cs:13 | Go returns full outbound/inbound gateway maps; .NET returns only counts | | `getMonitorGWOptions()` | golang/nats-server/server/monitor.go:2090 | MISSING | — | No options parsing in .NET GatewayzHandler | | `Server.createOutboundsRemoteGatewayz()` | golang/nats-server/server/monitor.go:2108 | MISSING | — | No outbound gateway detail | | `createOutboundRemoteGatewayz()` | golang/nats-server/server/monitor.go:2138 | MISSING | — | No outbound gateway detail | | `createOutboundAccountsGatewayz()` | golang/nats-server/server/monitor.go:2163 | MISSING | — | No gateway account interest detail | | `createAccountOutboundGatewayz()` | golang/nats-server/server/monitor.go:2192 | MISSING | — | No gateway account interest detail | | `Server.createInboundsRemoteGatewayz()` | golang/nats-server/server/monitor.go:2233 | MISSING | — | No inbound gateway detail | | `createInboundAccountsGatewayz()` | golang/nats-server/server/monitor.go:2265 | MISSING | — | No gateway account interest detail | | `createInboundAccountGatewayz()` | golang/nats-server/server/monitor.go:2292 | MISSING | — | No gateway account interest detail | | `Server.HandleGatewayz()` | golang/nats-server/server/monitor.go:2306 | PARTIAL | src/NATS.Server/Monitoring/MonitorServer.cs:81 | Endpoint mapped; query params (gw_name, accs, acc_name, subs) not parsed | | `Server.Leafz()` | golang/nats-server/server/monitor.go:2384 | PARTIAL | src/NATS.Server/Monitoring/LeafzHandler.cs:13 | Go returns full LeafInfo per leafnode; .NET returns only count | | `Server.HandleLeafz()` | golang/nats-server/server/monitor.go:2445 | PARTIAL | src/NATS.Server/Monitoring/MonitorServer.cs:86 | Endpoint mapped; `subs` and `acc` query params not parsed | | `Server.AccountStatz()` | golang/nats-server/server/monitor.go:2484 | PARTIAL | src/NATS.Server/Monitoring/AccountzHandler.cs:27 | .NET BuildStats() returns totals; no per-account `AccountStat` detail or `accounts` / `include_unused` filter | | `Server.HandleAccountStatz()` | golang/nats-server/server/monitor.go:2516 | PARTIAL | src/NATS.Server/Monitoring/MonitorServer.cs:106 | Endpoint mapped at `/accstatz`; `unused` query param not parsed | | `ResponseHandler()` | golang/nats-server/server/monitor.go:2542 | PARTIAL | src/NATS.Server/Monitoring/MonitorServer.cs:47 | .NET uses ASP.NET Core Results.Ok(); no JSONP callback support | | `handleResponse()` | golang/nats-server/server/monitor.go:2548 | PARTIAL | src/NATS.Server/Monitoring/MonitorServer.cs:47 | No custom status code support from handler level; no JSONP support | | `ClosedState.String()` | golang/nats-server/server/monitor.go:2565 | PORTED | src/NATS.Server/Monitoring/Connz.cs:511 | `ClosedReasonHelper.ToReasonString()` | | `Server.HandleAccountz()` | golang/nats-server/server/monitor.go:2718 | PARTIAL | src/NATS.Server/Monitoring/MonitorServer.cs:101 | Endpoint mapped; `acc` query param for account detail not parsed | | `Server.Accountz()` | golang/nats-server/server/monitor.go:2735 | PARTIAL | src/NATS.Server/Monitoring/AccountzHandler.cs:14 | Go returns full Accountz with optional AccountInfo detail; .NET returns simplified list | | `newExtServiceLatency()` | golang/nats-server/server/monitor.go:2652 | MISSING | — | JWT service latency detail not ported | | `newExtImport()` | golang/nats-server/server/monitor.go:2759 | MISSING | — | JWT import detail not ported | | `Server.accountInfo()` | golang/nats-server/server/monitor.go:2786 | MISSING | — | Full account info with exports/imports/mappings/JWT not ported | | `Server.JszAccount()` | golang/nats-server/server/monitor.go:3142 | MISSING | — | Per-account JSZ detail not ported | | `Server.raftNodeToClusterInfo()` | golang/nats-server/server/monitor.go:3162 | MISSING | — | RAFT cluster info helper not ported | | `Server.Jsz()` | golang/nats-server/server/monitor.go:3180 | PARTIAL | src/NATS.Server/Monitoring/JszHandler.cs:16 | Go Jsz() has full JSInfo with accounts/streams/consumers/meta; .NET JszHandler.Build() returns simplified flat fields | | `Server.accountDetail()` | golang/nats-server/server/monitor.go:3041 | MISSING | — | Per-account stream/consumer detail not ported | | `Server.HandleJsz()` | golang/nats-server/server/monitor.go:3334 | PARTIAL | src/NATS.Server/Monitoring/MonitorServer.cs:111 | Endpoint mapped; all query params (accounts, streams, consumers, config, offset, limit, leader-only, raft, stream-leader-only) not parsed | | `Server.HandleHealthz()` | golang/nats-server/server/monitor.go:3478 | PARTIAL | src/NATS.Server/Monitoring/MonitorServer.cs:59 | Endpoint mapped and now returns structured `HealthStatus`; Go JetStream-aware/dependency checks are still missing | | `Server.healthz()` | golang/nats-server/server/monitor.go:3537 | MISSING | — | Full healthz logic with JS stream/consumer recovery checks not ported | | `Server.Healthz()` | golang/nats-server/server/monitor.go:4014 | MISSING | — | Public Healthz() method not ported | | `Server.expvarz()` | golang/nats-server/server/monitor.go:4024 | MISSING | — | /expvarz endpoint not implemented | | `Server.profilez()` | golang/nats-server/server/monitor.go:4048 | PARTIAL | src/NATS.Server/Monitoring/PprofHandler.cs:24 | .NET CaptureCpuProfile() captures process metrics as JSON; Go uses pprof binary format | | `Server.HandleRaftz()` | golang/nats-server/server/monitor.go:4123 | MISSING | — | /raftz endpoint not implemented | | `Server.Raftz()` | golang/nats-server/server/monitor.go:4145 | MISSING | — | RAFT node status reporting not ported | --- ## Keeping This File Updated After porting work is completed: 1. **Update status**: Change `MISSING → PORTED` or `PARTIAL → PORTED` for each item completed 2. **Add .NET path**: Fill in the ".NET Equivalent" column with the actual file:line 3. **Re-count LOC**: Update the LOC numbers in `stillmissing.md`: ```bash # Re-count .NET source LOC for this module find src/NATS.Server/Monitoring/ -name '*.cs' -type f -exec cat {} + | wc -l # Re-count .NET test LOC for this module find tests/NATS.Server.Tests/Monitoring/ -name '*.cs' -type f -exec cat {} + | wc -l ``` 4. **Add a changelog entry** below with date and summary of what was ported 5. **Update the parity DB** if new test mappings were created: ```bash sqlite3 docs/test_parity.db "INSERT INTO test_mappings (go_test_id, dotnet_test_id, confidence, notes) VALUES (?, ?, 'manual', 'ported in YYYY-MM-DD session')" ``` ## Change Log | Date | Change | By | |------|--------|----| | 2026-02-26 | Improved connz parity for `ConnInfo`/`ProxyInfo`: added Go-style `stalls`, `jwt`, `issuer_key`, `name_tag`, `tags`, and structured `proxy` output; wired JWT/tag decode and closed-conn snapshot fields; added focused monitoring parity tests. | codex | | 2026-02-25 | Ported monitoring TLS peer-cert parity slice: added `TLSPeerCert` model and `tls_peer_certs` JSON output with SHA256 fields, wired open/closed conn snapshots via `TlsPeerCertMapper`, and added focused tests (`TlsPeerCertParityTests`). | codex | | 2026-02-25 | File created with LLM analysis instructions | auto | | 2026-02-25 | Full gap inventory populated: 63 PORTED, 42 PARTIAL, 61 MISSING, 3 NOT_APPLICABLE, 0 DEFERRED (169 total rows) | claude-sonnet-4-6 |