forked from ethereum/go-ethereum
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/geth, metrics: separate process metric collection, add disk
- Loading branch information
Showing
5 changed files
with
130 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package metrics | ||
|
||
// DiskStats is the per process disk io stats. | ||
type DiskStats struct { | ||
ReadCount int64 // Number of read operations executed | ||
ReadBytes int64 // Total number of bytes read | ||
WriteCount int64 // Number of write operations executed | ||
WriteBytes int64 // Total number of byte written | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// Contains the Linux implementation of process disk IO counter retrieval. | ||
|
||
package metrics | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"io" | ||
"os" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
// ReadDiskStats retrieves the disk IO stats belonging to the current process. | ||
func ReadDiskStats(stats *DiskStats) error { | ||
// Open the process disk IO counter file | ||
inf, err := os.Open(fmt.Sprintf("/proc/%d/io", os.Getpid())) | ||
if err != nil { | ||
return err | ||
} | ||
in := bufio.NewReader(inf) | ||
|
||
// Iterate over the IO counter, and extract what we need | ||
for { | ||
// Read the next line and split to key and value | ||
line, err := in.ReadString('\n') | ||
if err != nil { | ||
if err == io.EOF { | ||
return nil | ||
} | ||
return err | ||
} | ||
key, value := "", int64(0) | ||
if parts := strings.Split(line, ":"); len(parts) != 2 { | ||
continue | ||
} else { | ||
key = strings.TrimSpace(parts[0]) | ||
if value, err = strconv.ParseInt(strings.TrimSpace(parts[1]), 10, 64); err != nil { | ||
return err | ||
} | ||
} | ||
// Update the counter based on the key | ||
switch key { | ||
case "syscr": | ||
stats.ReadCount = value | ||
case "syscw": | ||
stats.WriteCount = value | ||
case "rchar": | ||
stats.ReadBytes = value | ||
case "wchar": | ||
stats.WriteBytes = value | ||
} | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// +build !linux | ||
|
||
package metrics | ||
|
||
import "errors" | ||
|
||
// ReadDiskStats retrieves the disk IO stats belonging to the current process. | ||
func ReadDiskStats(stats *DiskStats) error { | ||
return errors.New("Not implemented") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// Package metrics provides general system and process level metrics collection. | ||
package metrics | ||
|
||
import ( | ||
"runtime" | ||
"time" | ||
|
||
"github.com/ethereum/go-ethereum/logger" | ||
"github.com/ethereum/go-ethereum/logger/glog" | ||
"github.com/rcrowley/go-metrics" | ||
) | ||
|
||
// CollectProcessMetrics periodically collects various metrics about the running | ||
// process. | ||
func CollectProcessMetrics(refresh time.Duration) { | ||
// Create the various data collectors | ||
memstats := make([]*runtime.MemStats, 2) | ||
diskstats := make([]*DiskStats, 2) | ||
for i := 0; i < len(memstats); i++ { | ||
memstats[i] = new(runtime.MemStats) | ||
diskstats[i] = new(DiskStats) | ||
} | ||
// Define the various metrics to collect | ||
memAllocs := metrics.GetOrRegisterMeter("system/memory/allocs", metrics.DefaultRegistry) | ||
memFrees := metrics.GetOrRegisterMeter("system/memory/frees", metrics.DefaultRegistry) | ||
memInuse := metrics.GetOrRegisterMeter("system/memory/inuse", metrics.DefaultRegistry) | ||
memPauses := metrics.GetOrRegisterMeter("system/memory/pauses", metrics.DefaultRegistry) | ||
|
||
var diskReads, diskReadBytes, diskWrites, diskWriteBytes metrics.Meter | ||
if err := ReadDiskStats(diskstats[0]); err == nil { | ||
diskReads = metrics.GetOrRegisterMeter("system/disk/readcount", metrics.DefaultRegistry) | ||
diskReadBytes = metrics.GetOrRegisterMeter("system/disk/readdata", metrics.DefaultRegistry) | ||
diskWrites = metrics.GetOrRegisterMeter("system/disk/writecount", metrics.DefaultRegistry) | ||
diskWriteBytes = metrics.GetOrRegisterMeter("system/disk/writedata", metrics.DefaultRegistry) | ||
} else { | ||
glog.V(logger.Debug).Infof("failed to read disk metrics: %v", err) | ||
} | ||
// Iterate loading the different stats and updating the meters | ||
for i := 1; ; i++ { | ||
runtime.ReadMemStats(memstats[i%2]) | ||
memAllocs.Mark(int64(memstats[i%2].Mallocs - memstats[(i-1)%2].Mallocs)) | ||
memFrees.Mark(int64(memstats[i%2].Frees - memstats[(i-1)%2].Frees)) | ||
memInuse.Mark(int64(memstats[i%2].Alloc - memstats[(i-1)%2].Alloc)) | ||
memPauses.Mark(int64(memstats[i%2].PauseTotalNs - memstats[(i-1)%2].PauseTotalNs)) | ||
|
||
if ReadDiskStats(diskstats[i%2]) == nil { | ||
diskReads.Mark(int64(diskstats[i%2].ReadCount - diskstats[(i-1)%2].ReadCount)) | ||
diskReadBytes.Mark(int64(diskstats[i%2].ReadBytes - diskstats[(i-1)%2].ReadBytes)) | ||
diskWrites.Mark(int64(diskstats[i%2].WriteCount - diskstats[(i-1)%2].WriteCount)) | ||
diskWriteBytes.Mark(int64(diskstats[i%2].WriteBytes - diskstats[(i-1)%2].WriteBytes)) | ||
} | ||
time.Sleep(refresh) | ||
} | ||
} |