prometheusmetricshost-metricsmachine-metricsnode-metricsprocfsprometheus-exportersystem-informationsystem-metrics
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
9.4 KiB
239 lines
9.4 KiB
// Copyright 2020 The Prometheus 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. |
|
|
|
package collector |
|
|
|
import ( |
|
"fmt" |
|
"log/slog" |
|
"reflect" |
|
|
|
"github.com/prometheus/client_golang/prometheus" |
|
"github.com/prometheus/procfs" |
|
) |
|
|
|
const zoneinfoSubsystem = "zoneinfo" |
|
|
|
type zoneinfoCollector struct { |
|
gaugeMetricDescs map[string]*prometheus.Desc |
|
counterMetricDescs map[string]*prometheus.Desc |
|
logger *slog.Logger |
|
fs procfs.FS |
|
} |
|
|
|
func init() { |
|
registerCollector("zoneinfo", defaultDisabled, NewZoneinfoCollector) |
|
} |
|
|
|
// NewZoneinfoCollector returns a new Collector exposing zone stats. |
|
func NewZoneinfoCollector(logger *slog.Logger) (Collector, error) { |
|
fs, err := procfs.NewFS(*procPath) |
|
if err != nil { |
|
return nil, fmt.Errorf("failed to open procfs: %w", err) |
|
} |
|
return &zoneinfoCollector{ |
|
gaugeMetricDescs: createGaugeMetricDescriptions(), |
|
counterMetricDescs: createCounterMetricDescriptions(), |
|
logger: logger, |
|
fs: fs, |
|
}, nil |
|
} |
|
|
|
func (c *zoneinfoCollector) Update(ch chan<- prometheus.Metric) error { |
|
metrics, err := c.fs.Zoneinfo() |
|
if err != nil { |
|
return fmt.Errorf("couldn't get zoneinfo: %w", err) |
|
} |
|
for _, metric := range metrics { |
|
node := metric.Node |
|
zone := metric.Zone |
|
metricStruct := reflect.ValueOf(metric) |
|
typeOfMetricStruct := metricStruct.Type() |
|
for i := 0; i < metricStruct.NumField(); i++ { |
|
value := reflect.Indirect(metricStruct.Field(i)) |
|
if value.Kind() != reflect.Int64 { |
|
continue |
|
} |
|
metricName := typeOfMetricStruct.Field(i).Name |
|
desc, ok := c.gaugeMetricDescs[metricName] |
|
metricType := prometheus.GaugeValue |
|
if !ok { |
|
desc = c.counterMetricDescs[metricName] |
|
metricType = prometheus.CounterValue |
|
} |
|
ch <- prometheus.MustNewConstMetric(desc, metricType, |
|
float64(reflect.Indirect(metricStruct.Field(i)).Int()), |
|
node, zone) |
|
} |
|
for i, value := range metric.Protection { |
|
metricName := fmt.Sprintf("protection_%d", i) |
|
desc, ok := c.gaugeMetricDescs[metricName] |
|
if !ok { |
|
desc = prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, metricName), |
|
fmt.Sprintf("Protection array %d. field", i), |
|
[]string{"node", "zone"}, nil) |
|
c.gaugeMetricDescs[metricName] = desc |
|
} |
|
ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, |
|
float64(*value), node, zone) |
|
} |
|
|
|
} |
|
return nil |
|
} |
|
func createGaugeMetricDescriptions() map[string]*prometheus.Desc { |
|
return map[string]*prometheus.Desc{ |
|
"NrFreePages": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_free_pages"), |
|
"Total number of free pages in the zone", |
|
[]string{"node", "zone"}, nil), |
|
"Min": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "min_pages"), |
|
"Zone watermark pages_min", |
|
[]string{"node", "zone"}, nil), |
|
"Low": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "low_pages"), |
|
"Zone watermark pages_low", |
|
[]string{"node", "zone"}, nil), |
|
"High": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "high_pages"), |
|
"Zone watermark pages_high", |
|
[]string{"node", "zone"}, nil), |
|
"Scanned": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "scanned_pages"), |
|
"Pages scanned since last reclaim", |
|
[]string{"node", "zone"}, nil), |
|
"Spanned": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "spanned_pages"), |
|
"Total pages spanned by the zone, including holes", |
|
[]string{"node", "zone"}, nil), |
|
"Present": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "present_pages"), |
|
"Physical pages existing within the zone", |
|
[]string{"node", "zone"}, nil), |
|
"Managed": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "managed_pages"), |
|
"Present pages managed by the buddy system", |
|
[]string{"node", "zone"}, nil), |
|
"NrActiveAnon": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_active_anon_pages"), |
|
"Number of anonymous pages recently more used", |
|
[]string{"node", "zone"}, nil), |
|
"NrInactiveAnon": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_inactive_anon_pages"), |
|
"Number of anonymous pages recently less used", |
|
[]string{"node", "zone"}, nil), |
|
"NrIsolatedAnon": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_isolated_anon_pages"), |
|
"Temporary isolated pages from anon lru", |
|
[]string{"node", "zone"}, nil), |
|
"NrAnonPages": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_anon_pages"), |
|
"Number of anonymous pages currently used by the system", |
|
[]string{"node", "zone"}, nil), |
|
"NrAnonTransparentHugepages": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_anon_transparent_hugepages"), |
|
"Number of anonymous transparent huge pages currently used by the system", |
|
[]string{"node", "zone"}, nil), |
|
"NrActiveFile": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_active_file_pages"), |
|
"Number of active pages with file-backing", |
|
[]string{"node", "zone"}, nil), |
|
"NrInactiveFile": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_inactive_file_pages"), |
|
"Number of inactive pages with file-backing", |
|
[]string{"node", "zone"}, nil), |
|
"NrIsolatedFile": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_isolated_file_pages"), |
|
"Temporary isolated pages from file lru", |
|
[]string{"node", "zone"}, nil), |
|
"NrFilePages": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_file_pages"), |
|
"Number of file pages", |
|
[]string{"node", "zone"}, nil), |
|
"NrSlabReclaimable": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_slab_reclaimable_pages"), |
|
"Number of reclaimable slab pages", |
|
[]string{"node", "zone"}, nil), |
|
"NrSlabUnreclaimable": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_slab_unreclaimable_pages"), |
|
"Number of unreclaimable slab pages", |
|
[]string{"node", "zone"}, nil), |
|
"NrMlockStack": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_mlock_stack_pages"), |
|
"mlock()ed pages found and moved off LRU", |
|
[]string{"node", "zone"}, nil), |
|
"NrKernelStack": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_kernel_stacks"), |
|
"Number of kernel stacks", |
|
[]string{"node", "zone"}, nil), |
|
"NrMapped": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_mapped_pages"), |
|
"Number of mapped pages", |
|
[]string{"node", "zone"}, nil), |
|
"NrDirty": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_dirty_pages"), |
|
"Number of dirty pages", |
|
[]string{"node", "zone"}, nil), |
|
"NrWriteback": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_writeback_pages"), |
|
"Number of writeback pages", |
|
[]string{"node", "zone"}, nil), |
|
"NrUnevictable": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_unevictable_pages"), |
|
"Number of unevictable pages", |
|
[]string{"node", "zone"}, nil), |
|
"NrShmem": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_shmem_pages"), |
|
"Number of shmem pages (included tmpfs/GEM pages)", |
|
[]string{"node", "zone"}, nil), |
|
} |
|
|
|
} |
|
func createCounterMetricDescriptions() map[string]*prometheus.Desc { |
|
return map[string]*prometheus.Desc{ |
|
"NrDirtied": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_dirtied_total"), |
|
"Page dirtyings since bootup", |
|
[]string{"node", "zone"}, nil), |
|
"NrWritten": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "nr_written_total"), |
|
"Page writings since bootup", |
|
[]string{"node", "zone"}, nil), |
|
"NumaHit": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "numa_hit_total"), |
|
"Allocated in intended node", |
|
[]string{"node", "zone"}, nil), |
|
"NumaMiss": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "numa_miss_total"), |
|
"Allocated in non intended node", |
|
[]string{"node", "zone"}, nil), |
|
"NumaForeign": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "numa_foreign_total"), |
|
"Was intended here, hit elsewhere", |
|
[]string{"node", "zone"}, nil), |
|
"NumaInterleave": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "numa_interleave_total"), |
|
"Interleaver preferred this zone", |
|
[]string{"node", "zone"}, nil), |
|
"NumaLocal": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "numa_local_total"), |
|
"Allocation from local node", |
|
[]string{"node", "zone"}, nil), |
|
"NumaOther": prometheus.NewDesc( |
|
prometheus.BuildFQName(namespace, zoneinfoSubsystem, "numa_other_total"), |
|
"Allocation from other node", |
|
[]string{"node", "zone"}, nil), |
|
} |
|
}
|
|
|