as400 improvements (#21158)
* added percentage of cpu entitled * added as400 query latency chart
Costa Tsaousis committed
Oct 16, 2025 at 13:08 UTC
c30192e39a32d4bf0fdf077048c4e7d552dc333a
9 files changed
+715
-36
src/go/plugin/ibm.d/modules/as400/README.md
+1
@@ -122,6 +122,7 @@ Metrics:
122
| Metric | Dimensions | Unit |
123
|:-------|:-----------|:-----|
124
| as400.cpu_utilization | utilization | percentage |
125
+| as400.cpu_utilization_entitled | utilization | percentage |
126
| as400.cpu_configuration | configured | cpus |
127
| as400.cpu_capacity | capacity | percentage |
128
| as400.total_jobs | total | jobs |
src/go/plugin/ibm.d/modules/as400/collect_activejobs.go
+2
-2
@@ -14,7 +14,7 @@ import (
14
// countActiveJobs returns the number of active jobs for cardinality check
15
func (a *Collector) countActiveJobs(ctx context.Context) (int, error) {
16
var count int
17
- err := a.doQueryRow(ctx, queryCountActiveJobs, func(column, value string) {
17
+ err := a.doQueryRow(ctx, "count_active_jobs", queryCountActiveJobs, func(column, value string) {
18
if column == "COUNT" {
19
if v, err := strconv.Atoi(value); err == nil {
20
count = v
@@ -48,7 +48,7 @@ func (a *Collector) collectActiveJobs(ctx context.Context) error {
48
currentJobName string
49
currentJob *activeJobMetrics
50
)
51
- err = a.doQuery(ctx, query, func(column, value string, lineEnd bool) {
51
+ err = a.doQuery(ctx, "top_active_jobs", query, func(column, value string, lineEnd bool) {
52
switch column {
53
case "JOB_NAME":
54
currentJobName = value
src/go/plugin/ibm.d/modules/as400/collect_data.go
+87
-27
@@ -82,6 +82,22 @@ func (a *Collector) parseInt64Value(value string, multiplier int64) (int64, bool
82
83
// parseFloat64Value parses a value as float64, returns (result, ok)
84
// Logs all parse attempts in debug mode
85
+func (a *Collector) computeEntitledCPUPercentage(cpuUtilization float64) int64 {
86
+ if a.mx.CurrentCPUCapacity <= 0 {
87
+ return 0
88
+ }
89
+ capacityPercent := float64(a.mx.CurrentCPUCapacity) / float64(precision)
90
+ if capacityPercent <= 0 {
91
+ return 0
92
+ }
93
+ perCorePercent := cpuUtilization / float64(precision)
94
+ entitled := (perCorePercent / capacityPercent) * 100.0
95
+ if entitled < 0 {
96
+ entitled = 0
97
+ }
98
+ return int64(math.Round(entitled * float64(precision)))
99
+}
100
+
101
func (a *Collector) parseFloat64Value(value string) (float64, bool) {
102
cleaned := cleanNumericString(value)
103
if cleaned == "" || cleaned == "-" || cleaned == "." || cleaned == "+" {
@@ -203,9 +219,34 @@ func (a *Collector) collect(ctx context.Context) error {
219
return nil
220
}
221
222
+func (a *Collector) recordQueryLatency(queryName string, duration time.Duration) {
223
+ if a.mx == nil {
224
+ return
225
+ }
226
+ if queryName == "" {
227
+ queryName = "unknown_query"
228
+ }
229
+
230
+ sanitized := cleanName(queryName)
231
+ if sanitized == "" {
232
+ sanitized = "unknown_query"
233
+ }
234
+
235
+ if a.mx.queryLatencies == nil {
236
+ a.mx.queryLatencies = make(map[string]int64)
237
+ }
238
+
239
+ latency := duration.Microseconds()
240
+ if latency == 0 && duration > 0 {
241
+ latency = 1
242
+ }
243
+
244
+ a.mx.queryLatencies[sanitized] += latency
245
+}
246
+
247
func (a *Collector) collectSystemStatus(ctx context.Context) error {
248
// Use comprehensive query to get all system status metrics at once
208
- err := a.doQuery(ctx, a.systemStatusQuery(), func(column, value string, lineEnd bool) {
249
+ err := a.doQuery(ctx, "system_status", a.systemStatusQuery(), func(column, value string, lineEnd bool) {
250
// Debug log all columns to see what we're receiving
251
if strings.Contains(column, "STORAGE") || strings.Contains(column, "MEMORY") {
252
a.Debugf("collectSystemStatus: column='%s', value='%s'", column, value)
@@ -222,6 +263,7 @@ func (a *Collector) collectSystemStatus(ctx context.Context) error {
263
// AVERAGE_CPU_UTILIZATION is system-wide 0-100% (deprecated in IBM i 7.4+)
264
if v, ok := a.parseInt64Value(value, precision); ok {
265
a.mx.CPUPercentage = v
266
+ a.mx.EntitledCPUPercentage = a.computeEntitledCPUPercentage(float64(v))
267
}
268
case "CURRENT_CPU_CAPACITY":
269
// CURRENT_CPU_CAPACITY comes from IBM as decimal fraction (0.0-1.0)
@@ -302,7 +344,7 @@ func (a *Collector) collectSystemStatus(ctx context.Context) error {
344
345
func (a *Collector) collectMemoryPools(ctx context.Context) error {
346
var currentPoolName string
305
- return a.doQuery(ctx, a.memoryPoolQuery(), func(column, value string, lineEnd bool) {
347
+ return a.doQuery(ctx, "memory_pools", a.memoryPoolQuery(), func(column, value string, lineEnd bool) {
348
switch column {
349
case "POOL_NAME":
350
currentPoolName = strings.TrimSpace(value)
@@ -361,7 +403,7 @@ func (a *Collector) collectMemoryPools(ctx context.Context) error {
403
404
func (a *Collector) collectDiskStatus(ctx context.Context) error {
405
// Try modern query first
364
- err := a.doQuery(ctx, queryDiskStatus, func(column, value string, lineEnd bool) {
406
+ err := a.doQuery(ctx, "disk_status", queryDiskStatus, func(column, value string, lineEnd bool) {
407
if column == "AVG_DISK_BUSY" {
408
if v, ok := a.parseInt64Value(value, precision); ok {
409
a.mx.DiskBusyPercentage = v
@@ -374,7 +416,7 @@ func (a *Collector) collectDiskStatus(ctx context.Context) error {
416
417
func (a *Collector) collectJobInfo(ctx context.Context) error {
418
// Try modern query first
377
- err := a.doQuery(ctx, queryJobInfo, func(column, value string, lineEnd bool) {
419
+ err := a.doQuery(ctx, "job_info", queryJobInfo, func(column, value string, lineEnd bool) {
420
if column == "JOB_QUEUE_LENGTH" {
421
if v, ok := a.parseInt64Value(value, 1); ok {
422
a.mx.JobQueueLength = v
@@ -415,7 +457,7 @@ func (a *Collector) collectMessageQueues(ctx context.Context) error {
457
metrics messageQueueInstanceMetrics
458
)
459
418
- return a.doQuery(ctx, query, func(column, value string, lineEnd bool) {
460
+ return a.doQuery(ctx, "message_queue_aggregates", query, func(column, value string, lineEnd bool) {
461
switch column {
462
case "MESSAGE_QUEUE_LIBRARY":
463
library = normalizeValue(value)
@@ -486,7 +528,7 @@ func (a *Collector) collectOutputQueues(ctx context.Context) error {
528
metrics outputQueueInstanceMetrics
529
)
530
489
- return a.doQuery(ctx, query, func(column, value string, lineEnd bool) {
531
+ return a.doQuery(ctx, "output_queue_info", query, func(column, value string, lineEnd bool) {
532
switch column {
533
case "OUTPUT_QUEUE_LIBRARY_NAME":
534
library = normalizeValue(value)
@@ -519,7 +561,7 @@ func (a *Collector) collectOutputQueues(ctx context.Context) error {
561
})
562
}
563
522
-func (a *Collector) doQuery(ctx context.Context, query string, assign func(column, value string, lineEnd bool)) error {
564
+func (a *Collector) doQuery(ctx context.Context, queryName, query string, assign func(column, value string, lineEnd bool)) error {
565
var (
566
capture bool
567
columnsSaved []string
@@ -528,6 +570,12 @@ func (a *Collector) doQuery(ctx context.Context, query string, assign func(colum
570
if a.dump != nil {
571
capture = true
572
}
573
+
574
+ start := time.Now()
575
+ defer func() {
576
+ a.recordQueryLatency(queryName, time.Since(start))
577
+ }()
578
+
579
err := a.client.Query(ctx, query, func(columns []string, values []string) error {
580
for i, col := range columns {
581
assign(col, values[i], i == len(columns)-1)
@@ -559,7 +607,7 @@ func (a *Collector) doQuery(ctx context.Context, query string, assign func(colum
607
}
608
609
// doQueryRow executes a query that returns a single row
562
-func (a *Collector) doQueryRow(ctx context.Context, query string, assign func(column, value string)) error {
610
+func (a *Collector) doQueryRow(ctx context.Context, queryName, query string, assign func(column, value string)) error {
611
var (
612
capture bool
613
columnsSaved []string
@@ -568,6 +616,12 @@ func (a *Collector) doQueryRow(ctx context.Context, query string, assign func(co
616
if a.dump != nil {
617
capture = true
618
}
619
+
620
+ start := time.Now()
621
+ defer func() {
622
+ a.recordQueryLatency(queryName, time.Since(start))
623
+ }()
624
+
625
err := a.client.QueryWithLimit(ctx, query, 1, func(columns []string, values []string) error {
626
for i, col := range columns {
627
assign(col, values[i])
@@ -609,7 +663,7 @@ func (a *Collector) collectDiskInstances(ctx context.Context) error {
663
}
664
665
var currentUnit string
612
- return a.doQuery(ctx, queryDiskInstances, func(column, value string, lineEnd bool) {
666
+ return a.doQuery(ctx, "disk_instances", queryDiskInstances, func(column, value string, lineEnd bool) {
667
668
switch column {
669
case "UNIT_NUMBER":
@@ -843,7 +897,7 @@ func (a *Collector) collectDiskInstances(ctx context.Context) error {
897
898
func (a *Collector) countDisks(ctx context.Context) (int, error) {
899
var count int
846
- err := a.doQuery(ctx, queryCountDisks, func(column, value string, lineEnd bool) {
900
+ err := a.doQuery(ctx, "count_disks", queryCountDisks, func(column, value string, lineEnd bool) {
901
if column == "COUNT" {
902
count = int(parseInt64OrZero(value))
903
}
@@ -853,7 +907,7 @@ func (a *Collector) countDisks(ctx context.Context) (int, error) {
907
908
// Network connections collection
909
func (a *Collector) collectNetworkConnections(ctx context.Context) error {
856
- return a.doQuery(ctx, queryNetworkConnections, func(column, value string, lineEnd bool) {
910
+ return a.doQuery(ctx, "network_connections", queryNetworkConnections, func(column, value string, lineEnd bool) {
911
switch column {
912
case "REMOTE_CONNECTIONS":
913
if v, ok := a.parseInt64Value(value, 1); ok {
@@ -877,7 +931,7 @@ func (a *Collector) collectNetworkConnections(ctx context.Context) error {
931
932
func (a *Collector) countNetworkInterfaces(ctx context.Context) (int, error) {
933
var count int
880
- err := a.doQueryRow(ctx, queryCountNetworkInterfaces, func(column, value string) {
934
+ err := a.doQueryRow(ctx, "count_network_interfaces", queryCountNetworkInterfaces, func(column, value string) {
935
if column == "COUNT" {
936
if v, ok := a.parseInt64Value(value, 1); ok {
937
count = int(v)
@@ -889,7 +943,7 @@ func (a *Collector) countNetworkInterfaces(ctx context.Context) (int, error) {
943
944
func (a *Collector) countMessageQueues(ctx context.Context) (int, error) {
945
var count int
892
- err := a.doQueryRow(ctx, queryCountMessageQueues, func(column, value string) {
946
+ err := a.doQueryRow(ctx, "count_message_queues", queryCountMessageQueues, func(column, value string) {
947
if column == "COUNT" {
948
if v, ok := a.parseInt64Value(value, 1); ok {
949
count = int(v)
@@ -901,7 +955,7 @@ func (a *Collector) countMessageQueues(ctx context.Context) (int, error) {
955
956
func (a *Collector) countOutputQueues(ctx context.Context) (int, error) {
957
var count int
904
- err := a.doQueryRow(ctx, queryCountOutputQueues, func(column, value string) {
958
+ err := a.doQueryRow(ctx, "count_output_queues", queryCountOutputQueues, func(column, value string) {
959
if column == "COUNT" {
960
if v, ok := a.parseInt64Value(value, 1); ok {
961
count = int(v)
@@ -913,7 +967,7 @@ func (a *Collector) countOutputQueues(ctx context.Context) (int, error) {
967
968
func (a *Collector) countHTTPServers(ctx context.Context) (int, error) {
969
var count int64
916
- err := a.doQueryRow(ctx, queryCountHTTPServers, func(column, value string) {
970
+ err := a.doQueryRow(ctx, "count_http_servers", queryCountHTTPServers, func(column, value string) {
971
if column == "COUNT" {
972
if v, ok := a.parseInt64Value(value, 1); ok {
973
count = v
@@ -937,7 +991,7 @@ func withFetchLimit(query string, limit int) string {
991
992
func (a *Collector) countSubsystems(ctx context.Context) (int, error) {
993
var count int64
940
- err := a.doQueryRow(ctx, queryCountSubsystems, func(column, value string) {
994
+ err := a.doQueryRow(ctx, "count_subsystems", queryCountSubsystems, func(column, value string) {
995
if column == "COUNT" {
996
if v, ok := a.parseInt64Value(value, 1); ok {
997
count = v
@@ -949,7 +1003,7 @@ func (a *Collector) countSubsystems(ctx context.Context) (int, error) {
1003
1004
func (a *Collector) countJobQueues(ctx context.Context) (int, error) {
1005
var count int64
952
- err := a.doQueryRow(ctx, queryCountJobQueues, func(column, value string) {
1006
+ err := a.doQueryRow(ctx, "count_job_queues", queryCountJobQueues, func(column, value string) {
1007
if column == "COUNT" {
1008
if v, ok := a.parseInt64Value(value, 1); ok {
1009
count = v
@@ -962,7 +1016,7 @@ func (a *Collector) countJobQueues(ctx context.Context) (int, error) {
1016
// Temporary storage collection
1017
func (a *Collector) collectTempStorage(ctx context.Context) error {
1018
// Collect total temp storage
965
- err := a.doQuery(ctx, queryTempStorageTotal, func(column, value string, lineEnd bool) {
1019
+ err := a.doQuery(ctx, "temp_storage_total", queryTempStorageTotal, func(column, value string, lineEnd bool) {
1020
switch column {
1021
case "CURRENT_SIZE":
1022
if v, ok := a.parseInt64Value(value, 1); ok {
@@ -980,7 +1034,7 @@ func (a *Collector) collectTempStorage(ctx context.Context) error {
1034
1035
// Collect named temp storage buckets
1036
var currentBucket string
983
- return a.doQuery(ctx, queryTempStorageNamed, func(column, value string, lineEnd bool) {
1037
+ return a.doQuery(ctx, "temp_storage_named", queryTempStorageNamed, func(column, value string, lineEnd bool) {
1038
switch column {
1039
case "NAME":
1040
currentBucket = value
@@ -1025,7 +1079,7 @@ func (a *Collector) collectSubsystems(ctx context.Context) error {
1079
}
1080
1081
var currentSubsystem string
1028
- return a.doQuery(ctx, query, func(column, value string, lineEnd bool) {
1082
+ return a.doQuery(ctx, "subsystems", query, func(column, value string, lineEnd bool) {
1083
switch column {
1084
case "SUBSYSTEM_NAME":
1085
name := strings.TrimSpace(value)
@@ -1093,7 +1147,7 @@ func (a *Collector) collectJobQueues(ctx context.Context) error {
1147
}
1148
1149
var currentQueue string
1096
- return a.doQuery(ctx, query, func(column, value string, lineEnd bool) {
1150
+ return a.doQuery(ctx, "job_queues", query, func(column, value string, lineEnd bool) {
1151
switch column {
1152
case "QUEUE_NAME":
1153
name := strings.TrimSpace(value)
@@ -1153,7 +1207,7 @@ func (a *Collector) collectDiskInstancesEnhanced(ctx context.Context) error {
1207
}
1208
1209
var currentUnit string
1156
- return a.doQuery(ctx, queryDiskInstancesEnhanced, func(column, value string, lineEnd bool) {
1210
+ return a.doQuery(ctx, "disk_instances_enhanced", queryDiskInstancesEnhanced, func(column, value string, lineEnd bool) {
1211
switch column {
1212
case "UNIT_NUMBER":
1213
currentUnit = value
@@ -1333,7 +1387,7 @@ func (a *Collector) collectNetworkInterfaces(ctx context.Context) error {
1387
}
1388
1389
var currentInterface string
1336
- return a.doQuery(ctx, queryNetworkInterfaces, func(column, value string, lineEnd bool) {
1390
+ return a.doQuery(ctx, "network_interfaces", queryNetworkInterfaces, func(column, value string, lineEnd bool) {
1391
switch column {
1392
case "LINE_DESCRIPTION":
1393
iface := strings.TrimSpace(value)
@@ -1444,7 +1498,7 @@ func (a *Collector) collectHTTPServerInfo(ctx context.Context) error {
1498
currentKey string
1499
)
1500
1447
- return a.doQuery(ctx, queryHTTPServerInfo, func(column, value string, lineEnd bool) {
1501
+ return a.doQuery(ctx, "http_server_info", queryHTTPServerInfo, func(column, value string, lineEnd bool) {
1502
switch column {
1503
case "SERVER_NAME":
1504
serverName = strings.TrimSpace(value)
@@ -1561,10 +1615,12 @@ func (a *Collector) collectPlanCache(ctx context.Context) error {
1615
if err := a.client.Exec(ctx, callAnalyzePlanCache); err != nil {
1616
return fmt.Errorf("failed to analyze plan cache: %w", err)
1617
}
1564
- a.Debugf("plan cache analysis completed in %v", time.Since(start))
1618
+ elapsed := time.Since(start)
1619
+ a.Debugf("plan cache analysis completed in %v", elapsed)
1620
+ a.recordQueryLatency("analyze_plan_cache", elapsed)
1621
1622
var currentHeading string
1567
- return a.doQuery(ctx, queryPlanCacheSummary, func(column, value string, lineEnd bool) {
1623
+ return a.doQuery(ctx, "plan_cache_summary", queryPlanCacheSummary, func(column, value string, lineEnd bool) {
1624
switch column {
1625
case "HEADING":
1626
currentHeading = strings.TrimSpace(value)
@@ -1599,6 +1655,8 @@ func (a *Collector) collectSystemActivity(ctx context.Context) error {
1655
// Query both potential data sources in one query
1656
query := a.systemActivityQuery()
1657
1658
+ a.mx.EntitledCPUPercentage = 0
1659
+
1660
var (
1661
totalCPUTime int64 // Nanoseconds since IPL (NULL if no *JOBCTL)
1662
elapsedTime int64 // Seconds since last reset
@@ -1607,7 +1665,7 @@ func (a *Collector) collectSystemActivity(ctx context.Context) error {
1665
hasElapsedData bool
1666
)
1667
1610
- err := a.doQuery(ctx, query, func(column, value string, lineEnd bool) {
1668
+ err := a.doQuery(ctx, "system_activity", query, func(column, value string, lineEnd bool) {
1669
switch column {
1670
case "TOTAL_CPU_TIME":
1671
// This will be NULL if user doesn't have *JOBCTL authority
@@ -1665,6 +1723,7 @@ func (a *Collector) collectSystemActivity(ctx context.Context) error {
1723
a.mx.systemActivity.AverageCPUUtilization = int64(cpuUtilization)
1724
a.mx.systemActivity.AverageCPURate = int64(cpuUtilization)
1725
a.mx.CPUPercentage = int64(cpuUtilization)
1726
+ a.mx.EntitledCPUPercentage = a.computeEntitledCPUPercentage(cpuUtilization)
1727
} else {
1728
if cpuUtilization < 0 {
1729
a.Warningf("CPU collection: calculated utilization negative (%.2f%%), skipping this sample", cpuUtilization/precision)
@@ -1718,6 +1777,7 @@ func (a *Collector) collectSystemActivity(ctx context.Context) error {
1777
a.mx.systemActivity.AverageCPUUtilization = int64(cpuUtilization)
1778
a.mx.systemActivity.AverageCPURate = int64(cpuUtilization)
1779
a.mx.CPUPercentage = int64(cpuUtilization)
1780
+ a.mx.EntitledCPUPercentage = a.computeEntitledCPUPercentage(cpuUtilization)
1781
} else {
1782
if cpuUtilization < 0 {
1783
a.Warningf("CPU collection: interval utilization negative (%.2f%%), skipping this sample", cpuUtilization/precision)
src/go/plugin/ibm.d/modules/as400/collector.go
+78
@@ -112,6 +112,7 @@ func (c *Collector) resetInstanceCaches() {
112
c.mx.networkInterfaces = make(map[string]networkInterfaceInstanceMetrics)
113
c.mx.httpServers = make(map[string]httpServerInstanceMetrics)
114
c.mx.planCache = make(map[string]planCacheInstanceMetrics)
115
+ c.mx.queryLatencies = make(map[string]int64)
116
}
117
118
func (c *Collector) prepareIterationState() {
@@ -184,6 +185,7 @@ func (c *Collector) CollectOnce() error {
185
c.exportSystemActivityMetrics()
186
c.exportHTTPServerMetrics()
187
c.exportPlanCacheMetrics()
188
+ c.exportQueryLatencyMetrics()
189
c.applyGlobalLabels()
190
191
return nil
@@ -334,6 +336,10 @@ func (c *Collector) exportSystemMetrics() {
336
Utilization: c.mx.CPUPercentage,
337
})
338
339
+ contexts.System.CPUEntitledUtilization.Set(c.State, labels, contexts.SystemCPUEntitledUtilizationValues{
340
+ Utilization: c.mx.EntitledCPUPercentage,
341
+ })
342
+
343
contexts.System.CPUDetails.Set(c.State, labels, contexts.SystemCPUDetailsValues{
344
Configured: c.mx.ConfiguredCPUs,
345
})
@@ -772,6 +778,78 @@ func (c *Collector) exportPlanCacheMetrics() {
778
}
779
}
780
781
+func (c *Collector) exportQueryLatencyMetrics() {
782
+ if c.mx == nil || len(c.mx.queryLatencies) == 0 {
783
+ return
784
+ }
785
+
786
+ values := contexts.ObservabilityQueryLatencyValues{}
787
+ fieldMap := map[string]*int64{
788
+ "analyze_plan_cache": &values.Analyze_plan_cache,
789
+ "count_active_jobs": &values.Count_active_jobs,
790
+ "count_disks": &values.Count_disks,
791
+ "count_http_servers": &values.Count_http_servers,
792
+ "count_job_queues": &values.Count_job_queues,
793
+ "count_message_queues": &values.Count_message_queues,
794
+ "count_network_interfaces": &values.Count_network_interfaces,
795
+ "count_output_queues": &values.Count_output_queues,
796
+ "count_subsystems": &values.Count_subsystems,
797
+ "detect_ibmi_version_primary": &values.Detect_ibmi_version_primary,
798
+ "detect_ibmi_version_fallback": &values.Detect_ibmi_version_fallback,
799
+ "disk_instances": &values.Disk_instances,
800
+ "disk_instances_enhanced": &values.Disk_instances_enhanced,
801
+ "disk_status": &values.Disk_status,
802
+ "http_server_info": &values.Http_server_info,
803
+ "job_info": &values.Job_info,
804
+ "job_queues": &values.Job_queues,
805
+ "memory_pools": &values.Memory_pools,
806
+ "message_queue_aggregates": &values.Message_queue_aggregates,
807
+ "network_connections": &values.Network_connections,
808
+ "network_interfaces": &values.Network_interfaces,
809
+ "output_queue_info": &values.Output_queue_info,
810
+ "plan_cache_summary": &values.Plan_cache_summary,
811
+ "serial_number": &values.Serial_number,
812
+ "system_activity": &values.System_activity,
813
+ "system_model": &values.System_model,
814
+ "system_status": &values.System_status,
815
+ "temp_storage_named": &values.Temp_storage_named,
816
+ "temp_storage_total": &values.Temp_storage_total,
817
+ "technology_refresh_level": &values.Technology_refresh_level,
818
+ "top_active_jobs": &values.Top_active_jobs,
819
+ }
820
+
821
+ var otherTotal int64
822
+
823
+ for name, latency := range c.mx.queryLatencies {
824
+ if latency == 0 {
825
+ continue
826
+ }
827
+ if target, ok := fieldMap[name]; ok {
828
+ *target += latency
829
+ } else {
830
+ otherTotal += latency
831
+ }
832
+ }
833
+
834
+ if otherTotal > 0 {
835
+ values.Other = otherTotal
836
+ }
837
+
838
+ var total int64
839
+ for _, ptr := range fieldMap {
840
+ if ptr != nil {
841
+ total += *ptr
842
+ }
843
+ }
844
+ total += values.Other
845
+
846
+ if total == 0 {
847
+ return
848
+ }
849
+
850
+ contexts.Observability.QueryLatency.Set(c.State, contexts.EmptyLabels{}, values)
851
+}
852
+
853
func (c *Collector) exportSystemActivityMetrics() {
854
if c.mx.systemActivity.AverageCPURate == 0 && c.mx.systemActivity.AverageCPUUtilization == 0 {
855
return
src/go/plugin/ibm.d/modules/as400/contexts/contexts.yaml
+118
@@ -12,6 +12,17 @@ System:
12
- name: utilization
13
algo: absolute
14
div: 1000
15
+ - name: CPUEntitledUtilization
16
+ context: as400.cpu_utilization_entitled
17
+ title: CPU Utilization (as % of entitlement)
18
+ family: compute/cpu
19
+ units: percentage
20
+ type: line
21
+ priority: 102
22
+ dimensions:
23
+ - name: utilization
24
+ algo: absolute
25
+ div: 1000
26
- name: CPUDetails
27
context: as400.cpu_configuration
28
title: CPU Configuration
@@ -643,3 +654,110 @@ PlanCache:
654
- name: value
655
algo: absolute
656
div: 1000
657
+Observability:
658
+ labels: []
659
+ contexts:
660
+ - name: QueryLatency
661
+ context: netdata.plugin_ibm.as400_query_latency
662
+ title: AS400 Query Latency
663
+ family: plugins/ibm.d/latency
664
+ units: ms
665
+ type: stacked
666
+ priority: 146000
667
+ dimensions:
668
+ - name: analyze_plan_cache
669
+ algo: absolute
670
+ div: 1000
671
+ - name: count_active_jobs
672
+ algo: absolute
673
+ div: 1000
674
+ - name: count_disks
675
+ algo: absolute
676
+ div: 1000
677
+ - name: count_http_servers
678
+ algo: absolute
679
+ div: 1000
680
+ - name: count_job_queues
681
+ algo: absolute
682
+ div: 1000
683
+ - name: count_message_queues
684
+ algo: absolute
685
+ div: 1000
686
+ - name: count_network_interfaces
687
+ algo: absolute
688
+ div: 1000
689
+ - name: count_output_queues
690
+ algo: absolute
691
+ div: 1000
692
+ - name: count_subsystems
693
+ algo: absolute
694
+ div: 1000
695
+ - name: detect_ibmi_version_primary
696
+ algo: absolute
697
+ div: 1000
698
+ - name: detect_ibmi_version_fallback
699
+ algo: absolute
700
+ div: 1000
701
+ - name: disk_instances
702
+ algo: absolute
703
+ div: 1000
704
+ - name: disk_instances_enhanced
705
+ algo: absolute
706
+ div: 1000
707
+ - name: disk_status
708
+ algo: absolute
709
+ div: 1000
710
+ - name: http_server_info
711
+ algo: absolute
712
+ div: 1000
713
+ - name: job_info
714
+ algo: absolute
715
+ div: 1000
716
+ - name: job_queues
717
+ algo: absolute
718
+ div: 1000
719
+ - name: memory_pools
720
+ algo: absolute
721
+ div: 1000
722
+ - name: message_queue_aggregates
723
+ algo: absolute
724
+ div: 1000
725
+ - name: network_connections
726
+ algo: absolute
727
+ div: 1000
728
+ - name: network_interfaces
729
+ algo: absolute
730
+ div: 1000
731
+ - name: output_queue_info
732
+ algo: absolute
733
+ div: 1000
734
+ - name: plan_cache_summary
735
+ algo: absolute
736
+ div: 1000
737
+ - name: serial_number
738
+ algo: absolute
739
+ div: 1000
740
+ - name: system_activity
741
+ algo: absolute
742
+ div: 1000
743
+ - name: system_model
744
+ algo: absolute
745
+ div: 1000
746
+ - name: system_status
747
+ algo: absolute
748
+ div: 1000
749
+ - name: temp_storage_named
750
+ algo: absolute
751
+ div: 1000
752
+ - name: temp_storage_total
753
+ algo: absolute
754
+ div: 1000
755
+ - name: technology_refresh_level
756
+ algo: absolute
757
+ div: 1000
758
+ - name: top_active_jobs
759
+ algo: absolute
760
+ div: 1000
761
+ - name: other
762
+ algo: absolute
763
+ div: 1000
src/go/plugin/ibm.d/modules/as400/contexts/zz_generated_contexts.go
+376
@@ -1329,6 +1329,336 @@ var NetworkInterface = struct {
1329
},
1330
}
1331
1332
+// --- Observability ---
1333
+
1334
+// ObservabilityQueryLatencyValues defines the type-safe values for Observability.QueryLatency context
1335
+type ObservabilityQueryLatencyValues struct {
1336
+ Analyze_plan_cache int64
1337
+ Count_active_jobs int64
1338
+ Count_disks int64
1339
+ Count_http_servers int64
1340
+ Count_job_queues int64
1341
+ Count_message_queues int64
1342
+ Count_network_interfaces int64
1343
+ Count_output_queues int64
1344
+ Count_subsystems int64
1345
+ Detect_ibmi_version_primary int64
1346
+ Detect_ibmi_version_fallback int64
1347
+ Disk_instances int64
1348
+ Disk_instances_enhanced int64
1349
+ Disk_status int64
1350
+ Http_server_info int64
1351
+ Job_info int64
1352
+ Job_queues int64
1353
+ Memory_pools int64
1354
+ Message_queue_aggregates int64
1355
+ Network_connections int64
1356
+ Network_interfaces int64
1357
+ Output_queue_info int64
1358
+ Plan_cache_summary int64
1359
+ Serial_number int64
1360
+ System_activity int64
1361
+ System_model int64
1362
+ System_status int64
1363
+ Temp_storage_named int64
1364
+ Temp_storage_total int64
1365
+ Technology_refresh_level int64
1366
+ Top_active_jobs int64
1367
+ Other int64
1368
+}
1369
+
1370
+// ObservabilityQueryLatencyContext provides type-safe operations for Observability.QueryLatency context
1371
+type ObservabilityQueryLatencyContext struct {
1372
+ framework.Context[EmptyLabels]
1373
+}
1374
+
1375
+// Set provides type-safe dimension setting for Observability.QueryLatency context
1376
+func (c ObservabilityQueryLatencyContext) Set(state *framework.CollectorState, labels EmptyLabels, values ObservabilityQueryLatencyValues) {
1377
+ state.SetMetricsForGeneratedCode(&c.Context, nil, map[string]int64{
1378
+ "analyze_plan_cache": values.Analyze_plan_cache,
1379
+ "count_active_jobs": values.Count_active_jobs,
1380
+ "count_disks": values.Count_disks,
1381
+ "count_http_servers": values.Count_http_servers,
1382
+ "count_job_queues": values.Count_job_queues,
1383
+ "count_message_queues": values.Count_message_queues,
1384
+ "count_network_interfaces": values.Count_network_interfaces,
1385
+ "count_output_queues": values.Count_output_queues,
1386
+ "count_subsystems": values.Count_subsystems,
1387
+ "detect_ibmi_version_primary": values.Detect_ibmi_version_primary,
1388
+ "detect_ibmi_version_fallback": values.Detect_ibmi_version_fallback,
1389
+ "disk_instances": values.Disk_instances,
1390
+ "disk_instances_enhanced": values.Disk_instances_enhanced,
1391
+ "disk_status": values.Disk_status,
1392
+ "http_server_info": values.Http_server_info,
1393
+ "job_info": values.Job_info,
1394
+ "job_queues": values.Job_queues,
1395
+ "memory_pools": values.Memory_pools,
1396
+ "message_queue_aggregates": values.Message_queue_aggregates,
1397
+ "network_connections": values.Network_connections,
1398
+ "network_interfaces": values.Network_interfaces,
1399
+ "output_queue_info": values.Output_queue_info,
1400
+ "plan_cache_summary": values.Plan_cache_summary,
1401
+ "serial_number": values.Serial_number,
1402
+ "system_activity": values.System_activity,
1403
+ "system_model": values.System_model,
1404
+ "system_status": values.System_status,
1405
+ "temp_storage_named": values.Temp_storage_named,
1406
+ "temp_storage_total": values.Temp_storage_total,
1407
+ "technology_refresh_level": values.Technology_refresh_level,
1408
+ "top_active_jobs": values.Top_active_jobs,
1409
+ "other": values.Other,
1410
+ })
1411
+}
1412
+
1413
+// SetUpdateEvery sets the update interval for this instance
1414
+func (c ObservabilityQueryLatencyContext) SetUpdateEvery(state *framework.CollectorState, labels EmptyLabels, updateEvery int) {
1415
+ state.SetUpdateEveryOverrideForGeneratedCode(&c.Context, nil, updateEvery)
1416
+}
1417
+
1418
+// Observability contains all metric contexts for Observability
1419
+var Observability = struct {
1420
+ QueryLatency ObservabilityQueryLatencyContext
1421
+}{
1422
+ QueryLatency: ObservabilityQueryLatencyContext{
1423
+ Context: framework.Context[EmptyLabels]{
1424
+ Name: "netdata.plugin_ibm.as400_query_latency",
1425
+ Family: "plugins/ibm.d/latency",
1426
+ Title: "AS400 Query Latency",
1427
+ Units: "ms",
1428
+ Type: module.Stacked,
1429
+ Priority: 146000,
1430
+ UpdateEvery: 1,
1431
+ Dimensions: []framework.Dimension{
1432
+ {
1433
+ Name: "analyze_plan_cache",
1434
+ Algorithm: module.Absolute,
1435
+ Mul: 1,
1436
+ Div: 1000,
1437
+ Precision: 1,
1438
+ },
1439
+ {
1440
+ Name: "count_active_jobs",
1441
+ Algorithm: module.Absolute,
1442
+ Mul: 1,
1443
+ Div: 1000,
1444
+ Precision: 1,
1445
+ },
1446
+ {
1447
+ Name: "count_disks",
1448
+ Algorithm: module.Absolute,
1449
+ Mul: 1,
1450
+ Div: 1000,
1451
+ Precision: 1,
1452
+ },
1453
+ {
1454
+ Name: "count_http_servers",
1455
+ Algorithm: module.Absolute,
1456
+ Mul: 1,
1457
+ Div: 1000,
1458
+ Precision: 1,
1459
+ },
1460
+ {
1461
+ Name: "count_job_queues",
1462
+ Algorithm: module.Absolute,
1463
+ Mul: 1,
1464
+ Div: 1000,
1465
+ Precision: 1,
1466
+ },
1467
+ {
1468
+ Name: "count_message_queues",
1469
+ Algorithm: module.Absolute,
1470
+ Mul: 1,
1471
+ Div: 1000,
1472
+ Precision: 1,
1473
+ },
1474
+ {
1475
+ Name: "count_network_interfaces",
1476
+ Algorithm: module.Absolute,
1477
+ Mul: 1,
1478
+ Div: 1000,
1479
+ Precision: 1,
1480
+ },
1481
+ {
1482
+ Name: "count_output_queues",
1483
+ Algorithm: module.Absolute,
1484
+ Mul: 1,
1485
+ Div: 1000,
1486
+ Precision: 1,
1487
+ },
1488
+ {
1489
+ Name: "count_subsystems",
1490
+ Algorithm: module.Absolute,
1491
+ Mul: 1,
1492
+ Div: 1000,
1493
+ Precision: 1,
1494
+ },
1495
+ {
1496
+ Name: "detect_ibmi_version_primary",
1497
+ Algorithm: module.Absolute,
1498
+ Mul: 1,
1499
+ Div: 1000,
1500
+ Precision: 1,
1501
+ },
1502
+ {
1503
+ Name: "detect_ibmi_version_fallback",
1504
+ Algorithm: module.Absolute,
1505
+ Mul: 1,
1506
+ Div: 1000,
1507
+ Precision: 1,
1508
+ },
1509
+ {
1510
+ Name: "disk_instances",
1511
+ Algorithm: module.Absolute,
1512
+ Mul: 1,
1513
+ Div: 1000,
1514
+ Precision: 1,
1515
+ },
1516
+ {
1517
+ Name: "disk_instances_enhanced",
1518
+ Algorithm: module.Absolute,
1519
+ Mul: 1,
1520
+ Div: 1000,
1521
+ Precision: 1,
1522
+ },
1523
+ {
1524
+ Name: "disk_status",
1525
+ Algorithm: module.Absolute,
1526
+ Mul: 1,
1527
+ Div: 1000,
1528
+ Precision: 1,
1529
+ },
1530
+ {
1531
+ Name: "http_server_info",
1532
+ Algorithm: module.Absolute,
1533
+ Mul: 1,
1534
+ Div: 1000,
1535
+ Precision: 1,
1536
+ },
1537
+ {
1538
+ Name: "job_info",
1539
+ Algorithm: module.Absolute,
1540
+ Mul: 1,
1541
+ Div: 1000,
1542
+ Precision: 1,
1543
+ },
1544
+ {
1545
+ Name: "job_queues",
1546
+ Algorithm: module.Absolute,
1547
+ Mul: 1,
1548
+ Div: 1000,
1549
+ Precision: 1,
1550
+ },
1551
+ {
1552
+ Name: "memory_pools",
1553
+ Algorithm: module.Absolute,
1554
+ Mul: 1,
1555
+ Div: 1000,
1556
+ Precision: 1,
1557
+ },
1558
+ {
1559
+ Name: "message_queue_aggregates",
1560
+ Algorithm: module.Absolute,
1561
+ Mul: 1,
1562
+ Div: 1000,
1563
+ Precision: 1,
1564
+ },
1565
+ {
1566
+ Name: "network_connections",
1567
+ Algorithm: module.Absolute,
1568
+ Mul: 1,
1569
+ Div: 1000,
1570
+ Precision: 1,
1571
+ },
1572
+ {
1573
+ Name: "network_interfaces",
1574
+ Algorithm: module.Absolute,
1575
+ Mul: 1,
1576
+ Div: 1000,
1577
+ Precision: 1,
1578
+ },
1579
+ {
1580
+ Name: "output_queue_info",
1581
+ Algorithm: module.Absolute,
1582
+ Mul: 1,
1583
+ Div: 1000,
1584
+ Precision: 1,
1585
+ },
1586
+ {
1587
+ Name: "plan_cache_summary",
1588
+ Algorithm: module.Absolute,
1589
+ Mul: 1,
1590
+ Div: 1000,
1591
+ Precision: 1,
1592
+ },
1593
+ {
1594
+ Name: "serial_number",
1595
+ Algorithm: module.Absolute,
1596
+ Mul: 1,
1597
+ Div: 1000,
1598
+ Precision: 1,
1599
+ },
1600
+ {
1601
+ Name: "system_activity",
1602
+ Algorithm: module.Absolute,
1603
+ Mul: 1,
1604
+ Div: 1000,
1605
+ Precision: 1,
1606
+ },
1607
+ {
1608
+ Name: "system_model",
1609
+ Algorithm: module.Absolute,
1610
+ Mul: 1,
1611
+ Div: 1000,
1612
+ Precision: 1,
1613
+ },
1614
+ {
1615
+ Name: "system_status",
1616
+ Algorithm: module.Absolute,
1617
+ Mul: 1,
1618
+ Div: 1000,
1619
+ Precision: 1,
1620
+ },
1621
+ {
1622
+ Name: "temp_storage_named",
1623
+ Algorithm: module.Absolute,
1624
+ Mul: 1,
1625
+ Div: 1000,
1626
+ Precision: 1,
1627
+ },
1628
+ {
1629
+ Name: "temp_storage_total",
1630
+ Algorithm: module.Absolute,
1631
+ Mul: 1,
1632
+ Div: 1000,
1633
+ Precision: 1,
1634
+ },
1635
+ {
1636
+ Name: "technology_refresh_level",
1637
+ Algorithm: module.Absolute,
1638
+ Mul: 1,
1639
+ Div: 1000,
1640
+ Precision: 1,
1641
+ },
1642
+ {
1643
+ Name: "top_active_jobs",
1644
+ Algorithm: module.Absolute,
1645
+ Mul: 1,
1646
+ Div: 1000,
1647
+ Precision: 1,
1648
+ },
1649
+ {
1650
+ Name: "other",
1651
+ Algorithm: module.Absolute,
1652
+ Mul: 1,
1653
+ Div: 1000,
1654
+ Precision: 1,
1655
+ },
1656
+ },
1657
+ LabelKeys: []string{},
1658
+ },
1659
+ },
1660
+}
1661
+
1662
// --- OutputQueue ---
1663
1664
// OutputQueueFilesValues defines the type-safe values for OutputQueue.Files context
@@ -1658,6 +1988,28 @@ func (c SystemCPUUtilizationContext) SetUpdateEvery(state *framework.CollectorSt
1988
state.SetUpdateEveryOverrideForGeneratedCode(&c.Context, nil, updateEvery)
1989
}
1990
1991
+// SystemCPUEntitledUtilizationValues defines the type-safe values for System.CPUEntitledUtilization context
1992
+type SystemCPUEntitledUtilizationValues struct {
1993
+ Utilization int64
1994
+}
1995
+
1996
+// SystemCPUEntitledUtilizationContext provides type-safe operations for System.CPUEntitledUtilization context
1997
+type SystemCPUEntitledUtilizationContext struct {
1998
+ framework.Context[EmptyLabels]
1999
+}
2000
+
2001
+// Set provides type-safe dimension setting for System.CPUEntitledUtilization context
2002
+func (c SystemCPUEntitledUtilizationContext) Set(state *framework.CollectorState, labels EmptyLabels, values SystemCPUEntitledUtilizationValues) {
2003
+ state.SetMetricsForGeneratedCode(&c.Context, nil, map[string]int64{
2004
+ "utilization": values.Utilization,
2005
+ })
2006
+}
2007
+
2008
+// SetUpdateEvery sets the update interval for this instance
2009
+func (c SystemCPUEntitledUtilizationContext) SetUpdateEvery(state *framework.CollectorState, labels EmptyLabels, updateEvery int) {
2010
+ state.SetUpdateEveryOverrideForGeneratedCode(&c.Context, nil, updateEvery)
2011
+}
2012
+
2013
// SystemCPUDetailsValues defines the type-safe values for System.CPUDetails context
2014
type SystemCPUDetailsValues struct {
2015
Configured int64
@@ -2177,6 +2529,7 @@ func (c SystemSystemActivityCPUUtilizationContext) SetUpdateEvery(state *framewo
2529
// System contains all metric contexts for System
2530
var System = struct {
2531
CPUUtilization SystemCPUUtilizationContext
2532
+ CPUEntitledUtilization SystemCPUEntitledUtilizationContext
2533
CPUDetails SystemCPUDetailsContext
2534
CPUCapacity SystemCPUCapacityContext
2535
TotalJobs SystemTotalJobsContext
@@ -2221,6 +2574,27 @@ var System = struct {
2574
LabelKeys: []string{},
2575
},
2576
},
2577
+ CPUEntitledUtilization: SystemCPUEntitledUtilizationContext{
2578
+ Context: framework.Context[EmptyLabels]{
2579
+ Name: "as400.cpu_utilization_entitled",
2580
+ Family: "compute/cpu",
2581
+ Title: "CPU Utilization (as % of entitlement)",
2582
+ Units: "percentage",
2583
+ Type: module.Line,
2584
+ Priority: 102,
2585
+ UpdateEvery: 1,
2586
+ Dimensions: []framework.Dimension{
2587
+ {
2588
+ Name: "utilization",
2589
+ Algorithm: module.Absolute,
2590
+ Mul: 1,
2591
+ Div: 1000,
2592
+ Precision: 1,
2593
+ },
2594
+ },
2595
+ LabelKeys: []string{},
2596
+ },
2597
+ },
2598
CPUDetails: SystemCPUDetailsContext{
2599
Context: framework.Context[EmptyLabels]{
2600
Name: "as400.cpu_configuration",
@@ -2894,12 +3268,14 @@ func GetAllContexts() []interface{} {
3268
&MessageQueue.Severity.Context,
3269
&NetworkInterface.Status.Context,
3270
&NetworkInterface.MTU.Context,
3271
+ &Observability.QueryLatency.Context,
3272
&OutputQueue.Files.Context,
3273
&OutputQueue.Writers.Context,
3274
&OutputQueue.Status.Context,
3275
&PlanCache.Summary.Context,
3276
&Subsystem.Jobs.Context,
3277
&System.CPUUtilization.Context,
3278
+ &System.CPUEntitledUtilization.Context,
3279
&System.CPUDetails.Context,
3280
&System.CPUCapacity.Context,
3281
&System.TotalJobs.Context,
src/go/plugin/ibm.d/modules/as400/helpers.go
+4
-4
@@ -51,7 +51,7 @@ func (c *Collector) collectSingleMetric(ctx context.Context, metricKey string, q
51
return nil
52
}
53
54
- err := c.doQuery(ctx, query, func(column, value string, lineEnd bool) {
54
+ err := c.doQuery(ctx, metricKey, query, func(column, value string, lineEnd bool) {
55
if value != "" {
56
handler(value)
57
}
@@ -70,7 +70,7 @@ func (c *Collector) detectIBMiVersion(ctx context.Context) error {
70
var version, release string
71
versionDetected := false
72
73
- err := c.doQuery(ctx, queryIBMiVersion, func(column, value string, lineEnd bool) {
73
+ err := c.doQuery(ctx, "detect_ibmi_version_primary", queryIBMiVersion, func(column, value string, lineEnd bool) {
74
switch column {
75
case "OS_NAME":
76
// ignore
@@ -88,7 +88,7 @@ func (c *Collector) detectIBMiVersion(ctx context.Context) error {
88
} else if err != nil {
89
c.Debugf("ENV_SYS_INFO query failed: %v, trying fallback method", err)
90
91
- err = c.doQuery(ctx, queryIBMiVersionDataArea, func(column, value string, lineEnd bool) {
91
+ err = c.doQuery(ctx, "detect_ibmi_version_fallback", queryIBMiVersionDataArea, func(column, value string, lineEnd bool) {
92
if column == "VERSION" {
93
dataAreaValue := strings.TrimSpace(value)
94
if len(dataAreaValue) >= 6 {
@@ -131,7 +131,7 @@ func (c *Collector) collectSystemInfo(ctx context.Context) {
131
c.Debugf("detected system model: %s", c.model)
132
})
133
134
- err := c.doQuery(ctx, queryTechnologyRefresh, func(column, value string, lineEnd bool) {
134
+ err := c.doQuery(ctx, "technology_refresh_level", queryTechnologyRefresh, func(column, value string, lineEnd bool) {
135
if column == "TR_LEVEL" && value != "" {
136
trLevel := strings.TrimSpace(value)
137
if trLevel != "" {
src/go/plugin/ibm.d/modules/as400/metadata.yaml
+43
@@ -451,6 +451,12 @@ modules:
451
chart_type: line
452
dimensions:
453
- name: utilization
454
+ - name: as400.cpu_utilization_entitled
455
+ description: CPU Utilization (as % of entitlement)
456
+ unit: percentage
457
+ chart_type: line
458
+ dimensions:
459
+ - name: utilization
460
- name: as400.cpu_configuration
461
description: CPU Configuration
462
unit: cpus
@@ -599,6 +605,43 @@ modules:
605
- name: average
606
- name: minimum
607
- name: maximum
608
+ - name: netdata.plugin_ibm.as400_query_latency
609
+ description: Query Collection Latency
610
+ unit: ms
611
+ chart_type: stacked
612
+ dimensions:
613
+ - name: analyze_plan_cache
614
+ - name: count_active_jobs
615
+ - name: count_disks
616
+ - name: count_http_servers
617
+ - name: count_job_queues
618
+ - name: count_message_queues
619
+ - name: count_network_interfaces
620
+ - name: count_output_queues
621
+ - name: count_subsystems
622
+ - name: detect_ibmi_version_primary
623
+ - name: detect_ibmi_version_fallback
624
+ - name: disk_instances
625
+ - name: disk_instances_enhanced
626
+ - name: disk_status
627
+ - name: http_server_info
628
+ - name: job_info
629
+ - name: job_queues
630
+ - name: memory_pools
631
+ - name: message_queue_aggregates
632
+ - name: network_connections
633
+ - name: network_interfaces
634
+ - name: output_queue_info
635
+ - name: plan_cache_summary
636
+ - name: serial_number
637
+ - name: system_activity
638
+ - name: system_model
639
+ - name: system_status
640
+ - name: temp_storage_named
641
+ - name: temp_storage_total
642
+ - name: technology_refresh_level
643
+ - name: top_active_jobs
644
+ - name: other
645
- name: tempstoragebucket
646
description: These metrics refer to tempstoragebucket instances.
647
labels:
src/go/plugin/ibm.d/modules/as400/metrics.go
+6
-3
@@ -7,9 +7,10 @@ package as400
7
8
type metricsData struct {
9
// CPU metrics from SYSTEM_STATUS()
10
- CPUPercentage int64 `stm:"cpu_percentage"` // AVERAGE_CPU_UTILIZATION
11
- CurrentCPUCapacity int64 `stm:"current_cpu_capacity"` // CURRENT_CPU_CAPACITY
12
- ConfiguredCPUs int64 `stm:"configured_cpus"` // CONFIGURED_CPUS
10
+ CPUPercentage int64 `stm:"cpu_percentage"` // AVERAGE_CPU_UTILIZATION
11
+ CurrentCPUCapacity int64 `stm:"current_cpu_capacity"` // CURRENT_CPU_CAPACITY
12
+ ConfiguredCPUs int64 `stm:"configured_cpus"` // CONFIGURED_CPUS
13
+ EntitledCPUPercentage int64 `stm:"entitled_cpu_percentage"`
14
15
// Memory metrics from SYSTEM_STATUS()
16
MainStorageSize int64 `stm:"main_storage_size"` // MAIN_STORAGE_SIZE (KB)
@@ -76,6 +77,8 @@ type metricsData struct {
77
httpServers map[string]httpServerInstanceMetrics
78
planCache map[string]planCacheInstanceMetrics
79
systemActivity systemActivityMetrics
80
+
81
+ queryLatencies map[string]int64 `stm:"-"`
82
}
83
84
// Per-instance metric structures for stm conversion