github.com/netdata/go.d.plugin@v0.58.1/modules/consul/charts.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package consul
     4  
     5  import (
     6  	"fmt"
     7  
     8  	"github.com/blang/semver/v4"
     9  
    10  	"github.com/netdata/go.d.plugin/agent/module"
    11  )
    12  
    13  const (
    14  	_ = module.Priority + iota
    15  	prioKVSApplyTime
    16  	prioKVSApplyOperations
    17  	prioTXNApplyTime
    18  	prioTXNApplyOperations
    19  	prioRaftCommitTime
    20  	prioRaftCommitsRate
    21  
    22  	prioServerLeadershipStatus
    23  	prioRaftLeaderLastContactTime
    24  	prioRaftFollowerLastContactLeaderTime
    25  	prioRaftLeaderElections
    26  	prioRaftLeadershipTransitions
    27  
    28  	prioAutopilotClusterHealthStatus
    29  	prioAutopilotFailureTolerance
    30  	prioAutopilotServerHealthStatus
    31  	prioAutopilotServerStableTime
    32  	prioAutopilotServerSerfStatus
    33  	prioAutopilotServerVoterStatus
    34  
    35  	prioNetworkLanRTT
    36  
    37  	prioRPCRequests
    38  	prioRPCRequestsExceeded
    39  	prioRPCRequestsFailed
    40  
    41  	prioRaftThreadMainSaturation
    42  	prioRaftThreadFSMSaturation
    43  
    44  	prioRaftFSMLastRestoreDuration
    45  	prioRaftLeaderOldestLogAge
    46  	prioRaftRPCInstallSnapshotTime
    47  
    48  	prioBoltDBFreelistBytes
    49  	prioBoltDBLogsPerBatch
    50  	prioBoltDBStoreLogsTime
    51  
    52  	prioMemoryAllocated
    53  	prioMemorySys
    54  	prioGCPauseTime
    55  
    56  	prioServiceHealthCheckStatus
    57  	prioNodeHealthCheckStatus
    58  
    59  	prioLicenseExpirationTime
    60  )
    61  
    62  var (
    63  	clientCharts = module.Charts{
    64  		clientRPCRequestsRateChart.Copy(),
    65  		clientRPCRequestsExceededRateChart.Copy(),
    66  		clientRPCRequestsFailedRateChart.Copy(),
    67  
    68  		memoryAllocatedChart.Copy(),
    69  		memorySysChart.Copy(),
    70  		gcPauseTimeChart.Copy(),
    71  
    72  		licenseExpirationTimeChart.Copy(),
    73  	}
    74  
    75  	serverLeaderCharts = module.Charts{
    76  		raftCommitTimeChart.Copy(),
    77  		raftLeaderLastContactTimeChart.Copy(),
    78  		raftCommitsRateChart.Copy(),
    79  		raftLeaderOldestLogAgeChart.Copy(),
    80  	}
    81  	serverFollowerCharts = module.Charts{
    82  		raftFollowerLastContactLeaderTimeChart.Copy(),
    83  		raftRPCInstallSnapshotTimeChart.Copy(),
    84  	}
    85  	serverAutopilotHealthCharts = module.Charts{
    86  		autopilotServerHealthStatusChart.Copy(),
    87  		autopilotServerStableTimeChart.Copy(),
    88  		autopilotServerSerfStatusChart.Copy(),
    89  		autopilotServerVoterStatusChart.Copy(),
    90  	}
    91  	serverCommonCharts = module.Charts{
    92  		kvsApplyTimeChart.Copy(),
    93  		kvsApplyOperationsRateChart.Copy(),
    94  		txnApplyTimeChart.Copy(),
    95  		txnApplyOperationsRateChart.Copy(),
    96  
    97  		autopilotClusterHealthStatusChart.Copy(),
    98  		autopilotFailureTolerance.Copy(),
    99  
   100  		raftLeaderElectionsRateChart.Copy(),
   101  		raftLeadershipTransitionsRateChart.Copy(),
   102  		serverLeadershipStatusChart.Copy(),
   103  
   104  		networkLanRTTChart.Copy(),
   105  
   106  		clientRPCRequestsRateChart.Copy(),
   107  		clientRPCRequestsExceededRateChart.Copy(),
   108  		clientRPCRequestsFailedRateChart.Copy(),
   109  
   110  		raftThreadMainSaturationPercChart.Copy(),
   111  		raftThreadFSMSaturationPercChart.Copy(),
   112  
   113  		raftFSMLastRestoreDurationChart.Copy(),
   114  
   115  		raftBoltDBFreelistBytesChart.Copy(),
   116  		raftBoltDBLogsPerBatchChart.Copy(),
   117  		raftBoltDBStoreLogsTimeChart.Copy(),
   118  
   119  		memoryAllocatedChart.Copy(),
   120  		memorySysChart.Copy(),
   121  		gcPauseTimeChart.Copy(),
   122  
   123  		licenseExpirationTimeChart.Copy(),
   124  	}
   125  
   126  	kvsApplyTimeChart = module.Chart{
   127  		ID:       "kvs_apply_time",
   128  		Title:    "KVS apply time",
   129  		Units:    "ms",
   130  		Fam:      "transaction timing",
   131  		Ctx:      "consul.kvs_apply_time",
   132  		Priority: prioKVSApplyTime,
   133  		Dims: module.Dims{
   134  			{ID: "kvs_apply_quantile=0.5", Name: "quantile_0.5", Div: precision * precision},
   135  			{ID: "kvs_apply_quantile=0.9", Name: "quantile_0.9", Div: precision * precision},
   136  			{ID: "kvs_apply_quantile=0.99", Name: "quantile_0.99", Div: precision * precision},
   137  		},
   138  	}
   139  	kvsApplyOperationsRateChart = module.Chart{
   140  		ID:       "kvs_apply_operations_rate",
   141  		Title:    "KVS apply operations",
   142  		Units:    "ops/s",
   143  		Fam:      "transaction timing",
   144  		Ctx:      "consul.kvs_apply_operations_rate",
   145  		Priority: prioKVSApplyOperations,
   146  		Dims: module.Dims{
   147  			{ID: "kvs_apply_count", Name: "kvs_apply"},
   148  		},
   149  	}
   150  	txnApplyTimeChart = module.Chart{
   151  		ID:       "txn_apply_time",
   152  		Title:    "Transaction apply time",
   153  		Units:    "ms",
   154  		Fam:      "transaction timing",
   155  		Ctx:      "consul.txn_apply_time",
   156  		Priority: prioTXNApplyTime,
   157  		Dims: module.Dims{
   158  			{ID: "txn_apply_quantile=0.5", Name: "quantile_0.5", Div: precision * precision},
   159  			{ID: "txn_apply_quantile=0.9", Name: "quantile_0.9", Div: precision * precision},
   160  			{ID: "txn_apply_quantile=0.99", Name: "quantile_0.99", Div: precision * precision},
   161  		},
   162  	}
   163  	txnApplyOperationsRateChart = module.Chart{
   164  		ID:       "txn_apply_operations_rate",
   165  		Title:    "Transaction apply operations",
   166  		Units:    "ops/s",
   167  		Fam:      "transaction timing",
   168  		Ctx:      "consul.txn_apply_operations_rate",
   169  		Priority: prioTXNApplyOperations,
   170  		Dims: module.Dims{
   171  			{ID: "txn_apply_count", Name: "kvs_apply"},
   172  		},
   173  	}
   174  
   175  	raftCommitTimeChart = module.Chart{
   176  		ID:       "raft_commit_time",
   177  		Title:    "Raft commit time",
   178  		Units:    "ms",
   179  		Fam:      "transaction timing",
   180  		Ctx:      "consul.raft_commit_time",
   181  		Priority: prioRaftCommitTime,
   182  		Dims: module.Dims{
   183  			{ID: "raft_commitTime_quantile=0.5", Name: "quantile_0.5", Div: precision * precision},
   184  			{ID: "raft_commitTime_quantile=0.9", Name: "quantile_0.9", Div: precision * precision},
   185  			{ID: "raft_commitTime_quantile=0.99", Name: "quantile_0.99", Div: precision * precision},
   186  		},
   187  	}
   188  	raftCommitsRateChart = module.Chart{
   189  		ID:       "raft_commits_rate",
   190  		Title:    "Raft commits rate",
   191  		Units:    "commits/s",
   192  		Fam:      "transaction timing",
   193  		Ctx:      "consul.raft_commits_rate",
   194  		Priority: prioRaftCommitsRate,
   195  		Dims: module.Dims{
   196  			{ID: "raft_apply", Name: "commits", Div: precision, Algo: module.Incremental},
   197  		},
   198  	}
   199  
   200  	autopilotClusterHealthStatusChart = module.Chart{
   201  		ID:       "autopilot_health_status",
   202  		Title:    "Autopilot cluster health status",
   203  		Units:    "status",
   204  		Fam:      "autopilot",
   205  		Ctx:      "consul.autopilot_health_status",
   206  		Priority: prioAutopilotClusterHealthStatus,
   207  		Dims: module.Dims{
   208  			{ID: "autopilot_healthy_yes", Name: "healthy"},
   209  			{ID: "autopilot_healthy_no", Name: "unhealthy"},
   210  		},
   211  	}
   212  	autopilotFailureTolerance = module.Chart{
   213  		ID:       "autopilot_failure_tolerance",
   214  		Title:    "Autopilot cluster failure tolerance",
   215  		Units:    "servers",
   216  		Fam:      "autopilot",
   217  		Ctx:      "consul.autopilot_failure_tolerance",
   218  		Priority: prioAutopilotFailureTolerance,
   219  		Dims: module.Dims{
   220  			{ID: "autopilot_failure_tolerance", Name: "failure_tolerance"},
   221  		},
   222  	}
   223  	autopilotServerHealthStatusChart = module.Chart{
   224  		ID:       "autopilot_server_health_status",
   225  		Title:    "Autopilot server health status",
   226  		Units:    "status",
   227  		Fam:      "autopilot",
   228  		Ctx:      "consul.autopilot_server_health_status",
   229  		Priority: prioAutopilotServerHealthStatus,
   230  		Dims: module.Dims{
   231  			{ID: "autopilot_server_healthy_yes", Name: "healthy"},
   232  			{ID: "autopilot_server_healthy_no", Name: "unhealthy"},
   233  		},
   234  	}
   235  	autopilotServerStableTimeChart = module.Chart{
   236  		ID:       "autopilot_server_stable_time",
   237  		Title:    "Autopilot server stable time",
   238  		Units:    "seconds",
   239  		Fam:      "autopilot",
   240  		Ctx:      "consul.autopilot_server_stable_time",
   241  		Priority: prioAutopilotServerStableTime,
   242  		Dims: module.Dims{
   243  			{ID: "autopilot_server_stable_time", Name: "stable"},
   244  		},
   245  	}
   246  	autopilotServerSerfStatusChart = module.Chart{
   247  		ID:       "autopilot_server_serf_status",
   248  		Title:    "Autopilot server Serf status",
   249  		Units:    "status",
   250  		Fam:      "autopilot",
   251  		Ctx:      "consul.autopilot_server_serf_status",
   252  		Priority: prioAutopilotServerSerfStatus,
   253  		Dims: module.Dims{
   254  			{ID: "autopilot_server_sefStatus_alive", Name: "alive"},
   255  			{ID: "autopilot_server_sefStatus_failed", Name: "failed"},
   256  			{ID: "autopilot_server_sefStatus_left", Name: "left"},
   257  			{ID: "autopilot_server_sefStatus_none", Name: "none"},
   258  		},
   259  	}
   260  	autopilotServerVoterStatusChart = module.Chart{
   261  		ID:       "autopilot_server_voter_status",
   262  		Title:    "Autopilot server Raft voting membership",
   263  		Units:    "status",
   264  		Fam:      "autopilot",
   265  		Ctx:      "consul.autopilot_server_voter_status",
   266  		Priority: prioAutopilotServerVoterStatus,
   267  		Dims: module.Dims{
   268  			{ID: "autopilot_server_voter_yes", Name: "voter"},
   269  			{ID: "autopilot_server_voter_no", Name: "not_voter"},
   270  		},
   271  	}
   272  
   273  	raftLeaderLastContactTimeChart = module.Chart{
   274  		ID:       "raft_leader_last_contact_time",
   275  		Title:    "Raft leader last contact time",
   276  		Units:    "ms",
   277  		Fam:      "leadership changes",
   278  		Ctx:      "consul.raft_leader_last_contact_time",
   279  		Priority: prioRaftLeaderLastContactTime,
   280  		Dims: module.Dims{
   281  			{ID: "raft_leader_lastContact_quantile=0.5", Name: "quantile_0.5", Div: precision * precision},
   282  			{ID: "raft_leader_lastContact_quantile=0.9", Name: "quantile_0.9", Div: precision * precision},
   283  			{ID: "raft_leader_lastContact_quantile=0.99", Name: "quantile_0.99", Div: precision * precision},
   284  		},
   285  	}
   286  	raftFollowerLastContactLeaderTimeChart = module.Chart{
   287  		ID:       "raft_follower_last_contact_leader_time",
   288  		Title:    "Raft follower last contact with the leader time",
   289  		Units:    "ms",
   290  		Fam:      "leadership changes",
   291  		Ctx:      "consul.raft_follower_last_contact_leader_time",
   292  		Priority: prioRaftFollowerLastContactLeaderTime,
   293  		Dims: module.Dims{
   294  			{ID: "autopilot_server_lastContact_leader", Name: "leader_last_contact"},
   295  		},
   296  	}
   297  	raftLeaderElectionsRateChart = module.Chart{
   298  		ID:       "raft_leader_elections_rate",
   299  		Title:    "Raft leader elections rate",
   300  		Units:    "elections/s",
   301  		Fam:      "leadership changes",
   302  		Ctx:      "consul.raft_leader_elections_rate",
   303  		Priority: prioRaftLeaderElections,
   304  		Dims: module.Dims{
   305  			{ID: "raft_state_candidate", Name: "leader", Algo: module.Incremental},
   306  		},
   307  	}
   308  	raftLeadershipTransitionsRateChart = module.Chart{
   309  		ID:       "raft_leadership_transitions_rate",
   310  		Title:    "Raft leadership transitions rate",
   311  		Units:    "transitions/s",
   312  		Fam:      "leadership changes",
   313  		Ctx:      "consul.raft_leadership_transitions_rate",
   314  		Priority: prioRaftLeadershipTransitions,
   315  		Dims: module.Dims{
   316  			{ID: "raft_state_leader", Name: "leadership", Algo: module.Incremental},
   317  		},
   318  	}
   319  	serverLeadershipStatusChart = module.Chart{
   320  		ID:       "server_leadership_status",
   321  		Title:    "Server leadership status",
   322  		Units:    "status",
   323  		Fam:      "leadership changes",
   324  		Ctx:      "consul.server_leadership_status",
   325  		Priority: prioServerLeadershipStatus,
   326  		Dims: module.Dims{
   327  			{ID: "server_isLeader_yes", Name: "leader"},
   328  			{ID: "server_isLeader_no", Name: "not_leader"},
   329  		},
   330  	}
   331  
   332  	networkLanRTTChart = module.Chart{
   333  		ID:       "network_lan_rtt",
   334  		Title:    "Network lan RTT",
   335  		Units:    "ms",
   336  		Fam:      "network rtt",
   337  		Ctx:      "consul.network_lan_rtt",
   338  		Type:     module.Area,
   339  		Priority: prioNetworkLanRTT,
   340  		Dims: module.Dims{
   341  			{ID: "network_lan_rtt_min", Name: "min", Div: 1e6},
   342  			{ID: "network_lan_rtt_max", Name: "max", Div: 1e6},
   343  			{ID: "network_lan_rtt_avg", Name: "avg", Div: 1e6},
   344  		},
   345  	}
   346  
   347  	clientRPCRequestsRateChart = module.Chart{
   348  		ID:       "client_rpc_requests_rate",
   349  		Title:    "Client RPC requests",
   350  		Units:    "requests/s",
   351  		Fam:      "rpc network activity",
   352  		Ctx:      "consul.client_rpc_requests_rate",
   353  		Priority: prioRPCRequests,
   354  		Dims: module.Dims{
   355  			{ID: "client_rpc", Name: "rpc", Algo: module.Incremental},
   356  		},
   357  	}
   358  	clientRPCRequestsExceededRateChart = module.Chart{
   359  		ID:       "client_rpc_requests_exceeded_rate",
   360  		Title:    "Client rate-limited RPC requests",
   361  		Units:    "requests/s",
   362  		Fam:      "rpc network activity",
   363  		Ctx:      "consul.client_rpc_requests_exceeded_rate",
   364  		Priority: prioRPCRequestsExceeded,
   365  		Dims: module.Dims{
   366  			{ID: "client_rpc_exceeded", Name: "exceeded", Algo: module.Incremental},
   367  		},
   368  	}
   369  	clientRPCRequestsFailedRateChart = module.Chart{
   370  		ID:       "client_rpc_requests_failed_rate",
   371  		Title:    "Client failed RPC requests",
   372  		Units:    "requests/s",
   373  		Fam:      "rpc network activity",
   374  		Ctx:      "consul.client_rpc_requests_failed_rate",
   375  		Priority: prioRPCRequestsFailed,
   376  		Dims: module.Dims{
   377  			{ID: "client_rpc_failed", Name: "failed", Algo: module.Incremental},
   378  		},
   379  	}
   380  
   381  	raftThreadMainSaturationPercChart = module.Chart{
   382  		ID:       "raft_thread_main_saturation_perc",
   383  		Title:    "Raft main thread saturation",
   384  		Units:    "percentage",
   385  		Fam:      "raft saturation",
   386  		Ctx:      "consul.raft_thread_main_saturation_perc",
   387  		Priority: prioRaftThreadMainSaturation,
   388  		Dims: module.Dims{
   389  			{ID: "raft_thread_main_saturation_quantile=0.5", Name: "quantile_0.5", Div: precision * 10},
   390  			{ID: "raft_thread_main_saturation_quantile=0.9", Name: "quantile_0.9", Div: precision * 10},
   391  			{ID: "raft_thread_main_saturation_quantile=0.99", Name: "quantile_0.99", Div: precision * 10},
   392  		},
   393  	}
   394  	raftThreadFSMSaturationPercChart = module.Chart{
   395  		ID:       "raft_thread_fsm_saturation_perc",
   396  		Title:    "Raft FSM thread saturation",
   397  		Units:    "percentage",
   398  		Fam:      "raft saturation",
   399  		Ctx:      "consul.raft_thread_fsm_saturation_perc",
   400  		Priority: prioRaftThreadFSMSaturation,
   401  		Dims: module.Dims{
   402  			{ID: "raft_thread_fsm_saturation_quantile=0.5", Name: "quantile_0.5", Div: precision * 10},
   403  			{ID: "raft_thread_fsm_saturation_quantile=0.9", Name: "quantile_0.9", Div: precision * 10},
   404  			{ID: "raft_thread_fsm_saturation_quantile=0.99", Name: "quantile_0.99", Div: precision * 10},
   405  		},
   406  	}
   407  
   408  	raftFSMLastRestoreDurationChart = module.Chart{
   409  		ID:       "raft_fsm_last_restore_duration",
   410  		Title:    "Raft last restore duration",
   411  		Units:    "ms",
   412  		Fam:      "raft replication capacity",
   413  		Ctx:      "consul.raft_fsm_last_restore_duration",
   414  		Priority: prioRaftFSMLastRestoreDuration,
   415  		Dims: module.Dims{
   416  			{ID: "raft_fsm_lastRestoreDuration", Name: "last_restore_duration"},
   417  		},
   418  	}
   419  	raftLeaderOldestLogAgeChart = module.Chart{
   420  		ID:       "raft_leader_oldest_log_age",
   421  		Title:    "Raft leader oldest log age",
   422  		Units:    "seconds",
   423  		Fam:      "raft replication capacity",
   424  		Ctx:      "consul.raft_leader_oldest_log_age",
   425  		Priority: prioRaftLeaderOldestLogAge,
   426  		Dims: module.Dims{
   427  			{ID: "raft_leader_oldestLogAge", Name: "oldest_log_age", Div: 1000},
   428  		},
   429  	}
   430  	raftRPCInstallSnapshotTimeChart = module.Chart{
   431  		ID:       "raft_rpc_install_snapshot_time",
   432  		Title:    "Raft RPC install snapshot time",
   433  		Units:    "ms",
   434  		Fam:      "raft replication capacity",
   435  		Ctx:      "consul.raft_rpc_install_snapshot_time",
   436  		Priority: prioRaftRPCInstallSnapshotTime,
   437  		Dims: module.Dims{
   438  			{ID: "raft_rpc_installSnapshot_quantile=0.5", Name: "quantile_0.5", Div: precision * precision},
   439  			{ID: "raft_rpc_installSnapshot_quantile=0.9", Name: "quantile_0.9", Div: precision * precision},
   440  			{ID: "raft_rpc_installSnapshot_quantile=0.99", Name: "quantile_0.99", Div: precision * precision},
   441  		},
   442  	}
   443  
   444  	raftBoltDBFreelistBytesChart = module.Chart{
   445  		ID:       "raft_boltdb_freelist_bytes",
   446  		Title:    "Raft BoltDB freelist",
   447  		Units:    "bytes",
   448  		Fam:      "boltdb performance",
   449  		Ctx:      "consul.raft_boltdb_freelist_bytes",
   450  		Priority: prioBoltDBFreelistBytes,
   451  		Dims: module.Dims{
   452  			{ID: "raft_boltdb_freelistBytes", Name: "freelist"},
   453  		},
   454  	}
   455  	raftBoltDBLogsPerBatchChart = module.Chart{
   456  		ID:       "raft_boltdb_logs_per_batch_rate",
   457  		Title:    "Raft BoltDB logs written per batch",
   458  		Units:    "logs/s",
   459  		Fam:      "boltdb performance",
   460  		Ctx:      "consul.raft_boltdb_logs_per_batch_rate",
   461  		Priority: prioBoltDBLogsPerBatch,
   462  		Dims: module.Dims{
   463  			{ID: "raft_boltdb_logsPerBatch_sum", Name: "written", Algo: module.Incremental},
   464  		},
   465  	}
   466  
   467  	raftBoltDBStoreLogsTimeChart = module.Chart{
   468  		ID:       "raft_boltdb_store_logs_time",
   469  		Title:    "Raft BoltDB store logs time",
   470  		Units:    "ms",
   471  		Fam:      "boltdb performance",
   472  		Ctx:      "consul.raft_boltdb_store_logs_time",
   473  		Priority: prioBoltDBStoreLogsTime,
   474  		Dims: module.Dims{
   475  			{ID: "raft_boltdb_storeLogs_quantile=0.5", Name: "quantile_0.5", Div: precision * precision},
   476  			{ID: "raft_boltdb_storeLogs_quantile=0.9", Name: "quantile_0.9", Div: precision * precision},
   477  			{ID: "raft_boltdb_storeLogs_quantile=0.99", Name: "quantile_0.99", Div: precision * precision},
   478  		},
   479  	}
   480  
   481  	memoryAllocatedChart = module.Chart{
   482  		ID:       "memory_allocated",
   483  		Title:    "Memory allocated by the Consul process",
   484  		Units:    "bytes",
   485  		Fam:      "memory",
   486  		Ctx:      "consul.memory_allocated",
   487  		Priority: prioMemoryAllocated,
   488  		Dims: module.Dims{
   489  			{ID: "runtime_alloc_bytes", Name: "allocated"},
   490  		},
   491  	}
   492  	memorySysChart = module.Chart{
   493  		ID:       "memory_sys",
   494  		Title:    "Memory obtained from the OS",
   495  		Units:    "bytes",
   496  		Fam:      "memory",
   497  		Ctx:      "consul.memory_sys",
   498  		Priority: prioMemorySys,
   499  		Dims: module.Dims{
   500  			{ID: "runtime_sys_bytes", Name: "sys"},
   501  		},
   502  	}
   503  
   504  	gcPauseTimeChart = module.Chart{
   505  		ID:       "gc_pause_time",
   506  		Title:    "Garbage collection stop-the-world pause time",
   507  		Units:    "seconds",
   508  		Fam:      "garbage collection",
   509  		Ctx:      "consul.gc_pause_time",
   510  		Priority: prioGCPauseTime,
   511  		Dims: module.Dims{
   512  			{ID: "runtime_total_gc_pause_ns", Name: "gc_pause", Algo: module.Incremental, Div: 1e9},
   513  		},
   514  	}
   515  
   516  	licenseExpirationTimeChart = module.Chart{
   517  		ID:       "license_expiration_time",
   518  		Title:    "License expiration time",
   519  		Units:    "seconds",
   520  		Fam:      "license",
   521  		Ctx:      "consul.license_expiration_time",
   522  		Priority: prioLicenseExpirationTime,
   523  		Dims: module.Dims{
   524  			{ID: "system_licenseExpiration", Name: "license_expiration"},
   525  		},
   526  	}
   527  )
   528  
   529  var (
   530  	serviceHealthCheckStatusChartTmpl = module.Chart{
   531  		ID:       "health_check_%s_status",
   532  		Title:    "Service health check status",
   533  		Units:    "status",
   534  		Fam:      "service health checks",
   535  		Ctx:      "consul.service_health_check_status",
   536  		Priority: prioServiceHealthCheckStatus,
   537  		Dims: module.Dims{
   538  			{ID: "health_check_%s_passing_status", Name: "passing"},
   539  			{ID: "health_check_%s_critical_status", Name: "critical"},
   540  			{ID: "health_check_%s_maintenance_status", Name: "maintenance"},
   541  			{ID: "health_check_%s_warning_status", Name: "warning"},
   542  		},
   543  	}
   544  	nodeHealthCheckStatusChartTmpl = module.Chart{
   545  		ID:       "health_check_%s_status",
   546  		Title:    "Node health check status",
   547  		Units:    "status",
   548  		Fam:      "node health checks",
   549  		Ctx:      "consul.node_health_check_status",
   550  		Priority: prioNodeHealthCheckStatus,
   551  		Dims: module.Dims{
   552  			{ID: "health_check_%s_passing_status", Name: "passing"},
   553  			{ID: "health_check_%s_critical_status", Name: "critical"},
   554  			{ID: "health_check_%s_maintenance_status", Name: "maintenance"},
   555  			{ID: "health_check_%s_warning_status", Name: "warning"},
   556  		},
   557  	}
   558  )
   559  
   560  func (c *Consul) addGlobalCharts() {
   561  	if !c.isTelemetryPrometheusEnabled() {
   562  		return
   563  	}
   564  
   565  	var charts *module.Charts
   566  
   567  	if !c.isServer() {
   568  		charts = clientCharts.Copy()
   569  	} else {
   570  		charts = serverCommonCharts.Copy()
   571  
   572  		// can't really rely on checking if a response contains a metric due to retention of some metrics
   573  		// https://github.com/hashicorp/go-metrics/blob/b6d5c860c07ef6eeec89f4a662c7b452dd4d0c93/prometheus/prometheus.go#L75-L76
   574  		if c.version != nil {
   575  			if c.version.LT(semver.Version{Major: 1, Minor: 13, Patch: 0}) {
   576  				_ = charts.Remove(raftThreadMainSaturationPercChart.ID)
   577  				_ = charts.Remove(raftThreadFSMSaturationPercChart.ID)
   578  			}
   579  			if c.version.LT(semver.Version{Major: 1, Minor: 11, Patch: 0}) {
   580  				_ = charts.Remove(kvsApplyTimeChart.ID)
   581  				_ = charts.Remove(kvsApplyOperationsRateChart.ID)
   582  				_ = charts.Remove(txnApplyTimeChart.ID)
   583  				_ = charts.Remove(txnApplyOperationsRateChart.ID)
   584  				_ = charts.Remove(raftBoltDBFreelistBytesChart.ID)
   585  			}
   586  		}
   587  	}
   588  
   589  	if !c.hasLicense() {
   590  		_ = charts.Remove(licenseExpirationTimeChart.ID)
   591  	}
   592  
   593  	for _, chart := range *charts {
   594  		chart.Labels = []module.Label{
   595  			{Key: "datacenter", Value: c.cfg.Config.Datacenter},
   596  			{Key: "node_name", Value: c.cfg.Config.NodeName},
   597  		}
   598  	}
   599  
   600  	if err := c.Charts().Add(*charts.Copy()...); err != nil {
   601  		c.Warning(err)
   602  	}
   603  }
   604  
   605  func (c *Consul) addServerAutopilotHealthCharts() {
   606  	charts := serverAutopilotHealthCharts.Copy()
   607  
   608  	for _, chart := range *charts {
   609  		chart.Labels = []module.Label{
   610  			{Key: "datacenter", Value: c.cfg.Config.Datacenter},
   611  			{Key: "node_name", Value: c.cfg.Config.NodeName},
   612  		}
   613  	}
   614  
   615  	if err := c.Charts().Add(*charts...); err != nil {
   616  		c.Warning(err)
   617  	}
   618  }
   619  
   620  func newServiceHealthCheckChart(check *agentCheck) *module.Chart {
   621  	chart := serviceHealthCheckStatusChartTmpl.Copy()
   622  	chart.ID = fmt.Sprintf(chart.ID, check.CheckID)
   623  	chart.Labels = []module.Label{
   624  		{Key: "node_name", Value: check.Node},
   625  		{Key: "check_name", Value: check.Name},
   626  		{Key: "service_name", Value: check.ServiceName},
   627  	}
   628  	for _, d := range chart.Dims {
   629  		d.ID = fmt.Sprintf(d.ID, check.CheckID)
   630  	}
   631  	return chart
   632  }
   633  
   634  func newNodeHealthCheckChart(check *agentCheck) *module.Chart {
   635  	chart := nodeHealthCheckStatusChartTmpl.Copy()
   636  	chart.ID = fmt.Sprintf(chart.ID, check.CheckID)
   637  	chart.Labels = []module.Label{
   638  		{Key: "node_name", Value: check.Node},
   639  		{Key: "check_name", Value: check.Name},
   640  	}
   641  	for _, d := range chart.Dims {
   642  		d.ID = fmt.Sprintf(d.ID, check.CheckID)
   643  	}
   644  	return chart
   645  }
   646  
   647  func (c *Consul) addHealthCheckCharts(check *agentCheck) {
   648  	var chart *module.Chart
   649  
   650  	if check.ServiceName != "" {
   651  		chart = newServiceHealthCheckChart(check)
   652  	} else {
   653  		chart = newNodeHealthCheckChart(check)
   654  	}
   655  
   656  	chart.Labels = append(chart.Labels, module.Label{
   657  		Key:   "datacenter",
   658  		Value: c.cfg.Config.Datacenter,
   659  	})
   660  
   661  	if err := c.Charts().Add(chart); err != nil {
   662  		c.Warning(err)
   663  	}
   664  }
   665  
   666  func (c *Consul) removeHealthCheckCharts(checkID string) {
   667  	id := fmt.Sprintf("health_check_%s_status", checkID)
   668  
   669  	chart := c.Charts().Get(id)
   670  	if chart == nil {
   671  		c.Warningf("failed to remove '%s' chart: the chart does not exist", id)
   672  		return
   673  	}
   674  
   675  	chart.MarkRemove()
   676  	chart.MarkNotCreated()
   677  }
   678  
   679  func (c *Consul) addLeaderCharts() {
   680  	charts := serverLeaderCharts.Copy()
   681  
   682  	for _, chart := range *charts {
   683  		chart.Labels = []module.Label{
   684  			{Key: "datacenter", Value: c.cfg.Config.Datacenter},
   685  			{Key: "node_name", Value: c.cfg.Config.NodeName},
   686  		}
   687  	}
   688  
   689  	if err := c.Charts().Add(*charts...); err != nil {
   690  		c.Warning(err)
   691  	}
   692  }
   693  
   694  func (c *Consul) removeLeaderCharts() {
   695  	s := make(map[string]bool)
   696  	for _, v := range serverLeaderCharts {
   697  		s[v.ID] = true
   698  	}
   699  
   700  	for _, v := range *c.Charts() {
   701  		if s[v.ID] {
   702  			v.MarkRemove()
   703  			v.MarkNotCreated()
   704  		}
   705  	}
   706  }
   707  
   708  func (c *Consul) addFollowerCharts() {
   709  	charts := serverFollowerCharts.Copy()
   710  	if c.isCloudManaged() {
   711  		// 'autopilot_server_lastContact_leader' comes from 'operator/autopilot/health' which is disabled
   712  		_ = charts.Remove(raftFollowerLastContactLeaderTimeChart.ID)
   713  	}
   714  
   715  	for _, chart := range *charts {
   716  		chart.Labels = []module.Label{
   717  			{Key: "datacenter", Value: c.cfg.Config.Datacenter},
   718  			{Key: "node_name", Value: c.cfg.Config.NodeName},
   719  		}
   720  	}
   721  
   722  	if err := c.Charts().Add(*charts...); err != nil {
   723  		c.Warning(err)
   724  	}
   725  }
   726  
   727  func (c *Consul) removeFollowerCharts() {
   728  	s := make(map[string]bool)
   729  	for _, v := range serverFollowerCharts {
   730  		s[v.ID] = true
   731  	}
   732  
   733  	for _, v := range *c.Charts() {
   734  		if s[v.ID] {
   735  			v.MarkRemove()
   736  			v.MarkNotCreated()
   737  		}
   738  	}
   739  }