From f9bf87ea28c388dfb0575331739e732af81639ac Mon Sep 17 00:00:00 2001 From: Benjamin Drung Date: Wed, 27 Oct 2021 13:56:37 +0200 Subject: [PATCH] Add DMI collector (#2131) Add a DMI collector to expose the Desktop Management Interface (DMI) info from `/sys/class/dmi/id/`. This will expose information about the BIOS, mainboard, chassis, and product. Closes: https://github.com/prometheus/node_exporter/issues/303 Signed-off-by: Benjamin Drung --- CHANGELOG.md | 1 + README.md | 1 + collector/dmi.go | 105 +++++++++++++++++++ collector/fixtures/e2e-64k-page-output.txt | 4 + collector/fixtures/e2e-output.txt | 4 + collector/fixtures/sys.ttar | 116 +++++++++++++++++++++ go.mod | 2 +- go.sum | 4 +- 8 files changed, 234 insertions(+), 3 deletions(-) create mode 100644 collector/dmi.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ea3142623..3fd2407883 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * [BUGFIX] * [ENHANCEMENT] Add flag to disable guest CPU metrics #2123 +* [ENHANCEMENT] Add DMI collector #303 * [BUGFIX] Fix possible panic on macOS #2133 ## 1.2.2 / 2021-08-06 diff --git a/README.md b/README.md index 5c8bf07797..a586128dda 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ conntrack | Shows conntrack statistics (does nothing if no `/proc/sys/net/netfil cpu | Exposes CPU statistics | Darwin, Dragonfly, FreeBSD, Linux, Solaris, OpenBSD cpufreq | Exposes CPU frequency statistics | Linux, Solaris diskstats | Exposes disk I/O statistics. | Darwin, Linux, OpenBSD +dmi | Expose Desktop Management Interface (DMI) info from `/sys/class/dmi/id/` | Linux edac | Exposes error detection and correction statistics. | Linux entropy | Exposes available entropy. | Linux exec | Exposes execution statistics. | Dragonfly, FreeBSD diff --git a/collector/dmi.go b/collector/dmi.go new file mode 100644 index 0000000000..3cc2a8a517 --- /dev/null +++ b/collector/dmi.go @@ -0,0 +1,105 @@ +// Copyright 2021 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. + +//go:build linux && !nodmi +// +build linux,!nodmi + +package collector + +import ( + "errors" + "fmt" + "os" + + "github.com/go-kit/log" + "github.com/go-kit/log/level" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/procfs/sysfs" +) + +type dmiCollector struct { + infoDesc *prometheus.Desc + values []string +} + +func init() { + registerCollector("dmi", defaultEnabled, NewDMICollector) +} + +// NewDMICollector returns a new Collector exposing DMI information. +func NewDMICollector(logger log.Logger) (Collector, error) { + fs, err := sysfs.NewFS(*sysPath) + if err != nil { + return nil, fmt.Errorf("failed to open sysfs: %w", err) + } + + dmi, err := fs.DMIClass() + if err != nil { + if errors.Is(err, os.ErrNotExist) { + level.Debug(logger).Log("msg", "Platform does not support Desktop Management Interface (DMI) information", "err", err) + dmi = &sysfs.DMIClass{} + } else { + return nil, fmt.Errorf("failed to read Desktop Management Interface (DMI) information: %w", err) + } + } + + var labels, values []string + for label, value := range map[string]*string{ + "bios_date": dmi.BiosDate, + "bios_release": dmi.BiosRelease, + "bios_vendor": dmi.BiosVendor, + "bios_version": dmi.BiosVersion, + "board_asset_tag": dmi.BoardAssetTag, + "board_name": dmi.BoardName, + "board_serial": dmi.BoardSerial, + "board_vendor": dmi.BoardVendor, + "board_version": dmi.BoardVersion, + "chassis_asset_tag": dmi.ChassisAssetTag, + "chassis_serial": dmi.ChassisSerial, + "chassis_vendor": dmi.ChassisVendor, + "chassis_version": dmi.ChassisVersion, + "product_family": dmi.ProductFamily, + "product_name": dmi.ProductName, + "product_serial": dmi.ProductSerial, + "product_sku": dmi.ProductSKU, + "product_uuid": dmi.ProductUUID, + "product_version": dmi.ProductVersion, + "system_vendor": dmi.SystemVendor, + } { + if value != nil { + labels = append(labels, label) + values = append(values, *value) + } + } + + // Construct DMI metric only once since it will not change until the next reboot. + return &dmiCollector{ + infoDesc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "dmi", "info"), + "A metric with a constant '1' value labeled by bios_date, bios_release, bios_vendor, bios_version, "+ + "board_asset_tag, board_name, board_serial, board_vendor, board_version, chassis_asset_tag, "+ + "chassis_serial, chassis_vendor, chassis_version, product_family, product_name, product_serial, "+ + "product_sku, product_uuid, product_version, system_vendor if provided by DMI.", + labels, nil, + ), + values: values, + }, nil +} + +func (c *dmiCollector) Update(ch chan<- prometheus.Metric) error { + if len(c.values) == 0 { + return ErrNoData + } + ch <- prometheus.MustNewConstMetric(c.infoDesc, prometheus.GaugeValue, 1.0, c.values...) + return nil +} diff --git a/collector/fixtures/e2e-64k-page-output.txt b/collector/fixtures/e2e-64k-page-output.txt index ec900bc061..845a9089b9 100644 --- a/collector/fixtures/e2e-64k-page-output.txt +++ b/collector/fixtures/e2e-64k-page-output.txt @@ -506,6 +506,9 @@ node_disk_written_bytes_total{device="sda"} 2.58916880384e+11 node_disk_written_bytes_total{device="sdb"} 1.01012736e+09 node_disk_written_bytes_total{device="sr0"} 0 node_disk_written_bytes_total{device="vda"} 1.0938236928e+11 +# HELP node_dmi_info A metric with a constant '1' value labeled by bios_date, bios_release, bios_vendor, bios_version, board_asset_tag, board_name, board_serial, board_vendor, board_version, chassis_asset_tag, chassis_serial, chassis_vendor, chassis_version, product_family, product_name, product_serial, product_sku, product_uuid, product_version, system_vendor if provided by DMI. +# TYPE node_dmi_info gauge +node_dmi_info{bios_date="04/12/2021",bios_release="2.2",bios_vendor="Dell Inc.",bios_version="2.2.4",board_name="07PXPY",board_serial=".7N62AI2.GRTCL6944100GP.",board_vendor="Dell Inc.",board_version="A01",chassis_asset_tag="",chassis_serial="7N62AI2",chassis_vendor="Dell Inc.",chassis_version="",product_family="PowerEdge",product_name="PowerEdge R6515",product_serial="7N62AI2",product_sku="SKU=NotProvided;ModelName=PowerEdge R6515",product_uuid="83340ca8-cb49-4474-8c29-d2088ca84dd9",product_version="",system_vendor="Dell Inc."} 1 # HELP node_drbd_activitylog_writes_total Number of updates of the activity log area of the meta data. # TYPE node_drbd_activitylog_writes_total counter node_drbd_activitylog_writes_total{device="drbd1"} 1100 @@ -2576,6 +2579,7 @@ node_scrape_collector_success{collector="conntrack"} 1 node_scrape_collector_success{collector="cpu"} 1 node_scrape_collector_success{collector="cpufreq"} 1 node_scrape_collector_success{collector="diskstats"} 1 +node_scrape_collector_success{collector="dmi"} 1 node_scrape_collector_success{collector="drbd"} 1 node_scrape_collector_success{collector="edac"} 1 node_scrape_collector_success{collector="entropy"} 1 diff --git a/collector/fixtures/e2e-output.txt b/collector/fixtures/e2e-output.txt index 4c954f8d77..391377c4ce 100644 --- a/collector/fixtures/e2e-output.txt +++ b/collector/fixtures/e2e-output.txt @@ -876,6 +876,9 @@ node_disk_written_bytes_total{device="sdb"} 1.01012736e+09 node_disk_written_bytes_total{device="sdc"} 8.852736e+07 node_disk_written_bytes_total{device="sr0"} 0 node_disk_written_bytes_total{device="vda"} 1.0938236928e+11 +# HELP node_dmi_info A metric with a constant '1' value labeled by bios_date, bios_release, bios_vendor, bios_version, board_asset_tag, board_name, board_serial, board_vendor, board_version, chassis_asset_tag, chassis_serial, chassis_vendor, chassis_version, product_family, product_name, product_serial, product_sku, product_uuid, product_version, system_vendor if provided by DMI. +# TYPE node_dmi_info gauge +node_dmi_info{bios_date="04/12/2021",bios_release="2.2",bios_vendor="Dell Inc.",bios_version="2.2.4",board_name="07PXPY",board_serial=".7N62AI2.GRTCL6944100GP.",board_vendor="Dell Inc.",board_version="A01",chassis_asset_tag="",chassis_serial="7N62AI2",chassis_vendor="Dell Inc.",chassis_version="",product_family="PowerEdge",product_name="PowerEdge R6515",product_serial="7N62AI2",product_sku="SKU=NotProvided;ModelName=PowerEdge R6515",product_uuid="83340ca8-cb49-4474-8c29-d2088ca84dd9",product_version="",system_vendor="Dell Inc."} 1 # HELP node_drbd_activitylog_writes_total Number of updates of the activity log area of the meta data. # TYPE node_drbd_activitylog_writes_total counter node_drbd_activitylog_writes_total{device="drbd1"} 1100 @@ -3240,6 +3243,7 @@ node_scrape_collector_success{collector="conntrack"} 1 node_scrape_collector_success{collector="cpu"} 1 node_scrape_collector_success{collector="cpufreq"} 1 node_scrape_collector_success{collector="diskstats"} 1 +node_scrape_collector_success{collector="dmi"} 1 node_scrape_collector_success{collector="drbd"} 1 node_scrape_collector_success{collector="edac"} 1 node_scrape_collector_success{collector="entropy"} 1 diff --git a/collector/fixtures/sys.ttar b/collector/fixtures/sys.ttar index fc03e1228e..6e9ebe51ef 100644 --- a/collector/fixtures/sys.ttar +++ b/collector/fixtures/sys.ttar @@ -38,6 +38,122 @@ SymlinkTo: ../../../devices/system/node/node1 Directory: sys/class Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: sys/class/dmi +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: sys/class/dmi/id +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/bios_date +Lines: 1 +04/12/2021 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/bios_release +Lines: 1 +2.2 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/bios_vendor +Lines: 1 +Dell Inc. +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/bios_version +Lines: 1 +2.2.4 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/board_name +Lines: 1 +07PXPY +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/board_serial +Lines: 1 +.7N62AI2.GRTCL6944100GP. +Mode: 400 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/board_vendor +Lines: 1 +Dell Inc. +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/board_version +Lines: 1 +A01 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/chassis_asset_tag +Lines: 1 + +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/chassis_serial +Lines: 1 +7N62AI2 +Mode: 400 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/chassis_type +Lines: 1 +23 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/chassis_vendor +Lines: 1 +Dell Inc. +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/chassis_version +Lines: 1 + +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/modalias +Lines: 1 +dmi:bvnDellInc.:bvr2.2.4:bd04/12/2021:br2.2:svnDellInc.:pnPowerEdgeR6515:pvr:rvnDellInc.:rn07PXPY:rvrA01:cvnDellInc.:ct23:cvr: +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/product_family +Lines: 1 +PowerEdge +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/product_name +Lines: 1 +PowerEdge R6515 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/product_serial +Lines: 1 +7N62AI2 +Mode: 400 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/product_sku +Lines: 1 +SKU=NotProvided;ModelName=PowerEdge R6515 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/product_uuid +Lines: 1 +83340ca8-cb49-4474-8c29-d2088ca84dd9 +Mode: 400 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/product_version +Lines: 1 + +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/sys_vendor +Lines: 1 +Dell Inc. +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: sys/class/dmi/id/uevent +Lines: 1 +MODALIAS=dmi:bvnDellInc.:bvr2.2.4:bd04/12/2021:br2.2:svnDellInc.:pnPowerEdgeR6515:pvr:rvnDellInc.:rn07PXPY:rvrA01:cvnDellInc.:ct23:cvr: +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: sys/class/fc_host Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/go.mod b/go.mod index 81f80dd44a..e0a752565f 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/prometheus/client_model v0.2.0 github.com/prometheus/common v0.31.1 github.com/prometheus/exporter-toolkit v0.6.1 - github.com/prometheus/procfs v0.7.3 + github.com/prometheus/procfs v0.7.4-0.20211011103944-1a7a2bd3279f github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1 github.com/siebenmann/go-kstat v0.0.0-20210513183136-173c9b0a9973 // indirect github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a diff --git a/go.sum b/go.sum index 78cf609007..4704703e34 100644 --- a/go.sum +++ b/go.sum @@ -241,8 +241,8 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.4-0.20211011103944-1a7a2bd3279f h1:ncXqc93eJV1Ncr3f6GA3MrIDNkNHvcPonRC2QgZaVkQ= +github.com/prometheus/procfs v0.7.4-0.20211011103944-1a7a2bd3279f/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/promu v0.2.0 h1:QKoCatPW0XeOG/9ghBv4qESc4G74NHCzuIzsm6SLVt4= github.com/prometheus/promu v0.2.0/go.mod h1:7vT+16au8n5E4UrtokdU7btmuJ1bF9df9F9s79Cgs3E= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=