fix merge conflicts, update import paths

This commit is contained in:
JP 2015-08-13 18:57:05 -05:00
commit 3145a732f2
14 changed files with 313 additions and 133 deletions

View File

@ -1,4 +1,10 @@
## v0.1.5 [unreleased]
## v0.1.6 [unreleased]
### Features
### Bugfixes
## v0.1.5 [2015-08-13]
### Features
- [#54](https://github.com/influxdb/telegraf/pull/54): MongoDB plugin. Thanks @jipperinbham!
@ -15,6 +21,8 @@
- [#103](https://github.com/influxdb/telegraf/pull/103): Filter by metric tags. Thanks @srfraser!
- [#106](https://github.com/influxdb/telegraf/pull/106): Options to filter plugins on startup. Thanks @zepouet!
- [#107](https://github.com/influxdb/telegraf/pull/107): Multiple outputs beyong influxdb. Thanks @jipperinbham!
- [#108](https://github.com/influxdb/telegraf/issues/108): Support setting per-CPU and total-CPU gathering.
- [#111](https://github.com/influxdb/telegraf/pull/111): Report CPU Usage in cpu plugin. Thanks @jpalay!
### Bugfixes
- [#85](https://github.com/influxdb/telegraf/pull/85): Fix GetLocalHost testutil function for mac users

128
README.md
View File

@ -18,9 +18,14 @@ writing new plugins.
### Linux packages for Debian/Ubuntu and RHEL/CentOS:
NOTE: version 0.1.5 has introduced some breaking changes! A 0.1.5 telegraf
agent is NOT backwards-compatible with a config file from 0.1.4 and below.
That being said, the difference is not huge, see below for an example on
how to setup the new config file.
```
http://get.influxdb.org/telegraf/telegraf_0.1.4_amd64.deb
http://get.influxdb.org/telegraf/telegraf-0.1.4-1.x86_64.rpm
http://get.influxdb.org/telegraf/telegraf_0.1.5_amd64.deb
http://get.influxdb.org/telegraf/telegraf-0.1.5-1.x86_64.rpm
```
### OSX via Homebrew:
@ -35,22 +40,10 @@ brew install telegraf
* Run `telegraf -sample-config > telegraf.toml` to create an initial configuration
* Edit the configuration to match your needs
* Run `telegraf -config telegraf.toml -test` to output one full measurement sample to STDOUT
* Run `telegraf -config telegraf.toml` to gather and send metrics to InfluxDB
* Run `telegraf -config telegraf.toml -filter system:swap` to enable only two plugins described into config file
* Run `telegraf -config telegraf.toml` to gather and send metrics to configured outputs.
* Run `telegraf -config telegraf.toml -filter system:swap`
to enable only the system & swap plugins defined in the config.
### Telegraf Usage
```telegraf --help```
* -config="": configuration file to load
* -debug=false: show metrics as they're generated to stdout
* -filter="": filter the plugins to enable, separator is :
* -httptest.serve="": if non-empty, httptest.NewServer serves on this address and blocks
* -pidfile="": file to write our pid to
* -sample-config=false: print out full sample configuration
* -test=false: gather metrics, print them out, and exit
* -version=false: display the version
## Telegraf Options
Telegraf has a few options you can configure under the `agent` section of the
@ -66,6 +59,62 @@ unit parser, ie "10s" for 10 seconds or "5m" for 5 minutes.
* **debug**: Set to true to gather and send metrics to STDOUT as well as
InfluxDB.
## Plugin Options
There are 5 configuration options that are configurable per plugin:
* **pass**: An array of strings that is used to filter metrics generated by the
current plugin. Each string in the array is tested as a prefix against metric names
and if it matches, the metric is emitted.
* **drop**: The inverse of pass, if a metric name matches, it is not emitted.
* **tagpass**: tag names and arrays of strings that are used to filter metrics by
the current plugin. Each string in the array is tested as an exact match against
the tag name, and if it matches the metric is emitted.
* **tagdrop**: The inverse of tagpass. If a tag matches, the metric is not emitted.
This is tested on metrics that have passed the tagpass test.
* **interval**: How often to gather this metric. Normal plugins use a single
global interval, but if one particular plugin should be run less or more often,
you can configure that here.
### Plugin Configuration Examples
This is a full working config that will output CPU data to an InfluxDB instance
at 192.168.59.103:8086, tagging measurements with dc="Denver-1". It will output
measurements at a 10s interval and will collect totalcpu & percpu data.
```
[outputs]
[outputs.influxdb]
url = "http://192.168.59.103:8086" # required.
database = "telegraf" # required.
[tags]
dc = "denver-1"
[agent]
interval = "10s"
# PLUGINS
[cpu]
percpu = true
totalcpu = true
```
Below is how to configure `tagpass` parameters (added in 0.1.5)
```
# Don't collect CPU data for cpu6 & cpu7
[cpu.tagdrop]
cpu = [ "cpu6", "cpu7" ]
[disk]
[disk.tagpass]
# tagpass conditions are OR, not AND.
# If the (filesystem is ext4 or xfs) OR (the path is /opt or /home)
# then the metric passes
fstype = [ "ext4", "xfs" ]
path = [ "/opt", "/home" ]
```
## Supported Plugins
Telegraf currently has support for collecting metrics from:
@ -87,51 +136,6 @@ Telegraf currently has support for collecting metrics from:
We'll be adding support for many more over the coming months. Read on if you
want to add support for another service or third-party API.
## Plugin Options
There are 3 configuration options that are configurable per plugin:
* **pass**: An array of strings that is used to filter metrics generated by the
current plugin. Each string in the array is tested as a prefix against metric names
and if it matches, the metric is emitted.
* **drop**: The inverse of pass, if a metric name matches, it is not emitted.
* **tagpass**: tag names and arrays of strings that are used to filter metrics by
the current plugin. Each string in the array is tested as an exact match against
the tag name, and if it matches the metric is emitted.
* **tagdrop**: The inverse of tagpass. If a tag matches, the metric is not emitted.
This is tested on metrics that have passed the tagpass test.
* **interval**: How often to gather this metric. Normal plugins use a single
global interval, but if one particular plugin should be run less or more often,
you can configure that here.
### Plugin Configuration Examples
```
# Read metrics about disk usage by mount point
[disk]
interval = "1m" # Run at a 1 minute interval instead of the default
[disk.tagpass]
# These tag conditions are OR, not AND.
# If the (filesystem is ext4 or xfs) or (the path is /opt or /home) then the metric passes
fstype = [ "ext4", "xfs" ]
path = [ "/opt", "/home" ]
[postgresql]
[postgresql.tagdrop]
# Don't report stats about the database name 'testdatabase'
db = [ "testdatabase" ]
```
```
[disk]
# Don't report stats about the following filesystem types
[disk.tagdrop]
fstype = [ "nfs", "tmpfs", "ecryptfs" ]
```
## Plugins
This section is for developers that want to create new collection plugins.

View File

@ -13,11 +13,11 @@ test:
# install binaries
- go install ./...
# Go fmt should pass all files
- "[ `git ls-files | grep '.go$' | xargs gofmt -l 2>&1 | wc -l` -eq 0 ]"
- "[ `git ls-files | grep '.go$' | xargs gofmt -l | tee /tmp/foo | wc -l` -eq 0 ] || (cat /tmp/foo; exit 1)"
- go vet ./...
- golint .
- golint testutil/...
- golint cmd/...
- "[ `golint . | tee /tmp/foo | wc -l` == 0 ] || (cat /tmp/foo; exit 1)"
- "[ `golint testutil/... | tee /tmp/foo | wc -l` == 0 ] || (cat /tmp/foo; exit 1)"
- "[ `golint cmd/... | tee /tmp/foo | wc -l` == 0 ] || (cat /tmp/foo; exit 1)"
override:
- make test-short
post:

View File

@ -8,9 +8,9 @@ import (
"os/signal"
"strings"
"github.com/influxdb/telegraf"
_ "github.com/influxdb/telegraf/outputs/all"
_ "github.com/influxdb/telegraf/plugins/all"
"github.com/jipperinbham/telegraf"
_ "github.com/jipperinbham/telegraf/outputs/all"
)
var fDebug = flag.Bool("debug", false, "show metrics as they're generated to stdout")
@ -22,7 +22,7 @@ var fPidfile = flag.String("pidfile", "", "file to write our pid to")
var fPLuginsFilter = flag.String("filter", "", "filter the plugins to enable, separator is :")
// Telegraf version
var Version = "0.1.5-dev"
var Version = "0.1.6-dev"
func main() {
flag.Parse()
@ -48,7 +48,9 @@ func main() {
log.Fatal(err)
}
} else {
config = telegraf.DefaultConfig()
fmt.Println("Usage: Telegraf")
flag.PrintDefaults()
return
}
ag, err := telegraf.NewAgent(config)
@ -65,7 +67,7 @@ func main() {
log.Fatal(err)
}
if len(outputs) == 0 {
log.Printf("Error: no outputs found, did you provide a config file?")
log.Printf("Error: no outputs found, did you provide a valid config file?")
os.Exit(1)
}
@ -74,7 +76,7 @@ func main() {
log.Fatal(err)
}
if len(plugins) == 0 {
log.Printf("Error: no plugins found, did you provide a config file?")
log.Printf("Error: no plugins found, did you provide a valid config file?")
os.Exit(1)
}
@ -116,7 +118,7 @@ func main() {
log.Printf("Agent Config: Interval:%s, Debug:%#v, Hostname:%#v\n",
ag.Interval, ag.Debug, ag.Hostname)
}
log.Printf("Tags enabled: %v", config.ListTags())
log.Printf("Tags enabled: %s", config.ListTags())
if *fPidfile != "" {
f, err := os.Create(*fPidfile)

View File

@ -51,7 +51,7 @@ func (c *Config) Outputs() map[string]*ast.Table {
return c.outputs
}
// The name of a tag, and the values on which to filter
// TagFilter is the name of a tag, and the values on which to filter
type TagFilter struct {
Name string
Filter []string
@ -253,11 +253,6 @@ func declared(endpoints map[string]*ast.Table) []string {
return names
}
// DefaultConfig returns an empty default configuration
func DefaultConfig() *Config {
return &Config{}
}
var errInvalidConfig = errors.New("invalid configuration")
// LoadConfig loads the given config file and returns a *Config pointer

View File

@ -1,6 +1,6 @@
package all
import (
_ "github.com/influxdb/telegraf/outputs/datadog"
_ "github.com/influxdb/telegraf/outputs/influxdb"
_ "github.com/jipperinbham/telegraf/outputs/datadog"
)

View File

@ -224,7 +224,7 @@ EOF
if [ $# -ne 1 ]; then
usage 1
elif [ $1 == "-h" ]; then
elif [ "$1" == "-h" ]; then
usage 0
else
VERSION=$1
@ -232,11 +232,11 @@ fi
echo -e "\nStarting package process...\n"
if [ $CIRCLE_BRANCH == "" ]; then
if [ "$CIRCLE_BRANCH" == "" ]; then
check_gvm
fi
check_gopath
if [ $CIRCLE_BRANCH == "" ]; then
if [ "$CIRCLE_BRANCH" == "" ]; then
check_clean_tree
update_tree
fi
@ -282,7 +282,7 @@ generate_postinstall_script $VERSION
###########################################################################
# Create the actual packages.
if [ $CIRCLE_BRANCH == "" ]; then
if [ "$CIRCLE_BRANCH" == "" ]; then
echo -n "Commence creation of $ARCH packages, version $VERSION? [Y/n] "
read response
response=`echo $response | tr 'A-Z' 'a-z'`
@ -323,7 +323,7 @@ echo "Debian package created successfully."
###########################################################################
# Offer to tag the repo.
if [ $CIRCLE_BRANCH == "" ]; then
if [ "$CIRCLE_BRANCH" == "" ]; then
echo -n "Tag source tree with v$VERSION and push to repo? [y/N] "
read response
response=`echo $response | tr 'A-Z' 'a-z'`
@ -347,7 +347,7 @@ fi
###########################################################################
# Offer to publish the packages.
if [ $CIRCLE_BRANCH == "" ]; then
if [ "$CIRCLE_BRANCH" == "" ]; then
echo -n "Publish packages to S3? [y/N] "
read response
response=`echo $response | tr 'A-Z' 'a-z'`

View File

@ -4,29 +4,51 @@ import (
"fmt"
"github.com/influxdb/telegraf/plugins"
"github.com/influxdb/telegraf/plugins/system/ps/cpu"
)
type CPUStats struct {
ps PS
ps PS
lastStats []cpu.CPUTimesStat
PerCPU bool `toml:"percpu"`
TotalCPU bool `toml:"totalcpu"`
}
func NewCPUStats(ps PS) *CPUStats {
return &CPUStats{
ps: ps,
}
}
func (_ *CPUStats) Description() string {
return "Read metrics about cpu usage"
}
func (_ *CPUStats) SampleConfig() string { return "" }
var sampleConfig = `
# Whether to report per-cpu stats or not
percpu = true
# Whether to report total system cpu stats or not
totalcpu = true`
func (_ *CPUStats) SampleConfig() string {
return sampleConfig
}
func (s *CPUStats) Gather(acc plugins.Accumulator) error {
times, err := s.ps.CPUTimes()
times, err := s.ps.CPUTimes(s.PerCPU, s.TotalCPU)
if err != nil {
return fmt.Errorf("error getting CPU info: %s", err)
}
for _, cts := range times {
for i, cts := range times {
tags := map[string]string{
"cpu": cts.CPU,
}
busy, total := busyAndTotalCpuTime(cts)
// Add total cpu numbers
add(acc, "user", cts.User, tags)
add(acc, "system", cts.System, tags)
add(acc, "idle", cts.Idle, tags)
@ -38,11 +60,54 @@ func (s *CPUStats) Gather(acc plugins.Accumulator) error {
add(acc, "guest", cts.Guest, tags)
add(acc, "guestNice", cts.GuestNice, tags)
add(acc, "stolen", cts.Stolen, tags)
add(acc, "busy", busy, tags)
// Add in percentage
if len(s.lastStats) == 0 {
// If it's the 1st gather, can't get CPU stats yet
continue
}
lastCts := s.lastStats[i]
lastBusy, lastTotal := busyAndTotalCpuTime(lastCts)
busyDelta := busy - lastBusy
totalDelta := total - lastTotal
if totalDelta < 0 {
return fmt.Errorf("Error: current total CPU time is less than previous total CPU time")
}
if totalDelta == 0 {
continue
}
add(acc, "percentageUser", 100*(cts.User-lastCts.User)/totalDelta, tags)
add(acc, "percentageSystem", 100*(cts.System-lastCts.System)/totalDelta, tags)
add(acc, "percentageIdle", 100*(cts.Idle-lastCts.Idle)/totalDelta, tags)
add(acc, "percentageNice", 100*(cts.Nice-lastCts.Nice)/totalDelta, tags)
add(acc, "percentageIowait", 100*(cts.Iowait-lastCts.Iowait)/totalDelta, tags)
add(acc, "percentageIrq", 100*(cts.Irq-lastCts.Irq)/totalDelta, tags)
add(acc, "percentageSoftirq", 100*(cts.Softirq-lastCts.Softirq)/totalDelta, tags)
add(acc, "percentageSteal", 100*(cts.Steal-lastCts.Steal)/totalDelta, tags)
add(acc, "percentageGuest", 100*(cts.Guest-lastCts.Guest)/totalDelta, tags)
add(acc, "percentageGuestNice", 100*(cts.GuestNice-lastCts.GuestNice)/totalDelta, tags)
add(acc, "percentageStolen", 100*(cts.Stolen-lastCts.Stolen)/totalDelta, tags)
add(acc, "percentageBusy", 100*busyDelta/totalDelta, tags)
}
s.lastStats = times
return nil
}
func busyAndTotalCpuTime(t cpu.CPUTimesStat) (float64, float64) {
busy := t.User + t.System + t.Nice + t.Iowait + t.Irq + t.Softirq + t.Steal +
t.Guest + t.GuestNice + t.Stolen
return busy, busy + t.Idle
}
func init() {
plugins.Add("cpu", func() plugins.Plugin {
return &CPUStats{ps: &systemPS{}}

View File

@ -21,7 +21,7 @@ func (m *MockPS) LoadAvg() (*load.LoadAvgStat, error) {
return r0, r1
}
func (m *MockPS) CPUTimes() ([]cpu.CPUTimesStat, error) {
func (m *MockPS) CPUTimes(perCPU, totalCPU bool) ([]cpu.CPUTimesStat, error) {
ret := m.Called()
r0 := ret.Get(0).([]cpu.CPUTimesStat)

View File

@ -25,7 +25,7 @@ type DockerContainerStat struct {
type PS interface {
LoadAvg() (*load.LoadAvgStat, error)
CPUTimes() ([]cpu.CPUTimesStat, error)
CPUTimes(perCPU, totalCPU bool) ([]cpu.CPUTimesStat, error)
DiskUsage() ([]*disk.DiskUsageStat, error)
NetIO() ([]net.NetIOCountersStat, error)
DiskIO() (map[string]disk.DiskIOCountersStat, error)
@ -49,8 +49,23 @@ func (s *systemPS) LoadAvg() (*load.LoadAvgStat, error) {
return load.LoadAvg()
}
func (s *systemPS) CPUTimes() ([]cpu.CPUTimesStat, error) {
return cpu.CPUTimes(true)
func (s *systemPS) CPUTimes(perCPU, totalCPU bool) ([]cpu.CPUTimesStat, error) {
var cpuTimes []cpu.CPUTimesStat
if perCPU {
if perCPUTimes, err := cpu.CPUTimes(true); err == nil {
cpuTimes = append(cpuTimes, perCPUTimes...)
} else {
return nil, err
}
}
if totalCPU {
if totalCPUTimes, err := cpu.CPUTimes(false); err == nil {
cpuTimes = append(cpuTimes, totalCPUTimes...)
} else {
return nil, err
}
}
return cpuTimes, nil
}
func (s *systemPS) DiskUsage() ([]*disk.DiskUsageStat, error) {

View File

@ -85,18 +85,11 @@ func perCPUTimes() ([]CPUTimesStat, error) {
}
c := CPUTimesStat{
CPU: fmt.Sprintf("cpu%d", i),
User: float64(cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec,
System: float64(cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec,
Nice: float64(cpu_ticks[C.CPU_STATE_NICE]) / ClocksPerSec,
Idle: float64(cpu_ticks[C.CPU_STATE_IDLE]) / ClocksPerSec,
Iowait: -1,
Irq: -1,
Softirq: -1,
Steal: -1,
Guest: -1,
GuestNice: -1,
Stolen: -1,
CPU: fmt.Sprintf("cpu%d", i),
User: float64(cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec,
System: float64(cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec,
Nice: float64(cpu_ticks[C.CPU_STATE_NICE]) / ClocksPerSec,
Idle: float64(cpu_ticks[C.CPU_STATE_IDLE]) / ClocksPerSec,
}
ret = append(ret, c)
@ -119,18 +112,11 @@ func allCPUTimes() ([]CPUTimesStat, error) {
}
c := CPUTimesStat{
CPU: "cpu-total",
User: float64(cpuload.cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec,
System: float64(cpuload.cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec,
Nice: float64(cpuload.cpu_ticks[C.CPU_STATE_NICE]) / ClocksPerSec,
Idle: float64(cpuload.cpu_ticks[C.CPU_STATE_IDLE]) / ClocksPerSec,
Iowait: -1,
Irq: -1,
Softirq: -1,
Steal: -1,
Guest: -1,
GuestNice: -1,
Stolen: -1,
CPU: "cpu-total",
User: float64(cpuload.cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec,
System: float64(cpuload.cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec,
Nice: float64(cpuload.cpu_ticks[C.CPU_STATE_NICE]) / ClocksPerSec,
Idle: float64(cpuload.cpu_ticks[C.CPU_STATE_IDLE]) / ClocksPerSec,
}
return []CPUTimesStat{c}, nil

View File

@ -1,6 +1,8 @@
package system
import (
"fmt"
"reflect"
"testing"
"github.com/influxdb/telegraf/plugins/system/ps/cpu"
@ -44,6 +46,21 @@ func TestSystemStats_GenerateStats(t *testing.T) {
Stolen: 0.051,
}
cts2 := cpu.CPUTimesStat{
CPU: "cpu0",
User: 11.4, // increased by 8.3
System: 10.9, // increased by 2.7
Idle: 158.8699, // increased by 78.7699 (for total increase of 100)
Nice: 2.5, // increased by 1.2
Iowait: 0.7, // increased by 0.5
Irq: 1.2, // increased by 1.1
Softirq: 0.31, // increased by 0.2
Steal: 0.0002, // increased by 0.0001
Guest: 12.9, // increased by 4.8
GuestNice: 2.524, // increased by 2.2
Stolen: 0.281, // increased by 0.23
}
mps.On("CPUTimes").Return([]cpu.CPUTimesStat{cts}, nil)
du := &disk.DiskUsageStat{
@ -171,26 +188,72 @@ func TestSystemStats_GenerateStats(t *testing.T) {
assert.True(t, acc.CheckValue("load5", 1.5))
assert.True(t, acc.CheckValue("load15", 0.8))
cs := &CPUStats{ps: &mps}
cs := NewCPUStats(&mps)
cputags := map[string]string{
"cpu": "cpu0",
}
preCPUPoints := len(acc.Points)
err = cs.Gather(&acc)
require.NoError(t, err)
numCPUPoints := len(acc.Points) - preCPUPoints
expectedCPUPoints := 12
assert.Equal(t, numCPUPoints, expectedCPUPoints)
// Computed values are checked with delta > 0 becasue of floating point arithmatic
// imprecision
assertContainsTaggedFloat(t, acc, "user", 3.1, 0, cputags)
assertContainsTaggedFloat(t, acc, "system", 8.2, 0, cputags)
assertContainsTaggedFloat(t, acc, "idle", 80.1, 0, cputags)
assertContainsTaggedFloat(t, acc, "nice", 1.3, 0, cputags)
assertContainsTaggedFloat(t, acc, "iowait", 0.2, 0, cputags)
assertContainsTaggedFloat(t, acc, "irq", 0.1, 0, cputags)
assertContainsTaggedFloat(t, acc, "softirq", 0.11, 0, cputags)
assertContainsTaggedFloat(t, acc, "steal", 0.0001, 0, cputags)
assertContainsTaggedFloat(t, acc, "guest", 8.1, 0, cputags)
assertContainsTaggedFloat(t, acc, "guestNice", 0.324, 0, cputags)
assertContainsTaggedFloat(t, acc, "stolen", 0.051, 0, cputags)
assertContainsTaggedFloat(t, acc, "busy", 21.4851, 0.0005, cputags)
mps2 := MockPS{}
mps2.On("CPUTimes").Return([]cpu.CPUTimesStat{cts2}, nil)
cs.ps = &mps2
// Should have added cpu percentages too
err = cs.Gather(&acc)
require.NoError(t, err)
assert.True(t, acc.CheckTaggedValue("user", 3.1, cputags))
assert.True(t, acc.CheckTaggedValue("system", 8.2, cputags))
assert.True(t, acc.CheckTaggedValue("idle", 80.1, cputags))
assert.True(t, acc.CheckTaggedValue("nice", 1.3, cputags))
assert.True(t, acc.CheckTaggedValue("iowait", 0.2, cputags))
assert.True(t, acc.CheckTaggedValue("irq", 0.1, cputags))
assert.True(t, acc.CheckTaggedValue("softirq", 0.11, cputags))
assert.True(t, acc.CheckTaggedValue("steal", 0.0001, cputags))
assert.True(t, acc.CheckTaggedValue("guest", 8.1, cputags))
assert.True(t, acc.CheckTaggedValue("guestNice", 0.324, cputags))
assert.True(t, acc.CheckTaggedValue("stolen", 0.051, cputags))
numCPUPoints = len(acc.Points) - (preCPUPoints + numCPUPoints)
expectedCPUPoints = 24
assert.Equal(t, numCPUPoints, expectedCPUPoints)
assertContainsTaggedFloat(t, acc, "user", 11.4, 0, cputags)
assertContainsTaggedFloat(t, acc, "system", 10.9, 0, cputags)
assertContainsTaggedFloat(t, acc, "idle", 158.8699, 0, cputags)
assertContainsTaggedFloat(t, acc, "nice", 2.5, 0, cputags)
assertContainsTaggedFloat(t, acc, "iowait", 0.7, 0, cputags)
assertContainsTaggedFloat(t, acc, "irq", 1.2, 0, cputags)
assertContainsTaggedFloat(t, acc, "softirq", 0.31, 0, cputags)
assertContainsTaggedFloat(t, acc, "steal", 0.0002, 0, cputags)
assertContainsTaggedFloat(t, acc, "guest", 12.9, 0, cputags)
assertContainsTaggedFloat(t, acc, "guestNice", 2.524, 0, cputags)
assertContainsTaggedFloat(t, acc, "stolen", 0.281, 0, cputags)
assertContainsTaggedFloat(t, acc, "busy", 42.7152, 0.0005, cputags)
assertContainsTaggedFloat(t, acc, "percentageUser", 8.3, 0.0005, cputags)
assertContainsTaggedFloat(t, acc, "percentageSystem", 2.7, 0.0005, cputags)
assertContainsTaggedFloat(t, acc, "percentageIdle", 78.7699, 0.0005, cputags)
assertContainsTaggedFloat(t, acc, "percentageNice", 1.2, 0.0005, cputags)
assertContainsTaggedFloat(t, acc, "percentageIowait", 0.5, 0.0005, cputags)
assertContainsTaggedFloat(t, acc, "percentageIrq", 1.1, 0.0005, cputags)
assertContainsTaggedFloat(t, acc, "percentageSoftirq", 0.2, 0.0005, cputags)
assertContainsTaggedFloat(t, acc, "percentageSteal", 0.0001, 0.0005, cputags)
assertContainsTaggedFloat(t, acc, "percentageGuest", 4.8, 0.0005, cputags)
assertContainsTaggedFloat(t, acc, "percentageGuestNice", 2.2, 0.0005, cputags)
assertContainsTaggedFloat(t, acc, "percentageStolen", 0.23, 0.0005, cputags)
assertContainsTaggedFloat(t, acc, "percentageBusy", 21.2301, 0.0005, cputags)
err = (&DiskStats{&mps}).Gather(&acc)
require.NoError(t, err)
@ -319,3 +382,44 @@ func TestSystemStats_GenerateStats(t *testing.T) {
assert.True(t, acc.CheckTaggedValue("total_active_file", uint64(26), dockertags))
assert.True(t, acc.CheckTaggedValue("total_unevictable", uint64(27), dockertags))
}
// Asserts that a given accumulator contains a measurment of type float64 with
// specific tags within a certain distance of a given expected value. Asserts a failure
// if the measurement is of the wrong type, or if no matching measurements are found
//
// Paramaters:
// t *testing.T : Testing object to use
// acc testutil.Accumulator: Accumulator to examine
// measurement string : Name of the measurement to examine
// expectedValue float64 : Value to search for within the measurement
// delta float64 : Maximum acceptable distance of an accumulated value
// from the expectedValue parameter. Useful when
// floating-point arithmatic imprecision makes looking
// for an exact match impractical
// tags map[string]string : Tag set the found measurement must have. Set to nil to
// ignore the tag set.
func assertContainsTaggedFloat(
t *testing.T,
acc testutil.Accumulator,
measurement string,
expectedValue float64,
delta float64,
tags map[string]string,
) {
for _, pt := range acc.Points {
if pt.Measurement == measurement {
if (tags == nil) || reflect.DeepEqual(pt.Tags, tags) {
if value, ok := pt.Values["value"].(float64); ok {
if (value >= expectedValue-delta) && (value <= expectedValue+delta) {
// Found the point, return without failing
return
}
} else {
assert.Fail(t, fmt.Sprintf("Measurement \"%s\" does not have type float64", measurement))
}
}
}
}
assert.Fail(t, fmt.Sprintf("Could not find measurement \"%s\" with requested tags within %f of %f", measurement, delta, expectedValue))
}

View File

@ -11,7 +11,7 @@ password = "root"
database = "telegraf"
[tags]
dc = "us-phx-1" }
dc = "us-phx-1"
[redis]
address = ":6379"

View File

@ -57,7 +57,8 @@ database = "telegraf" # required.
# Read metrics about cpu usage
[cpu]
# no configuration
totalcpu = true
percpu = false
# Read metrics about disk usage by mount point
[disk]