Skip to content
This repository has been archived by the owner on Nov 8, 2022. It is now read-only.

Commit

Permalink
Merge pull request #34 from marcin-krolik/feat/dynamic-metrics
Browse files Browse the repository at this point in the history
Dynamic metrics for cpu and net statistics
  • Loading branch information
kindermoumoute authored Sep 27, 2016
2 parents 04c1179 + 9b01797 commit d442d4c
Show file tree
Hide file tree
Showing 11 changed files with 363 additions and 319 deletions.
51 changes: 32 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,28 @@ This plugin has the ability to gather the following metrics:

Namespace | Description (optional)
----------|-----------------------
/intel/psutil/[CPU]/guest | time spent in guest mode
/intel/psutil/[CPU]/guest_nice | time spent running a niced guest (virtual CPU for guest operating systems under the control of the Linux kernel)
/intel/psutil/[CPU]/idle | time spent in the idle task. This value should be USER_HZ times the second entry in the /proc/uptime pseudo-file
/intel/psutil/[CPU]/iowait | time waiting for I/O to complete
/intel/psutil/[CPU]/irq | time servicing interrupts
/intel/psutil/[CPU]/nice | time spent in user mode with low priority (nice)
/intel/psutil/[CPU]/softirq | time spent servicing softirqs
/intel/psutil/[CPU]/steal | stolen time, which is the time spent in other operating systems when running in a virtualized environment
/intel/psutil/[CPU]/stolen |
/intel/psutil/[CPU]/system | time spent in system mode
/intel/psutil/[CPU]/user | time spent in user mode
/intel/psutil/cpu/cpu-total/guest | time spent in guest mode accumulated over all cpus
/intel/psutil/cpu/cpu-total/guest_nice | time spent running a niced guest (virtual CPU for guest operating systems under the control of the Linux kernel) accumulated over all cpus
/intel/psutil/cpu/cpu-total/idle | time spent in the idle task accumulated over all cpus. This value should be USER_HZ times the second entry in the /proc/uptime pseudo-file
/intel/psutil/cpu/cpu-total/iowait | time waiting for I/O to complete accumulated over all cpus
/intel/psutil/cpu/cpu-total/irq | time servicing interrupts accumulated over all cpus
/intel/psutil/cpu/cpu-total/nice | time spent in user mode with low priority (nice) accumulated over all cpus
/intel/psutil/cpu/cpu-total/softirq | time spent servicing softirqs accumulated over all cpus
/intel/psutil/cpu/cpu-total/steal | stolen time, which is the time spent in other operating systems when running in a virtualized environment accumulated over all cpus
/intel/psutil/cpu/cpu-total/stolen |
/intel/psutil/cpu/cpu-total/system | time spent in system mode accumulated over all cpus
/intel/psutil/cpu/cpu-total/user | time spent in user mode accumulated over all cpus
/intel/psutil/cpu/[CPU]/guest | time spent in guest mode
/intel/psutil/cpu/[CPU]/guest_nice | time spent running a niced guest (virtual CPU for guest operating systems under the control of the Linux kernel)
/intel/psutil/cpu/[CPU]/idle | time spent in the idle task. This value should be USER_HZ times the second entry in the /proc/uptime pseudo-file
/intel/psutil/cpu/[CPU]/iowait | time waiting for I/O to complete
/intel/psutil/cpu/[CPU]/irq | time servicing interrupts
/intel/psutil/cpu/[CPU]/nice | time spent in user mode with low priority (nice)
/intel/psutil/cpu/[CPU]/softirq | time spent servicing softirqs
/intel/psutil/cpu/[CPU]/steal | stolen time, which is the time spent in other operating systems when running in a virtualized environment
/intel/psutil/cpu/[CPU]/stolen |
/intel/psutil/cpu/[CPU]/system | time spent in system mode
/intel/psutil/cpu/[CPU]/user | time spent in user mode
|
/intel/psutil/load/load1 | load average over the last 1 minute
/intel/psutil/load/load15 | load average over the last 15 minutes
Expand All @@ -90,14 +101,14 @@ Namespace | Description (optional)
/intel/psutil/net/all/errout | total number of errors while sending
/intel/psutil/net/all/packets_recv | number of packets received
/intel/psutil/net/all/packets_sent | number of packets sent
/intel/psutil/net/[INTERFACE]/bytes_recv |
/intel/psutil/net/[INTERFACE]/bytes_sent |
/intel/psutil/net/[INTERFACE]/dropin |
/intel/psutil/net/[INTERFACE]/dropout |
/intel/psutil/net/[INTERFACE]/errin |
/intel/psutil/net/[INTERFACE]/errout |
/intel/psutil/net/[INTERFACE]/packets_recv |
/intel/psutil/net/[INTERFACE]/packets_sent |
/intel/psutil/net/[INTERFACE]/bytes_recv | number of bytes sent on given interface
/intel/psutil/net/[INTERFACE]/bytes_sent | number of bytes received on given interface
/intel/psutil/net/[INTERFACE]/dropin | total number of incoming packets which were dropped on given interface
/intel/psutil/net/[INTERFACE]/dropout | total number of outgoing packets which were dropped (always 0 on OSX and BSD) o given interface
/intel/psutil/net/[INTERFACE]/errin | total number of errors while receiving on given interface
/intel/psutil/net/[INTERFACE]/errout | total number of errors while sending on given interface
/intel/psutil/net/[INTERFACE]/packets_recv | number of packets received on given interface
/intel/psutil/net/[INTERFACE]/packets_sent | number of packets sent on given interface
|
/intel/psutil/vm/active | memory currently in use or very recently used, and so it is in RAM
/intel/psutil/vm/available | the actual amount of available memory that can be given instantly to processes that request more memory in bytes; this is calculated by summing different memory values depending on the platform (e.g. free + buffers + cached on Linux) and it is supposed to be used to monitor actual memory usage in a cross platform fashion
Expand Down Expand Up @@ -145,6 +156,8 @@ Create a task manifest file (e.g. `task-psutil.json`):
"/intel/psutil/load/load1": {},
"/intel/psutil/load/load5": {},
"/intel/psutil/load/load15": {},
"/intel/psutil/cpu/*/user": {},
"/intel/psutil/net/*/bytes_sent": {},
"/intel/psutil/vm/available": {},
"/intel/psutil/vm/free": {},
"/intel/psutil/vm/used": {}
Expand Down
8 changes: 4 additions & 4 deletions examples/tasks/mock-psutil.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ PLUGIN_PATH=${PLUGIN_PATH:-"${TMPDIR}/snap/plugins"}
mkdir -p $PLUGIN_PATH

_info "downloading plugins"
(cd $PLUGIN_PATH && curl -sSO http://snap.ci.snap-telemetry.io/snap/master/latest/snap-plugin-publisher-mock-file && chmod 755 snap-plugin-publisher-mock-file)
(cd $PLUGIN_PATH && curl -sSO http://snap.ci.snap-telemetry.io/snap/master/latest/snap-plugin-processor-passthru && chmod 755 snap-plugin-processor-passthru)
(cd $PLUGIN_PATH && curl -sSO http://snap.ci.snap-telemetry.io/plugins/snap-plugin-collector-psutil/latest/linux/x86_64/snap-plugin-collector-psutil && chmod 755 snap-plugin-collector-psutil)
(cd $PLUGIN_PATH && curl -sfLSO http://snap.ci.snap-telemetry.io/snap/master/latest/snap-plugin-publisher-mock-file && chmod 755 snap-plugin-publisher-mock-file)
(cd $PLUGIN_PATH && curl -sfLSO http://snap.ci.snap-telemetry.io/snap/master/latest/snap-plugin-processor-passthru && chmod 755 snap-plugin-processor-passthru)
(cd $PLUGIN_PATH && curl -sfLSO http://snap.ci.snap-telemetry.io/plugins/snap-plugin-collector-psutil/latest_build/linux/x86_64/snap-plugin-collector-psutil && chmod 755 snap-plugin-collector-psutil)

SNAP_FLAG=0

Expand Down Expand Up @@ -50,4 +50,4 @@ if [ $SNAP_FLAG -eq 0 ]
then
echo "Could not load snapctl or snapd"
exit 1
fi
fi
7 changes: 6 additions & 1 deletion examples/tasks/run-mock-psutil.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,10 @@ export PLUGIN_SRC="${__proj_dir}"

# downloads plugins, starts snap, load plugins and start a task
__id=$(docker run -e SNAP_VERSION=latest -d -v ${PLUGIN_SRC}:/${__proj_name} --net=host intelsdi/snap:alpine)
# clean up containers on exit
function finish {
(docker kill ${__id})
}
trap finish EXIT INT TERM

docker exec -it ${__id} bash -c "PLUGIN_PATH=/etc/snap/plugins /${__proj_name}/examples/tasks/mock-psutil.sh && printf \"\n\nhint: type 'snapctl task list'\ntype 'exit' when your done\n\n\" && bash"
docker kill ${__id}
196 changes: 103 additions & 93 deletions psutil/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ package psutil

import (
"fmt"
"regexp"
"runtime"
"time"

"github.com/intelsdi-x/snap/control/plugin"
"github.com/intelsdi-x/snap/core"
Expand Down Expand Up @@ -75,84 +75,106 @@ var cpuLabels = map[string]label{
},
}

func cpuTimes(ns core.Namespace) (*plugin.MetricType, error) {
cpus, err := cpu.Times(true)
func cpuTimes(nss []core.Namespace) ([]plugin.MetricType, error) {
// gather metrics per each cpu
timesCPUs, err := cpu.Times(true)
if err != nil {
return nil, err
}

for _, cpu := range cpus {
switch {
case regexp.MustCompile(`^/intel/psutil/cpu.*/user`).MatchString(ns.String()):
return &plugin.MetricType{
Namespace_: ns,
Data_: cpu.User,
Unit_: cpuLabels["cpu"].unit,
}, nil
case regexp.MustCompile(`^/intel/psutil/cpu.*/system`).MatchString(ns.String()):
return &plugin.MetricType{
Namespace_: ns,
Data_: cpu.System,
Unit_: cpuLabels["system"].unit,
}, nil
case regexp.MustCompile(`^/intel/psutil/cpu.*/idle`).MatchString(ns.String()):
return &plugin.MetricType{
Namespace_: ns,
Unit_: cpuLabels["idle"].unit,
}, nil
case regexp.MustCompile(`^/intel/psutil/cpu.*/nice`).MatchString(ns.String()):
return &plugin.MetricType{
Namespace_: ns,
Data_: cpu.Nice,
Unit_: cpuLabels["nice"].unit,
}, nil
case regexp.MustCompile(`^/intel/psutil/cpu.*/iowait`).MatchString(ns.String()):
return &plugin.MetricType{
Namespace_: ns,
Data_: cpu.Iowait,
Unit_: cpuLabels["iowait"].unit,
}, nil
case regexp.MustCompile(`^/intel/psutil/cpu.*/irq`).MatchString(ns.String()):
return &plugin.MetricType{
Namespace_: ns,
Data_: cpu.Irq,
Unit_: cpuLabels["irq"].unit,
}, nil
case regexp.MustCompile(`^/intel/psutil/cpu.*/softirq`).MatchString(ns.String()):
return &plugin.MetricType{
Namespace_: ns,
Data_: cpu.Softirq,
Unit_: cpuLabels["softirq"].unit,
}, nil
case regexp.MustCompile(`^/intel/psutil/cpu.*/steal`).MatchString(ns.String()):
return &plugin.MetricType{
Namespace_: ns,
Data_: cpu.Steal,
Unit_: cpuLabels["steal"].unit,
}, nil
case regexp.MustCompile(`^/intel/psutil/cpu.*/guest`).MatchString(ns.String()):
return &plugin.MetricType{
Namespace_: ns,
Data_: cpu.Guest,
Unit_: cpuLabels["guest"].unit,
}, nil
case regexp.MustCompile(`^/intel/psutil/cpu.*/guest_nice`).MatchString(ns.String()):
return &plugin.MetricType{
Namespace_: ns,
Data_: cpu.GuestNice,
Unit_: cpuLabels["guest_nice"].unit,
}, nil
case regexp.MustCompile(`^/intel/psutil/cpu.*/stolen`).MatchString(ns.String()):
return &plugin.MetricType{
// gather accumulated metrics for all cpus
timesAll, err := cpu.Times(false)
if err != nil {
return nil, err
}

results := []plugin.MetricType{}

for _, ns := range nss {
// set requested metric name from last namespace element
metricName := ns.Element(len(ns) - 1).Value
// check if requested metric is dynamic (requesting metrics for all cpu ids)
if ns[3].Value == "*" {
for _, timesCPU := range timesCPUs {
// prepare namespace copy to update value
// this will allow to keep namespace as dynamic (name != "")
dyn := make([]core.NamespaceElement, len(ns))
copy(dyn, ns)
dyn[3].Value = timesCPU.CPU
// get requested metric value
val, err := getCPUTimeValue(&timesCPU, metricName)
if err != nil {
return nil, err
}
metric := plugin.MetricType{
Namespace_: dyn,
Data_: val,
Timestamp_: time.Now(),
Unit_: cpuLabels[metricName].unit,
}
results = append(results, metric)
}
} else {
timeStats := append(timesAll, timesCPUs...)
// find stats for interface name or all cpus
timeStat := findCPUTimeStat(timeStats, ns[3].Value)
if timeStat == nil {
return nil, fmt.Errorf("Requested cpu id %s not found", ns[3].Value)
}
// get requested metric value from struct
val, err := getCPUTimeValue(timeStat, metricName)
if err != nil {
return nil, err
}
metric := plugin.MetricType{
Namespace_: ns,
Data_: cpu.Stolen,
Unit_: cpuLabels["stolen"].unit,
}, nil
Data_: val,
Timestamp_: time.Now(),
Unit_: cpuLabels[metricName].unit,
}
results = append(results, metric)
}
}

return results, nil
}

func findCPUTimeStat(timeStats []cpu.TimesStat, name string) *cpu.TimesStat {
for _, timeStat := range timeStats {
if timeStat.CPU == name {
return &timeStat
}
}
return nil
}

return nil, fmt.Errorf("Unknown error processing %v", ns)
func getCPUTimeValue(stat *cpu.TimesStat, name string) (float64, error) {
switch name {
case "user":
return stat.User, nil
case "system":
return stat.System, nil
case "idle":
return stat.Idle, nil
case "nice":
return stat.Nice, nil
case "iowait":
return stat.Iowait, nil
case "irq":
return stat.Irq, nil
case "softirq":
return stat.Softirq, nil
case "steal":
return stat.Steal, nil
case "guest":
return stat.Guest, nil
case "guest_nice":
return stat.GuestNice, nil
case "stolen":
return stat.Stolen, nil
default:
return 0, fmt.Errorf("Requested CPUTime statistic %s is not available", name)
}
}

func getCPUTimesMetricTypes() ([]plugin.MetricType, error) {
Expand All @@ -161,33 +183,21 @@ func getCPUTimesMetricTypes() ([]plugin.MetricType, error) {
mts := []plugin.MetricType{}
switch runtime.GOOS {
case "linux":
c, err := cpu.Times(true)
if err != nil {
return nil, err
}
for _, i := range c {
for k, label := range cpuLabels {
mts = append(mts, plugin.MetricType{
Namespace_: core.NewNamespace("intel", "psutil", i.CPU, k),
Description_: label.description,
Unit_: label.unit,
})
}
}
case "windows":
_, err := cpu.Times(true)
if err != nil {
return nil, err
}

for _, label := range []string{"idle", "system", "user"} {
for k, label := range cpuLabels {
mts = append(mts, plugin.MetricType{
Namespace_: core.NewNamespace("intel", "psutil", "cpu").AddDynamicElement("cpu_id", "physical cpu id").AddStaticElement(k),
Description_: label.description,
Unit_: label.unit,
})
mts = append(mts, plugin.MetricType{
Namespace_: core.NewNamespace("intel", "psutil", "cpu", label),
Description_: cpuLabels[label].description,
Unit_: cpuLabels[label].unit,
Namespace_: core.NewNamespace("intel", "psutil", "cpu", "cpu-total").AddStaticElement(k),
Description_: label.description,
Unit_: label.unit,
})
}

default:
return nil, fmt.Errorf("%s not supported by plugin", runtime.GOOS)
}
return mts, nil
}
Loading

0 comments on commit d442d4c

Please sign in to comment.