Skip to content

Commit

Permalink
add disk usage
Browse files Browse the repository at this point in the history
  • Loading branch information
e.martyn committed Mar 9, 2023
1 parent f3bf99b commit 18cd82d
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 51 deletions.
93 changes: 66 additions & 27 deletions internal/format/predefined.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,26 @@ const (
BuiltinMetricIDNetBandwidth = -80
BuiltinMetricIDNetPacket = -81
BuiltinMetricIDNetError = -82
BuiltinMetricIDDiskUsage = -83
BuiltinMetricIDINodeUsage = -84

BuiltinMetricNameCpuUsage = "host_cpu_usage"
BuiltinMetricNameMemUsage = "host_mem_usage"
BuiltinMetricNameBlockIOTime = "host_block_io_time"
BuiltinMetricNameCpuUsage = "test_host_cpu_usage"
BuiltinMetricNameMemUsage = "test_host_mem_usage"
BuiltinMetricNameBlockIOTime = "test_host_block_io_time"
BuiltinMetricNameDiskUsage = "test_host_disk_usage"
BuiltinMetricNameINodeUsage = "test_host_inode_usage"

BuiltinMetricNameSystemUptime = "host_system_uptime"
BuiltinMetricNameProcessCreated = "host_system_process_created"
BuiltinMetricNameProcessStatus = "host_system_process_status"
BuiltinMetricNameSystemUptime = "test_host_system_uptime"
BuiltinMetricNameProcessCreated = "test_host_system_process_created"
BuiltinMetricNameProcessStatus = "test_host_system_process_status"

BuiltinMetricNamePSICPU = "host_system_psi_cpu"
BuiltinMetricNamePSIMem = "host_system_psi_mem"
BuiltinMetricNamePSIIO = "host_system_psi_io"
BuiltinMetricNamePSICPU = "test_host_system_psi_cpu"
BuiltinMetricNamePSIMem = "test_host_system_psi_mem"
BuiltinMetricNamePSIIO = "test_host_system_psi_io"

BuiltinMetricNameNetBandwidth = "host_net_bandwidth"
BuiltinMetricNameNetPacket = "host_net_packet"
BuiltinMetricNameNetError = "host_net_error"
BuiltinMetricNameNetBandwidth = "test_host_net_bandwidth"
BuiltinMetricNameNetPacket = "test_host_net_packet"
BuiltinMetricNameNetError = "test_host_net_error"

RawIDTagNice = 1
RawIDTagSystem = 2
Expand Down Expand Up @@ -233,21 +237,22 @@ var hostMetrics = map[int32]*MetricMetaValue{
Name: BuiltinMetricNameNetError,
Kind: MetricKindCounter,
Description: "Number of network errors",
Tags: []MetricMetaTag{{
Description: "type",
Raw: true,
ValueComments: convertToValueComments(map[int32]string{
RawIDTagInHdrError: "InHdrError",
RawIDTagInDiscard: "InDiscard",
RawIDTagOutDiscard: "OutDiscards",
RawIDTagOutNoRoute: "OutNoRoute",
RawIDTagInAddrError: "InAddrError",
RawIDTagInUnknownProto: "InUnknownProto",
RawIDTagInErr: "InErr",
RawIDTagInCsumErr: "InCsumError",
RawIDTagRetransSeg: "RetransSeg",
}),
},
Tags: []MetricMetaTag{
{
Description: "type",
Raw: true,
ValueComments: convertToValueComments(map[int32]string{
RawIDTagInHdrError: "InHdrError",
RawIDTagInDiscard: "InDiscard",
RawIDTagOutDiscard: "OutDiscards",
RawIDTagOutNoRoute: "OutNoRoute",
RawIDTagInAddrError: "InAddrError",
RawIDTagInUnknownProto: "InUnknownProto",
RawIDTagInErr: "InErr",
RawIDTagInCsumErr: "InCsumError",
RawIDTagRetransSeg: "RetransSeg",
}),
},
{
Description: "protocol",
Raw: true,
Expand All @@ -259,4 +264,38 @@ var hostMetrics = map[int32]*MetricMetaValue{
}),
}},
},
BuiltinMetricIDDiskUsage: {
Name: BuiltinMetricNameDiskUsage,
Kind: MetricKindValue,
Description: "",
Tags: []MetricMetaTag{
{
Description: "state",
Raw: true,
ValueComments: convertToValueComments(map[int32]string{
RawIDTagFree: "free",
RawIDTagUsed: "used",
}),
},
{
Description: "device",
}},
},
BuiltinMetricIDINodeUsage: {
Name: BuiltinMetricNameINodeUsage,
Kind: MetricKindValue,
Description: "",
Tags: []MetricMetaTag{
{
Description: "state",
Raw: true,
ValueComments: convertToValueComments(map[int32]string{
RawIDTagFree: "free",
RawIDTagUsed: "used",
}),
},
{
Description: "device",
}},
},
}
3 changes: 1 addition & 2 deletions internal/stats/cpu_stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ type CPUStats struct {
pusher Pusher
}

