feat: port sessions 12 & 13 — Events/Monitoring/MsgTrace + Config Reload
Session 12 (218 features, IDs 854-950, 2166-2251, 2405-2439): - EventTypes: system subjects, event message types, InternalState, ConnectEventMsg, DisconnectEventMsg, AccountNumConns, ServerIdentity, DataStats - MonitorTypes: Connz, ConnInfo, ConnzOptions, ConnState, ProxyInfo, TlsPeerCert - MonitorSortOptions: SortOpt, ConnInfos, all 13 sort comparers - MsgTraceTypes: IMsgTrace, MsgTraceBase + 6 concrete types, custom JSON converter Session 13 (89 features, IDs 2800-2888): - ReloadOptions: IReloadOption interface, NoopReloadOption base, 50 option classes covering logging, TLS, auth, cluster, JetStream, MQTT, OCSP, misc
This commit is contained in:
294
dotnet/src/ZB.MOM.NatsNet.Server/Monitor/MonitorSortOptions.cs
Normal file
294
dotnet/src/ZB.MOM.NatsNet.Server/Monitor/MonitorSortOptions.cs
Normal file
@@ -0,0 +1,294 @@
|
||||
// Copyright 2013-2026 The NATS Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Adapted from server/monitor_sort_opts.go in the NATS server Go source.
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ZB.MOM.NatsNet.Server;
|
||||
|
||||
// ============================================================================
|
||||
// SortOpt — string wrapper type for connection-list sort options
|
||||
// Mirrors Go <c>SortOpt string</c> in server/monitor_sort_opts.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed sort option for <see cref="ConnzOptions.Sort"/>.
|
||||
/// Wraps a raw string value corresponding to the JSON sort key.
|
||||
/// Mirrors Go <c>SortOpt string</c> in server/monitor_sort_opts.go.
|
||||
/// </summary>
|
||||
public sealed class SortOpt
|
||||
{
|
||||
private readonly string _value;
|
||||
|
||||
private SortOpt(string value) => _value = value;
|
||||
|
||||
/// <summary>Returns the raw sort-option string value.</summary>
|
||||
public override string ToString() => _value;
|
||||
|
||||
/// <summary>Allows implicit conversion from a string literal.</summary>
|
||||
public static implicit operator SortOpt(string value) => new(value);
|
||||
|
||||
/// <summary>Allows implicit conversion back to a plain string.</summary>
|
||||
public static implicit operator string(SortOpt opt) => opt._value;
|
||||
|
||||
public override bool Equals(object? obj) =>
|
||||
obj is SortOpt other && _value == other._value;
|
||||
|
||||
public override int GetHashCode() => _value.GetHashCode();
|
||||
|
||||
// ---- Well-known sort-option constants ----
|
||||
// Mirrors Go const block in monitor_sort_opts.go.
|
||||
|
||||
/// <summary>Sort by connection ID (ascending). Mirrors Go <c>ByCid = "cid"</c>.</summary>
|
||||
public static readonly SortOpt ByCid = new("cid");
|
||||
|
||||
/// <summary>Sort by connection start time (same as ByCid). Mirrors Go <c>ByStart = "start"</c>.</summary>
|
||||
public static readonly SortOpt ByStart = new("start");
|
||||
|
||||
/// <summary>Sort by number of subscriptions (descending). Mirrors Go <c>BySubs = "subs"</c>.</summary>
|
||||
public static readonly SortOpt BySubs = new("subs");
|
||||
|
||||
/// <summary>Sort by pending bytes waiting to be sent (descending). Mirrors Go <c>ByPending = "pending"</c>.</summary>
|
||||
public static readonly SortOpt ByPending = new("pending");
|
||||
|
||||
/// <summary>Sort by number of outbound messages (descending). Mirrors Go <c>ByOutMsgs = "msgs_to"</c>.</summary>
|
||||
public static readonly SortOpt ByOutMsgs = new("msgs_to");
|
||||
|
||||
/// <summary>Sort by number of inbound messages (descending). Mirrors Go <c>ByInMsgs = "msgs_from"</c>.</summary>
|
||||
public static readonly SortOpt ByInMsgs = new("msgs_from");
|
||||
|
||||
/// <summary>Sort by bytes sent (descending). Mirrors Go <c>ByOutBytes = "bytes_to"</c>.</summary>
|
||||
public static readonly SortOpt ByOutBytes = new("bytes_to");
|
||||
|
||||
/// <summary>Sort by bytes received (descending). Mirrors Go <c>ByInBytes = "bytes_from"</c>.</summary>
|
||||
public static readonly SortOpt ByInBytes = new("bytes_from");
|
||||
|
||||
/// <summary>Sort by last activity time (descending). Mirrors Go <c>ByLast = "last"</c>.</summary>
|
||||
public static readonly SortOpt ByLast = new("last");
|
||||
|
||||
/// <summary>Sort by idle duration (descending). Mirrors Go <c>ByIdle = "idle"</c>.</summary>
|
||||
public static readonly SortOpt ByIdle = new("idle");
|
||||
|
||||
/// <summary>Sort by uptime (descending). Mirrors Go <c>ByUptime = "uptime"</c>.</summary>
|
||||
public static readonly SortOpt ByUptime = new("uptime");
|
||||
|
||||
/// <summary>Sort by stop time — only valid on closed connections. Mirrors Go <c>ByStop = "stop"</c>.</summary>
|
||||
public static readonly SortOpt ByStop = new("stop");
|
||||
|
||||
/// <summary>Sort by close reason — only valid on closed connections. Mirrors Go <c>ByReason = "reason"</c>.</summary>
|
||||
public static readonly SortOpt ByReason = new("reason");
|
||||
|
||||
/// <summary>Sort by round-trip time (descending). Mirrors Go <c>ByRTT = "rtt"</c>.</summary>
|
||||
public static readonly SortOpt ByRtt = new("rtt");
|
||||
|
||||
private static readonly HashSet<string> ValidValues =
|
||||
[
|
||||
"", "cid", "start", "subs", "pending",
|
||||
"msgs_to", "msgs_from", "bytes_to", "bytes_from",
|
||||
"last", "idle", "uptime", "stop", "reason", "rtt"
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this sort option is a recognised value.
|
||||
/// Mirrors Go <c>SortOpt.IsValid()</c> in monitor_sort_opts.go.
|
||||
/// </summary>
|
||||
public bool IsValid() => ValidValues.Contains(_value);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ConnInfos — sortable list wrapper for ConnInfo pointers
|
||||
// Mirrors Go <c>ConnInfos []*ConnInfo</c> in monitor_sort_opts.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// A list of <see cref="ConnInfo"/> objects that can be sorted using one of
|
||||
/// the <c>SortBy*</c> comparers defined in this file.
|
||||
/// Mirrors Go <c>ConnInfos []*ConnInfo</c> in server/monitor_sort_opts.go.
|
||||
/// </summary>
|
||||
public sealed class ConnInfos : List<ConnInfo>
|
||||
{
|
||||
public ConnInfos() { }
|
||||
public ConnInfos(IEnumerable<ConnInfo> items) : base(items) { }
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// IComparer<ConnInfo> implementations — one per sort option
|
||||
// Each class mirrors the corresponding Less() method in monitor_sort_opts.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>Sort by connection ID (ascending). Mirrors Go <c>SortByCid</c>.</summary>
|
||||
public sealed class SortByCid : IComparer<ConnInfo>
|
||||
{
|
||||
public static readonly SortByCid Instance = new();
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
return x.Cid.CompareTo(y.Cid);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sort by number of subscriptions (ascending for underlying sort; caller reverses if needed).</summary>
|
||||
/// Mirrors Go <c>SortBySubs</c>.
|
||||
public sealed class SortBySubs : IComparer<ConnInfo>
|
||||
{
|
||||
public static readonly SortBySubs Instance = new();
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
return x.NumSubs.CompareTo(y.NumSubs);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sort by pending bytes. Mirrors Go <c>SortByPending</c>.</summary>
|
||||
public sealed class SortByPending : IComparer<ConnInfo>
|
||||
{
|
||||
public static readonly SortByPending Instance = new();
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
return x.Pending.CompareTo(y.Pending);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sort by outbound message count. Mirrors Go <c>SortByOutMsgs</c>.</summary>
|
||||
public sealed class SortByOutMsgs : IComparer<ConnInfo>
|
||||
{
|
||||
public static readonly SortByOutMsgs Instance = new();
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
return x.OutMsgs.CompareTo(y.OutMsgs);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sort by inbound message count. Mirrors Go <c>SortByInMsgs</c>.</summary>
|
||||
public sealed class SortByInMsgs : IComparer<ConnInfo>
|
||||
{
|
||||
public static readonly SortByInMsgs Instance = new();
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
return x.InMsgs.CompareTo(y.InMsgs);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sort by outbound bytes. Mirrors Go <c>SortByOutBytes</c>.</summary>
|
||||
public sealed class SortByOutBytes : IComparer<ConnInfo>
|
||||
{
|
||||
public static readonly SortByOutBytes Instance = new();
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
return x.OutBytes.CompareTo(y.OutBytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sort by inbound bytes. Mirrors Go <c>SortByInBytes</c>.</summary>
|
||||
public sealed class SortByInBytes : IComparer<ConnInfo>
|
||||
{
|
||||
public static readonly SortByInBytes Instance = new();
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
return x.InBytes.CompareTo(y.InBytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sort by last activity timestamp. Mirrors Go <c>SortByLast</c>.</summary>
|
||||
public sealed class SortByLast : IComparer<ConnInfo>
|
||||
{
|
||||
public static readonly SortByLast Instance = new();
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
return x.LastActivity.CompareTo(y.LastActivity);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sort by idle duration (time since last activity), relative to a supplied
|
||||
/// reference time. Mirrors Go <c>SortByIdle</c>.
|
||||
/// </summary>
|
||||
public sealed class SortByIdle : IComparer<ConnInfo>
|
||||
{
|
||||
private readonly DateTime _now;
|
||||
|
||||
public SortByIdle(DateTime now) => _now = now;
|
||||
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
var idleX = _now - x.LastActivity;
|
||||
var idleY = _now - y.LastActivity;
|
||||
return idleX.CompareTo(idleY);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sort by uptime (time the connection has been open), relative to a supplied
|
||||
/// reference time. Mirrors Go <c>SortByUptime</c>.
|
||||
/// </summary>
|
||||
public sealed class SortByUptime : IComparer<ConnInfo>
|
||||
{
|
||||
private readonly DateTime _now;
|
||||
|
||||
public SortByUptime(DateTime now) => _now = now;
|
||||
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
var uptimeX = (x.Stop is null || x.Stop == default) ? _now - x.Start : x.Stop.Value - x.Start;
|
||||
var uptimeY = (y.Stop is null || y.Stop == default) ? _now - y.Start : y.Stop.Value - y.Start;
|
||||
return uptimeX.CompareTo(uptimeY);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sort by stop time (closed connections only). Mirrors Go <c>SortByStop</c>.</summary>
|
||||
public sealed class SortByStop : IComparer<ConnInfo>
|
||||
{
|
||||
public static readonly SortByStop Instance = new();
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
// If either stop is null treat as zero (shouldn't happen for closed-only queries)
|
||||
var stopX = x.Stop ?? DateTime.MinValue;
|
||||
var stopY = y.Stop ?? DateTime.MinValue;
|
||||
return stopX.CompareTo(stopY);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sort by close reason string. Mirrors Go <c>SortByReason</c>.</summary>
|
||||
public sealed class SortByReason : IComparer<ConnInfo>
|
||||
{
|
||||
public static readonly SortByReason Instance = new();
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
return string.Compare(x.Reason, y.Reason, StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sort by round-trip time (nanoseconds, internal field).
|
||||
/// Mirrors Go <c>SortByRTT</c>.
|
||||
/// </summary>
|
||||
public sealed class SortByRtt : IComparer<ConnInfo>
|
||||
{
|
||||
public static readonly SortByRtt Instance = new();
|
||||
public int Compare(ConnInfo? x, ConnInfo? y)
|
||||
{
|
||||
if (x is null || y is null) return 0;
|
||||
return x.RttNanos.CompareTo(y.RttNanos);
|
||||
}
|
||||
}
|
||||
387
dotnet/src/ZB.MOM.NatsNet.Server/Monitor/MonitorTypes.cs
Normal file
387
dotnet/src/ZB.MOM.NatsNet.Server/Monitor/MonitorTypes.cs
Normal file
@@ -0,0 +1,387 @@
|
||||
// Copyright 2013-2026 The NATS Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Adapted from server/monitor.go in the NATS server Go source.
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace ZB.MOM.NatsNet.Server;
|
||||
|
||||
// ============================================================================
|
||||
// Monitor list size defaults
|
||||
// Mirrors Go const block near top of monitor.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Default sizes for monitoring API response lists.
|
||||
/// Mirrors Go constants in server/monitor.go.
|
||||
/// </summary>
|
||||
public static class MonitorDefaults
|
||||
{
|
||||
/// <summary>Default maximum number of connection entries returned. Mirrors Go <c>DefaultConnListSize = 1024</c>.</summary>
|
||||
public const int DefaultConnListSize = 1024;
|
||||
|
||||
/// <summary>Default maximum number of subscription entries returned. Mirrors Go <c>DefaultSubListSize = 1024</c>.</summary>
|
||||
public const int DefaultSubListSize = 1024;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ConnState — connection state filter for Connz queries
|
||||
// Mirrors Go <c>ConnState</c> and its iota constants in monitor.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Filter applied to connection-list queries to select open, closed, or
|
||||
/// all connections.
|
||||
/// Mirrors Go <c>ConnState</c> in server/monitor.go.
|
||||
/// </summary>
|
||||
public enum ConnState
|
||||
{
|
||||
/// <summary>Only return open (active) connections. Mirrors Go <c>ConnOpen = 0</c>.</summary>
|
||||
ConnOpen = 0,
|
||||
|
||||
/// <summary>Only return closed connections. Mirrors Go <c>ConnClosed</c>.</summary>
|
||||
ConnClosed = 1,
|
||||
|
||||
/// <summary>Return all connections, open or closed. Mirrors Go <c>ConnAll</c>.</summary>
|
||||
ConnAll = 2,
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ConnzOptions — query options for the Connz endpoint
|
||||
// Mirrors Go <c>ConnzOptions</c> struct in server/monitor.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Options that control the output of a <c>Connz</c> monitoring query.
|
||||
/// Mirrors Go <c>ConnzOptions</c> struct in server/monitor.go.
|
||||
/// </summary>
|
||||
public sealed class ConnzOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// How to sort results. Only <c>ByCid</c> is ascending; all others are
|
||||
/// descending. Mirrors Go <c>Sort SortOpt</c>.
|
||||
/// </summary>
|
||||
[JsonPropertyName("sort")]
|
||||
public SortOpt Sort { get; set; } = SortOpt.ByCid;
|
||||
|
||||
/// <summary>When true, usernames are included in results. Mirrors Go <c>Username bool</c>.</summary>
|
||||
[JsonPropertyName("auth")]
|
||||
public bool Username { get; set; }
|
||||
|
||||
/// <summary>When true, subscription subjects are listed. Mirrors Go <c>Subscriptions bool</c>.</summary>
|
||||
[JsonPropertyName("subscriptions")]
|
||||
public bool Subscriptions { get; set; }
|
||||
|
||||
/// <summary>When true, verbose subscription detail is included. Mirrors Go <c>SubscriptionsDetail bool</c>.</summary>
|
||||
[JsonPropertyName("subscriptions_detail")]
|
||||
public bool SubscriptionsDetail { get; set; }
|
||||
|
||||
/// <summary>Zero-based offset for pagination. Mirrors Go <c>Offset int</c>.</summary>
|
||||
[JsonPropertyName("offset")]
|
||||
public int Offset { get; set; }
|
||||
|
||||
/// <summary>Maximum number of connections to return. Mirrors Go <c>Limit int</c>.</summary>
|
||||
[JsonPropertyName("limit")]
|
||||
public int Limit { get; set; }
|
||||
|
||||
/// <summary>Filter for a specific client connection by CID. Mirrors Go <c>CID uint64</c>.</summary>
|
||||
[JsonPropertyName("cid")]
|
||||
public ulong Cid { get; set; }
|
||||
|
||||
/// <summary>Filter for a specific MQTT client ID. Mirrors Go <c>MQTTClient string</c>.</summary>
|
||||
[JsonPropertyName("mqtt_client")]
|
||||
public string MqttClient { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Connection state filter. Mirrors Go <c>State ConnState</c>.</summary>
|
||||
[JsonPropertyName("state")]
|
||||
public ConnState State { get; set; } = ConnState.ConnOpen;
|
||||
|
||||
/// <summary>Filter by username. Mirrors Go <c>User string</c>.</summary>
|
||||
[JsonPropertyName("user")]
|
||||
public string User { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Filter by account name. Mirrors Go <c>Account string</c>.</summary>
|
||||
[JsonPropertyName("acc")]
|
||||
public string Account { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Filter by subject interest (requires Account filter). Mirrors Go <c>FilterSubject string</c>.</summary>
|
||||
[JsonPropertyName("filter_subject")]
|
||||
public string FilterSubject { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Connz — top-level connection list monitoring response
|
||||
// Mirrors Go <c>Connz</c> struct in server/monitor.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Top-level response type for the <c>/connz</c> monitoring endpoint.
|
||||
/// Contains the current connection list and pagination metadata.
|
||||
/// Mirrors Go <c>Connz</c> struct in server/monitor.go.
|
||||
/// </summary>
|
||||
public sealed class Connz
|
||||
{
|
||||
[JsonPropertyName("server_id")]
|
||||
public string Id { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("now")]
|
||||
public DateTime Now { get; set; }
|
||||
|
||||
[JsonPropertyName("num_connections")]
|
||||
public int NumConns { get; set; }
|
||||
|
||||
[JsonPropertyName("total")]
|
||||
public int Total { get; set; }
|
||||
|
||||
[JsonPropertyName("offset")]
|
||||
public int Offset { get; set; }
|
||||
|
||||
[JsonPropertyName("limit")]
|
||||
public int Limit { get; set; }
|
||||
|
||||
[JsonPropertyName("connections")]
|
||||
public List<ConnInfo> Conns { get; set; } = [];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ConnInfo — per-connection detail record
|
||||
// Mirrors Go <c>ConnInfo</c> struct in server/monitor.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Detailed information about a single client connection, as returned by the
|
||||
/// <c>/connz</c> monitoring endpoint.
|
||||
/// Mirrors Go <c>ConnInfo</c> struct in server/monitor.go.
|
||||
/// </summary>
|
||||
public sealed class ConnInfo
|
||||
{
|
||||
[JsonPropertyName("cid")]
|
||||
public ulong Cid { get; set; }
|
||||
|
||||
[JsonPropertyName("kind")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Kind { get; set; }
|
||||
|
||||
[JsonPropertyName("type")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Type { get; set; }
|
||||
|
||||
[JsonPropertyName("ip")]
|
||||
public string Ip { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("port")]
|
||||
public int Port { get; set; }
|
||||
|
||||
[JsonPropertyName("start")]
|
||||
public DateTime Start { get; set; }
|
||||
|
||||
[JsonPropertyName("last_activity")]
|
||||
public DateTime LastActivity { get; set; }
|
||||
|
||||
[JsonPropertyName("stop")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public DateTime? Stop { get; set; }
|
||||
|
||||
[JsonPropertyName("reason")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Reason { get; set; }
|
||||
|
||||
[JsonPropertyName("rtt")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Rtt { get; set; }
|
||||
|
||||
[JsonPropertyName("uptime")]
|
||||
public string Uptime { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("idle")]
|
||||
public string Idle { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("pending_bytes")]
|
||||
public int Pending { get; set; }
|
||||
|
||||
[JsonPropertyName("in_msgs")]
|
||||
public long InMsgs { get; set; }
|
||||
|
||||
[JsonPropertyName("out_msgs")]
|
||||
public long OutMsgs { get; set; }
|
||||
|
||||
[JsonPropertyName("in_bytes")]
|
||||
public long InBytes { get; set; }
|
||||
|
||||
[JsonPropertyName("out_bytes")]
|
||||
public long OutBytes { get; set; }
|
||||
|
||||
[JsonPropertyName("stalls")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
|
||||
public long Stalls { get; set; }
|
||||
|
||||
[JsonPropertyName("subscriptions")]
|
||||
public uint NumSubs { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("lang")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Lang { get; set; }
|
||||
|
||||
[JsonPropertyName("version")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Version { get; set; }
|
||||
|
||||
[JsonPropertyName("tls_version")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? TlsVersion { get; set; }
|
||||
|
||||
[JsonPropertyName("tls_cipher_suite")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? TlsCipher { get; set; }
|
||||
|
||||
[JsonPropertyName("tls_peer_certs")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public List<TlsPeerCert>? TlsPeerCerts { get; set; }
|
||||
|
||||
[JsonPropertyName("tls_first")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
|
||||
public bool TlsFirst { get; set; }
|
||||
|
||||
[JsonPropertyName("authorized_user")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? AuthorizedUser { get; set; }
|
||||
|
||||
[JsonPropertyName("account")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Account { get; set; }
|
||||
|
||||
[JsonPropertyName("subscriptions_list")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public List<string>? Subs { get; set; }
|
||||
|
||||
[JsonPropertyName("subscriptions_list_detail")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public List<SubDetail>? SubsDetail { get; set; }
|
||||
|
||||
[JsonPropertyName("jwt")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Jwt { get; set; }
|
||||
|
||||
[JsonPropertyName("issuer_key")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? IssuerKey { get; set; }
|
||||
|
||||
[JsonPropertyName("name_tag")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? NameTag { get; set; }
|
||||
|
||||
[JsonPropertyName("tags")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string[]? Tags { get; set; }
|
||||
|
||||
[JsonPropertyName("mqtt_client")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? MqttClient { get; set; }
|
||||
|
||||
[JsonPropertyName("proxy")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public ProxyInfo? Proxy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Internal field used for fast RTT-based sorting.
|
||||
/// Mirrors Go <c>rtt int64</c> unexported field in ConnInfo.
|
||||
/// Not serialised.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
internal long RttNanos { get; set; }
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ProxyInfo — proxy connection metadata
|
||||
// Mirrors Go <c>ProxyInfo</c> struct in server/monitor.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Information about a proxied connection (e.g. HAProxy PROXY protocol).
|
||||
/// Mirrors Go <c>ProxyInfo</c> struct in server/monitor.go.
|
||||
/// </summary>
|
||||
public sealed class ProxyInfo
|
||||
{
|
||||
[JsonPropertyName("key")]
|
||||
public string Key { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TlsPeerCert — TLS peer certificate summary
|
||||
// Mirrors Go <c>TLSPeerCert</c> struct in server/monitor.go.
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Basic information about a TLS peer certificate.
|
||||
/// Mirrors Go <c>TLSPeerCert</c> struct in server/monitor.go.
|
||||
/// </summary>
|
||||
public sealed class TlsPeerCert
|
||||
{
|
||||
[JsonPropertyName("subject")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Subject { get; set; }
|
||||
|
||||
[JsonPropertyName("spki_sha256")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? SubjectPkiSha256 { get; set; }
|
||||
|
||||
[JsonPropertyName("cert_sha256")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? CertSha256 { get; set; }
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// SubDetail — verbose subscription information
|
||||
// Mirrors Go <c>SubDetail</c> struct in server/monitor.go (line ~961).
|
||||
// ============================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Verbose information about a single subscription, included in detailed
|
||||
/// connection or account monitoring responses.
|
||||
/// Mirrors Go <c>SubDetail</c> struct in server/monitor.go.
|
||||
/// </summary>
|
||||
public sealed class SubDetail
|
||||
{
|
||||
[JsonPropertyName("account")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Account { get; set; }
|
||||
|
||||
[JsonPropertyName("account_tag")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? AccountTag { get; set; }
|
||||
|
||||
[JsonPropertyName("subject")]
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("qgroup")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Queue { get; set; }
|
||||
|
||||
[JsonPropertyName("sid")]
|
||||
public string Sid { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("msgs")]
|
||||
public long Msgs { get; set; }
|
||||
|
||||
[JsonPropertyName("max")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
|
||||
public long Max { get; set; }
|
||||
|
||||
[JsonPropertyName("cid")]
|
||||
public ulong Cid { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user