@@ -2969,14 +2969,23 @@ type AccountDetail struct {
29692969 Streams []StreamDetail `json:"stream_detail,omitempty"`
29702970}
29712971
2972+ // MetaSnapshotStats shows information about meta snapshots.
2973+ type MetaSnapshotStats struct {
2974+ PendingEntries uint64 `json:"pending_entries"` // PendingEntries is the count of pending entries in the meta layer
2975+ PendingSize uint64 `json:"pending_size"` // PendingSize is the size in bytes of pending entries in the meta layer
2976+ LastTime time.Time `json:"last_time,omitempty"` // LastTime is when the last meta snapshot was taken
2977+ LastDuration time.Duration `json:"last_duration,omitempty"` // LastDuration is how long the last meta snapshot took
2978+ }
2979+
29722980// MetaClusterInfo shows information about the meta group.
29732981type MetaClusterInfo struct {
2974- Name string `json:"name,omitempty"` // Name is the name of the cluster
2975- Leader string `json:"leader,omitempty"` // Leader is the server name of the cluster leader
2976- Peer string `json:"peer,omitempty"` // Peer is unique ID of the leader
2977- Replicas []* PeerInfo `json:"replicas,omitempty"` // Replicas is a list of known peers
2978- Size int `json:"cluster_size"` // Size is the known size of the cluster
2979- Pending int `json:"pending"` // Pending is how many RAFT messages are not yet processed
2982+ Name string `json:"name,omitempty"` // Name is the name of the cluster
2983+ Leader string `json:"leader,omitempty"` // Leader is the server name of the cluster leader
2984+ Peer string `json:"peer,omitempty"` // Peer is unique ID of the leader
2985+ Replicas []* PeerInfo `json:"replicas,omitempty"` // Replicas is a list of known peers
2986+ Size int `json:"cluster_size"` // Size is the known size of the cluster
2987+ Pending int `json:"pending"` // Pending is how many RAFT messages are not yet processed
2988+ Snapshot * MetaSnapshotStats `json:"snapshot"` // Snapshot contains meta snapshot statistics
29802989}
29812990
29822991// JSInfo has detailed information on JetStream.
@@ -3181,13 +3190,33 @@ func (s *Server) Jsz(opts *JSzOptions) (*JSInfo, error) {
31813190
31823191 if mg := js .getMetaGroup (); mg != nil {
31833192 if ci := s .raftNodeToClusterInfo (mg ); ci != nil {
3193+ entries , bytes := mg .Size ()
31843194 jsi .Meta = & MetaClusterInfo {Name : ci .Name , Leader : ci .Leader , Peer : getHash (ci .Leader ), Size : mg .ClusterSize ()}
31853195 if isLeader {
31863196 jsi .Meta .Replicas = ci .Replicas
31873197 }
31883198 if ipq := s .jsAPIRoutedReqs ; ipq != nil {
31893199 jsi .Meta .Pending = ipq .len ()
31903200 }
3201+ // Add meta snapshot stats
3202+ jsi .Meta .Snapshot = & MetaSnapshotStats {
3203+ PendingEntries : entries ,
3204+ PendingSize : bytes ,
3205+ }
3206+ // Read atomic snapshot timing (no lock needed for atomics)
3207+ js .mu .RLock ()
3208+ cluster := js .cluster
3209+ js .mu .RUnlock ()
3210+ if cluster != nil {
3211+ timeNanos := atomic .LoadInt64 (& cluster .lastMetaSnapTime )
3212+ durationNanos := atomic .LoadInt64 (& cluster .lastMetaSnapDuration )
3213+ if timeNanos > 0 {
3214+ jsi .Meta .Snapshot .LastTime = time .Unix (0 , timeNanos ).UTC ()
3215+ }
3216+ if durationNanos > 0 {
3217+ jsi .Meta .Snapshot .LastDuration = time .Duration (durationNanos )
3218+ }
3219+ }
31913220 }
31923221 }
31933222
0 commit comments