const bt = "test_system_uptime"
const cpu = format.BuiltinMetricNameCpuUsage
const irq = ""
const sirq = ""
Expand Down Expand Up @@ -87,7 +86,7 @@ func (c *CPUStats) pushCPUMetrics(stat procfs.Stat) error {

func (c *CPUStats) pushSystemMetrics(stat procfs.Stat) error {
uptime := uint64(time.Now().Unix()) - stat.BootTime
c.pusher.PushSystemMetricValue(bt, float64(uptime))
c.pusher.PushSystemMetricValue(format.BuiltinMetricNameSystemUptime, float64(uptime))
c.pusher.PushSystemMetricValue(format.BuiltinMetricNameProcessStatus, float64(stat.ProcessesRunning), format.RawIDTagRunning)
c.pusher.PushSystemMetricValue(format.BuiltinMetricNameProcessStatus, float64(stat.ProcessesBlocked), format.RawIDTagBlocked)
c.pusher.PushSystemMetricCount(format.BuiltinMetricNameProcessCreated, float64(stat.ProcessCreated-c.stat.ProcessCreated))
Expand Down
111 changes: 100 additions & 11 deletions internal/stats/disk_stats.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,35 @@
package stats

import (
"bufio"
"errors"
"fmt"
"os"
"regexp"
"strings"

"github.com/prometheus/procfs/blockdevice"
"github.com/vkcom/statshouse/internal/format"
"golang.org/x/sys/unix"
)

type DiskStats struct {
fs blockdevice.FS

pusher Pusher
old map[string]blockdevice.Diskstats
pusher Pusher
old map[string]blockdevice.Diskstats
excludedMountPointsPattern *regexp.Regexp
excludedFSTypesPattern *regexp.Regexp
}

const disk = "test_block_io"
type mount struct {
device, mountPoint, fsType, options string
}

const (
defMountPointsExcluded = "^/(dev|proc|run/credentials/.+|sys|var/lib/docker/.+|var/lib/containers/storage/.+)($|/)"
defFSTypesExcluded = "^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$"
)

func (*DiskStats) Name() string {
return "disk_stats"
Expand All @@ -26,8 +41,10 @@ func NewDiskStats(pusher Pusher) (*DiskStats, error) {
return nil, fmt.Errorf("failed to initialize procfs: %w", err)
}
return &DiskStats{
fs: fs,
pusher: pusher,
fs: fs,
pusher: pusher,
excludedMountPointsPattern: regexp.MustCompile(defMountPointsExcluded),
excludedFSTypesPattern: regexp.MustCompile(defFSTypesExcluded),
}, nil
}

Expand All @@ -47,17 +64,89 @@ func (c *DiskStats) PushMetrics() error {
writeIO := stat.WriteIOs - oldStat.WriteIOs
discardIO := stat.DiscardIOs - oldStat.DiscardIOs

c.pusher.PushSystemMetricCount(disk, float64(readIO), format.RawIDTagRead)
c.pusher.PushSystemMetricCount(disk, float64(writeIO), format.RawIDTagWrite)
c.pusher.PushSystemMetricCount(disk, float64(discardIO), format.RawIDTagDiscard)
c.pusher.PushSystemMetricCount(format.BuiltinMetricNameBlockIOTime, float64(readIO), format.RawIDTagRead)
c.pusher.PushSystemMetricCount(format.BuiltinMetricNameBlockIOTime, float64(writeIO), format.RawIDTagWrite)
c.pusher.PushSystemMetricCount(format.BuiltinMetricNameBlockIOTime, float64(discardIO), format.RawIDTagDiscard)

readIOTicks := float64(stat.ReadTicks-oldStat.ReadTicks) / 1000
writeIOTicks := float64(stat.WriteTicks-oldStat.WriteTicks) / 1000
discardIOTicks := float64(stat.DiscardTicks-oldStat.DiscardTicks) / 1000

c.pusher.PushSystemMetricValue(disk, readIOTicks, format.RawIDTagRead)
c.pusher.PushSystemMetricValue(disk, writeIOTicks, format.RawIDTagWrite)
c.pusher.PushSystemMetricValue(disk, discardIOTicks, format.RawIDTagDiscard)
c.pusher.PushSystemMetricValue(format.BuiltinMetricNameBlockIOTime, readIOTicks, format.RawIDTagRead)
c.pusher.PushSystemMetricValue(format.BuiltinMetricNameBlockIOTime, writeIOTicks, format.RawIDTagWrite)
c.pusher.PushSystemMetricValue(format.BuiltinMetricNameBlockIOTime, discardIOTicks, format.RawIDTagDiscard)
}
c.pushFSStats()
return nil
}

func (c *DiskStats) pushFSStats() {
stats, err := parseMounts()
if err != nil {
//todo logger
_ = 2
}
seen := map[string]bool{}
for _, stat := range stats {
if c.excludedMountPointsPattern.MatchString(stat.mountPoint) {
continue
}
if c.excludedFSTypesPattern.MatchString(stat.fsType) {
continue
}
if seen[stat.device] {
continue
}
seen[stat.device] = true
s := unix.Statfs_t{}
err := unix.Statfs(stat.mountPoint, &s)
if err != nil {
continue
}
free := float64(s.Bfree) * float64(s.Bsize)
used := float64(s.Blocks)*float64(s.Bsize) - free
c.pusher.PushSystemMetricValue(format.BuiltinMetricNameDiskUsage, free, format.RawIDTagFree)
c.pusher.PushSystemMetricValue(format.BuiltinMetricNameDiskUsage, used, format.RawIDTagUsed)

inodeFree := float64(s.Ffree)
inodeUsed := float64(s.Files) - inodeFree
c.pusher.PushSystemMetricValue(format.BuiltinMetricNameINodeUsage, inodeFree, format.RawIDTagFree)
c.pusher.PushSystemMetricValue(format.BuiltinMetricNameINodeUsage, inodeUsed, format.RawIDTagUsed)
}
}

func parseMounts() ([]mount, error) {
file, err := os.Open("/proc/1/mounts")
if errors.Is(err, os.ErrNotExist) {
file, err = os.Open("/proc/mounts")
}
if err != nil {
return nil, err
}
defer file.Close()

var mounts []mount

scanner := bufio.NewScanner(file)
for scanner.Scan() {
parts := strings.Fields(scanner.Text())

if len(parts) < 4 {
return nil, fmt.Errorf("malformed mount point information: %q", scanner.Text())
}

// Ensure we handle the translation of \040 and \011
// as per fstab(5).
parts[1] = strings.Replace(parts[1], "\\040", " ", -1)
parts[1] = strings.Replace(parts[1], "\\011", "\t", -1)

mounts = append(mounts, mount{
device: parts[0],
mountPoint: parts[1],
fsType: parts[2],
options: parts[3],
})
}

return mounts, scanner.Err()
}
16 changes: 5 additions & 11 deletions internal/stats/net_stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,6 @@ type NetStats struct {
pusher Pusher
}

const (
bandwidth = "test_net_bandwidth"
ipPackets = "test_net_ip_packet"
ipPacketsErrors = "test_net_ip_packet_errors"
tcpPackets = "test_net_tcp_packets"
tcpPacketsErrors = "test_net_tcp_packets_errors"
udpPackets = "test_net_udp_datagrams"
)

type netStat struct {
ip ip
tcp tcp
Expand Down Expand Up @@ -162,8 +153,11 @@ func (c *NetStats) pushNetDev() error {
total := dev.Total()

if len(c.oldNetDev) > 0 {
c.pusher.PushSystemMetricValue(bandwidth, float64(total.RxBytes-c.oldNetDevTotal.RxBytes), format.RawIDTagReceived)
c.pusher.PushSystemMetricValue(bandwidth, float64(total.TxBytes-c.oldNetDevTotal.TxBytes), format.RawIDTagSent)
c.pusher.PushSystemMetricValue(format.BuiltinMetricNameNetBandwidth, float64(total.RxBytes-c.oldNetDevTotal.RxBytes), format.RawIDTagReceived)
c.pusher.PushSystemMetricValue(format.BuiltinMetricNameNetBandwidth, float64(total.TxBytes-c.oldNetDevTotal.TxBytes), format.RawIDTagSent)

c.pusher.PushSystemMetricCount(format.BuiltinMetricNameNetBandwidth, float64(total.RxPackets-c.oldNetDevTotal.RxPackets), format.RawIDTagReceived)
c.pusher.PushSystemMetricCount(format.BuiltinMetricNameNetBandwidth, float64(total.TxPackets-c.oldNetDevTotal.TxPackets), format.RawIDTagSent)
}

c.oldNetDev = dev
Expand Down

0 comments on commit 18cd82d

Please sign in to comment.