[MM-68458] Improve diagnostics.yaml readability: reorder server fields and add inline YAML comments (#36703)

* MM-68458: Improve diagnostics.yaml readability — reorder server fields and add inline comments

Regroup the SupportPacketDiagnostics.Server fields into Machine /
Capacity / Process lifecycle / Software clusters (declaration order
determines YAML emit order in goccy/go-yaml), and emit YAML head /
line comments at marshal time via yaml.MarshalWithOptions +
yaml.WithComment.

Comments cover the non-obvious cases support engineers hit during
triage: host RAM vs cgroup quota, omitempty fields that silently
disappear when no container limit is set, sql.DBStats counters that
are cumulative-since-process-start, and PostgreSQL-only fields that
vanish on MySQL. file_store: local-driver-only fields are similarly
annotated.

No struct reorder outside server:; no public-API or JSON shape
changes; no new dependencies (goccy/go-yaml already supports
WithComment).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* gofmt: realign diagnosticsYAMLComments map literal

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ben Schumacher
2026-05-27 08:43:42 +02:00
committed by GitHub
parent fc7b5c78a5
commit 8a957afce2
2 changed files with 70 additions and 17 deletions
+47 -1
View File
@@ -33,6 +33,52 @@ const (
unknownDataPoint = "unknown"
)
// diagnosticsYAMLComments annotates non-obvious fields in diagnostics.yaml
// with inline (and a few group-header) comments so support engineers reading
// the file under triage conditions have units, omitempty semantics, and
// cumulative-vs-point-in-time semantics visible at a glance.
var diagnosticsYAMLComments = yaml.CommentMap{
// server: — grouped into Machine / Capacity / Process lifecycle / Software
"$.server.os": {yaml.HeadComment(" Machine")},
"$.server.cpu_cores": {yaml.HeadComment(" Capacity (hardware → effective quota)"), yaml.LineComment(" logical CPUs visible to the OS")},
"$.server.total_memory_mb": {yaml.LineComment(" host/VM total RAM; may exceed container limit")},
"$.server.container_cpu_limit": {yaml.LineComment(" cgroup v2 CPU quota in CPUs; Linux only, omitted if no limit set")},
"$.server.container_memory_limit_mb": {yaml.LineComment(" cgroup v2 memory quota in MB; Linux only, omitted if no limit set")},
"$.server.process_id": {yaml.HeadComment(" Process lifecycle")},
"$.server.started_at": {yaml.LineComment(" when Mattermost process started")},
"$.server.host_started_at": {yaml.LineComment(" when the host OS booted; omitted if unavailable")},
"$.server.open_file_descriptors": {yaml.LineComment(" current open FDs for this process")},
"$.server.max_file_descriptors": {yaml.LineComment(" system limit (ulimit -n)")},
"$.server.version": {yaml.HeadComment(" Software")},
// database: sql.DBStats cumulative counters (lifetime of process; all drivers)
"$.database.master_pool_wait_count": {yaml.LineComment(" cumulative; total times a goroutine waited for a connection since process start")},
"$.database.master_pool_wait_duration_ms": {yaml.LineComment(" cumulative wait time across all goroutines since process start")},
"$.database.master_connections_closed_max_idle": {yaml.LineComment(" cumulative; connections closed because the idle pool was full")},
"$.database.master_connections_closed_max_lifetime": {yaml.LineComment(" cumulative; connections closed for exceeding ConnMaxLifetime")},
"$.database.replica_pool_wait_count": {yaml.LineComment(" cumulative across all replicas; see master_pool_wait_count")},
"$.database.replica_pool_wait_duration_ms": {yaml.LineComment(" cumulative across all replicas")},
"$.database.replica_connections_closed_max_idle": {yaml.LineComment(" cumulative across all replicas")},
"$.database.replica_connections_closed_max_lifetime": {yaml.LineComment(" cumulative across all replicas")},
// database: PostgreSQL-only fields (omitted on MySQL)
"$.database.cache_hit_ratio": {yaml.HeadComment(" PostgreSQL-only (these fields are omitted on MySQL)"), yaml.LineComment(" blks_hit / (blks_hit + blks_read) from pg_stat_database; cumulative since stats reset")},
"$.database.deadlocks": {yaml.LineComment(" cumulative since pg_stat_database reset")},
"$.database.temp_files": {yaml.LineComment(" cumulative count of temp files created since stats reset")},
"$.database.temp_bytes_mb": {yaml.LineComment(" cumulative bytes written to temp files, in MB")},
"$.database.rollbacks": {yaml.LineComment(" cumulative transaction rollbacks since stats reset")},
"$.database.idle_in_transaction_count": {yaml.LineComment(" point-in-time count from pg_stat_activity")},
"$.database.longest_query_duration_seconds": {yaml.LineComment(" point-in-time; max age of any active query right now")},
"$.database.waiting_for_lock_count": {yaml.LineComment(" point-in-time count of backends waiting on a Lock wait_event_type")},
"$.database.posts_dead_tuples": {yaml.LineComment(" n_dead_tup for the posts table from pg_stat_user_tables")},
"$.database.posts_last_autovacuum": {yaml.LineComment(" last autovacuum on posts; null if never autovacuumed (then omitted)")},
// file_store: local driver only fields
"$.file_store.filesystem_type": {yaml.LineComment(" local driver only (e.g. ext4, xfs); omitted for s3 and other remote drivers")},
"$.file_store.total_mb": {yaml.LineComment(" local driver only; capacity of the volume hosting FileSettings.Directory")},
"$.file_store.available_mb": {yaml.LineComment(" local driver only; free space remaining on that volume")},
}
func (ps *PlatformService) GenerateSupportPacket(rctx request.CTX, options *model.SupportPacketOptions) ([]model.FileData, error) {
functions := map[string]func(request.CTX) (*model.FileData, error){
"diagnostics": ps.getSupportPacketDiagnostics,
@@ -321,7 +367,7 @@ func (ps *PlatformService) getSupportPacketDiagnostics(rctx request.CTX) (*model
d.Notifications.Push.Status = model.StatusDisabled
}
b, err := yaml.Marshal(&d)
b, err := yaml.MarshalWithOptions(&d, yaml.WithComment(diagnosticsYAMLComments))
if err != nil {
rErr = multierror.Append(errors.Wrap(err, "failed to marshal Support Packet into yaml"))
}
+23 -16
View File
@@ -26,22 +26,29 @@ type SupportPacketDiagnostics struct {
} `yaml:"license"`
Server struct {
OS string `yaml:"os"`
Architecture string `yaml:"architecture"`
CPUCores int `yaml:"cpu_cores"`
TotalMemoryMB uint64 `yaml:"total_memory_mb"`
ContainerCPULimit float64 `yaml:"container_cpu_limit,omitempty"`
ContainerMemoryLimitMB uint64 `yaml:"container_memory_limit_mb,omitempty"`
OpenFileDescriptors int64 `yaml:"open_file_descriptors"`
MaxFileDescriptors int64 `yaml:"max_file_descriptors"`
Hostname string `yaml:"hostname"`
ProcessID int `yaml:"process_id"`
StartedAt time.Time `yaml:"started_at"`
HostStartedAt time.Time `yaml:"host_started_at,omitempty"`
Version string `yaml:"version"`
BuildHash string `yaml:"build_hash"`
GoVersion string `yaml:"go_version"`
InstallationType string `yaml:"installation_type"`
// Machine
OS string `yaml:"os"`
Architecture string `yaml:"architecture"`
Hostname string `yaml:"hostname"`
InstallationType string `yaml:"installation_type"`
// Capacity
CPUCores int `yaml:"cpu_cores"`
TotalMemoryMB uint64 `yaml:"total_memory_mb"`
ContainerCPULimit float64 `yaml:"container_cpu_limit,omitempty"`
ContainerMemoryLimitMB uint64 `yaml:"container_memory_limit_mb,omitempty"`
// Process lifecycle
ProcessID int `yaml:"process_id"`
StartedAt time.Time `yaml:"started_at"`
HostStartedAt time.Time `yaml:"host_started_at,omitempty"`
OpenFileDescriptors int64 `yaml:"open_file_descriptors"`
MaxFileDescriptors int64 `yaml:"max_file_descriptors"`
// Software
Version string `yaml:"version"`
BuildHash string `yaml:"build_hash"`
GoVersion string `yaml:"go_version"`
} `yaml:"server"`
Config struct {