| 
									
										
										
										
											2015-09-26 08:36:40 -07:00
										 |  |  | // Copyright 2015 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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-03 04:35:24 -07:00
										 |  |  | //go:build !nodevstat
 | 
					
						
							| 
									
										
										
										
											2015-07-13 07:00:14 -07:00
										 |  |  | // +build !nodevstat
 | 
					
						
							| 
									
										
										
										
											2015-06-23 06:50:12 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | package collector | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"errors" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 	"log/slog" | 
					
						
							| 
									
										
										
										
											2016-12-30 22:23:55 -08:00
										 |  |  | 	"sync" | 
					
						
							| 
									
										
										
										
											2016-12-30 21:52:44 -08:00
										 |  |  | 	"unsafe" | 
					
						
							| 
									
										
										
										
											2015-06-23 06:50:12 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/prometheus/client_golang/prometheus" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-20 09:59:45 -07:00
										 |  |  | // #cgo LDFLAGS: -ldevstat -lkvm -lelf
 | 
					
						
							| 
									
										
										
										
											2016-12-30 19:15:25 -08:00
										 |  |  | // #include "devstat_freebsd.h"
 | 
					
						
							| 
									
										
										
										
											2015-06-23 06:50:12 -07:00
										 |  |  | import "C" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							|  |  |  | 	devstatSubsystem = "devstat" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type devstatCollector struct { | 
					
						
							| 
									
										
										
										
											2016-12-30 22:23:55 -08:00
										 |  |  | 	mu      sync.Mutex | 
					
						
							|  |  |  | 	devinfo *C.struct_devinfo | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-14 10:50:19 -07:00
										 |  |  | 	bytes     typedDesc | 
					
						
							|  |  |  | 	transfers typedDesc | 
					
						
							|  |  |  | 	duration  typedDesc | 
					
						
							|  |  |  | 	busyTime  typedDesc | 
					
						
							|  |  |  | 	blocks    typedDesc | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | 	logger    *slog.Logger | 
					
						
							| 
									
										
										
										
											2015-06-23 06:50:12 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func init() { | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 	registerCollector("devstat", defaultDisabled, NewDevstatCollector) | 
					
						
							| 
									
										
										
										
											2015-06-23 06:50:12 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-14 04:16:26 -07:00
										 |  |  | // NewDevstatCollector returns a new Collector exposing Device stats.
 | 
					
						
							| 
									
										
										
										
											2024-09-11 01:51:28 -07:00
										 |  |  | func NewDevstatCollector(logger *slog.Logger) (Collector, error) { | 
					
						
							| 
									
										
										
										
											2015-06-23 06:50:12 -07:00
										 |  |  | 	return &devstatCollector{ | 
					
						
							| 
									
										
										
										
											2016-12-30 22:23:55 -08:00
										 |  |  | 		devinfo: &C.struct_devinfo{}, | 
					
						
							| 
									
										
										
										
											2016-12-28 06:21:31 -08:00
										 |  |  | 		bytes: typedDesc{prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, devstatSubsystem, "bytes_total"), | 
					
						
							| 
									
										
										
										
											2016-12-28 06:21:31 -08:00
										 |  |  | 			"The total number of bytes in transactions.", | 
					
						
							|  |  |  | 			[]string{"device", "type"}, nil, | 
					
						
							|  |  |  | 		), prometheus.CounterValue}, | 
					
						
							|  |  |  | 		transfers: typedDesc{prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, devstatSubsystem, "transfers_total"), | 
					
						
							| 
									
										
										
										
											2016-12-28 06:21:31 -08:00
										 |  |  | 			"The total number of transactions.", | 
					
						
							|  |  |  | 			[]string{"device", "type"}, nil, | 
					
						
							|  |  |  | 		), prometheus.CounterValue}, | 
					
						
							|  |  |  | 		duration: typedDesc{prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, devstatSubsystem, "duration_seconds_total"), | 
					
						
							| 
									
										
										
										
											2016-12-28 06:21:31 -08:00
										 |  |  | 			"The total duration of transactions in seconds.", | 
					
						
							|  |  |  | 			[]string{"device", "type"}, nil, | 
					
						
							|  |  |  | 		), prometheus.CounterValue}, | 
					
						
							|  |  |  | 		busyTime: typedDesc{prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, devstatSubsystem, "busy_time_seconds_total"), | 
					
						
							| 
									
										
										
										
											2016-12-28 06:21:31 -08:00
										 |  |  | 			"Total time the device had one or more transactions outstanding in seconds.", | 
					
						
							|  |  |  | 			[]string{"device"}, nil, | 
					
						
							|  |  |  | 		), prometheus.CounterValue}, | 
					
						
							|  |  |  | 		blocks: typedDesc{prometheus.NewDesc( | 
					
						
							| 
									
										
										
										
											2017-09-28 06:06:26 -07:00
										 |  |  | 			prometheus.BuildFQName(namespace, devstatSubsystem, "blocks_transferred_total"), | 
					
						
							| 
									
										
										
										
											2016-12-28 06:21:31 -08:00
										 |  |  | 			"The total number of blocks transferred.", | 
					
						
							|  |  |  | 			[]string{"device"}, nil, | 
					
						
							|  |  |  | 		), prometheus.CounterValue}, | 
					
						
							| 
									
										
										
										
											2019-12-31 08:19:37 -08:00
										 |  |  | 		logger: logger, | 
					
						
							| 
									
										
										
										
											2015-06-23 06:50:12 -07:00
										 |  |  | 	}, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-30 21:52:44 -08:00
										 |  |  | func (c *devstatCollector) Update(ch chan<- prometheus.Metric) error { | 
					
						
							| 
									
										
										
										
											2016-12-30 22:23:55 -08:00
										 |  |  | 	c.mu.Lock() | 
					
						
							|  |  |  | 	defer c.mu.Unlock() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-30 21:52:44 -08:00
										 |  |  | 	var stats *C.Stats | 
					
						
							| 
									
										
										
										
											2016-12-30 22:23:55 -08:00
										 |  |  | 	n := C._get_stats(c.devinfo, &stats) | 
					
						
							| 
									
										
										
										
											2016-12-30 21:52:44 -08:00
										 |  |  | 	if n == -1 { | 
					
						
							|  |  |  | 		return errors.New("devstat_getdevs failed") | 
					
						
							| 
									
										
										
										
											2015-06-23 06:50:12 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-30 21:52:44 -08:00
										 |  |  | 	base := unsafe.Pointer(stats) | 
					
						
							|  |  |  | 	for i := C.int(0); i < n; i++ { | 
					
						
							|  |  |  | 		offset := i * C.int(C.sizeof_Stats) | 
					
						
							|  |  |  | 		stat := (*C.Stats)(unsafe.Pointer(uintptr(base) + uintptr(offset))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		device := fmt.Sprintf("%s%d", C.GoString(&stat.device[0]), stat.unit) | 
					
						
							|  |  |  | 		ch <- c.bytes.mustNewConstMetric(float64(stat.bytes.read), device, "read") | 
					
						
							|  |  |  | 		ch <- c.bytes.mustNewConstMetric(float64(stat.bytes.write), device, "write") | 
					
						
							|  |  |  | 		ch <- c.transfers.mustNewConstMetric(float64(stat.transfers.other), device, "other") | 
					
						
							|  |  |  | 		ch <- c.transfers.mustNewConstMetric(float64(stat.transfers.read), device, "read") | 
					
						
							|  |  |  | 		ch <- c.transfers.mustNewConstMetric(float64(stat.transfers.write), device, "write") | 
					
						
							|  |  |  | 		ch <- c.duration.mustNewConstMetric(float64(stat.duration.other), device, "other") | 
					
						
							|  |  |  | 		ch <- c.duration.mustNewConstMetric(float64(stat.duration.read), device, "read") | 
					
						
							|  |  |  | 		ch <- c.duration.mustNewConstMetric(float64(stat.duration.write), device, "write") | 
					
						
							|  |  |  | 		ch <- c.busyTime.mustNewConstMetric(float64(stat.busyTime), device) | 
					
						
							|  |  |  | 		ch <- c.blocks.mustNewConstMetric(float64(stat.blocks), device) | 
					
						
							| 
									
										
										
										
											2015-06-23 06:50:12 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-12-30 21:52:44 -08:00
										 |  |  | 	C.free(unsafe.Pointer(stats)) | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2015-06-23 06:50:12 -07:00
										 |  |  | } |