| 
									
										
										
										
											2022-05-13 00:19:19 -07:00
										 |  |  | // Copyright 2022 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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 06:29:03 -07:00
										 |  |  | //go:build !noslabinfo
 | 
					
						
							|  |  |  | // +build !noslabinfo
 | 
					
						
							| 
									
										
										
										
											2022-05-13 00:19:19 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | package collector | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 	"log/slog" | 
					
						
							| 
									
										
										
										
											2022-05-13 00:19:19 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-06 09:37:22 -07:00
										 |  |  | 	"github.com/alecthomas/kingpin/v2" | 
					
						
							| 
									
										
										
										
											2022-05-13 00:19:19 -07:00
										 |  |  | 	"github.com/prometheus/client_golang/prometheus" | 
					
						
							|  |  |  | 	"github.com/prometheus/procfs" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-06 09:37:22 -07:00
										 |  |  | var ( | 
					
						
							|  |  |  | 	slabNameInclude = kingpin.Flag("collector.slabinfo.slabs-include", "Regexp of slabs to include in slabinfo collector.").Default(".*").String() | 
					
						
							|  |  |  | 	slabNameExclude = kingpin.Flag("collector.slabinfo.slabs-exclude", "Regexp of slabs to exclude in slabinfo collector.").Default("").String() | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 00:19:19 -07:00
										 |  |  | type slabinfoCollector struct { | 
					
						
							| 
									
										
										
										
											2024-06-06 09:37:22 -07:00
										 |  |  | 	fs             procfs.FS | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 	logger         *slog.Logger | 
					
						
							| 
									
										
										
										
											2024-06-06 09:37:22 -07:00
										 |  |  | 	subsystem      string | 
					
						
							|  |  |  | 	labels         []string | 
					
						
							|  |  |  | 	slabNameFilter deviceFilter | 
					
						
							| 
									
										
										
										
											2022-05-13 00:19:19 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func init() { | 
					
						
							|  |  |  | 	registerCollector("slabinfo", defaultDisabled, NewSlabinfoCollector) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | func NewSlabinfoCollector(logger *slog.Logger) (Collector, error) { | 
					
						
							| 
									
										
										
										
											2022-05-13 00:19:19 -07:00
										 |  |  | 	fs, err := procfs.NewFS(*procPath) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("failed to open procfs: %w", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return &slabinfoCollector{logger: logger, | 
					
						
							| 
									
										
										
										
											2024-06-06 09:37:22 -07:00
										 |  |  | 		fs:             fs, | 
					
						
							|  |  |  | 		subsystem:      "slabinfo", | 
					
						
							|  |  |  | 		labels:         []string{"slab"}, | 
					
						
							|  |  |  | 		slabNameFilter: newDeviceFilter(*slabNameExclude, *slabNameInclude), | 
					
						
							| 
									
										
										
										
											2022-05-13 00:19:19 -07:00
										 |  |  | 	}, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *slabinfoCollector) Update(ch chan<- prometheus.Metric) error { | 
					
						
							|  |  |  | 	slabinfo, err := c.fs.SlabInfo() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("couldn't get %s: %w", c.subsystem, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, slab := range slabinfo.Slabs { | 
					
						
							| 
									
										
										
										
											2024-06-06 09:37:22 -07:00
										 |  |  | 		if c.slabNameFilter.ignored(slab.Name) { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-05-13 00:19:19 -07:00
										 |  |  | 		ch <- c.activeObjects(slab.Name, slab.ObjActive) | 
					
						
							|  |  |  | 		ch <- c.objects(slab.Name, slab.ObjNum) | 
					
						
							|  |  |  | 		ch <- c.objectSizeBytes(slab.Name, slab.ObjSize) | 
					
						
							|  |  |  | 		ch <- c.objectsPerSlab(slab.Name, slab.ObjPerSlab) | 
					
						
							|  |  |  | 		ch <- c.pagesPerSlab(slab.Name, slab.PagesPerSlab) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *slabinfoCollector) activeObjects(label string, val int64) prometheus.Metric { | 
					
						
							|  |  |  | 	desc := prometheus.NewDesc( | 
					
						
							|  |  |  | 		prometheus.BuildFQName(namespace, c.subsystem, "active_objects"), | 
					
						
							|  |  |  | 		"The number of objects that are currently active (i.e., in use).", | 
					
						
							|  |  |  | 		c.labels, nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		desc, prometheus.GaugeValue, float64(val), label, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *slabinfoCollector) objects(label string, val int64) prometheus.Metric { | 
					
						
							|  |  |  | 	desc := prometheus.NewDesc( | 
					
						
							|  |  |  | 		prometheus.BuildFQName(namespace, c.subsystem, "objects"), | 
					
						
							|  |  |  | 		"The total number of allocated objects (i.e., objects that are both in use and not in use).", | 
					
						
							|  |  |  | 		c.labels, nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		desc, prometheus.GaugeValue, float64(val), label, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *slabinfoCollector) objectSizeBytes(label string, val int64) prometheus.Metric { | 
					
						
							|  |  |  | 	desc := prometheus.NewDesc( | 
					
						
							|  |  |  | 		prometheus.BuildFQName(namespace, c.subsystem, "object_size_bytes"), | 
					
						
							|  |  |  | 		"The size of objects in this slab, in bytes.", | 
					
						
							|  |  |  | 		c.labels, nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		desc, prometheus.GaugeValue, float64(val), label, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *slabinfoCollector) objectsPerSlab(label string, val int64) prometheus.Metric { | 
					
						
							|  |  |  | 	desc := prometheus.NewDesc( | 
					
						
							|  |  |  | 		prometheus.BuildFQName(namespace, c.subsystem, "objects_per_slab"), | 
					
						
							|  |  |  | 		"The number of objects stored in each slab.", | 
					
						
							|  |  |  | 		c.labels, nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		desc, prometheus.GaugeValue, float64(val), label, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *slabinfoCollector) pagesPerSlab(label string, val int64) prometheus.Metric { | 
					
						
							|  |  |  | 	desc := prometheus.NewDesc( | 
					
						
							|  |  |  | 		prometheus.BuildFQName(namespace, c.subsystem, "pages_per_slab"), | 
					
						
							|  |  |  | 		"The number of pages allocated for each slab.", | 
					
						
							|  |  |  | 		c.labels, nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return prometheus.MustNewConstMetric( | 
					
						
							|  |  |  | 		desc, prometheus.GaugeValue, float64(val), label, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } |