Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion collector/fixtures/e2e-64k-page-output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2825,7 +2825,22 @@ node_nfsd_server_rpcs_total 18628
node_nfsd_server_threads 8
# HELP node_nvme_info Non-numeric data from /sys/class/nvme/<device>, value is always 1.
# TYPE node_nvme_info gauge
node_nvme_info{device="nvme0",firmware_revision="1B2QEXP7",model="Samsung SSD 970 PRO 512GB",serial="S680HF8N190894I",state="live"} 1
node_nvme_info{cntlid="1997",device="nvme0",firmware_revision="1B2QEXP7",model="Samsung SSD 970 PRO 512GB",serial="S680HF8N190894I",state="live"} 1
# HELP node_nvme_namespace_capacity_bytes Capacity of the NVMe namespace in bytes. Computed as namespace_size * namespace_logical_block_size
# TYPE node_nvme_namespace_capacity_bytes gauge
node_nvme_namespace_capacity_bytes{device="nvme0",nsid="0"} 1.6e+13
# HELP node_nvme_namespace_info Information about NVMe namespaces. Value is always 1
# TYPE node_nvme_namespace_info gauge
node_nvme_namespace_info{ana_state="optimized",device="nvme0",nsid="0"} 1
# HELP node_nvme_namespace_logical_block_size_bytes Logical block size of the NVMe namespace in bytes. Usually 4Kb. Available in /sys/class/nvme/<device>/<namespace>/queue/logical_block_size
# TYPE node_nvme_namespace_logical_block_size_bytes gauge
node_nvme_namespace_logical_block_size_bytes{device="nvme0",nsid="0"} 4096
# HELP node_nvme_namespace_size_bytes Size of the NVMe namespace in bytes. Available in /sys/class/nvme/<device>/<namespace>/size
# TYPE node_nvme_namespace_size_bytes gauge
node_nvme_namespace_size_bytes{device="nvme0",nsid="0"} 1.6e+13
# HELP node_nvme_namespace_used_bytes Used space of the NVMe namespace in bytes. Available in /sys/class/nvme/<device>/<namespace>/nuse
# TYPE node_nvme_namespace_used_bytes gauge
node_nvme_namespace_used_bytes{device="nvme0",nsid="0"} 2e+12
# HELP node_os_info A metric with a constant '1' value labeled by build_id, id, id_like, image_id, image_version, name, pretty_name, variant, variant_id, version, version_codename, version_id.
# TYPE node_os_info gauge
node_os_info{build_id="",id="ubuntu",id_like="debian",image_id="",image_version="",name="Ubuntu",pretty_name="Ubuntu 20.04.2 LTS",variant="",variant_id="",version="20.04.2 LTS (Focal Fossa)",version_codename="focal",version_id="20.04"} 1
Expand Down
17 changes: 16 additions & 1 deletion collector/fixtures/e2e-output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2857,7 +2857,22 @@ node_nfsd_server_rpcs_total 18628
node_nfsd_server_threads 8
# HELP node_nvme_info Non-numeric data from /sys/class/nvme/<device>, value is always 1.
# TYPE node_nvme_info gauge
node_nvme_info{device="nvme0",firmware_revision="1B2QEXP7",model="Samsung SSD 970 PRO 512GB",serial="S680HF8N190894I",state="live"} 1
node_nvme_info{cntlid="1997",device="nvme0",firmware_revision="1B2QEXP7",model="Samsung SSD 970 PRO 512GB",serial="S680HF8N190894I",state="live"} 1
# HELP node_nvme_namespace_capacity_bytes Capacity of the NVMe namespace in bytes. Computed as namespace_size * namespace_logical_block_size
# TYPE node_nvme_namespace_capacity_bytes gauge
node_nvme_namespace_capacity_bytes{device="nvme0",nsid="0"} 1.6e+13
# HELP node_nvme_namespace_info Information about NVMe namespaces. Value is always 1
# TYPE node_nvme_namespace_info gauge
node_nvme_namespace_info{ana_state="optimized",device="nvme0",nsid="0"} 1
# HELP node_nvme_namespace_logical_block_size_bytes Logical block size of the NVMe namespace in bytes. Usually 4Kb. Available in /sys/class/nvme/<device>/<namespace>/queue/logical_block_size
# TYPE node_nvme_namespace_logical_block_size_bytes gauge
node_nvme_namespace_logical_block_size_bytes{device="nvme0",nsid="0"} 4096
# HELP node_nvme_namespace_size_bytes Size of the NVMe namespace in bytes. Available in /sys/class/nvme/<device>/<namespace>/size
# TYPE node_nvme_namespace_size_bytes gauge
node_nvme_namespace_size_bytes{device="nvme0",nsid="0"} 1.6e+13
# HELP node_nvme_namespace_used_bytes Used space of the NVMe namespace in bytes. Available in /sys/class/nvme/<device>/<namespace>/nuse
# TYPE node_nvme_namespace_used_bytes gauge
node_nvme_namespace_used_bytes{device="nvme0",nsid="0"} 2e+12
# HELP node_os_info A metric with a constant '1' value labeled by build_id, id, id_like, image_id, image_version, name, pretty_name, variant, variant_id, version, version_codename, version_id.
# TYPE node_os_info gauge
node_os_info{build_id="",id="ubuntu",id_like="debian",image_id="",image_version="",name="Ubuntu",pretty_name="Ubuntu 20.04.2 LTS",variant="",variant_id="",version="20.04.2 LTS (Focal Fossa)",version_codename="focal",version_id="20.04"} 1
Expand Down
26 changes: 26 additions & 0 deletions collector/fixtures/sys.ttar
Original file line number Diff line number Diff line change
Expand Up @@ -2229,6 +2229,32 @@ Lines: 1
live
Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: sys/class/nvme/nvme0/nvme0c0n0
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: sys/class/nvme/nvme0/nvme0c0n0/ana_state
Lines: 1
optimized
Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: sys/class/nvme/nvme0/nvme0c0n0/size
Lines: 1
3906250000
Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: sys/class/nvme/nvme0/nvme0c0n0/nuse
Lines: 1
488281250
Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: sys/class/nvme/nvme0/nvme0c0n0/queue
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: sys/class/nvme/nvme0/nvme0c0n0/queue/logical_block_size
Lines: 1
4096
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: sys/class/power_supply
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand Down
123 changes: 112 additions & 11 deletions collector/nvme_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,14 @@ import (
)

type nvmeCollector struct {
fs sysfs.FS
logger *slog.Logger
fs sysfs.FS
logger *slog.Logger
namespaceInfo *prometheus.Desc
namespaceCapacityBytes *prometheus.Desc
namespaceSizeBytes *prometheus.Desc
namespaceUsedBytes *prometheus.Desc
namespaceLogicalBlockSizeBytes *prometheus.Desc
info *prometheus.Desc
}

func init() {
Expand All @@ -41,9 +47,51 @@ func NewNVMeCollector(logger *slog.Logger) (Collector, error) {
return nil, fmt.Errorf("failed to open sysfs: %w", err)
}

info := prometheus.NewDesc(
prometheus.BuildFQName(namespace, "nvme", "info"),
"Non-numeric data from /sys/class/nvme/<device>, value is always 1.",
[]string{"device", "firmware_revision", "model", "serial", "state", "cntlid"},
nil,
)
namespaceInfo := prometheus.NewDesc(
prometheus.BuildFQName(namespace, "nvme", "namespace_info"),
"Information about NVMe namespaces. Value is always 1",
[]string{"device", "nsid", "ana_state"}, nil,
)

namespaceCapacityBytes := prometheus.NewDesc(
prometheus.BuildFQName(namespace, "nvme", "namespace_capacity_bytes"),
"Capacity of the NVMe namespace in bytes. Computed as namespace_size * namespace_logical_block_size",
[]string{"device", "nsid"}, nil,
)

namespaceSizeBytes := prometheus.NewDesc(
prometheus.BuildFQName(namespace, "nvme", "namespace_size_bytes"),
"Size of the NVMe namespace in bytes. Available in /sys/class/nvme/<device>/<namespace>/size",
[]string{"device", "nsid"}, nil,
)

namespaceUsedBytes := prometheus.NewDesc(
prometheus.BuildFQName(namespace, "nvme", "namespace_used_bytes"),
"Used space of the NVMe namespace in bytes. Available in /sys/class/nvme/<device>/<namespace>/nuse",
[]string{"device", "nsid"}, nil,
)

namespaceLogicalBlockSizeBytes := prometheus.NewDesc(
prometheus.BuildFQName(namespace, "nvme", "namespace_logical_block_size_bytes"),
"Logical block size of the NVMe namespace in bytes. Usually 4Kb. Available in /sys/class/nvme/<device>/<namespace>/queue/logical_block_size",
[]string{"device", "nsid"}, nil,
)

return &nvmeCollector{
fs: fs,
logger: logger,
fs: fs,
logger: logger,
namespaceInfo: namespaceInfo,
namespaceCapacityBytes: namespaceCapacityBytes,
namespaceSizeBytes: namespaceSizeBytes,
namespaceUsedBytes: namespaceUsedBytes,
namespaceLogicalBlockSizeBytes: namespaceLogicalBlockSizeBytes,
info: info,
}, nil
}

Expand All @@ -58,14 +106,67 @@ func (c *nvmeCollector) Update(ch chan<- prometheus.Metric) error {
}

for _, device := range devices {
infoDesc := prometheus.NewDesc(
prometheus.BuildFQName(namespace, "nvme", "info"),
"Non-numeric data from /sys/class/nvme/<device>, value is always 1.",
[]string{"device", "firmware_revision", "model", "serial", "state"},
nil,
// Export device-level metrics
ch <- prometheus.MustNewConstMetric(
c.info,
prometheus.GaugeValue,
1.0,
device.Name,
device.FirmwareRevision,
device.Model,
device.Serial,
device.State,
device.ControllerID,
)
infoValue := 1.0
ch <- prometheus.MustNewConstMetric(infoDesc, prometheus.GaugeValue, infoValue, device.Name, device.FirmwareRevision, device.Model, device.Serial, device.State)

// Export namespace-level metrics
for _, namespace := range device.Namespaces {
// Namespace info metric
ch <- prometheus.MustNewConstMetric(
c.namespaceInfo,
prometheus.GaugeValue,
1.0,
device.Name,
namespace.ID,
namespace.ANAState,
)

// Namespace capacity in bytes
ch <- prometheus.MustNewConstMetric(
c.namespaceCapacityBytes,
prometheus.GaugeValue,
float64(namespace.CapacityBytes),
device.Name,
namespace.ID,
)

// Namespace size in bytes
ch <- prometheus.MustNewConstMetric(
c.namespaceSizeBytes,
prometheus.GaugeValue,
float64(namespace.SizeBytes),
device.Name,
namespace.ID,
)

// Namespace used space in bytes
ch <- prometheus.MustNewConstMetric(
c.namespaceUsedBytes,
prometheus.GaugeValue,
float64(namespace.UsedBytes),
device.Name,
namespace.ID,
)

// Namespace logical block size in bytes
ch <- prometheus.MustNewConstMetric(
c.namespaceLogicalBlockSizeBytes,
prometheus.GaugeValue,
float64(namespace.LogicalBlockSize),
device.Name,
namespace.ID,
)
}
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ require (
github.com/prometheus/client_model v0.6.2
github.com/prometheus/common v0.67.5
github.com/prometheus/exporter-toolkit v0.15.1
github.com/prometheus/procfs v0.20.0
github.com/prometheus/procfs v0.20.1
github.com/safchain/ethtool v0.7.0
golang.org/x/sys v0.41.0
howett.net/plist v1.0.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTU
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/exporter-toolkit v0.15.1 h1:XrGGr/qWl8Gd+pqJqTkNLww9eG8vR/CoRk0FubOKfLE=
github.com/prometheus/exporter-toolkit v0.15.1/go.mod h1:P/NR9qFRGbCFgpklyhix9F6v6fFr/VQB/CVsrMDGKo4=
github.com/prometheus/procfs v0.20.0 h1:AA7aCvjxwAquZAlonN7888f2u4IN8WVeFgBi4k82M4Q=
github.com/prometheus/procfs v0.20.0/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/safchain/ethtool v0.7.0 h1:rlJzfDetsVvT61uz8x1YIcFn12akMfuPulHtZjtb7Is=
Expand Down
Loading