mirror of
				https://github.com/prometheus/node_exporter.git
				synced 2025-08-20 18:33:52 -07:00 
			
		
		
		
	add diskstats on Darwin (#593)
* Add diskstats collector for Darwin * Update year in the header * Update README.md * Add github.com/lufia/iostat to vendored packages * Change stats to follow naming guidelines * Add a entry of github.com/lufia/iostat into vendor.json * Remove /proc/diskstats from description
This commit is contained in:
		
							parent
							
								
									ab3414e6fd
								
							
						
					
					
						commit
						a077024f51
					
				| 
						 | 
					@ -24,7 +24,7 @@ Name     | Description | OS
 | 
				
			||||||
arp | Exposes ARP statistics from `/proc/net/arp`. | Linux
 | 
					arp | Exposes ARP statistics from `/proc/net/arp`. | Linux
 | 
				
			||||||
conntrack | Shows conntrack statistics (does nothing if no `/proc/sys/net/netfilter/` present). | Linux
 | 
					conntrack | Shows conntrack statistics (does nothing if no `/proc/sys/net/netfilter/` present). | Linux
 | 
				
			||||||
cpu | Exposes CPU statistics | Darwin, Dragonfly, FreeBSD, Linux
 | 
					cpu | Exposes CPU statistics | Darwin, Dragonfly, FreeBSD, Linux
 | 
				
			||||||
diskstats | Exposes disk I/O statistics from `/proc/diskstats`. | Linux
 | 
					diskstats | Exposes disk I/O statistics. | Darwin, Linux
 | 
				
			||||||
edac | Exposes error detection and correction statistics. | Linux
 | 
					edac | Exposes error detection and correction statistics. | Linux
 | 
				
			||||||
entropy | Exposes available entropy. | Linux
 | 
					entropy | Exposes available entropy. | Linux
 | 
				
			||||||
exec | Exposes execution statistics. | Dragonfly, FreeBSD
 | 
					exec | Exposes execution statistics. | Dragonfly, FreeBSD
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										177
									
								
								collector/diskstats_darwin.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								collector/diskstats_darwin.go
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,177 @@
 | 
				
			||||||
 | 
					// Copyright 2017 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// +build !nodiskstats
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package collector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/lufia/iostat"
 | 
				
			||||||
 | 
						"github.com/prometheus/client_golang/prometheus"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						diskSubsystem = "disk"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type typedDescFunc struct {
 | 
				
			||||||
 | 
						typedDesc
 | 
				
			||||||
 | 
						value func(stat *iostat.DriveStats) float64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type diskstatsCollector struct {
 | 
				
			||||||
 | 
						descs []typedDescFunc
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						Factories["diskstats"] = NewDiskstatsCollector
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewDiskstatsCollector returns a new Collector exposing disk device stats.
 | 
				
			||||||
 | 
					func NewDiskstatsCollector() (Collector, error) {
 | 
				
			||||||
 | 
						var diskLabelNames = []string{"device"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &diskstatsCollector{
 | 
				
			||||||
 | 
							descs: []typedDescFunc{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									typedDesc: typedDesc{
 | 
				
			||||||
 | 
										desc: prometheus.NewDesc(
 | 
				
			||||||
 | 
											prometheus.BuildFQName(Namespace, diskSubsystem, "reads_completed_total"),
 | 
				
			||||||
 | 
											"The total number of reads completed successfully.",
 | 
				
			||||||
 | 
											diskLabelNames,
 | 
				
			||||||
 | 
											nil,
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
 | 
										valueType: prometheus.CounterValue,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									value: func(stat *iostat.DriveStats) float64 {
 | 
				
			||||||
 | 
										return float64(stat.NumRead)
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									typedDesc: typedDesc{
 | 
				
			||||||
 | 
										desc: prometheus.NewDesc(
 | 
				
			||||||
 | 
											prometheus.BuildFQName(Namespace, diskSubsystem, "read_sectors_total"),
 | 
				
			||||||
 | 
											"The total number of sectors read successfully.",
 | 
				
			||||||
 | 
											diskLabelNames,
 | 
				
			||||||
 | 
											nil,
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
 | 
										valueType: prometheus.CounterValue,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									value: func(stat *iostat.DriveStats) float64 {
 | 
				
			||||||
 | 
										return float64(stat.NumRead) / float64(stat.BlockSize)
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									typedDesc: typedDesc{
 | 
				
			||||||
 | 
										desc: prometheus.NewDesc(
 | 
				
			||||||
 | 
											prometheus.BuildFQName(Namespace, diskSubsystem, "read_seconds_total"),
 | 
				
			||||||
 | 
											"The total number of seconds spent by all reads.",
 | 
				
			||||||
 | 
											diskLabelNames,
 | 
				
			||||||
 | 
											nil,
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
 | 
										valueType: prometheus.CounterValue,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									value: func(stat *iostat.DriveStats) float64 {
 | 
				
			||||||
 | 
										return stat.TotalReadTime.Seconds()
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									typedDesc: typedDesc{
 | 
				
			||||||
 | 
										desc: prometheus.NewDesc(
 | 
				
			||||||
 | 
											prometheus.BuildFQName(Namespace, diskSubsystem, "writes_completed_total"),
 | 
				
			||||||
 | 
											"The total number of writes completed successfully.",
 | 
				
			||||||
 | 
											diskLabelNames,
 | 
				
			||||||
 | 
											nil,
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
 | 
										valueType: prometheus.CounterValue,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									value: func(stat *iostat.DriveStats) float64 {
 | 
				
			||||||
 | 
										return float64(stat.NumWrite)
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									typedDesc: typedDesc{
 | 
				
			||||||
 | 
										desc: prometheus.NewDesc(
 | 
				
			||||||
 | 
											prometheus.BuildFQName(Namespace, diskSubsystem, "written_sectors_total"),
 | 
				
			||||||
 | 
											"The total number of sectors written successfully.",
 | 
				
			||||||
 | 
											diskLabelNames,
 | 
				
			||||||
 | 
											nil,
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
 | 
										valueType: prometheus.CounterValue,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									value: func(stat *iostat.DriveStats) float64 {
 | 
				
			||||||
 | 
										return float64(stat.NumWrite) / float64(stat.BlockSize)
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									typedDesc: typedDesc{
 | 
				
			||||||
 | 
										desc: prometheus.NewDesc(
 | 
				
			||||||
 | 
											prometheus.BuildFQName(Namespace, diskSubsystem, "write_seconds_total"),
 | 
				
			||||||
 | 
											"This is the total number of seconds spent by all writes.",
 | 
				
			||||||
 | 
											diskLabelNames,
 | 
				
			||||||
 | 
											nil,
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
 | 
										valueType: prometheus.CounterValue,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									value: func(stat *iostat.DriveStats) float64 {
 | 
				
			||||||
 | 
										return stat.TotalWriteTime.Seconds()
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									typedDesc: typedDesc{
 | 
				
			||||||
 | 
										desc: prometheus.NewDesc(
 | 
				
			||||||
 | 
											prometheus.BuildFQName(Namespace, diskSubsystem, "read_bytes_total"),
 | 
				
			||||||
 | 
											"The total number of bytes read successfully.",
 | 
				
			||||||
 | 
											diskLabelNames,
 | 
				
			||||||
 | 
											nil,
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
 | 
										valueType: prometheus.CounterValue,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									value: func(stat *iostat.DriveStats) float64 {
 | 
				
			||||||
 | 
										return float64(stat.BytesRead)
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									typedDesc: typedDesc{
 | 
				
			||||||
 | 
										desc: prometheus.NewDesc(
 | 
				
			||||||
 | 
											prometheus.BuildFQName(Namespace, diskSubsystem, "written_bytes_total"),
 | 
				
			||||||
 | 
											"The total number of bytes written successfully.",
 | 
				
			||||||
 | 
											diskLabelNames,
 | 
				
			||||||
 | 
											nil,
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
 | 
										valueType: prometheus.CounterValue,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									value: func(stat *iostat.DriveStats) float64 {
 | 
				
			||||||
 | 
										return float64(stat.BytesWritten)
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
 | 
				
			||||||
 | 
						diskStats, err := iostat.ReadDriveStats()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("couldn't get diskstats: %s", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, stats := range diskStats {
 | 
				
			||||||
 | 
							for _, desc := range c.descs {
 | 
				
			||||||
 | 
								v := desc.value(stats)
 | 
				
			||||||
 | 
								ch <- desc.mustNewConstMetric(v, stats.Name)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								vendor/github.com/lufia/iostat/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/lufia/iostat/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					BSD 3-Clause License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (c) 2017, kadota kyohei
 | 
				
			||||||
 | 
					All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					modification, are permitted provided that the following conditions are met:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Redistributions of source code must retain the above copyright notice, this
 | 
				
			||||||
 | 
					  list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Redistributions in binary form must reproduce the above copyright notice,
 | 
				
			||||||
 | 
					  this list of conditions and the following disclaimer in the documentation
 | 
				
			||||||
 | 
					  and/or other materials provided with the distribution.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Neither the name of the copyright holder nor the names of its
 | 
				
			||||||
 | 
					  contributors may be used to endorse or promote products derived from
 | 
				
			||||||
 | 
					  this software without specific prior written permission.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
				
			||||||
 | 
					AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
				
			||||||
 | 
					IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
				
			||||||
 | 
					DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 | 
				
			||||||
 | 
					FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
				
			||||||
 | 
					DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
				
			||||||
 | 
					SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
				
			||||||
 | 
					CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
				
			||||||
 | 
					OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
				
			||||||
 | 
					OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
							
								
								
									
										7
									
								
								vendor/github.com/lufia/iostat/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/lufia/iostat/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					# iostat - reports I/O statistics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[](https://godoc.org/github.com/lufia/iostat)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*iostat* reports I/O statistics. currently supported OSes are:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* macOS
 | 
				
			||||||
							
								
								
									
										20
									
								
								vendor/github.com/lufia/iostat/iostat.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/lufia/iostat/iostat.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					// Package iostat presents I/O statistics.
 | 
				
			||||||
 | 
					package iostat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DriveStats represents I/O statistics of a drive.
 | 
				
			||||||
 | 
					type DriveStats struct {
 | 
				
			||||||
 | 
						Name      string // drive name
 | 
				
			||||||
 | 
						Size      int64  // total drive size in bytes
 | 
				
			||||||
 | 
						BlockSize int64  // block size in bytes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BytesRead      int64
 | 
				
			||||||
 | 
						BytesWritten   int64
 | 
				
			||||||
 | 
						NumRead        int64
 | 
				
			||||||
 | 
						NumWrite       int64
 | 
				
			||||||
 | 
						TotalReadTime  time.Duration
 | 
				
			||||||
 | 
						TotalWriteTime time.Duration
 | 
				
			||||||
 | 
						ReadLatency    time.Duration
 | 
				
			||||||
 | 
						WriteLatency   time.Duration
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										128
									
								
								vendor/github.com/lufia/iostat/iostat_darwin.c
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								vendor/github.com/lufia/iostat/iostat_darwin.c
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,128 @@
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include "iostat_darwin.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define IOKIT	1	/* to get io_name_t in device_types.h */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <CoreFoundation/CoreFoundation.h>
 | 
				
			||||||
 | 
					#include <IOKit/IOKitLib.h>
 | 
				
			||||||
 | 
					#include <IOKit/storage/IOBlockStorageDriver.h>
 | 
				
			||||||
 | 
					#include <IOKit/storage/IOMedia.h>
 | 
				
			||||||
 | 
					#include <IOKit/IOBSD.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int getdrivestat(io_registry_entry_t d, DriveStats *stat);
 | 
				
			||||||
 | 
					static int fillstat(io_registry_entry_t d, DriveStats *stat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					readdrivestat(DriveStats a[], int n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						mach_port_t port;
 | 
				
			||||||
 | 
						CFMutableDictionaryRef match;
 | 
				
			||||||
 | 
						io_iterator_t drives;
 | 
				
			||||||
 | 
						io_registry_entry_t d;
 | 
				
			||||||
 | 
						kern_return_t status;
 | 
				
			||||||
 | 
						int na, rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						IOMasterPort(bootstrap_port, &port);
 | 
				
			||||||
 | 
						match = IOServiceMatching("IOMedia");
 | 
				
			||||||
 | 
						CFDictionaryAddValue(match, CFSTR(kIOMediaWholeKey), kCFBooleanTrue);
 | 
				
			||||||
 | 
						status = IOServiceGetMatchingServices(port, match, &drives);
 | 
				
			||||||
 | 
						if(status != KERN_SUCCESS)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						na = 0;
 | 
				
			||||||
 | 
						while(na < n && (d=IOIteratorNext(drives)) > 0){
 | 
				
			||||||
 | 
							rv = getdrivestat(d, &a[na]);
 | 
				
			||||||
 | 
							if(rv < 0)
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							if(rv > 0)
 | 
				
			||||||
 | 
								na++;
 | 
				
			||||||
 | 
							IOObjectRelease(d);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						IOObjectRelease(drives);
 | 
				
			||||||
 | 
						return na;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					getdrivestat(io_registry_entry_t d, DriveStats *stat)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						io_registry_entry_t parent;
 | 
				
			||||||
 | 
						kern_return_t status;
 | 
				
			||||||
 | 
						CFDictionaryRef props;
 | 
				
			||||||
 | 
						CFStringRef name;
 | 
				
			||||||
 | 
						CFNumberRef num;
 | 
				
			||||||
 | 
						int rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(stat, 0, sizeof *stat);
 | 
				
			||||||
 | 
						status = IORegistryEntryGetParentEntry(d, kIOServicePlane, &parent);
 | 
				
			||||||
 | 
						if(status != KERN_SUCCESS)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						if(!IOObjectConformsTo(parent, "IOBlockStorageDriver")){
 | 
				
			||||||
 | 
							IOObjectRelease(parent);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						status = IORegistryEntryCreateCFProperties(d, (CFMutableDictionaryRef *)&props, kCFAllocatorDefault, kNilOptions);
 | 
				
			||||||
 | 
						if(status != KERN_SUCCESS){
 | 
				
			||||||
 | 
							IOObjectRelease(parent);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						name = (CFStringRef)CFDictionaryGetValue(props, CFSTR(kIOBSDNameKey));
 | 
				
			||||||
 | 
						CFStringGetCString(name, stat->name, NAMELEN, CFStringGetSystemEncoding());
 | 
				
			||||||
 | 
						num = (CFNumberRef)CFDictionaryGetValue(props, CFSTR(kIOMediaSizeKey));
 | 
				
			||||||
 | 
						CFNumberGetValue(num, kCFNumberSInt64Type, &stat->size);
 | 
				
			||||||
 | 
						num = (CFNumberRef)CFDictionaryGetValue(props, CFSTR(kIOMediaPreferredBlockSizeKey));
 | 
				
			||||||
 | 
						CFNumberGetValue(num, kCFNumberSInt64Type, &stat->blocksize);
 | 
				
			||||||
 | 
						CFRelease(props);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rv = fillstat(parent, stat);
 | 
				
			||||||
 | 
						IOObjectRelease(parent);
 | 
				
			||||||
 | 
						if(rv < 0)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct {
 | 
				
			||||||
 | 
						char *key;
 | 
				
			||||||
 | 
						size_t off;
 | 
				
			||||||
 | 
					} statstab[] = {
 | 
				
			||||||
 | 
						{kIOBlockStorageDriverStatisticsBytesReadKey, offsetof(DriveStats, read)},
 | 
				
			||||||
 | 
						{kIOBlockStorageDriverStatisticsBytesWrittenKey, offsetof(DriveStats, written)},
 | 
				
			||||||
 | 
						{kIOBlockStorageDriverStatisticsReadsKey, offsetof(DriveStats, nread)},
 | 
				
			||||||
 | 
						{kIOBlockStorageDriverStatisticsWritesKey, offsetof(DriveStats, nwrite)},
 | 
				
			||||||
 | 
						{kIOBlockStorageDriverStatisticsTotalReadTimeKey, offsetof(DriveStats, readtime)},
 | 
				
			||||||
 | 
						{kIOBlockStorageDriverStatisticsTotalWriteTimeKey, offsetof(DriveStats, writetime)},
 | 
				
			||||||
 | 
						{kIOBlockStorageDriverStatisticsLatentReadTimeKey, offsetof(DriveStats, readlat)},
 | 
				
			||||||
 | 
						{kIOBlockStorageDriverStatisticsLatentWriteTimeKey, offsetof(DriveStats, writelat)},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					fillstat(io_registry_entry_t d, DriveStats *stat)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						CFDictionaryRef props, v;
 | 
				
			||||||
 | 
						CFNumberRef num;
 | 
				
			||||||
 | 
						kern_return_t status;
 | 
				
			||||||
 | 
						typeof(statstab[0]) *bp, *ep;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						status = IORegistryEntryCreateCFProperties(d, (CFMutableDictionaryRef *)&props, kCFAllocatorDefault, kNilOptions);
 | 
				
			||||||
 | 
						if(status != KERN_SUCCESS)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						v = (CFDictionaryRef)CFDictionaryGetValue(props, CFSTR(kIOBlockStorageDriverStatisticsKey));
 | 
				
			||||||
 | 
						if(v == NULL){
 | 
				
			||||||
 | 
							CFRelease(props);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ep = &statstab[sizeof(statstab)/sizeof(statstab[0])];
 | 
				
			||||||
 | 
						for(bp = &statstab[0]; bp < ep; bp++){
 | 
				
			||||||
 | 
							CFStringRef s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							s = CFStringCreateWithCString(kCFAllocatorDefault, bp->key, CFStringGetSystemEncoding());
 | 
				
			||||||
 | 
							num = (CFNumberRef)CFDictionaryGetValue(v, s);
 | 
				
			||||||
 | 
							if(num)
 | 
				
			||||||
 | 
								CFNumberGetValue(num, kCFNumberSInt64Type, ((char*)stat)+bp->off);
 | 
				
			||||||
 | 
							CFRelease(s);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CFRelease(props);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								vendor/github.com/lufia/iostat/iostat_darwin.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/lufia/iostat/iostat_darwin.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,37 @@
 | 
				
			||||||
 | 
					// +build darwin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package iostat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit
 | 
				
			||||||
 | 
					// #include <stdint.h>
 | 
				
			||||||
 | 
					// #include "iostat_darwin.h"
 | 
				
			||||||
 | 
					import "C"
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ReadDriveStats returns statictics of each of the drives.
 | 
				
			||||||
 | 
					func ReadDriveStats() ([]*DriveStats, error) {
 | 
				
			||||||
 | 
						var buf [C.NDRIVE]C.DriveStats
 | 
				
			||||||
 | 
						n, err := C.readdrivestat(&buf[0], C.int(len(buf)))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stats := make([]*DriveStats, n)
 | 
				
			||||||
 | 
						for i := 0; i < int(n); i++ {
 | 
				
			||||||
 | 
							stats[i] = &DriveStats{
 | 
				
			||||||
 | 
								Name:           C.GoString(&buf[i].name[0]),
 | 
				
			||||||
 | 
								Size:           int64(buf[i].size),
 | 
				
			||||||
 | 
								BlockSize:      int64(buf[i].blocksize),
 | 
				
			||||||
 | 
								BytesRead:      int64(buf[i].read),
 | 
				
			||||||
 | 
								BytesWritten:   int64(buf[i].written),
 | 
				
			||||||
 | 
								NumRead:        int64(buf[i].nread),
 | 
				
			||||||
 | 
								NumWrite:       int64(buf[i].nwrite),
 | 
				
			||||||
 | 
								TotalReadTime:  time.Duration(buf[i].readtime),
 | 
				
			||||||
 | 
								TotalWriteTime: time.Duration(buf[i].writetime),
 | 
				
			||||||
 | 
								ReadLatency:    time.Duration(buf[i].readlat),
 | 
				
			||||||
 | 
								WriteLatency:   time.Duration(buf[i].writelat),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return stats, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										23
									
								
								vendor/github.com/lufia/iostat/iostat_darwin.h
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/lufia/iostat/iostat_darwin.h
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					typedef struct DriveStats DriveStats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						NDRIVE = 16,
 | 
				
			||||||
 | 
						NAMELEN = 31
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct DriveStats {
 | 
				
			||||||
 | 
						char name[NAMELEN+1];
 | 
				
			||||||
 | 
						int64_t size;
 | 
				
			||||||
 | 
						int64_t blocksize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int64_t read;
 | 
				
			||||||
 | 
						int64_t written;
 | 
				
			||||||
 | 
						int64_t nread;
 | 
				
			||||||
 | 
						int64_t nwrite;
 | 
				
			||||||
 | 
						int64_t readtime;
 | 
				
			||||||
 | 
						int64_t writetime;
 | 
				
			||||||
 | 
						int64_t readlat;
 | 
				
			||||||
 | 
						int64_t writelat;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int readdrivestat(DriveStats a[], int n);
 | 
				
			||||||
							
								
								
									
										12
									
								
								vendor/github.com/lufia/iostat/iostat_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/lufia/iostat/iostat_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					// +build !darwin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package iostat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ReadDriveStats returns statictics of each of the drives.
 | 
				
			||||||
 | 
					func ReadDriveStats() ([]*DriveStats, error) {
 | 
				
			||||||
 | 
						return nil, errors.New("not implement")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										6
									
								
								vendor/vendor.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/vendor.json
									
									
									
									
										vendored
									
									
								
							| 
						 | 
					@ -50,6 +50,12 @@
 | 
				
			||||||
			"revision": "0826b98aaa29c0766956cb40d45cf7482a597671",
 | 
								"revision": "0826b98aaa29c0766956cb40d45cf7482a597671",
 | 
				
			||||||
			"revisionTime": "2015-04-13T19:18:30Z"
 | 
								"revisionTime": "2015-04-13T19:18:30Z"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"checksumSHA1": "82wQShWC1Udgn1UbTK42s0l/IpY=",
 | 
				
			||||||
 | 
								"path": "github.com/lufia/iostat",
 | 
				
			||||||
 | 
								"revision": "8c7e013c17ce06e6651d2affabe369045b98d3b7",
 | 
				
			||||||
 | 
								"revisionTime": "2017-06-03T08:40:47Z"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"checksumSHA1": "bKMZjd2wPw13VwoE7mBeSv5djFA=",
 | 
								"checksumSHA1": "bKMZjd2wPw13VwoE7mBeSv5djFA=",
 | 
				
			||||||
			"path": "github.com/matttproud/golang_protobuf_extensions/pbutil",
 | 
								"path": "github.com/matttproud/golang_protobuf_extensions/pbutil",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue