Add perf exporter (#1274)
Signed-off-by: Daniel Hodges <hodges.daniel.scott@gmail.com>
This commit is contained in:
parent
0c6b90be4e
commit
7882009870
41 changed files with 4285 additions and 0 deletions
157
vendor/github.com/hodgesds/perf-utils/hardware_profiler.go
generated
vendored
Normal file
157
vendor/github.com/hodgesds/perf-utils/hardware_profiler.go
generated
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
// +build linux
|
||||
|
||||
package perf
|
||||
|
||||
import (
|
||||
"go.uber.org/multierr"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
type hardwareProfiler struct {
|
||||
// map of perf counter type to file descriptor
|
||||
profilers map[int]Profiler
|
||||
}
|
||||
|
||||
// NewHardwareProfiler returns a new hardware profiler.
|
||||
func NewHardwareProfiler(pid, cpu int, opts ...int) HardwareProfiler {
|
||||
profilers := map[int]Profiler{}
|
||||
|
||||
cpuCycleProfiler, err := NewCPUCycleProfiler(pid, cpu, opts...)
|
||||
if err == nil {
|
||||
profilers[unix.PERF_COUNT_HW_CPU_CYCLES] = cpuCycleProfiler
|
||||
}
|
||||
|
||||
instrProfiler, err := NewInstrProfiler(pid, cpu, opts...)
|
||||
if err == nil {
|
||||
profilers[unix.PERF_COUNT_HW_INSTRUCTIONS] = instrProfiler
|
||||
}
|
||||
|
||||
cacheRefProfiler, err := NewCacheRefProfiler(pid, cpu, opts...)
|
||||
if err == nil {
|
||||
profilers[unix.PERF_COUNT_HW_CACHE_REFERENCES] = cacheRefProfiler
|
||||
}
|
||||
|
||||
cacheMissesProfiler, err := NewCacheMissesProfiler(pid, cpu, opts...)
|
||||
if err == nil {
|
||||
profilers[unix.PERF_COUNT_HW_CACHE_MISSES] = cacheMissesProfiler
|
||||
}
|
||||
|
||||
branchInstrProfiler, err := NewBranchInstrProfiler(pid, cpu, opts...)
|
||||
if err == nil {
|
||||
profilers[unix.PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = branchInstrProfiler
|
||||
}
|
||||
|
||||
branchMissesProfiler, err := NewBranchMissesProfiler(pid, cpu, opts...)
|
||||
if err == nil {
|
||||
profilers[unix.PERF_COUNT_HW_BRANCH_MISSES] = branchMissesProfiler
|
||||
}
|
||||
|
||||
busCyclesProfiler, err := NewBusCyclesProfiler(pid, cpu, opts...)
|
||||
if err == nil {
|
||||
profilers[unix.PERF_COUNT_HW_BUS_CYCLES] = busCyclesProfiler
|
||||
}
|
||||
|
||||
stalledCyclesFrontProfiler, err := NewStalledCyclesFrontProfiler(pid, cpu, opts...)
|
||||
if err == nil {
|
||||
profilers[unix.PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = stalledCyclesFrontProfiler
|
||||
}
|
||||
|
||||
stalledCyclesBackProfiler, err := NewStalledCyclesBackProfiler(pid, cpu, opts...)
|
||||
if err == nil {
|
||||
profilers[unix.PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = stalledCyclesBackProfiler
|
||||
}
|
||||
|
||||
refCPUCyclesProfiler, err := NewRefCPUCyclesProfiler(pid, cpu, opts...)
|
||||
if err == nil {
|
||||
profilers[unix.PERF_COUNT_HW_REF_CPU_CYCLES] = refCPUCyclesProfiler
|
||||
}
|
||||
|
||||
return &hardwareProfiler{
|
||||
profilers: profilers,
|
||||
}
|
||||
}
|
||||
|
||||
// Start is used to start the HardwareProfiler.
|
||||
func (p *hardwareProfiler) Start() error {
|
||||
if len(p.profilers) == 0 {
|
||||
return ErrNoProfiler
|
||||
}
|
||||
var err error
|
||||
for _, profiler := range p.profilers {
|
||||
err = multierr.Append(err, profiler.Start())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Reset is used to reset the HardwareProfiler.
|
||||
func (p *hardwareProfiler) Reset() error {
|
||||
var err error
|
||||
for _, profiler := range p.profilers {
|
||||
err = multierr.Append(err, profiler.Reset())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Stop is used to reset the HardwareProfiler.
|
||||
func (p *hardwareProfiler) Stop() error {
|
||||
var err error
|
||||
for _, profiler := range p.profilers {
|
||||
err = multierr.Append(err, profiler.Stop())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Close is used to reset the HardwareProfiler.
|
||||
func (p *hardwareProfiler) Close() error {
|
||||
var err error
|
||||
for _, profiler := range p.profilers {
|
||||
err = multierr.Append(err, profiler.Close())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Profile is used to read the HardwareProfiler HardwareProfile it returns an
|
||||
// error only if all profiles fail.
|
||||
func (p *hardwareProfiler) Profile() (*HardwareProfile, error) {
|
||||
var err error
|
||||
hwProfile := &HardwareProfile{}
|
||||
for profilerType, profiler := range p.profilers {
|
||||
profileVal, err2 := profiler.Profile()
|
||||
err = multierr.Append(err, err2)
|
||||
if err2 == nil {
|
||||
if hwProfile.TimeEnabled == nil {
|
||||
hwProfile.TimeEnabled = &profileVal.TimeEnabled
|
||||
}
|
||||
if hwProfile.TimeRunning == nil {
|
||||
hwProfile.TimeRunning = &profileVal.TimeRunning
|
||||
}
|
||||
switch profilerType {
|
||||
case unix.PERF_COUNT_HW_CPU_CYCLES:
|
||||
hwProfile.CPUCycles = &profileVal.Value
|
||||
case unix.PERF_COUNT_HW_INSTRUCTIONS:
|
||||
hwProfile.Instructions = &profileVal.Value
|
||||
case unix.PERF_COUNT_HW_CACHE_REFERENCES:
|
||||
hwProfile.CacheRefs = &profileVal.Value
|
||||
case unix.PERF_COUNT_HW_CACHE_MISSES:
|
||||
hwProfile.CacheMisses = &profileVal.Value
|
||||
case unix.PERF_COUNT_HW_BRANCH_INSTRUCTIONS:
|
||||
hwProfile.BranchInstr = &profileVal.Value
|
||||
case unix.PERF_COUNT_HW_BRANCH_MISSES:
|
||||
hwProfile.BranchMisses = &profileVal.Value
|
||||
case unix.PERF_COUNT_HW_BUS_CYCLES:
|
||||
hwProfile.BusCycles = &profileVal.Value
|
||||
case unix.PERF_COUNT_HW_STALLED_CYCLES_FRONTEND:
|
||||
hwProfile.StalledCyclesFrontend = &profileVal.Value
|
||||
case unix.PERF_COUNT_HW_STALLED_CYCLES_BACKEND:
|
||||
hwProfile.StalledCyclesBackend = &profileVal.Value
|
||||
case unix.PERF_COUNT_HW_REF_CPU_CYCLES:
|
||||
hwProfile.RefCPUCycles = &profileVal.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(multierr.Errors(err)) == len(p.profilers) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return hwProfile, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue