Compare commits
1 Commits
0.10.4
...
0.10.3-win
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0074696e67 |
19
CHANGELOG.md
19
CHANGELOG.md
@@ -1,30 +1,13 @@
|
|||||||
## v0.10.5 [unreleased]
|
## v0.10.4 [unreleased]
|
||||||
|
|
||||||
### Release Notes
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
### Bugfixes
|
|
||||||
|
|
||||||
## v0.10.4 [2016-02-24]
|
|
||||||
|
|
||||||
### Release Notes
|
|
||||||
- The pass/drop parameters have been renamed to fielddrop/fieldpass parameters,
|
|
||||||
to more accurately indicate their purpose.
|
|
||||||
- There are also now namedrop/namepass parameters for passing/dropping based
|
|
||||||
on the metric _name_.
|
|
||||||
- Experimental windows builds now available.
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
- [#727](https://github.com/influxdata/telegraf/pull/727): riak input, thanks @jcoene!
|
- [#727](https://github.com/influxdata/telegraf/pull/727): riak input, thanks @jcoene!
|
||||||
- [#694](https://github.com/influxdata/telegraf/pull/694): DNS Query input, thanks @mjasion!
|
- [#694](https://github.com/influxdata/telegraf/pull/694): DNS Query input, thanks @mjasion!
|
||||||
- [#724](https://github.com/influxdata/telegraf/pull/724): username matching for procstat input, thanks @zorel!
|
- [#724](https://github.com/influxdata/telegraf/pull/724): username matching for procstat input, thanks @zorel!
|
||||||
- [#736](https://github.com/influxdata/telegraf/pull/736): Ignore dummy filesystems from disk plugin. Thanks @PierreF!
|
- [#736](https://github.com/influxdata/telegraf/pull/736): Ignore dummy filesystems from disk plugin. Thanks @PierreF!
|
||||||
- [#737](https://github.com/influxdata/telegraf/pull/737): Support multiple fields for statsd input. Thanks @mattheath!
|
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
- [#701](https://github.com/influxdata/telegraf/pull/701): output write count shouldnt print in quiet mode.
|
- [#701](https://github.com/influxdata/telegraf/pull/701): output write count shouldnt print in quiet mode.
|
||||||
- [#746](https://github.com/influxdata/telegraf/pull/746): httpjson plugin: Fix HTTP GET parameters.
|
|
||||||
|
|
||||||
## v0.10.3 [2016-02-18]
|
## v0.10.3 [2016-02-18]
|
||||||
|
|
||||||
|
|||||||
24
README.md
24
README.md
@@ -27,12 +27,12 @@ the [release blog post](https://influxdata.com/blog/announcing-telegraf-0-10-0/)
|
|||||||
### Linux deb and rpm Packages:
|
### Linux deb and rpm Packages:
|
||||||
|
|
||||||
Latest:
|
Latest:
|
||||||
* http://get.influxdb.org/telegraf/telegraf_0.10.4-1_amd64.deb
|
* http://get.influxdb.org/telegraf/telegraf_0.10.3-1_amd64.deb
|
||||||
* http://get.influxdb.org/telegraf/telegraf-0.10.4-1.x86_64.rpm
|
* http://get.influxdb.org/telegraf/telegraf-0.10.3-1.x86_64.rpm
|
||||||
|
|
||||||
Latest (arm):
|
Latest (arm):
|
||||||
* http://get.influxdb.org/telegraf/telegraf_0.10.4-1_arm.deb
|
* http://get.influxdb.org/telegraf/telegraf_0.10.3-1_arm.deb
|
||||||
* http://get.influxdb.org/telegraf/telegraf-0.10.4-1.arm.rpm
|
* http://get.influxdb.org/telegraf/telegraf-0.10.3-1.arm.rpm
|
||||||
|
|
||||||
0.2.x:
|
0.2.x:
|
||||||
* http://get.influxdb.org/telegraf/telegraf_0.2.4_amd64.deb
|
* http://get.influxdb.org/telegraf/telegraf_0.2.4_amd64.deb
|
||||||
@@ -56,9 +56,9 @@ for instructions, replacing the `influxdb` package name with `telegraf`.
|
|||||||
### Linux tarballs:
|
### Linux tarballs:
|
||||||
|
|
||||||
Latest:
|
Latest:
|
||||||
* http://get.influxdb.org/telegraf/telegraf-0.10.4-1_linux_amd64.tar.gz
|
* http://get.influxdb.org/telegraf/telegraf-0.10.3-1_linux_amd64.tar.gz
|
||||||
* http://get.influxdb.org/telegraf/telegraf-0.10.4-1_linux_i386.tar.gz
|
* http://get.influxdb.org/telegraf/telegraf-0.10.3-1_linux_i386.tar.gz
|
||||||
* http://get.influxdb.org/telegraf/telegraf-0.10.4-1_linux_arm.tar.gz
|
* http://get.influxdb.org/telegraf/telegraf-0.10.3-1_linux_arm.tar.gz
|
||||||
|
|
||||||
0.2.x:
|
0.2.x:
|
||||||
* http://get.influxdb.org/telegraf/telegraf_linux_amd64_0.2.4.tar.gz
|
* http://get.influxdb.org/telegraf/telegraf_linux_amd64_0.2.4.tar.gz
|
||||||
@@ -70,13 +70,13 @@ Latest:
|
|||||||
To install the full directory structure with config file, run:
|
To install the full directory structure with config file, run:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo tar -C / -zxvf ./telegraf-0.10.4-1_linux_amd64.tar.gz
|
sudo tar -C / -zxvf ./telegraf-0.10.3-1_linux_amd64.tar.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
To extract only the binary, run:
|
To extract only the binary, run:
|
||||||
|
|
||||||
```
|
```
|
||||||
tar -zxvf telegraf-0.10.4-1_linux_amd64.tar.gz --strip-components=3 ./usr/bin/telegraf
|
tar -zxvf telegraf-0.10.3-1_linux_amd64.tar.gz --strip-components=3 ./usr/bin/telegraf
|
||||||
```
|
```
|
||||||
|
|
||||||
### Ansible Role:
|
### Ansible Role:
|
||||||
@@ -90,12 +90,6 @@ brew update
|
|||||||
brew install telegraf
|
brew install telegraf
|
||||||
```
|
```
|
||||||
|
|
||||||
### Windows Binaries (EXPERIMENTAL)
|
|
||||||
|
|
||||||
Latest:
|
|
||||||
* http://get.influxdb.org/telegraf/telegraf-0.10.4-1_windows_amd64.zip
|
|
||||||
* http://get.influxdb.org/telegraf/telegraf-0.10.4-1_windows_i386.zip
|
|
||||||
|
|
||||||
### From Source:
|
### From Source:
|
||||||
|
|
||||||
Telegraf manages dependencies via [gdm](https://github.com/sparrc/gdm),
|
Telegraf manages dependencies via [gdm](https://github.com/sparrc/gdm),
|
||||||
|
|||||||
@@ -1,164 +0,0 @@
|
|||||||
# Telegraf configuration
|
|
||||||
|
|
||||||
# Telegraf is entirely plugin driven. All metrics are gathered from the
|
|
||||||
# declared inputs, and sent to the declared outputs.
|
|
||||||
|
|
||||||
# Plugins must be declared in here to be active.
|
|
||||||
# To deactivate a plugin, comment out the name and any variables.
|
|
||||||
|
|
||||||
# Use 'telegraf -config telegraf.conf -test' to see what metrics a config
|
|
||||||
# file would generate.
|
|
||||||
|
|
||||||
# Global tags can be specified here in key="value" format.
|
|
||||||
[global_tags]
|
|
||||||
# dc = "us-east-1" # will tag all metrics with dc=us-east-1
|
|
||||||
# rack = "1a"
|
|
||||||
|
|
||||||
# Configuration for telegraf agent
|
|
||||||
[agent]
|
|
||||||
## Default data collection interval for all inputs
|
|
||||||
interval = "10s"
|
|
||||||
## Rounds collection interval to 'interval'
|
|
||||||
## ie, if interval="10s" then always collect on :00, :10, :20, etc.
|
|
||||||
round_interval = true
|
|
||||||
|
|
||||||
## Telegraf will cache metric_buffer_limit metrics for each output, and will
|
|
||||||
## flush this buffer on a successful write.
|
|
||||||
metric_buffer_limit = 10000
|
|
||||||
## Flush the buffer whenever full, regardless of flush_interval.
|
|
||||||
flush_buffer_when_full = true
|
|
||||||
|
|
||||||
## Collection jitter is used to jitter the collection by a random amount.
|
|
||||||
## Each plugin will sleep for a random time within jitter before collecting.
|
|
||||||
## This can be used to avoid many plugins querying things like sysfs at the
|
|
||||||
## same time, which can have a measurable effect on the system.
|
|
||||||
collection_jitter = "0s"
|
|
||||||
|
|
||||||
## Default flushing interval for all outputs. You shouldn't set this below
|
|
||||||
## interval. Maximum flush_interval will be flush_interval + flush_jitter
|
|
||||||
flush_interval = "10s"
|
|
||||||
## Jitter the flush interval by a random amount. This is primarily to avoid
|
|
||||||
## large write spikes for users running a large number of telegraf instances.
|
|
||||||
## ie, a jitter of 5s and interval 10s means flushes will happen every 10-15s
|
|
||||||
flush_jitter = "0s"
|
|
||||||
|
|
||||||
## Run telegraf in debug mode
|
|
||||||
debug = false
|
|
||||||
## Run telegraf in quiet mode
|
|
||||||
quiet = false
|
|
||||||
## Override default hostname, if empty use os.Hostname()
|
|
||||||
hostname = ""
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# OUTPUTS #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
# Configuration for influxdb server to send metrics to
|
|
||||||
[[outputs.influxdb]]
|
|
||||||
# The full HTTP or UDP endpoint URL for your InfluxDB instance.
|
|
||||||
# Multiple urls can be specified but it is assumed that they are part of the same
|
|
||||||
# cluster, this means that only ONE of the urls will be written to each interval.
|
|
||||||
# urls = ["udp://localhost:8089"] # UDP endpoint example
|
|
||||||
urls = ["http://localhost:8086"] # required
|
|
||||||
# The target database for metrics (telegraf will create it if not exists)
|
|
||||||
database = "telegraf" # required
|
|
||||||
# Precision of writes, valid values are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
|
||||||
# note: using second precision greatly helps InfluxDB compression
|
|
||||||
precision = "s"
|
|
||||||
|
|
||||||
## Write timeout (for the InfluxDB client), formatted as a string.
|
|
||||||
## If not provided, will default to 5s. 0s means no timeout (not recommended).
|
|
||||||
timeout = "5s"
|
|
||||||
# username = "telegraf"
|
|
||||||
# password = "metricsmetricsmetricsmetrics"
|
|
||||||
# Set the user agent for HTTP POSTs (can be useful for log differentiation)
|
|
||||||
# user_agent = "telegraf"
|
|
||||||
# Set UDP payload size, defaults to InfluxDB UDP Client default (512 bytes)
|
|
||||||
# udp_payload = 512
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# INPUTS #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
# Windows Performance Counters plugin.
|
|
||||||
# These are the recommended method of monitoring system metrics on windows,
|
|
||||||
# as the regular system plugins (inputs.cpu, inputs.mem, etc.) rely on WMI,
|
|
||||||
# which utilizes a lot of system resources.
|
|
||||||
#
|
|
||||||
# See more configuration examples at:
|
|
||||||
# https://github.com/influxdata/telegraf/tree/master/plugins/inputs/win_perf_counters
|
|
||||||
|
|
||||||
[[inputs.win_perf_counters]]
|
|
||||||
[[inputs.win_perf_counters.object]]
|
|
||||||
# Processor usage, alternative to native, reports on a per core.
|
|
||||||
ObjectName = "Processor"
|
|
||||||
Instances = ["*"]
|
|
||||||
Counters = ["% Idle Time", "% Interrupt Time", "% Privileged Time", "% User Time", "% Processor Time"]
|
|
||||||
Measurement = "win_cpu"
|
|
||||||
#IncludeTotal=false #Set to true to include _Total instance when querying for all (*).
|
|
||||||
|
|
||||||
[[inputs.win_perf_counters.object]]
|
|
||||||
# Disk times and queues
|
|
||||||
ObjectName = "LogicalDisk"
|
|
||||||
Instances = ["*"]
|
|
||||||
Counters = ["% Idle Time", "% Disk Time","% Disk Read Time", "% Disk Write Time", "% User Time", "Current Disk Queue Length"]
|
|
||||||
Measurement = "win_disk"
|
|
||||||
#IncludeTotal=false #Set to true to include _Total instance when querying for all (*).
|
|
||||||
|
|
||||||
[[inputs.win_perf_counters.object]]
|
|
||||||
ObjectName = "System"
|
|
||||||
Counters = ["Context Switches/sec","System Calls/sec"]
|
|
||||||
Instances = ["------"]
|
|
||||||
Measurement = "win_system"
|
|
||||||
#IncludeTotal=false #Set to true to include _Total instance when querying for all (*).
|
|
||||||
|
|
||||||
[[inputs.win_perf_counters.object]]
|
|
||||||
# Example query where the Instance portion must be removed to get data back, such as from the Memory object.
|
|
||||||
ObjectName = "Memory"
|
|
||||||
Counters = ["Available Bytes","Cache Faults/sec","Demand Zero Faults/sec","Page Faults/sec","Pages/sec","Transition Faults/sec","Pool Nonpaged Bytes","Pool Paged Bytes"]
|
|
||||||
Instances = ["------"] # Use 6 x - to remove the Instance bit from the query.
|
|
||||||
Measurement = "win_mem"
|
|
||||||
#IncludeTotal=false #Set to true to include _Total instance when querying for all (*).
|
|
||||||
|
|
||||||
|
|
||||||
# Windows system plugins using WMI (disabled by default, using
|
|
||||||
# win_perf_counters over WMI is recommended)
|
|
||||||
|
|
||||||
# Read metrics about cpu usage
|
|
||||||
#[[inputs.cpu]]
|
|
||||||
## Whether to report per-cpu stats or not
|
|
||||||
#percpu = true
|
|
||||||
## Whether to report total system cpu stats or not
|
|
||||||
#totalcpu = true
|
|
||||||
## Comment this line if you want the raw CPU time metrics
|
|
||||||
#fielddrop = ["time_*"]
|
|
||||||
|
|
||||||
# Read metrics about disk usage by mount point
|
|
||||||
#[[inputs.disk]]
|
|
||||||
## By default, telegraf gather stats for all mountpoints.
|
|
||||||
## Setting mountpoints will restrict the stats to the specified mountpoints.
|
|
||||||
## mount_points=["/"]
|
|
||||||
|
|
||||||
## Ignore some mountpoints by filesystem type. For example (dev)tmpfs (usually
|
|
||||||
## present on /run, /var/run, /dev/shm or /dev).
|
|
||||||
#ignore_fs = ["tmpfs", "devtmpfs"]
|
|
||||||
|
|
||||||
# Read metrics about disk IO by device
|
|
||||||
#[[inputs.diskio]]
|
|
||||||
## By default, telegraf will gather stats for all devices including
|
|
||||||
## disk partitions.
|
|
||||||
## Setting devices will restrict the stats to the specified devices.
|
|
||||||
## devices = ["sda", "sdb"]
|
|
||||||
## Uncomment the following line if you do not need disk serial numbers.
|
|
||||||
## skip_serial_number = true
|
|
||||||
|
|
||||||
# Read metrics about memory usage
|
|
||||||
#[[inputs.mem]]
|
|
||||||
# no configuration
|
|
||||||
|
|
||||||
# Read metrics about swap memory usage
|
|
||||||
#[[inputs.swap]]
|
|
||||||
# no configuration
|
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var servers = []string{"8.8.8.8"}
|
var servers = []string{"8.8.8.8"}
|
||||||
var domains = []string{"google.com"}
|
var domains = []string{"mjasion.pl"}
|
||||||
|
|
||||||
func TestGathering(t *testing.T) {
|
func TestGathering(t *testing.T) {
|
||||||
var dnsConfig = DnsQuery{
|
var dnsConfig = DnsQuery{
|
||||||
@@ -18,10 +18,8 @@ func TestGathering(t *testing.T) {
|
|||||||
}
|
}
|
||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
|
|
||||||
err := dnsConfig.Gather(&acc)
|
dnsConfig.Gather(&acc)
|
||||||
assert.NoError(t, err)
|
metric, _ := acc.Get("dns_query")
|
||||||
metric, ok := acc.Get("dns_query")
|
|
||||||
assert.True(t, ok)
|
|
||||||
queryTime, _ := metric.Fields["query_time_ms"].(float64)
|
queryTime, _ := metric.Fields["query_time_ms"].(float64)
|
||||||
|
|
||||||
assert.NotEqual(t, 0, queryTime)
|
assert.NotEqual(t, 0, queryTime)
|
||||||
@@ -35,10 +33,8 @@ func TestGatheringMxRecord(t *testing.T) {
|
|||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
dnsConfig.RecordType = "MX"
|
dnsConfig.RecordType = "MX"
|
||||||
|
|
||||||
err := dnsConfig.Gather(&acc)
|
dnsConfig.Gather(&acc)
|
||||||
assert.NoError(t, err)
|
metric, _ := acc.Get("dns_query")
|
||||||
metric, ok := acc.Get("dns_query")
|
|
||||||
assert.True(t, ok)
|
|
||||||
queryTime, _ := metric.Fields["query_time_ms"].(float64)
|
queryTime, _ := metric.Fields["query_time_ms"].(float64)
|
||||||
|
|
||||||
assert.NotEqual(t, 0, queryTime)
|
assert.NotEqual(t, 0, queryTime)
|
||||||
@@ -58,10 +54,8 @@ func TestGatheringRootDomain(t *testing.T) {
|
|||||||
}
|
}
|
||||||
fields := map[string]interface{}{}
|
fields := map[string]interface{}{}
|
||||||
|
|
||||||
err := dnsConfig.Gather(&acc)
|
dnsConfig.Gather(&acc)
|
||||||
assert.NoError(t, err)
|
metric, _ := acc.Get("dns_query")
|
||||||
metric, ok := acc.Get("dns_query")
|
|
||||||
assert.True(t, ok)
|
|
||||||
queryTime, _ := metric.Fields["query_time_ms"].(float64)
|
queryTime, _ := metric.Fields["query_time_ms"].(float64)
|
||||||
|
|
||||||
fields["query_time_ms"] = queryTime
|
fields["query_time_ms"] = queryTime
|
||||||
@@ -76,15 +70,13 @@ func TestMetricContainsServerAndDomainAndRecordTypeTags(t *testing.T) {
|
|||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
tags := map[string]string{
|
tags := map[string]string{
|
||||||
"server": "8.8.8.8",
|
"server": "8.8.8.8",
|
||||||
"domain": "google.com",
|
"domain": "mjasion.pl",
|
||||||
"record_type": "NS",
|
"record_type": "NS",
|
||||||
}
|
}
|
||||||
fields := map[string]interface{}{}
|
fields := map[string]interface{}{}
|
||||||
|
|
||||||
err := dnsConfig.Gather(&acc)
|
dnsConfig.Gather(&acc)
|
||||||
assert.NoError(t, err)
|
metric, _ := acc.Get("dns_query")
|
||||||
metric, ok := acc.Get("dns_query")
|
|
||||||
assert.True(t, ok)
|
|
||||||
queryTime, _ := metric.Fields["query_time_ms"].(float64)
|
queryTime, _ := metric.Fields["query_time_ms"].(float64)
|
||||||
|
|
||||||
fields["query_time_ms"] = queryTime
|
fields["query_time_ms"] = queryTime
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package httpjson
|
package httpjson
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -22,8 +23,7 @@ type HttpJson struct {
|
|||||||
TagKeys []string
|
TagKeys []string
|
||||||
Parameters map[string]string
|
Parameters map[string]string
|
||||||
Headers map[string]string
|
Headers map[string]string
|
||||||
|
client HTTPClient
|
||||||
client HTTPClient
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type HTTPClient interface {
|
type HTTPClient interface {
|
||||||
@@ -182,14 +182,15 @@ func (h *HttpJson) sendRequest(serverURL string) (string, float64, error) {
|
|||||||
return "", -1, fmt.Errorf("Invalid server URL \"%s\"", serverURL)
|
return "", -1, fmt.Errorf("Invalid server URL \"%s\"", serverURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params := url.Values{}
|
||||||
data := url.Values{}
|
data := url.Values{}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case h.Method == "GET":
|
case h.Method == "GET":
|
||||||
params := requestURL.Query()
|
requestURL.RawQuery = params.Encode()
|
||||||
for k, v := range h.Parameters {
|
for k, v := range h.Parameters {
|
||||||
params.Add(k, v)
|
params.Add(k, v)
|
||||||
}
|
}
|
||||||
requestURL.RawQuery = params.Encode()
|
|
||||||
|
|
||||||
case h.Method == "POST":
|
case h.Method == "POST":
|
||||||
requestURL.RawQuery = ""
|
requestURL.RawQuery = ""
|
||||||
@@ -199,8 +200,7 @@ func (h *HttpJson) sendRequest(serverURL string) (string, float64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create + send request
|
// Create + send request
|
||||||
req, err := http.NewRequest(h.Method, requestURL.String(),
|
req, err := http.NewRequest(h.Method, requestURL.String(), bytes.NewBufferString(data.Encode()))
|
||||||
strings.NewReader(data.Encode()))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", -1, err
|
return "", -1, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package httpjson
|
package httpjson
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -29,75 +27,6 @@ const validJSON = `
|
|||||||
"another_list": [4]
|
"another_list": [4]
|
||||||
}`
|
}`
|
||||||
|
|
||||||
const validJSON2 = `{
|
|
||||||
"user":{
|
|
||||||
"hash_rate":0,
|
|
||||||
"expected_24h_rewards":0,
|
|
||||||
"total_rewards":0.000595109232,
|
|
||||||
"paid_rewards":0,
|
|
||||||
"unpaid_rewards":0.000595109232,
|
|
||||||
"past_24h_rewards":0,
|
|
||||||
"total_work":"5172625408",
|
|
||||||
"blocks_found":0
|
|
||||||
},
|
|
||||||
"workers":{
|
|
||||||
"brminer.1":{
|
|
||||||
"hash_rate":0,
|
|
||||||
"hash_rate_24h":0,
|
|
||||||
"valid_shares":"6176",
|
|
||||||
"stale_shares":"0",
|
|
||||||
"invalid_shares":"0",
|
|
||||||
"rewards":4.5506464e-5,
|
|
||||||
"rewards_24h":0,
|
|
||||||
"reset_time":1455409950
|
|
||||||
},
|
|
||||||
"brminer.2":{
|
|
||||||
"hash_rate":0,
|
|
||||||
"hash_rate_24h":0,
|
|
||||||
"valid_shares":"0",
|
|
||||||
"stale_shares":"0",
|
|
||||||
"invalid_shares":"0",
|
|
||||||
"rewards":0,
|
|
||||||
"rewards_24h":0,
|
|
||||||
"reset_time":1455936726
|
|
||||||
},
|
|
||||||
"brminer.3":{
|
|
||||||
"hash_rate":0,
|
|
||||||
"hash_rate_24h":0,
|
|
||||||
"valid_shares":"0",
|
|
||||||
"stale_shares":"0",
|
|
||||||
"invalid_shares":"0",
|
|
||||||
"rewards":0,
|
|
||||||
"rewards_24h":0,
|
|
||||||
"reset_time":1455936733
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pool":{
|
|
||||||
"hash_rate":114100000,
|
|
||||||
"active_users":843,
|
|
||||||
"total_work":"5015346808842682368",
|
|
||||||
"pps_ratio":1.04,
|
|
||||||
"pps_rate":7.655e-9
|
|
||||||
},
|
|
||||||
"network":{
|
|
||||||
"hash_rate":1426117703,
|
|
||||||
"block_number":944895,
|
|
||||||
"time_per_block":156,
|
|
||||||
"difficulty":51825.72835216,
|
|
||||||
"next_difficulty":51916.15249019,
|
|
||||||
"retarget_time":95053
|
|
||||||
},
|
|
||||||
"market":{
|
|
||||||
"ltc_btc":0.00798,
|
|
||||||
"ltc_usd":3.37801,
|
|
||||||
"ltc_eur":3.113,
|
|
||||||
"ltc_gbp":2.32807,
|
|
||||||
"ltc_rub":241.796,
|
|
||||||
"ltc_cny":21.3883,
|
|
||||||
"btc_usd":422.852
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
|
|
||||||
const validJSONTags = `
|
const validJSONTags = `
|
||||||
{
|
{
|
||||||
"value": 15,
|
"value": 15,
|
||||||
@@ -220,222 +149,6 @@ func TestHttpJson200(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that GET Parameters from the url string are applied properly
|
|
||||||
func TestHttpJsonGET_URL(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
key := r.FormValue("api_key")
|
|
||||||
assert.Equal(t, "mykey", key)
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
fmt.Fprintln(w, validJSON2)
|
|
||||||
}))
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
a := HttpJson{
|
|
||||||
Servers: []string{ts.URL + "?api_key=mykey"},
|
|
||||||
Name: "",
|
|
||||||
Method: "GET",
|
|
||||||
client: RealHTTPClient{client: &http.Client{}},
|
|
||||||
}
|
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
err := a.Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// remove response_time from gathered fields because it's non-deterministic
|
|
||||||
delete(acc.Metrics[0].Fields, "response_time")
|
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
|
||||||
"market_btc_usd": float64(422.852),
|
|
||||||
"market_ltc_btc": float64(0.00798),
|
|
||||||
"market_ltc_cny": float64(21.3883),
|
|
||||||
"market_ltc_eur": float64(3.113),
|
|
||||||
"market_ltc_gbp": float64(2.32807),
|
|
||||||
"market_ltc_rub": float64(241.796),
|
|
||||||
"market_ltc_usd": float64(3.37801),
|
|
||||||
"network_block_number": float64(944895),
|
|
||||||
"network_difficulty": float64(51825.72835216),
|
|
||||||
"network_hash_rate": float64(1.426117703e+09),
|
|
||||||
"network_next_difficulty": float64(51916.15249019),
|
|
||||||
"network_retarget_time": float64(95053),
|
|
||||||
"network_time_per_block": float64(156),
|
|
||||||
"pool_active_users": float64(843),
|
|
||||||
"pool_hash_rate": float64(1.141e+08),
|
|
||||||
"pool_pps_rate": float64(7.655e-09),
|
|
||||||
"pool_pps_ratio": float64(1.04),
|
|
||||||
"user_blocks_found": float64(0),
|
|
||||||
"user_expected_24h_rewards": float64(0),
|
|
||||||
"user_hash_rate": float64(0),
|
|
||||||
"user_paid_rewards": float64(0),
|
|
||||||
"user_past_24h_rewards": float64(0),
|
|
||||||
"user_total_rewards": float64(0.000595109232),
|
|
||||||
"user_unpaid_rewards": float64(0.000595109232),
|
|
||||||
"workers_brminer.1_hash_rate": float64(0),
|
|
||||||
"workers_brminer.1_hash_rate_24h": float64(0),
|
|
||||||
"workers_brminer.1_reset_time": float64(1.45540995e+09),
|
|
||||||
"workers_brminer.1_rewards": float64(4.5506464e-05),
|
|
||||||
"workers_brminer.1_rewards_24h": float64(0),
|
|
||||||
"workers_brminer.2_hash_rate": float64(0),
|
|
||||||
"workers_brminer.2_hash_rate_24h": float64(0),
|
|
||||||
"workers_brminer.2_reset_time": float64(1.455936726e+09),
|
|
||||||
"workers_brminer.2_rewards": float64(0),
|
|
||||||
"workers_brminer.2_rewards_24h": float64(0),
|
|
||||||
"workers_brminer.3_hash_rate": float64(0),
|
|
||||||
"workers_brminer.3_hash_rate_24h": float64(0),
|
|
||||||
"workers_brminer.3_reset_time": float64(1.455936733e+09),
|
|
||||||
"workers_brminer.3_rewards": float64(0),
|
|
||||||
"workers_brminer.3_rewards_24h": float64(0),
|
|
||||||
}
|
|
||||||
|
|
||||||
acc.AssertContainsFields(t, "httpjson", fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that GET Parameters are applied properly
|
|
||||||
func TestHttpJsonGET(t *testing.T) {
|
|
||||||
params := map[string]string{
|
|
||||||
"api_key": "mykey",
|
|
||||||
}
|
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
key := r.FormValue("api_key")
|
|
||||||
assert.Equal(t, "mykey", key)
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
fmt.Fprintln(w, validJSON2)
|
|
||||||
}))
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
a := HttpJson{
|
|
||||||
Servers: []string{ts.URL},
|
|
||||||
Name: "",
|
|
||||||
Method: "GET",
|
|
||||||
Parameters: params,
|
|
||||||
client: RealHTTPClient{client: &http.Client{}},
|
|
||||||
}
|
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
err := a.Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// remove response_time from gathered fields because it's non-deterministic
|
|
||||||
delete(acc.Metrics[0].Fields, "response_time")
|
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
|
||||||
"market_btc_usd": float64(422.852),
|
|
||||||
"market_ltc_btc": float64(0.00798),
|
|
||||||
"market_ltc_cny": float64(21.3883),
|
|
||||||
"market_ltc_eur": float64(3.113),
|
|
||||||
"market_ltc_gbp": float64(2.32807),
|
|
||||||
"market_ltc_rub": float64(241.796),
|
|
||||||
"market_ltc_usd": float64(3.37801),
|
|
||||||
"network_block_number": float64(944895),
|
|
||||||
"network_difficulty": float64(51825.72835216),
|
|
||||||
"network_hash_rate": float64(1.426117703e+09),
|
|
||||||
"network_next_difficulty": float64(51916.15249019),
|
|
||||||
"network_retarget_time": float64(95053),
|
|
||||||
"network_time_per_block": float64(156),
|
|
||||||
"pool_active_users": float64(843),
|
|
||||||
"pool_hash_rate": float64(1.141e+08),
|
|
||||||
"pool_pps_rate": float64(7.655e-09),
|
|
||||||
"pool_pps_ratio": float64(1.04),
|
|
||||||
"user_blocks_found": float64(0),
|
|
||||||
"user_expected_24h_rewards": float64(0),
|
|
||||||
"user_hash_rate": float64(0),
|
|
||||||
"user_paid_rewards": float64(0),
|
|
||||||
"user_past_24h_rewards": float64(0),
|
|
||||||
"user_total_rewards": float64(0.000595109232),
|
|
||||||
"user_unpaid_rewards": float64(0.000595109232),
|
|
||||||
"workers_brminer.1_hash_rate": float64(0),
|
|
||||||
"workers_brminer.1_hash_rate_24h": float64(0),
|
|
||||||
"workers_brminer.1_reset_time": float64(1.45540995e+09),
|
|
||||||
"workers_brminer.1_rewards": float64(4.5506464e-05),
|
|
||||||
"workers_brminer.1_rewards_24h": float64(0),
|
|
||||||
"workers_brminer.2_hash_rate": float64(0),
|
|
||||||
"workers_brminer.2_hash_rate_24h": float64(0),
|
|
||||||
"workers_brminer.2_reset_time": float64(1.455936726e+09),
|
|
||||||
"workers_brminer.2_rewards": float64(0),
|
|
||||||
"workers_brminer.2_rewards_24h": float64(0),
|
|
||||||
"workers_brminer.3_hash_rate": float64(0),
|
|
||||||
"workers_brminer.3_hash_rate_24h": float64(0),
|
|
||||||
"workers_brminer.3_reset_time": float64(1.455936733e+09),
|
|
||||||
"workers_brminer.3_rewards": float64(0),
|
|
||||||
"workers_brminer.3_rewards_24h": float64(0),
|
|
||||||
}
|
|
||||||
|
|
||||||
acc.AssertContainsFields(t, "httpjson", fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that POST Parameters are applied properly
|
|
||||||
func TestHttpJsonPOST(t *testing.T) {
|
|
||||||
params := map[string]string{
|
|
||||||
"api_key": "mykey",
|
|
||||||
}
|
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
body, err := ioutil.ReadAll(r.Body)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, "api_key=mykey", string(body))
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
fmt.Fprintln(w, validJSON2)
|
|
||||||
}))
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
a := HttpJson{
|
|
||||||
Servers: []string{ts.URL},
|
|
||||||
Name: "",
|
|
||||||
Method: "POST",
|
|
||||||
Parameters: params,
|
|
||||||
client: RealHTTPClient{client: &http.Client{}},
|
|
||||||
}
|
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
err := a.Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// remove response_time from gathered fields because it's non-deterministic
|
|
||||||
delete(acc.Metrics[0].Fields, "response_time")
|
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
|
||||||
"market_btc_usd": float64(422.852),
|
|
||||||
"market_ltc_btc": float64(0.00798),
|
|
||||||
"market_ltc_cny": float64(21.3883),
|
|
||||||
"market_ltc_eur": float64(3.113),
|
|
||||||
"market_ltc_gbp": float64(2.32807),
|
|
||||||
"market_ltc_rub": float64(241.796),
|
|
||||||
"market_ltc_usd": float64(3.37801),
|
|
||||||
"network_block_number": float64(944895),
|
|
||||||
"network_difficulty": float64(51825.72835216),
|
|
||||||
"network_hash_rate": float64(1.426117703e+09),
|
|
||||||
"network_next_difficulty": float64(51916.15249019),
|
|
||||||
"network_retarget_time": float64(95053),
|
|
||||||
"network_time_per_block": float64(156),
|
|
||||||
"pool_active_users": float64(843),
|
|
||||||
"pool_hash_rate": float64(1.141e+08),
|
|
||||||
"pool_pps_rate": float64(7.655e-09),
|
|
||||||
"pool_pps_ratio": float64(1.04),
|
|
||||||
"user_blocks_found": float64(0),
|
|
||||||
"user_expected_24h_rewards": float64(0),
|
|
||||||
"user_hash_rate": float64(0),
|
|
||||||
"user_paid_rewards": float64(0),
|
|
||||||
"user_past_24h_rewards": float64(0),
|
|
||||||
"user_total_rewards": float64(0.000595109232),
|
|
||||||
"user_unpaid_rewards": float64(0.000595109232),
|
|
||||||
"workers_brminer.1_hash_rate": float64(0),
|
|
||||||
"workers_brminer.1_hash_rate_24h": float64(0),
|
|
||||||
"workers_brminer.1_reset_time": float64(1.45540995e+09),
|
|
||||||
"workers_brminer.1_rewards": float64(4.5506464e-05),
|
|
||||||
"workers_brminer.1_rewards_24h": float64(0),
|
|
||||||
"workers_brminer.2_hash_rate": float64(0),
|
|
||||||
"workers_brminer.2_hash_rate_24h": float64(0),
|
|
||||||
"workers_brminer.2_reset_time": float64(1.455936726e+09),
|
|
||||||
"workers_brminer.2_rewards": float64(0),
|
|
||||||
"workers_brminer.2_rewards_24h": float64(0),
|
|
||||||
"workers_brminer.3_hash_rate": float64(0),
|
|
||||||
"workers_brminer.3_hash_rate_24h": float64(0),
|
|
||||||
"workers_brminer.3_reset_time": float64(1.455936733e+09),
|
|
||||||
"workers_brminer.3_rewards": float64(0),
|
|
||||||
"workers_brminer.3_rewards_24h": float64(0),
|
|
||||||
}
|
|
||||||
|
|
||||||
acc.AssertContainsFields(t, "httpjson", fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test response to HTTP 500
|
// Test response to HTTP 500
|
||||||
func TestHttpJson500(t *testing.T) {
|
func TestHttpJson500(t *testing.T) {
|
||||||
httpjson := genMockHttpJson(validJSON, 500)
|
httpjson := genMockHttpJson(validJSON, 500)
|
||||||
|
|||||||
@@ -17,11 +17,7 @@ import (
|
|||||||
"github.com/influxdata/telegraf/plugins/inputs"
|
"github.com/influxdata/telegraf/plugins/inputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const UDP_PACKET_SIZE int = 1500
|
||||||
UDP_PACKET_SIZE int = 1500
|
|
||||||
|
|
||||||
defaultFieldName = "value"
|
|
||||||
)
|
|
||||||
|
|
||||||
var dropwarn = "ERROR: Message queue full. Discarding line [%s] " +
|
var dropwarn = "ERROR: Message queue full. Discarding line [%s] " +
|
||||||
"You may want to increase allowed_pending_messages in the config\n"
|
"You may want to increase allowed_pending_messages in the config\n"
|
||||||
@@ -117,9 +113,9 @@ type cachedcounter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type cachedtimings struct {
|
type cachedtimings struct {
|
||||||
name string
|
name string
|
||||||
fields map[string]RunningStats
|
stats RunningStats
|
||||||
tags map[string]string
|
tags map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ *Statsd) Description() string {
|
func (_ *Statsd) Description() string {
|
||||||
@@ -173,26 +169,16 @@ func (s *Statsd) Gather(acc telegraf.Accumulator) error {
|
|||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
for _, metric := range s.timings {
|
for _, metric := range s.timings {
|
||||||
// Defining a template to parse field names for timers allows us to split
|
|
||||||
// out multiple fields per timer. In this case we prefix each stat with the
|
|
||||||
// field name and store these all in a single measurement.
|
|
||||||
fields := make(map[string]interface{})
|
fields := make(map[string]interface{})
|
||||||
for fieldName, stats := range metric.fields {
|
fields["mean"] = metric.stats.Mean()
|
||||||
var prefix string
|
fields["stddev"] = metric.stats.Stddev()
|
||||||
if fieldName != defaultFieldName {
|
fields["upper"] = metric.stats.Upper()
|
||||||
prefix = fieldName + "_"
|
fields["lower"] = metric.stats.Lower()
|
||||||
}
|
fields["count"] = metric.stats.Count()
|
||||||
fields[prefix+"mean"] = stats.Mean()
|
for _, percentile := range s.Percentiles {
|
||||||
fields[prefix+"stddev"] = stats.Stddev()
|
name := fmt.Sprintf("%v_percentile", percentile)
|
||||||
fields[prefix+"upper"] = stats.Upper()
|
fields[name] = metric.stats.Percentile(percentile)
|
||||||
fields[prefix+"lower"] = stats.Lower()
|
|
||||||
fields[prefix+"count"] = stats.Count()
|
|
||||||
for _, percentile := range s.Percentiles {
|
|
||||||
name := fmt.Sprintf("%s%v_percentile", prefix, percentile)
|
|
||||||
fields[name] = stats.Percentile(percentile)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.AddFields(metric.name, fields, metric.tags, now)
|
acc.AddFields(metric.name, fields, metric.tags, now)
|
||||||
}
|
}
|
||||||
if s.DeleteTimings {
|
if s.DeleteTimings {
|
||||||
@@ -384,6 +370,11 @@ func (s *Statsd) parseStatsdLine(line string) error {
|
|||||||
|
|
||||||
// Parse the name & tags from bucket
|
// Parse the name & tags from bucket
|
||||||
m.name, m.field, m.tags = s.parseName(m.bucket)
|
m.name, m.field, m.tags = s.parseName(m.bucket)
|
||||||
|
// fields are not supported for timings, so if specified combine into
|
||||||
|
// the name
|
||||||
|
if (m.mtype == "ms" || m.mtype == "h") && m.field != "value" {
|
||||||
|
m.name += "_" + m.field
|
||||||
|
}
|
||||||
switch m.mtype {
|
switch m.mtype {
|
||||||
case "c":
|
case "c":
|
||||||
m.tags["metric_type"] = "counter"
|
m.tags["metric_type"] = "counter"
|
||||||
@@ -442,7 +433,7 @@ func (s *Statsd) parseName(bucket string) (string, string, map[string]string) {
|
|||||||
name = strings.Replace(name, "-", "__", -1)
|
name = strings.Replace(name, "-", "__", -1)
|
||||||
}
|
}
|
||||||
if field == "" {
|
if field == "" {
|
||||||
field = defaultFieldName
|
field = "value"
|
||||||
}
|
}
|
||||||
|
|
||||||
return name, field, tags
|
return name, field, tags
|
||||||
@@ -470,32 +461,26 @@ func parseKeyValue(keyvalue string) (string, string) {
|
|||||||
func (s *Statsd) aggregate(m metric) {
|
func (s *Statsd) aggregate(m metric) {
|
||||||
switch m.mtype {
|
switch m.mtype {
|
||||||
case "ms", "h":
|
case "ms", "h":
|
||||||
// Check if the measurement exists
|
|
||||||
cached, ok := s.timings[m.hash]
|
cached, ok := s.timings[m.hash]
|
||||||
if !ok {
|
if !ok {
|
||||||
cached = cachedtimings{
|
cached = cachedtimings{
|
||||||
name: m.name,
|
name: m.name,
|
||||||
fields: make(map[string]RunningStats),
|
tags: m.tags,
|
||||||
tags: m.tags,
|
stats: RunningStats{
|
||||||
}
|
PercLimit: s.PercentileLimit,
|
||||||
}
|
},
|
||||||
// Check if the field exists. If we've not enabled multiple fields per timer
|
|
||||||
// this will be the default field name, eg. "value"
|
|
||||||
field, ok := cached.fields[m.field]
|
|
||||||
if !ok {
|
|
||||||
field = RunningStats{
|
|
||||||
PercLimit: s.PercentileLimit,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.samplerate > 0 {
|
if m.samplerate > 0 {
|
||||||
for i := 0; i < int(1.0/m.samplerate); i++ {
|
for i := 0; i < int(1.0/m.samplerate); i++ {
|
||||||
field.AddValue(m.floatvalue)
|
cached.stats.AddValue(m.floatvalue)
|
||||||
}
|
}
|
||||||
|
s.timings[m.hash] = cached
|
||||||
} else {
|
} else {
|
||||||
field.AddValue(m.floatvalue)
|
cached.stats.AddValue(m.floatvalue)
|
||||||
|
s.timings[m.hash] = cached
|
||||||
}
|
}
|
||||||
cached.fields[m.field] = field
|
|
||||||
s.timings[m.hash] = cached
|
|
||||||
case "c":
|
case "c":
|
||||||
// check if the measurement exists
|
// check if the measurement exists
|
||||||
_, ok := s.counters[m.hash]
|
_, ok := s.counters[m.hash]
|
||||||
|
|||||||
@@ -561,12 +561,12 @@ func TestParse_MeasurementsWithMultipleValues(t *testing.T) {
|
|||||||
// A 0 with invalid samplerate will add a single 0,
|
// A 0 with invalid samplerate will add a single 0,
|
||||||
// plus the last bit of value 1
|
// plus the last bit of value 1
|
||||||
// which adds up to 12 individual datapoints to be cached
|
// which adds up to 12 individual datapoints to be cached
|
||||||
if cachedtiming.fields[defaultFieldName].n != 12 {
|
if cachedtiming.stats.n != 12 {
|
||||||
t.Errorf("Expected 11 additions, got %d", cachedtiming.fields[defaultFieldName].n)
|
t.Errorf("Expected 11 additions, got %d", cachedtiming.stats.n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cachedtiming.fields[defaultFieldName].upper != 1 {
|
if cachedtiming.stats.upper != 1 {
|
||||||
t.Errorf("Expected max input to be 1, got %f", cachedtiming.fields[defaultFieldName].upper)
|
t.Errorf("Expected max input to be 1, got %f", cachedtiming.stats.upper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -842,105 +842,7 @@ func TestParse_Timings(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
acc.AssertContainsFields(t, "test_timing", valid)
|
acc.AssertContainsFields(t, "test_timing", valid)
|
||||||
}
|
|
||||||
|
|
||||||
// Tests low-level functionality of timings when multiple fields is enabled
|
|
||||||
// and a measurement template has been defined which can parse field names
|
|
||||||
func TestParse_Timings_MultipleFieldsWithTemplate(t *testing.T) {
|
|
||||||
s := NewStatsd()
|
|
||||||
s.Templates = []string{"measurement.field"}
|
|
||||||
s.Percentiles = []int{90}
|
|
||||||
acc := &testutil.Accumulator{}
|
|
||||||
|
|
||||||
validLines := []string{
|
|
||||||
"test_timing.success:1|ms",
|
|
||||||
"test_timing.success:11|ms",
|
|
||||||
"test_timing.success:1|ms",
|
|
||||||
"test_timing.success:1|ms",
|
|
||||||
"test_timing.success:1|ms",
|
|
||||||
"test_timing.error:2|ms",
|
|
||||||
"test_timing.error:22|ms",
|
|
||||||
"test_timing.error:2|ms",
|
|
||||||
"test_timing.error:2|ms",
|
|
||||||
"test_timing.error:2|ms",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, line := range validLines {
|
|
||||||
err := s.parseStatsdLine(line)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Parsing line %s should not have resulted in an error\n", line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.Gather(acc)
|
|
||||||
|
|
||||||
valid := map[string]interface{}{
|
|
||||||
"success_90_percentile": float64(11),
|
|
||||||
"success_count": int64(5),
|
|
||||||
"success_lower": float64(1),
|
|
||||||
"success_mean": float64(3),
|
|
||||||
"success_stddev": float64(4),
|
|
||||||
"success_upper": float64(11),
|
|
||||||
|
|
||||||
"error_90_percentile": float64(22),
|
|
||||||
"error_count": int64(5),
|
|
||||||
"error_lower": float64(2),
|
|
||||||
"error_mean": float64(6),
|
|
||||||
"error_stddev": float64(8),
|
|
||||||
"error_upper": float64(22),
|
|
||||||
}
|
|
||||||
|
|
||||||
acc.AssertContainsFields(t, "test_timing", valid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests low-level functionality of timings when multiple fields is enabled
|
|
||||||
// but a measurement template hasn't been defined so we can't parse field names
|
|
||||||
// In this case the behaviour should be the same as normal behaviour
|
|
||||||
func TestParse_Timings_MultipleFieldsWithoutTemplate(t *testing.T) {
|
|
||||||
s := NewStatsd()
|
|
||||||
s.Templates = []string{}
|
|
||||||
s.Percentiles = []int{90}
|
|
||||||
acc := &testutil.Accumulator{}
|
|
||||||
|
|
||||||
validLines := []string{
|
|
||||||
"test_timing.success:1|ms",
|
|
||||||
"test_timing.success:11|ms",
|
|
||||||
"test_timing.success:1|ms",
|
|
||||||
"test_timing.success:1|ms",
|
|
||||||
"test_timing.success:1|ms",
|
|
||||||
"test_timing.error:2|ms",
|
|
||||||
"test_timing.error:22|ms",
|
|
||||||
"test_timing.error:2|ms",
|
|
||||||
"test_timing.error:2|ms",
|
|
||||||
"test_timing.error:2|ms",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, line := range validLines {
|
|
||||||
err := s.parseStatsdLine(line)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Parsing line %s should not have resulted in an error\n", line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.Gather(acc)
|
|
||||||
|
|
||||||
expectedSuccess := map[string]interface{}{
|
|
||||||
"90_percentile": float64(11),
|
|
||||||
"count": int64(5),
|
|
||||||
"lower": float64(1),
|
|
||||||
"mean": float64(3),
|
|
||||||
"stddev": float64(4),
|
|
||||||
"upper": float64(11),
|
|
||||||
}
|
|
||||||
expectedError := map[string]interface{}{
|
|
||||||
"90_percentile": float64(22),
|
|
||||||
"count": int64(5),
|
|
||||||
"lower": float64(2),
|
|
||||||
"mean": float64(6),
|
|
||||||
"stddev": float64(8),
|
|
||||||
"upper": float64(22),
|
|
||||||
}
|
|
||||||
|
|
||||||
acc.AssertContainsFields(t, "test_timing_success", expectedSuccess)
|
|
||||||
acc.AssertContainsFields(t, "test_timing_error", expectedError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParse_Timings_Delete(t *testing.T) {
|
func TestParse_Timings_Delete(t *testing.T) {
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ INIT_SCRIPT = "scripts/init.sh"
|
|||||||
SYSTEMD_SCRIPT = "scripts/telegraf.service"
|
SYSTEMD_SCRIPT = "scripts/telegraf.service"
|
||||||
LOGROTATE_SCRIPT = "etc/logrotate.d/telegraf"
|
LOGROTATE_SCRIPT = "etc/logrotate.d/telegraf"
|
||||||
DEFAULT_CONFIG = "etc/telegraf.conf"
|
DEFAULT_CONFIG = "etc/telegraf.conf"
|
||||||
DEFAULT_WINDOWS_CONFIG = "etc/telegraf_windows.conf"
|
|
||||||
POSTINST_SCRIPT = "scripts/post-install.sh"
|
POSTINST_SCRIPT = "scripts/post-install.sh"
|
||||||
PREINST_SCRIPT = "scripts/pre-install.sh"
|
PREINST_SCRIPT = "scripts/pre-install.sh"
|
||||||
|
|
||||||
@@ -355,7 +354,7 @@ def create_package_fs(build_root):
|
|||||||
def package_scripts(build_root, windows=False):
|
def package_scripts(build_root, windows=False):
|
||||||
print("\t- Copying scripts and sample configuration to build directory")
|
print("\t- Copying scripts and sample configuration to build directory")
|
||||||
if windows:
|
if windows:
|
||||||
shutil.copyfile(DEFAULT_WINDOWS_CONFIG, os.path.join(build_root, "telegraf.conf"))
|
shutil.copyfile(DEFAULT_CONFIG, os.path.join(build_root, "telegraf.conf"))
|
||||||
os.chmod(os.path.join(build_root, "telegraf.conf"), 0o644)
|
os.chmod(os.path.join(build_root, "telegraf.conf"), 0o644)
|
||||||
else:
|
else:
|
||||||
shutil.copyfile(INIT_SCRIPT, os.path.join(build_root, SCRIPT_DIR[1:], INIT_SCRIPT.split('/')[1]))
|
shutil.copyfile(INIT_SCRIPT, os.path.join(build_root, SCRIPT_DIR[1:], INIT_SCRIPT.split('/')[1]))
|
||||||
@@ -370,8 +369,8 @@ def package_scripts(build_root, windows=False):
|
|||||||
def go_get():
|
def go_get():
|
||||||
print("Retrieving Go dependencies...")
|
print("Retrieving Go dependencies...")
|
||||||
run("go get github.com/sparrc/gdm")
|
run("go get github.com/sparrc/gdm")
|
||||||
run("gdm restore -f Godeps_windows")
|
|
||||||
run("gdm restore")
|
run("gdm restore")
|
||||||
|
run("gdm restore -f Godeps_windows")
|
||||||
|
|
||||||
def generate_md5_from_file(path):
|
def generate_md5_from_file(path):
|
||||||
m = hashlib.md5()
|
m = hashlib.md5()
|
||||||
@@ -440,44 +439,35 @@ def build_packages(build_output, version, pkg_arch, nightly=False, rc=None, iter
|
|||||||
a = pkg_arch
|
a = pkg_arch
|
||||||
if a == '386':
|
if a == '386':
|
||||||
a = 'i386'
|
a = 'i386'
|
||||||
if package_type == 'zip':
|
fpm_command = "fpm {} --name {} -a {} -t {} --version {} --iteration {} -C {} -p {} ".format(
|
||||||
zip_command = "cd {} && zip {}.zip ./*".format(
|
fpm_common_args,
|
||||||
build_root,
|
name,
|
||||||
name)
|
a,
|
||||||
run(zip_command, shell=True)
|
package_type,
|
||||||
run("mv {}.zip {}".format(os.path.join(build_root, name), current_location), shell=True)
|
package_version,
|
||||||
outfile = os.path.join(current_location, name+".zip")
|
package_iteration,
|
||||||
outfiles.append(outfile)
|
build_root,
|
||||||
print("\t\tMD5 = {}".format(generate_md5_from_file(outfile)))
|
current_location)
|
||||||
|
if pkg_arch is not None:
|
||||||
|
a = saved_a
|
||||||
|
if package_type == "rpm":
|
||||||
|
fpm_command += "--depends coreutils "
|
||||||
|
fpm_command += "--depends lsof"
|
||||||
|
print(fpm_command)
|
||||||
|
out = run(fpm_command, shell=True)
|
||||||
|
matches = re.search(':path=>"(.*)"', out)
|
||||||
|
outfile = None
|
||||||
|
if matches is not None:
|
||||||
|
outfile = matches.groups()[0]
|
||||||
|
if outfile is None:
|
||||||
|
print("[ COULD NOT DETERMINE OUTPUT ]")
|
||||||
else:
|
else:
|
||||||
fpm_command = "fpm {} --name {} -a {} -t {} --version {} --iteration {} -C {} -p {} ".format(
|
# Strip nightly version (the unix epoch) from filename
|
||||||
fpm_common_args,
|
if nightly and package_type in ['deb', 'rpm']:
|
||||||
name,
|
outfile = rename_file(outfile, outfile.replace("{}-{}".format(version, iteration), "nightly"))
|
||||||
a,
|
outfiles.append(os.path.join(os.getcwd(), outfile))
|
||||||
package_type,
|
# Display MD5 hash for generated package
|
||||||
package_version,
|
print("\t\tMD5 = {}".format(generate_md5_from_file(outfile)))
|
||||||
package_iteration,
|
|
||||||
build_root,
|
|
||||||
current_location)
|
|
||||||
if pkg_arch is not None:
|
|
||||||
a = saved_a
|
|
||||||
if package_type == "rpm":
|
|
||||||
fpm_command += "--depends coreutils "
|
|
||||||
fpm_command += "--depends lsof"
|
|
||||||
out = run(fpm_command, shell=True)
|
|
||||||
matches = re.search(':path=>"(.*)"', out)
|
|
||||||
outfile = None
|
|
||||||
if matches is not None:
|
|
||||||
outfile = matches.groups()[0]
|
|
||||||
if outfile is None:
|
|
||||||
print("[ COULD NOT DETERMINE OUTPUT ]")
|
|
||||||
else:
|
|
||||||
# Strip nightly version (the unix epoch) from filename
|
|
||||||
if nightly and package_type in ['deb', 'rpm']:
|
|
||||||
outfile = rename_file(outfile, outfile.replace("{}-{}".format(version, iteration), "nightly"))
|
|
||||||
outfiles.append(os.path.join(os.getcwd(), outfile))
|
|
||||||
# Display MD5 hash for generated package
|
|
||||||
print("\t\tMD5 = {}".format(generate_md5_from_file(outfile)))
|
|
||||||
print("")
|
print("")
|
||||||
if debug:
|
if debug:
|
||||||
print("[DEBUG] package outfiles: {}".format(outfiles))
|
print("[DEBUG] package outfiles: {}".format(outfiles))
|
||||||
|
|||||||
@@ -133,7 +133,13 @@ func (a *Accumulator) AssertContainsTaggedFields(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if p.Measurement == measurement {
|
if p.Measurement == measurement {
|
||||||
assert.Equal(t, fields, p.Fields)
|
if !reflect.DeepEqual(fields, p.Fields) {
|
||||||
|
pActual, _ := json.MarshalIndent(p.Fields, "", " ")
|
||||||
|
pExp, _ := json.MarshalIndent(fields, "", " ")
|
||||||
|
msg := fmt.Sprintf("Actual:\n%s\n(%T) \nExpected:\n%s\n(%T)",
|
||||||
|
string(pActual), p.Fields, string(pExp), fields)
|
||||||
|
assert.Fail(t, msg)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,7 +156,13 @@ func (a *Accumulator) AssertContainsFields(
|
|||||||
defer a.Unlock()
|
defer a.Unlock()
|
||||||
for _, p := range a.Metrics {
|
for _, p := range a.Metrics {
|
||||||
if p.Measurement == measurement {
|
if p.Measurement == measurement {
|
||||||
assert.Equal(t, fields, p.Fields)
|
if !reflect.DeepEqual(fields, p.Fields) {
|
||||||
|
pActual, _ := json.MarshalIndent(p.Fields, "", " ")
|
||||||
|
pExp, _ := json.MarshalIndent(fields, "", " ")
|
||||||
|
msg := fmt.Sprintf("Actual:\n%s\n(%T) \nExpected:\n%s\n(%T)",
|
||||||
|
string(pActual), p.Fields, string(pExp), fields)
|
||||||
|
assert.Fail(t, msg)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user