Ben Kochie
8 years ago
committed by
GitHub
11 changed files with 306 additions and 8 deletions
@ -0,0 +1,24 @@
|
||||
extent_alloc 1 872 0 0 |
||||
abt 0 0 0 0 |
||||
blk_map 61 29 1 1 1 91 0 |
||||
bmbt 0 0 0 0 |
||||
dir 3 2 1 52 |
||||
trans 4 40 0 |
||||
ig 5 1 0 4 0 0 1 |
||||
log 8 21 0 5821 4 |
||||
push_ail 44 0 1102 15 0 2 0 2 0 2 |
||||
xstrat 1 0 |
||||
rw 28 0 |
||||
attr 0 0 0 0 |
||||
icluster 2 2 2 |
||||
vnodes 4 0 0 0 1 1 1 0 |
||||
buf 22 25 14 0 0 8 0 8 8 |
||||
abtb2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 |
||||
abtc2 2 1 1 1 0 0 0 0 0 0 0 0 0 0 0 |
||||
bmbt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
||||
ibt2 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 |
||||
fibt2 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 |
||||
rmapbt 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
||||
qm 0 0 0 0 0 0 0 0 |
||||
xpc 3571712 3568056 0 |
||||
debug 0 |
@ -0,0 +1,140 @@
|
||||
// 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.
|
||||
|
||||
package collector |
||||
|
||||
import ( |
||||
"fmt" |
||||
|
||||
"github.com/prometheus/client_golang/prometheus" |
||||
"github.com/prometheus/procfs/sysfs" |
||||
"github.com/prometheus/procfs/xfs" |
||||
) |
||||
|
||||
// An xfsCollector is a Collector which gathers metrics from XFS filesystems.
|
||||
type xfsCollector struct { |
||||
fs sysfs.FS |
||||
} |
||||
|
||||
func init() { |
||||
Factories["xfs"] = NewXFSCollector |
||||
} |
||||
|
||||
// NewXFSCollector returns a new Collector exposing XFS statistics.
|
||||
func NewXFSCollector() (Collector, error) { |
||||
fs, err := sysfs.NewFS(*sysPath) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("failed to open sysfs: %v", err) |
||||
} |
||||
|
||||
return &xfsCollector{ |
||||
fs: fs, |
||||
}, nil |
||||
} |
||||
|
||||
// Update implements Collector.
|
||||
func (c *xfsCollector) Update(ch chan<- prometheus.Metric) error { |
||||
stats, err := c.fs.XFSStats() |
||||
if err != nil { |
||||
return fmt.Errorf("failed to retrieve XFS stats: %v", err) |
||||
} |
||||
|
||||
for _, s := range stats { |
||||
c.updateXFSStats(ch, s) |
||||
} |
||||
|
||||
return nil |
||||
} |
||||
|
||||
// updateXFSStats collects statistics for a single XFS filesystem.
|
||||
func (c *xfsCollector) updateXFSStats(ch chan<- prometheus.Metric, s *xfs.Stats) { |
||||
const ( |
||||
subsystem = "xfs" |
||||
) |
||||
|
||||
var ( |
||||
labels = []string{"device"} |
||||
) |
||||
|
||||
// Metric names and descriptions are sourced from:
|
||||
// http://xfs.org/index.php/Runtime_Stats.
|
||||
//
|
||||
// Each metric has a name that roughly follows the pattern of
|
||||
// "node_xfs_category_value_total", using the categories and value names
|
||||
// found on the XFS wiki.
|
||||
//
|
||||
// Note that statistics for more than one internal B-tree are measured,
|
||||
// and as such, each one must be differentiated by name.
|
||||
metrics := []struct { |
||||
name string |
||||
desc string |
||||
value float64 |
||||
}{ |
||||
{ |
||||
name: "extent_allocation_extents_allocated_total", |
||||
desc: "Number of extents allocated for a filesystem.", |
||||
value: float64(s.ExtentAllocation.ExtentsAllocated), |
||||
}, |
||||
{ |
||||
name: "extent_allocation_blocks_allocated_total", |
||||
desc: "Number of blocks allocated for a filesystem.", |
||||
value: float64(s.ExtentAllocation.BlocksAllocated), |
||||
}, |
||||
{ |
||||
name: "extent_allocation_extents_freed_total", |
||||
desc: "Number of extents freed for a filesystem.", |
||||
value: float64(s.ExtentAllocation.ExtentsFreed), |
||||
}, |
||||
{ |
||||
name: "extent_allocation_blocks_freed_total", |
||||
desc: "Number of blocks freed for a filesystem.", |
||||
value: float64(s.ExtentAllocation.BlocksFreed), |
||||
}, |
||||
{ |
||||
name: "allocation_btree_lookups_total", |
||||
desc: "Number of allocation B-tree lookups for a filesystem.", |
||||
value: float64(s.AllocationBTree.Lookups), |
||||
}, |
||||
{ |
||||
name: "allocation_btree_compares_total", |
||||
desc: "Number of allocation B-tree compares for a filesystem.", |
||||
value: float64(s.AllocationBTree.Compares), |
||||
}, |
||||
{ |
||||
name: "allocation_btree_records_inserted_total", |
||||
desc: "Number of allocation B-tree records inserted for a filesystem.", |
||||
value: float64(s.AllocationBTree.RecordsInserted), |
||||
}, |
||||
{ |
||||
name: "allocation_btree_records_deleted_total", |
||||
desc: "Number of allocation B-tree records deleted for a filesystem.", |
||||
value: float64(s.AllocationBTree.RecordsDeleted), |
||||
}, |
||||
} |
||||
|
||||
for _, m := range metrics { |
||||
desc := prometheus.NewDesc( |
||||
prometheus.BuildFQName(Namespace, subsystem, m.name), |
||||
m.desc, |
||||
labels, |
||||
nil, |
||||
) |
||||
|
||||
ch <- prometheus.MustNewConstMetric( |
||||
desc, |
||||
prometheus.CounterValue, |
||||
m.value, |
||||
s.Name, |
||||
) |
||||
} |
||||
} |
@ -0,0 +1,16 @@
|
||||
// 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.
|
||||
|
||||
// Package sysfs provides functions to retrieve system and kernel metrics
|
||||
// from the pseudo-filesystem sys.
|
||||
package sysfs |
@ -0,0 +1,82 @@
|
||||
// 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.
|
||||
|
||||
package sysfs |
||||
|
||||
import ( |
||||
"fmt" |
||||
"os" |
||||
"path/filepath" |
||||
|
||||
"github.com/prometheus/procfs/xfs" |
||||
) |
||||
|
||||
// FS represents the pseudo-filesystem sys, which provides an interface to
|
||||
// kernel data structures.
|
||||
type FS string |
||||
|
||||
// DefaultMountPoint is the common mount point of the sys filesystem.
|
||||
const DefaultMountPoint = "/sys" |
||||
|
||||
// NewFS returns a new FS mounted under the given mountPoint. It will error
|
||||
// if the mount point can't be read.
|
||||
func NewFS(mountPoint string) (FS, error) { |
||||
info, err := os.Stat(mountPoint) |
||||
if err != nil { |
||||
return "", fmt.Errorf("could not read %s: %s", mountPoint, err) |
||||
} |
||||
if !info.IsDir() { |
||||
return "", fmt.Errorf("mount point %s is not a directory", mountPoint) |
||||
} |
||||
|
||||
return FS(mountPoint), nil |
||||
} |
||||
|
||||
// Path returns the path of the given subsystem relative to the sys root.
|
||||
func (fs FS) Path(p ...string) string { |
||||
return filepath.Join(append([]string{string(fs)}, p...)...) |
||||
} |
||||
|
||||
// XFSStats retrieves XFS filesystem runtime statistics for each mounted XFS
|
||||
// filesystem. Only available on kernel 4.4+. On older kernels, an empty
|
||||
// slice of *xfs.Stats will be returned.
|
||||
func (fs FS) XFSStats() ([]*xfs.Stats, error) { |
||||
matches, err := filepath.Glob(fs.Path("fs/xfs/*/stats/stats")) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
stats := make([]*xfs.Stats, 0, len(matches)) |
||||
for _, m := range matches { |
||||
f, err := os.Open(m) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
// "*" used in glob above indicates the name of the filesystem.
|
||||
name := filepath.Base(filepath.Dir(filepath.Dir(m))) |
||||
|
||||
// File must be closed after parsing, regardless of success or
|
||||
// failure. Defer is not used because of the loop.
|
||||
s, err := xfs.ParseStats(f) |
||||
_ = f.Close() |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
s.Name = name |
||||
stats = append(stats, s) |
||||
} |
||||
|
||||
return stats, nil |
||||
} |
Loading…
Reference in new issue