Compare commits
27 Commits
v0.10.0
...
v0.3.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b54c73ae4 | ||
|
|
c9ef073fba | ||
|
|
15f66d7d1b | ||
|
|
b0f79f43ec | ||
|
|
c584129758 | ||
|
|
d1930c90b5 | ||
|
|
1e76e36df2 | ||
|
|
a73b5257dc | ||
|
|
c16be04ca7 | ||
|
|
5513275f2c | ||
|
|
3a7b1688a3 | ||
|
|
35d5c7bae3 | ||
|
|
60b6693ae3 | ||
|
|
c1e1f2ace4 | ||
|
|
6698d195d8 | ||
|
|
23b21ca86a | ||
|
|
56e14e4731 | ||
|
|
7deb339b76 | ||
|
|
0e55c371b7 | ||
|
|
f284c8c154 | ||
|
|
e3b314cacb | ||
|
|
9fce094b36 | ||
|
|
319c363c8e | ||
|
|
40d84accee | ||
|
|
3fc43df84e | ||
|
|
59f804d77a | ||
|
|
96d5f0d0de |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,6 +1,4 @@
|
|||||||
tivan
|
tivan
|
||||||
.vagrant
|
.vagrant
|
||||||
/telegraf
|
telegraf
|
||||||
.idea
|
.idea
|
||||||
*~
|
|
||||||
*#
|
|
||||||
|
|||||||
38
CHANGELOG.md
38
CHANGELOG.md
@@ -1,38 +1,22 @@
|
|||||||
## v0.10.0 [unreleased]
|
## v0.3.0 [unreleased]
|
||||||
|
|
||||||
### Release Notes
|
### Release Notes
|
||||||
- Linux packages have been taken out of `opt`, the binary is now in `/usr/bin`
|
|
||||||
and configuration files are in `/etc/telegraf`
|
|
||||||
- **breaking change** `plugins` have been renamed to `inputs`. This was done because
|
|
||||||
`plugins` is too generic, as there are now also "output plugins", and will likely
|
|
||||||
be "aggregator plugins" and "filter plugins" in the future. Additionally,
|
|
||||||
`inputs/` and `outputs/` directories have been placed in the root-level `plugins/`
|
|
||||||
directory.
|
|
||||||
- **breaking change** the `io` plugin has been renamed `diskio`
|
- **breaking change** the `io` plugin has been renamed `diskio`
|
||||||
- **breaking change** plugin measurements aggregated into a single measurement.
|
- **breaking change** Plugin measurements aggregated into a single measurement.
|
||||||
- **breaking change** `jolokia` plugin: must use global tag/drop/pass parameters
|
- **breaking change** `jolokia` plugin: must use global tag/drop/pass parameters
|
||||||
for configuration.
|
for configuration.
|
||||||
- **breaking change** `twemproxy` plugin: `prefix` option removed.
|
- `twemproxy` plugin: `prefix` option removed.
|
||||||
- **breaking change** `procstat` cpu measurements are now prepended with `cpu_time_`
|
- `procstat` cpu measurements are now prepended with `cpu_time_` instead of
|
||||||
instead of only `cpu_`
|
only `cpu_`
|
||||||
- **breaking change** some command-line flags have been renamed to separate words.
|
|
||||||
`-configdirectory` -> `-config-directory`, `-filter` -> `-input-filter`,
|
|
||||||
`-outputfilter` -> `-output-filter`
|
|
||||||
- The prometheus plugin schema has not been changed (measurements have not been
|
- The prometheus plugin schema has not been changed (measurements have not been
|
||||||
aggregated).
|
aggregated).
|
||||||
|
|
||||||
### Packaging change note:
|
|
||||||
|
|
||||||
RHEL/CentOS users upgrading from 0.2.x to 0.10.0 will probably have their
|
|
||||||
configurations overwritten by the upgrade. There is a backup stored at
|
|
||||||
/etc/telegraf/telegraf.conf.$(date +%s).backup.
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
- Plugin measurements aggregated into a single measurement.
|
- Plugin measurements aggregated into a single measurement.
|
||||||
- Added ability to specify per-plugin tags
|
- Added ability to specify per-plugin tags
|
||||||
- Added ability to specify per-plugin measurement suffix and prefix.
|
- Added ability to specify per-plugin measurement suffix and prefix.
|
||||||
(`name_prefix` and `name_suffix`)
|
(`name_prefix` and `name_suffix`)
|
||||||
- Added ability to override base plugin measurement name. (`name_override`)
|
- Added ability to override base plugin name. (`name_override`)
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
@@ -76,11 +60,11 @@ functional.
|
|||||||
same type can be specified, like this:
|
same type can be specified, like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
[[inputs.cpu]]
|
[[plugins.cpu]]
|
||||||
percpu = false
|
percpu = false
|
||||||
totalcpu = true
|
totalcpu = true
|
||||||
|
|
||||||
[[inputs.cpu]]
|
[[plugins.cpu]]
|
||||||
percpu = true
|
percpu = true
|
||||||
totalcpu = false
|
totalcpu = false
|
||||||
drop = ["cpu_time"]
|
drop = ["cpu_time"]
|
||||||
@@ -107,7 +91,7 @@ same type can be specified, like this:
|
|||||||
lists of servers/URLs. 0.2.2 is being released solely to fix that bug
|
lists of servers/URLs. 0.2.2 is being released solely to fix that bug
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
- [#377](https://github.com/influxdb/telegraf/pull/377): Fix for duplicate slices in inputs.
|
- [#377](https://github.com/influxdb/telegraf/pull/377): Fix for duplicate slices in plugins.
|
||||||
|
|
||||||
## v0.2.1 [2015-11-16]
|
## v0.2.1 [2015-11-16]
|
||||||
|
|
||||||
@@ -168,7 +152,7 @@ be controlled via the `round_interval` and `flush_jitter` config options.
|
|||||||
- [#241](https://github.com/influxdb/telegraf/pull/241): MQTT Output. Thanks @shirou!
|
- [#241](https://github.com/influxdb/telegraf/pull/241): MQTT Output. Thanks @shirou!
|
||||||
- Memory plugin: cached and buffered measurements re-added
|
- Memory plugin: cached and buffered measurements re-added
|
||||||
- Logging: additional logging for each collection interval, track the number
|
- Logging: additional logging for each collection interval, track the number
|
||||||
of metrics collected and from how many inputs.
|
of metrics collected and from how many plugins.
|
||||||
- [#240](https://github.com/influxdb/telegraf/pull/240): procstat plugin, thanks @ranjib!
|
- [#240](https://github.com/influxdb/telegraf/pull/240): procstat plugin, thanks @ranjib!
|
||||||
- [#244](https://github.com/influxdb/telegraf/pull/244): netstat plugin, thanks @shirou!
|
- [#244](https://github.com/influxdb/telegraf/pull/244): netstat plugin, thanks @shirou!
|
||||||
- [#262](https://github.com/influxdb/telegraf/pull/262): zookeeper plugin, thanks @jrxFive!
|
- [#262](https://github.com/influxdb/telegraf/pull/262): zookeeper plugin, thanks @jrxFive!
|
||||||
@@ -201,7 +185,7 @@ will still be backwards compatible if only `url` is specified.
|
|||||||
- The -test flag will now output two metric collections
|
- The -test flag will now output two metric collections
|
||||||
- Support for filtering telegraf outputs on the CLI -- Telegraf will now
|
- Support for filtering telegraf outputs on the CLI -- Telegraf will now
|
||||||
allow filtering of output sinks on the command-line using the `-outputfilter`
|
allow filtering of output sinks on the command-line using the `-outputfilter`
|
||||||
flag, much like how the `-filter` flag works for inputs.
|
flag, much like how the `-filter` flag works for plugins.
|
||||||
- Support for filtering on config-file creation -- Telegraf now supports
|
- Support for filtering on config-file creation -- Telegraf now supports
|
||||||
filtering to -sample-config command. You can now run
|
filtering to -sample-config command. You can now run
|
||||||
`telegraf -sample-config -filter cpu -outputfilter influxdb` to get a config
|
`telegraf -sample-config -filter cpu -outputfilter influxdb` to get a config
|
||||||
|
|||||||
102
CONFIGURATION.md
102
CONFIGURATION.md
@@ -1,55 +1,33 @@
|
|||||||
# Telegraf Configuration
|
# Telegraf Configuration
|
||||||
|
|
||||||
## Generating a Configuration File
|
## Plugin Configuration
|
||||||
|
|
||||||
A default Telegraf config file can be generated using the `-sample-config` flag,
|
There are some configuration options that are configurable per plugin:
|
||||||
like this: `telegraf -sample-config`
|
|
||||||
|
|
||||||
To generate a file with specific inputs and outputs, you can use the
|
|
||||||
`-input-filter` and `-output-filter` flags, like this:
|
|
||||||
`telegraf -sample-config -input-filter cpu:mem:net:swap -output-filter influxdb:kafka`
|
|
||||||
|
|
||||||
## Telegraf Agent Configuration
|
|
||||||
|
|
||||||
Telegraf has a few options you can configure under the `agent` section of the
|
|
||||||
config.
|
|
||||||
|
|
||||||
* **hostname**: The hostname is passed as a tag. By default this will be
|
|
||||||
the value returned by `hostname` on the machine running Telegraf.
|
|
||||||
You can override that value here.
|
|
||||||
* **interval**: How often to gather metrics. Uses a simple number +
|
|
||||||
unit parser, e.g. "10s" for 10 seconds or "5m" for 5 minutes.
|
|
||||||
* **debug**: Set to true to gather and send metrics to STDOUT as well as
|
|
||||||
InfluxDB.
|
|
||||||
|
|
||||||
## Input Configuration
|
|
||||||
|
|
||||||
There are some configuration options that are configurable per input:
|
|
||||||
|
|
||||||
* **name_override**: Override the base name of the measurement.
|
* **name_override**: Override the base name of the measurement.
|
||||||
(Default is the name of the input).
|
(Default is the name of the plugin).
|
||||||
* **name_prefix**: Specifies a prefix to attach to the measurement name.
|
* **name_prefix**: Specifies a prefix to attach to the measurement name.
|
||||||
* **name_suffix**: Specifies a suffix to attach to the measurement name.
|
* **name_suffix**: Specifies a suffix to attach to the measurement name.
|
||||||
* **tags**: A map of tags to apply to a specific input's measurements.
|
* **tags**: A map of tags to apply to a specific plugin's measurements.
|
||||||
* **interval**: How often to gather this metric. Normal plugins use a single
|
|
||||||
global interval, but if one particular input should be run less or more often,
|
|
||||||
you can configure that here.
|
|
||||||
|
|
||||||
### Input Filters
|
### Plugin Filters
|
||||||
|
|
||||||
There are also filters that can be configured per input:
|
There are also filters that can be configured per plugin:
|
||||||
|
|
||||||
* **pass**: An array of strings that is used to filter metrics generated by the
|
* **pass**: An array of strings that is used to filter metrics generated by the
|
||||||
current input. Each string in the array is tested as a glob match against field names
|
current plugin. Each string in the array is tested as a glob match against field names
|
||||||
and if it matches, the field is emitted.
|
and if it matches, the field is emitted.
|
||||||
* **drop**: The inverse of pass, if a field name matches, it is not emitted.
|
* **drop**: The inverse of pass, if a field name matches, it is not emitted.
|
||||||
* **tagpass**: tag names and arrays of strings that are used to filter
|
* **tagpass**: tag names and arrays of strings that are used to filter
|
||||||
measurements by the current input. Each string in the array is tested as a glob
|
measurements by the current plugin. Each string in the array is tested as a glob
|
||||||
match against the tag name, and if it matches the measurement is emitted.
|
match against the tag name, and if it matches the measurement is emitted.
|
||||||
* **tagdrop**: The inverse of tagpass. If a tag matches, the measurement is not
|
* **tagdrop**: The inverse of tagpass. If a tag matches, the measurement is not emitted.
|
||||||
emitted. This is tested on measurements that have passed the tagpass test.
|
This is tested on measurements 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.
|
||||||
|
|
||||||
### Input Configuration Examples
|
### Plugin Configuration Examples
|
||||||
|
|
||||||
This is a full working config that will output CPU data to an InfluxDB instance
|
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
|
at 192.168.59.103:8086, tagging measurements with dc="denver-1". It will output
|
||||||
@@ -64,32 +42,35 @@ fields which begin with `time_`.
|
|||||||
interval = "10s"
|
interval = "10s"
|
||||||
|
|
||||||
# OUTPUTS
|
# OUTPUTS
|
||||||
|
[outputs]
|
||||||
[[outputs.influxdb]]
|
[[outputs.influxdb]]
|
||||||
url = "http://192.168.59.103:8086" # required.
|
url = "http://192.168.59.103:8086" # required.
|
||||||
database = "telegraf" # required.
|
database = "telegraf" # required.
|
||||||
precision = "s"
|
precision = "s"
|
||||||
|
|
||||||
# INPUTS
|
# PLUGINS
|
||||||
[[inputs.cpu]]
|
[plugins]
|
||||||
|
[[plugins.cpu]]
|
||||||
percpu = true
|
percpu = true
|
||||||
totalcpu = false
|
totalcpu = false
|
||||||
# filter all fields beginning with 'time_'
|
# filter all fields beginning with 'time_'
|
||||||
drop = ["time_*"]
|
drop = ["time_*"]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Input Config: tagpass and tagdrop
|
### Plugin Config: tagpass and tagdrop
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[[inputs.cpu]]
|
[plugins]
|
||||||
|
[[plugins.cpu]]
|
||||||
percpu = true
|
percpu = true
|
||||||
totalcpu = false
|
totalcpu = false
|
||||||
drop = ["cpu_time"]
|
drop = ["cpu_time"]
|
||||||
# Don't collect CPU data for cpu6 & cpu7
|
# Don't collect CPU data for cpu6 & cpu7
|
||||||
[inputs.cpu.tagdrop]
|
[plugins.cpu.tagdrop]
|
||||||
cpu = [ "cpu6", "cpu7" ]
|
cpu = [ "cpu6", "cpu7" ]
|
||||||
|
|
||||||
[[inputs.disk]]
|
[[plugins.disk]]
|
||||||
[inputs.disk.tagpass]
|
[plugins.disk.tagpass]
|
||||||
# tagpass conditions are OR, not AND.
|
# tagpass conditions are OR, not AND.
|
||||||
# If the (filesystem is ext4 or xfs) OR (the path is /opt or /home)
|
# If the (filesystem is ext4 or xfs) OR (the path is /opt or /home)
|
||||||
# then the metric passes
|
# then the metric passes
|
||||||
@@ -98,26 +79,26 @@ fields which begin with `time_`.
|
|||||||
path = [ "/opt", "/home*" ]
|
path = [ "/opt", "/home*" ]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Input Config: pass and drop
|
### Plugin Config: pass and drop
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
# Drop all metrics for guest & steal CPU usage
|
# Drop all metrics for guest & steal CPU usage
|
||||||
[[inputs.cpu]]
|
[[plugins.cpu]]
|
||||||
percpu = false
|
percpu = false
|
||||||
totalcpu = true
|
totalcpu = true
|
||||||
drop = ["usage_guest", "usage_steal"]
|
drop = ["usage_guest", "usage_steal"]
|
||||||
|
|
||||||
# Only store inode related metrics for disks
|
# Only store inode related metrics for disks
|
||||||
[[inputs.disk]]
|
[[plugins.disk]]
|
||||||
pass = ["inodes*"]
|
pass = ["inodes*"]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Input config: prefix, suffix, and override
|
### Plugin config: prefix, suffix, and override
|
||||||
|
|
||||||
This plugin will emit measurements with the name `cpu_total`
|
This plugin will emit measurements with the name `cpu_total`
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[[inputs.cpu]]
|
[[plugins.cpu]]
|
||||||
name_suffix = "_total"
|
name_suffix = "_total"
|
||||||
percpu = false
|
percpu = false
|
||||||
totalcpu = true
|
totalcpu = true
|
||||||
@@ -126,42 +107,39 @@ This plugin will emit measurements with the name `cpu_total`
|
|||||||
This will emit measurements with the name `foobar`
|
This will emit measurements with the name `foobar`
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[[inputs.cpu]]
|
[[plugins.cpu]]
|
||||||
name_override = "foobar"
|
name_override = "foobar"
|
||||||
percpu = false
|
percpu = false
|
||||||
totalcpu = true
|
totalcpu = true
|
||||||
```
|
```
|
||||||
|
|
||||||
### Input config: tags
|
### Plugin config: tags
|
||||||
|
|
||||||
This plugin will emit measurements with two additional tags: `tag1=foo` and
|
This plugin will emit measurements with two additional tags: `tag1=foo` and
|
||||||
`tag2=bar`
|
`tag2=bar`
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[[inputs.cpu]]
|
[[plugins.cpu]]
|
||||||
percpu = false
|
percpu = false
|
||||||
totalcpu = true
|
totalcpu = true
|
||||||
[inputs.cpu.tags]
|
[plugins.cpu.tags]
|
||||||
tag1 = "foo"
|
tag1 = "foo"
|
||||||
tag2 = "bar"
|
tag2 = "bar"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Multiple inputs of the same type
|
### Multiple plugins of the same type
|
||||||
|
|
||||||
Additional inputs (or outputs) of the same type can be specified,
|
Additional plugins (or outputs) of the same type can be specified,
|
||||||
just define more instances in the config file. It is highly recommended that
|
just define more instances in the config file:
|
||||||
you utilize `name_override`, `name_prefix`, or `name_suffix` config options
|
|
||||||
to avoid measurement collisions:
|
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[[inputs.cpu]]
|
[[plugins.cpu]]
|
||||||
percpu = false
|
percpu = false
|
||||||
totalcpu = true
|
totalcpu = true
|
||||||
|
|
||||||
[[inputs.cpu]]
|
[[plugins.cpu]]
|
||||||
percpu = true
|
percpu = true
|
||||||
totalcpu = false
|
totalcpu = false
|
||||||
name_override = "percpu_usage"
|
|
||||||
drop = ["cpu_time*"]
|
drop = ["cpu_time*"]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -171,8 +149,8 @@ Telegraf also supports specifying multiple output sinks to send data to,
|
|||||||
configuring each output sink is different, but examples can be
|
configuring each output sink is different, but examples can be
|
||||||
found by running `telegraf -sample-config`.
|
found by running `telegraf -sample-config`.
|
||||||
|
|
||||||
Outputs also support the same configurable options as inputs
|
Outputs also support the same configurable options as plugins
|
||||||
(pass, drop, tagpass, tagdrop)
|
(pass, drop, tagpass, tagdrop), added in 0.2.4
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[[outputs.influxdb]]
|
[[outputs.influxdb]]
|
||||||
|
|||||||
@@ -3,31 +3,33 @@
|
|||||||
Before we can merge a pull request, you will need to sign the CLA,
|
Before we can merge a pull request, you will need to sign the CLA,
|
||||||
which can be found [on our website](http://influxdb.com/community/cla.html)
|
which can be found [on our website](http://influxdb.com/community/cla.html)
|
||||||
|
|
||||||
## Input Plugins
|
## Plugins
|
||||||
|
|
||||||
This section is for developers who want to create new collection inputs.
|
This section is for developers who want to create new collection plugins.
|
||||||
Telegraf is entirely plugin driven. This interface allows for operators to
|
Telegraf is entirely plugin driven. This interface allows for operators to
|
||||||
pick and chose what is gathered as well as makes it easy for developers
|
pick and chose what is gathered as well as makes it easy for developers
|
||||||
to create new ways of generating metrics.
|
to create new ways of generating metrics.
|
||||||
|
|
||||||
Plugin authorship is kept as simple as possible to promote people to develop
|
Plugin authorship is kept as simple as possible to promote people to develop
|
||||||
and submit new inputs.
|
and submit new plugins.
|
||||||
|
|
||||||
### Input Plugin Guidelines
|
### Plugin Guidelines
|
||||||
|
|
||||||
* A plugin must conform to the `inputs.Input` interface.
|
* A plugin must conform to the `plugins.Plugin` interface.
|
||||||
* Input Plugins should call `inputs.Add` in their `init` function to register themselves.
|
* Each generated metric automatically has the name of the plugin that generated
|
||||||
|
it prepended. This is to keep plugins honest.
|
||||||
|
* Plugins should call `plugins.Add` in their `init` function to register themselves.
|
||||||
See below for a quick example.
|
See below for a quick example.
|
||||||
* Input Plugins must be added to the
|
* To be available within Telegraf itself, plugins must add themselves to the
|
||||||
`github.com/influxdb/telegraf/plugins/inputs/all/all.go` file.
|
`github.com/influxdb/telegraf/plugins/all/all.go` file.
|
||||||
* The `SampleConfig` function should return valid toml that describes how the
|
* The `SampleConfig` function should return valid toml that describes how the
|
||||||
plugin can be configured. This is include in `telegraf -sample-config`.
|
plugin can be configured. This is include in `telegraf -sample-config`.
|
||||||
* The `Description` function should say in one line what this plugin does.
|
* The `Description` function should say in one line what this plugin does.
|
||||||
|
|
||||||
### Input interface
|
### Plugin interface
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type Input interface {
|
type Plugin interface {
|
||||||
SampleConfig() string
|
SampleConfig() string
|
||||||
Description() string
|
Description() string
|
||||||
Gather(Accumulator) error
|
Gather(Accumulator) error
|
||||||
@@ -50,32 +52,52 @@ type Accumulator interface {
|
|||||||
The way that a plugin emits metrics is by interacting with the Accumulator.
|
The way that a plugin emits metrics is by interacting with the Accumulator.
|
||||||
|
|
||||||
The `Add` function takes 3 arguments:
|
The `Add` function takes 3 arguments:
|
||||||
* **measurement**: A string description of the metric. For instance `bytes_read` or `
|
* **measurement**: A string description of the metric. For instance `bytes_read` or `faults`.
|
||||||
faults`.
|
|
||||||
* **value**: A value for the metric. This accepts 5 different types of value:
|
* **value**: A value for the metric. This accepts 5 different types of value:
|
||||||
* **int**: The most common type. All int types are accepted but favor using `int64`
|
* **int**: The most common type. All int types are accepted but favor using `int64`
|
||||||
Useful for counters, etc.
|
Useful for counters, etc.
|
||||||
* **float**: Favor `float64`, useful for gauges, percentages, etc.
|
* **float**: Favor `float64`, useful for gauges, percentages, etc.
|
||||||
* **bool**: `true` or `false`, useful to indicate the presence of a state. `light_on`,
|
* **bool**: `true` or `false`, useful to indicate the presence of a state. `light_on`, etc.
|
||||||
etc.
|
* **string**: Typically used to indicate a message, or some kind of freeform information.
|
||||||
* **string**: Typically used to indicate a message, or some kind of freeform
|
* **time.Time**: Useful for indicating when a state last occurred, for instance `light_on_since`.
|
||||||
information.
|
|
||||||
* **time.Time**: Useful for indicating when a state last occurred, for instance `
|
|
||||||
light_on_since`.
|
|
||||||
* **tags**: This is a map of strings to strings to describe the where or who
|
* **tags**: This is a map of strings to strings to describe the where or who
|
||||||
about the metric. For instance, the `net` plugin adds a tag named `"interface"`
|
about the metric. For instance, the `net` plugin adds a tag named `"interface"`
|
||||||
set to the name of the network interface, like `"eth0"`.
|
set to the name of the network interface, like `"eth0"`.
|
||||||
|
|
||||||
|
The `AddFieldsWithTime` allows multiple values for a point to be passed. The values
|
||||||
|
used are the same type profile as **value** above. The **timestamp** argument
|
||||||
|
allows a point to be registered as having occurred at an arbitrary time.
|
||||||
|
|
||||||
Let's say you've written a plugin that emits metrics about processes on the current host.
|
Let's say you've written a plugin that emits metrics about processes on the current host.
|
||||||
|
|
||||||
### Input Plugin Example
|
```go
|
||||||
|
|
||||||
|
type Process struct {
|
||||||
|
CPUTime float64
|
||||||
|
MemoryBytes int64
|
||||||
|
PID int
|
||||||
|
}
|
||||||
|
|
||||||
|
func Gather(acc plugins.Accumulator) error {
|
||||||
|
for _, process := range system.Processes() {
|
||||||
|
tags := map[string]string {
|
||||||
|
"pid": fmt.Sprintf("%d", process.Pid),
|
||||||
|
}
|
||||||
|
|
||||||
|
acc.Add("cpu", process.CPUTime, tags, time.Now())
|
||||||
|
acc.Add("memory", process.MemoryBytes, tags, time.Now())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Plugin Example
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package simple
|
package simple
|
||||||
|
|
||||||
// simple.go
|
// simple.go
|
||||||
|
|
||||||
import "github.com/influxdb/telegraf/plugins/inputs"
|
import "github.com/influxdb/telegraf/plugins"
|
||||||
|
|
||||||
type Simple struct {
|
type Simple struct {
|
||||||
Ok bool
|
Ok bool
|
||||||
@@ -89,7 +111,7 @@ func (s *Simple) SampleConfig() string {
|
|||||||
return "ok = true # indicate if everything is fine"
|
return "ok = true # indicate if everything is fine"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Simple) Gather(acc inputs.Accumulator) error {
|
func (s *Simple) Gather(acc plugins.Accumulator) error {
|
||||||
if s.Ok {
|
if s.Ok {
|
||||||
acc.Add("state", "pretty good", nil)
|
acc.Add("state", "pretty good", nil)
|
||||||
} else {
|
} else {
|
||||||
@@ -100,19 +122,19 @@ func (s *Simple) Gather(acc inputs.Accumulator) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("simple", func() inputs.Input { return &Simple{} })
|
plugins.Add("simple", func() plugins.Plugin { return &Simple{} })
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Service Input Plugins
|
## Service Plugins
|
||||||
|
|
||||||
This section is for developers who want to create new "service" collection
|
This section is for developers who want to create new "service" collection
|
||||||
inputs. A service plugin differs from a regular plugin in that it operates
|
plugins. A service plugin differs from a regular plugin in that it operates
|
||||||
a background service while Telegraf is running. One example would be the `statsd`
|
a background service while Telegraf is running. One example would be the `statsd`
|
||||||
plugin, which operates a statsd server.
|
plugin, which operates a statsd server.
|
||||||
|
|
||||||
Service Input Plugins are substantially more complicated than a regular plugin, as they
|
Service Plugins are substantially more complicated than a regular plugin, as they
|
||||||
will require threads and locks to verify data integrity. Service Input Plugins should
|
will require threads and locks to verify data integrity. Service Plugins should
|
||||||
be avoided unless there is no way to create their behavior with a regular plugin.
|
be avoided unless there is no way to create their behavior with a regular plugin.
|
||||||
|
|
||||||
Their interface is quite similar to a regular plugin, with the addition of `Start()`
|
Their interface is quite similar to a regular plugin, with the addition of `Start()`
|
||||||
@@ -121,7 +143,7 @@ and `Stop()` methods.
|
|||||||
### Service Plugin Guidelines
|
### Service Plugin Guidelines
|
||||||
|
|
||||||
* Same as the `Plugin` guidelines, except that they must conform to the
|
* Same as the `Plugin` guidelines, except that they must conform to the
|
||||||
`inputs.ServiceInput` interface.
|
`plugins.ServicePlugin` interface.
|
||||||
|
|
||||||
### Service Plugin interface
|
### Service Plugin interface
|
||||||
|
|
||||||
@@ -135,19 +157,19 @@ type ServicePlugin interface {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Output Plugins
|
## Outputs
|
||||||
|
|
||||||
This section is for developers who want to create a new output sink. Outputs
|
This section is for developers who want to create a new output sink. Outputs
|
||||||
are created in a similar manner as collection plugins, and their interface has
|
are created in a similar manner as collection plugins, and their interface has
|
||||||
similar constructs.
|
similar constructs.
|
||||||
|
|
||||||
### Output Plugin Guidelines
|
### Output Guidelines
|
||||||
|
|
||||||
* An output must conform to the `outputs.Output` interface.
|
* An output must conform to the `outputs.Output` interface.
|
||||||
* Outputs should call `outputs.Add` in their `init` function to register themselves.
|
* Outputs should call `outputs.Add` in their `init` function to register themselves.
|
||||||
See below for a quick example.
|
See below for a quick example.
|
||||||
* To be available within Telegraf itself, plugins must add themselves to the
|
* To be available within Telegraf itself, plugins must add themselves to the
|
||||||
`github.com/influxdb/telegraf/plugins/outputs/all/all.go` file.
|
`github.com/influxdb/telegraf/outputs/all/all.go` file.
|
||||||
* The `SampleConfig` function should return valid toml that describes how the
|
* The `SampleConfig` function should return valid toml that describes how the
|
||||||
output can be configured. This is include in `telegraf -sample-config`.
|
output can be configured. This is include in `telegraf -sample-config`.
|
||||||
* The `Description` function should say in one line what this output does.
|
* The `Description` function should say in one line what this output does.
|
||||||
@@ -171,7 +193,7 @@ package simpleoutput
|
|||||||
|
|
||||||
// simpleoutput.go
|
// simpleoutput.go
|
||||||
|
|
||||||
import "github.com/influxdb/telegraf/plugins/outputs"
|
import "github.com/influxdb/telegraf/outputs"
|
||||||
|
|
||||||
type Simple struct {
|
type Simple struct {
|
||||||
Ok bool
|
Ok bool
|
||||||
@@ -208,7 +230,7 @@ func init() {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Service Output Plugins
|
## Service Outputs
|
||||||
|
|
||||||
This section is for developers who want to create new "service" output. A
|
This section is for developers who want to create new "service" output. A
|
||||||
service output differs from a regular output in that it operates a background service
|
service output differs from a regular output in that it operates a background service
|
||||||
@@ -221,7 +243,7 @@ and `Stop()` methods.
|
|||||||
### Service Output Guidelines
|
### Service Output Guidelines
|
||||||
|
|
||||||
* Same as the `Output` guidelines, except that they must conform to the
|
* Same as the `Output` guidelines, except that they must conform to the
|
||||||
`output.ServiceOutput` interface.
|
`plugins.ServiceOutput` interface.
|
||||||
|
|
||||||
### Service Output interface
|
### Service Output interface
|
||||||
|
|
||||||
@@ -252,7 +274,7 @@ which would take some time to replicate.
|
|||||||
To overcome this situation we've decided to use docker containers to provide a
|
To overcome this situation we've decided to use docker containers to provide a
|
||||||
fast and reproducible environment to test those services which require it.
|
fast and reproducible environment to test those services which require it.
|
||||||
For other situations
|
For other situations
|
||||||
(i.e: https://github.com/influxdb/telegraf/blob/master/plugins/redis/redis_test.go)
|
(i.e: https://github.com/influxdb/telegraf/blob/master/plugins/redis/redis_test.go )
|
||||||
a simple mock will suffice.
|
a simple mock will suffice.
|
||||||
|
|
||||||
To execute Telegraf tests follow these simple steps:
|
To execute Telegraf tests follow these simple steps:
|
||||||
|
|||||||
38
Godeps
38
Godeps
@@ -1,51 +1,51 @@
|
|||||||
git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git dbd8d5c40a582eb9adacde36b47932b3a3ad0034
|
git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git dbd8d5c40a582eb9adacde36b47932b3a3ad0034
|
||||||
github.com/Shopify/sarama d37c73f2b2bce85f7fa16b6a550d26c5372892ef
|
github.com/Shopify/sarama 159e9990b0796511607dd0d7aaa3eb37d1829d16
|
||||||
github.com/Sirupsen/logrus 446d1c146faa8ed3f4218f056fcd165f6bcfda81
|
github.com/Sirupsen/logrus 446d1c146faa8ed3f4218f056fcd165f6bcfda81
|
||||||
github.com/amir/raidman 6a8e089bbe32e6b907feae5ba688841974b3c339
|
github.com/amir/raidman 6a8e089bbe32e6b907feae5ba688841974b3c339
|
||||||
github.com/armon/go-metrics 345426c77237ece5dab0e1605c3e4b35c3f54757
|
github.com/armon/go-metrics 06b60999766278efd6d2b5d8418a58c3d5b99e87
|
||||||
github.com/aws/aws-sdk-go f09322ae1e6468fe828c862542389bc45baf3c00
|
github.com/aws/aws-sdk-go 999b1591218c36d5050d1ba7266eba956e65965f
|
||||||
github.com/beorn7/perks b965b613227fddccbfffe13eae360ed3fa822f8d
|
github.com/beorn7/perks b965b613227fddccbfffe13eae360ed3fa822f8d
|
||||||
github.com/boltdb/bolt 34a0fa5307f7562980fb8e7ff4723f7987edf49b
|
github.com/boltdb/bolt b34b35ea8d06bb9ae69d9a349119252e4c1d8ee0
|
||||||
github.com/cenkalti/backoff 4dc77674aceaabba2c7e3da25d4c823edfb73f99
|
github.com/cenkalti/backoff 4dc77674aceaabba2c7e3da25d4c823edfb73f99
|
||||||
github.com/dancannon/gorethink a124c9663325ed9f7fb669d17c69961b59151e6e
|
github.com/dancannon/gorethink a124c9663325ed9f7fb669d17c69961b59151e6e
|
||||||
github.com/davecgh/go-spew 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
|
github.com/davecgh/go-spew 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
|
||||||
github.com/eapache/go-resiliency b86b1ec0dd4209a588dc1285cdd471e73525c0b3
|
github.com/eapache/go-resiliency f341fb4dca45128e4aa86389fa6a675d55fe25e1
|
||||||
github.com/eapache/queue ded5959c0d4e360646dc9e9908cff48666781367
|
github.com/eapache/queue ded5959c0d4e360646dc9e9908cff48666781367
|
||||||
github.com/fsouza/go-dockerclient 175e1df973274f04e9b459a62cffc49808f1a649
|
github.com/fsouza/go-dockerclient 7177a9e3543b0891a5d91dbf7051e0f71455c8ef
|
||||||
github.com/go-ini/ini afbd495e5aaea13597b5e14fe514ddeaa4d76fc3
|
github.com/go-ini/ini 9314fb0ef64171d6a3d0a4fa570dfa33441cba05
|
||||||
github.com/go-sql-driver/mysql 7a8740a6bd8feb6af5786ab9a9f1513970019d8c
|
github.com/go-sql-driver/mysql d512f204a577a4ab037a1816604c48c9c13210be
|
||||||
github.com/gogo/protobuf 7b1331554dbe882cb3613ee8f1824a5583627963
|
github.com/gogo/protobuf e492fd34b12d0230755c45aa5fb1e1eea6a84aa9
|
||||||
github.com/golang/protobuf 2402d76f3d41f928c7902a765dfc872356dd3aad
|
github.com/golang/protobuf 68415e7123da32b07eab49c96d2c4d6158360e9b
|
||||||
github.com/golang/snappy 723cc1e459b8eea2dea4583200fd60757d40097a
|
github.com/golang/snappy 723cc1e459b8eea2dea4583200fd60757d40097a
|
||||||
github.com/gonuts/go-shellquote e842a11b24c6abfb3dd27af69a17f482e4b483c2
|
github.com/gonuts/go-shellquote e842a11b24c6abfb3dd27af69a17f482e4b483c2
|
||||||
github.com/hailocab/go-hostpool 50839ee41f32bfca8d03a183031aa634b2dc1c64
|
github.com/hailocab/go-hostpool 0637eae892be221164aff5fcbccc57171aea6406
|
||||||
github.com/hashicorp/go-msgpack fa3f63826f7c23912c15263591e65d54d080b458
|
github.com/hashicorp/go-msgpack fa3f63826f7c23912c15263591e65d54d080b458
|
||||||
github.com/hashicorp/raft d136cd15dfb7876fd7c89cad1995bc4f19ceb294
|
github.com/hashicorp/raft d136cd15dfb7876fd7c89cad1995bc4f19ceb294
|
||||||
github.com/hashicorp/raft-boltdb d1e82c1ec3f15ee991f7cc7ffd5b67ff6f5bbaee
|
github.com/hashicorp/raft-boltdb d1e82c1ec3f15ee991f7cc7ffd5b67ff6f5bbaee
|
||||||
github.com/influxdb/influxdb bd63489ef0faae2465ae5b1f0a28bd7e71e02e38
|
github.com/influxdb/influxdb 69a7664f2d4b75aec300b7cbfc7e57c971721f04
|
||||||
github.com/jmespath/go-jmespath c01cf91b011868172fdcd9f41838e80c9d716264
|
github.com/jmespath/go-jmespath c01cf91b011868172fdcd9f41838e80c9d716264
|
||||||
github.com/klauspost/crc32 a3b15ae34567abb20a22992b989cd76f48d09c47
|
github.com/klauspost/crc32 0aff1ea9c20474c3901672b5b6ead0ac611156de
|
||||||
github.com/lib/pq 11fc39a580a008f1f39bb3d11d984fb34ed778d9
|
github.com/lib/pq 11fc39a580a008f1f39bb3d11d984fb34ed778d9
|
||||||
github.com/matttproud/golang_protobuf_extensions d0c3fe89de86839aecf2e0579c40ba3bb336a453
|
github.com/matttproud/golang_protobuf_extensions d0c3fe89de86839aecf2e0579c40ba3bb336a453
|
||||||
github.com/mreiferson/go-snappystream 028eae7ab5c4c9e2d1cb4c4ca1e53259bbe7e504
|
github.com/mreiferson/go-snappystream 028eae7ab5c4c9e2d1cb4c4ca1e53259bbe7e504
|
||||||
github.com/naoina/go-stringutil 6b638e95a32d0c1131db0e7fe83775cbea4a0d0b
|
github.com/naoina/go-stringutil 6b638e95a32d0c1131db0e7fe83775cbea4a0d0b
|
||||||
github.com/naoina/toml 751171607256bb66e64c9f0220c00662420c38e9
|
github.com/naoina/toml 751171607256bb66e64c9f0220c00662420c38e9
|
||||||
github.com/nsqio/go-nsq 2118015c120962edc5d03325c680daf3163a8b5f
|
github.com/nsqio/go-nsq 2118015c120962edc5d03325c680daf3163a8b5f
|
||||||
github.com/pborman/uuid dee7705ef7b324f27ceb85a121c61f2c2e8ce988
|
github.com/pborman/uuid cccd189d45f7ac3368a0d127efb7f4d08ae0b655
|
||||||
github.com/pmezard/go-difflib e8554b8641db39598be7f6342874b958f12ae1d4
|
github.com/pmezard/go-difflib e8554b8641db39598be7f6342874b958f12ae1d4
|
||||||
github.com/prometheus/client_golang 67994f177195311c3ea3d4407ed0175e34a4256f
|
github.com/prometheus/client_golang 67994f177195311c3ea3d4407ed0175e34a4256f
|
||||||
github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
|
github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
|
||||||
github.com/prometheus/common 0a3005bb37bc411040083a55372e77c405f6464c
|
github.com/prometheus/common 56b90312e937d43b930f06a59bf0d6a4ae1944bc
|
||||||
github.com/prometheus/procfs 406e5b7bfd8201a36e2bb5f7bdae0b03380c2ce8
|
github.com/prometheus/procfs 406e5b7bfd8201a36e2bb5f7bdae0b03380c2ce8
|
||||||
github.com/samuel/go-zookeeper 218e9c81c0dd8b3b18172b2bbfad92cc7d6db55f
|
github.com/samuel/go-zookeeper 218e9c81c0dd8b3b18172b2bbfad92cc7d6db55f
|
||||||
github.com/shirou/gopsutil ef151b7ff7fe76308f89a389447b7b78dfa02e0f
|
github.com/shirou/gopsutil fc932d9090f13a84fb4b3cb8baa124610cab184c
|
||||||
github.com/streadway/amqp b4f3ceab0337f013208d31348b578d83c0064744
|
github.com/streadway/amqp b4f3ceab0337f013208d31348b578d83c0064744
|
||||||
github.com/stretchr/objx 1a9d0bb9f541897e62256577b352fdbc1fb4fd94
|
github.com/stretchr/objx 1a9d0bb9f541897e62256577b352fdbc1fb4fd94
|
||||||
github.com/stretchr/testify c92828f29518bc633893affbce12904ba41a7cfa
|
github.com/stretchr/testify e3a8ff8ce36581f87a15341206f205b1da467059
|
||||||
github.com/wvanbergen/kafka 1a8639a45164fcc245d5c7b4bd3ccfbd1a0ffbf3
|
github.com/wvanbergen/kafka 1a8639a45164fcc245d5c7b4bd3ccfbd1a0ffbf3
|
||||||
github.com/wvanbergen/kazoo-go 0f768712ae6f76454f987c3356177e138df258f8
|
github.com/wvanbergen/kazoo-go 0f768712ae6f76454f987c3356177e138df258f8
|
||||||
golang.org/x/crypto f23ba3a5ee43012fcb4b92e1a2a405a92554f4f2
|
golang.org/x/crypto 7b85b097bf7527677d54d3220065e966a0e3b613
|
||||||
golang.org/x/net 520af5de654dc4dd4f0f65aa40e66dbbd9043df1
|
golang.org/x/net 1796f9b8b7178e3c7587dff118d3bb9d37f9b0b3
|
||||||
gopkg.in/dancannon/gorethink.v1 a124c9663325ed9f7fb669d17c69961b59151e6e
|
gopkg.in/dancannon/gorethink.v1 a124c9663325ed9f7fb669d17c69961b59151e6e
|
||||||
gopkg.in/fatih/pool.v2 cba550ebf9bce999a02e963296d4bc7a486cb715
|
gopkg.in/fatih/pool.v2 cba550ebf9bce999a02e963296d4bc7a486cb715
|
||||||
gopkg.in/mgo.v2 e30de8ac9ae3b30df7065f766c71f88bba7d4e49
|
gopkg.in/mgo.v2 e30de8ac9ae3b30df7065f766c71f88bba7d4e49
|
||||||
|
|||||||
111
README.md
111
README.md
@@ -1,42 +1,30 @@
|
|||||||
# Telegraf [](https://circleci.com/gh/influxdata/telegraf)
|
# Telegraf - A native agent for InfluxDB [](https://circleci.com/gh/influxdb/telegraf)
|
||||||
|
|
||||||
Telegraf is an agent written in Go for collecting metrics from the system it's
|
Telegraf is an agent written in Go for collecting metrics from the system it's
|
||||||
running on, or from other services, and writing them into InfluxDB or other
|
running on, or from other services, and writing them into InfluxDB.
|
||||||
[outputs](https://github.com/influxdata/telegraf#supported-output-plugins).
|
|
||||||
|
|
||||||
Design goals are to have a minimal memory footprint with a plugin system so
|
Design goals are to have a minimal memory footprint with a plugin system so
|
||||||
that developers in the community can easily add support for collecting metrics
|
that developers in the community can easily add support for collecting metrics
|
||||||
from well known services (like Hadoop, Postgres, or Redis) and third party
|
from well known services (like Hadoop, Postgres, or Redis) and third party
|
||||||
APIs (like Mailchimp, AWS CloudWatch, or Google Analytics).
|
APIs (like Mailchimp, AWS CloudWatch, or Google Analytics).
|
||||||
|
|
||||||
New input and output plugins are designed to be easy to contribute,
|
We'll eagerly accept pull requests for new plugins and will manage the set of
|
||||||
we'll eagerly accept pull
|
plugins that Telegraf supports. See the
|
||||||
requests and will manage the set of plugins that Telegraf supports.
|
[contributing guide](CONTRIBUTING.md) for instructions on
|
||||||
See the [contributing guide](CONTRIBUTING.md) for instructions on writing
|
writing new plugins.
|
||||||
new plugins.
|
|
||||||
|
|
||||||
## Installation:
|
## Installation:
|
||||||
|
|
||||||
NOTE: Telegraf 0.10.x is **not** backwards-compatible with previous versions of
|
|
||||||
telegraf, both in the database layout and the configuration file. 0.2.x will
|
|
||||||
continue to be supported, see below for download links.
|
|
||||||
|
|
||||||
TODO: link to blog post about 0.10.x changes.
|
|
||||||
|
|
||||||
### Linux deb and rpm packages:
|
### Linux deb and rpm packages:
|
||||||
|
|
||||||
Latest:
|
Latest:
|
||||||
* http://get.influxdb.org/telegraf/telegraf_0.10.0_amd64.deb
|
|
||||||
* http://get.influxdb.org/telegraf/telegraf-0.10.0-1.x86_64.rpm
|
|
||||||
|
|
||||||
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
|
||||||
* http://get.influxdb.org/telegraf/telegraf-0.2.4-1.x86_64.rpm
|
* http://get.influxdb.org/telegraf/telegraf-0.2.4-1.x86_64.rpm
|
||||||
|
|
||||||
##### Package instructions:
|
##### Package instructions:
|
||||||
|
|
||||||
* Telegraf binary is installed in `/usr/bin/telegraf`
|
* Telegraf binary is installed in `/opt/telegraf/telegraf`
|
||||||
* Telegraf daemon configuration file is in `/etc/telegraf/telegraf.conf`
|
* Telegraf daemon configuration file is in `/etc/opt/telegraf/telegraf.conf`
|
||||||
* On sysv systems, the telegraf daemon can be controlled via
|
* On sysv systems, the telegraf daemon can be controlled via
|
||||||
`service telegraf [action]`
|
`service telegraf [action]`
|
||||||
* On systemd systems (such as Ubuntu 15+), the telegraf daemon can be
|
* On systemd systems (such as Ubuntu 15+), the telegraf daemon can be
|
||||||
@@ -45,11 +33,6 @@ controlled via `systemctl [action] telegraf`
|
|||||||
### Linux binaries:
|
### Linux binaries:
|
||||||
|
|
||||||
Latest:
|
Latest:
|
||||||
* http://get.influxdb.org/telegraf/telegraf_linux_amd64_0.10.0.tar.gz
|
|
||||||
* http://get.influxdb.org/telegraf/telegraf_linux_386_0.10.0.tar.gz
|
|
||||||
* http://get.influxdb.org/telegraf/telegraf_linux_arm_0.10.0.tar.gz
|
|
||||||
|
|
||||||
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
|
||||||
* http://get.influxdb.org/telegraf/telegraf_linux_386_0.2.4.tar.gz
|
* http://get.influxdb.org/telegraf/telegraf_linux_386_0.2.4.tar.gz
|
||||||
* http://get.influxdb.org/telegraf/telegraf_linux_arm_0.2.4.tar.gz
|
* http://get.influxdb.org/telegraf/telegraf_linux_arm_0.2.4.tar.gz
|
||||||
@@ -82,49 +65,40 @@ if you don't have it already. You also must build with golang version 1.4+.
|
|||||||
|
|
||||||
### How to use it:
|
### How to use it:
|
||||||
|
|
||||||
```console
|
* Run `telegraf -sample-config > telegraf.conf` to create an initial configuration.
|
||||||
$ telegraf -help
|
* Or run `telegraf -sample-config -filter cpu:mem -outputfilter influxdb > telegraf.conf`.
|
||||||
Telegraf, The plugin-driven server agent for reporting metrics into InfluxDB
|
to create a config file with only CPU and memory plugins defined, and InfluxDB
|
||||||
|
output defined.
|
||||||
|
* Edit the configuration to match your needs.
|
||||||
|
* Run `telegraf -config telegraf.conf -test` to output one full measurement
|
||||||
|
sample to STDOUT. NOTE: you may want to run as the telegraf user if you are using
|
||||||
|
the linux packages `sudo -u telegraf telegraf -config telegraf.conf -test`
|
||||||
|
* Run `telegraf -config telegraf.conf` to gather and send metrics to configured outputs.
|
||||||
|
* Run `telegraf -config telegraf.conf -filter system:swap`.
|
||||||
|
to run telegraf with only the system & swap plugins defined in the config.
|
||||||
|
|
||||||
Usage:
|
## Telegraf Options
|
||||||
|
|
||||||
telegraf <flags>
|
Telegraf has a few options you can configure under the `agent` section of the
|
||||||
|
config.
|
||||||
|
|
||||||
The flags are:
|
* **hostname**: The hostname is passed as a tag. By default this will be
|
||||||
|
the value returned by `hostname` on the machine running Telegraf.
|
||||||
-config <file> configuration file to load
|
You can override that value here.
|
||||||
-test gather metrics once, print them to stdout, and exit
|
* **interval**: How often to gather metrics. Uses a simple number +
|
||||||
-sample-config print out full sample configuration to stdout
|
unit parser, e.g. "10s" for 10 seconds or "5m" for 5 minutes.
|
||||||
-config-directory directory containing additional *.conf files
|
* **debug**: Set to true to gather and send metrics to STDOUT as well as
|
||||||
-input-filter filter the input plugins to enable, separator is :
|
InfluxDB.
|
||||||
-output-filter filter the output plugins to enable, separator is :
|
|
||||||
-usage print usage for a plugin, ie, 'telegraf -usage mysql'
|
|
||||||
-version print the version to stdout
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
# generate a telegraf config file:
|
|
||||||
telegraf -sample-config > telegraf.conf
|
|
||||||
|
|
||||||
# generate config with only cpu input & influxdb output plugins defined
|
|
||||||
telegraf -sample-config -input-filter cpu -output-filter influxdb
|
|
||||||
|
|
||||||
# run a single telegraf collection, outputing metrics to stdout
|
|
||||||
telegraf -config telegraf.conf -test
|
|
||||||
|
|
||||||
# run telegraf with all plugins defined in config file
|
|
||||||
telegraf -config telegraf.conf
|
|
||||||
|
|
||||||
# run telegraf, enabling the cpu & memory input, and influxdb output plugins
|
|
||||||
telegraf -config telegraf.conf -input-filter cpu:mem -output-filter influxdb
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
See the [configuration guide](CONFIGURATION.md) for a rundown of the more advanced
|
See the [configuration guide](CONFIGURATION.md) for a rundown of the more advanced
|
||||||
configuration options.
|
configuration options.
|
||||||
|
|
||||||
## Supported Input Plugins
|
## Supported Plugins
|
||||||
|
|
||||||
|
**You can view usage instructions for each plugin by running**
|
||||||
|
`telegraf -usage <pluginname>`.
|
||||||
|
|
||||||
Telegraf currently has support for collecting metrics from:
|
Telegraf currently has support for collecting metrics from:
|
||||||
|
|
||||||
@@ -166,7 +140,9 @@ Telegraf currently has support for collecting metrics from:
|
|||||||
* diskio
|
* diskio
|
||||||
* swap
|
* swap
|
||||||
|
|
||||||
Telegraf can also collect metrics via the following service plugins:
|
## Supported Service Plugins
|
||||||
|
|
||||||
|
Telegraf can collect metrics via the following services:
|
||||||
|
|
||||||
* statsd
|
* statsd
|
||||||
* kafka_consumer
|
* kafka_consumer
|
||||||
@@ -174,19 +150,18 @@ Telegraf can also collect metrics via the following service plugins:
|
|||||||
We'll be adding support for many more over the coming months. Read on if you
|
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.
|
want to add support for another service or third-party API.
|
||||||
|
|
||||||
## Supported Output Plugins
|
## Supported Outputs
|
||||||
|
|
||||||
* influxdb
|
* influxdb
|
||||||
* amon
|
|
||||||
* amqp
|
|
||||||
* datadog
|
|
||||||
* kafka
|
|
||||||
* amazon kinesis
|
|
||||||
* librato
|
|
||||||
* mqtt
|
|
||||||
* nsq
|
* nsq
|
||||||
|
* kafka
|
||||||
|
* datadog
|
||||||
* opentsdb
|
* opentsdb
|
||||||
|
* amqp (rabbitmq)
|
||||||
|
* mqtt
|
||||||
|
* librato
|
||||||
* prometheus
|
* prometheus
|
||||||
|
* amon
|
||||||
* riemann
|
* riemann
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|||||||
@@ -29,12 +29,12 @@ type Accumulator interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewAccumulator(
|
func NewAccumulator(
|
||||||
inputConfig *config.InputConfig,
|
pluginConfig *config.PluginConfig,
|
||||||
points chan *client.Point,
|
points chan *client.Point,
|
||||||
) Accumulator {
|
) Accumulator {
|
||||||
acc := accumulator{}
|
acc := accumulator{}
|
||||||
acc.points = points
|
acc.points = points
|
||||||
acc.inputConfig = inputConfig
|
acc.pluginConfig = pluginConfig
|
||||||
return &acc
|
return &acc
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ type accumulator struct {
|
|||||||
|
|
||||||
debug bool
|
debug bool
|
||||||
|
|
||||||
inputConfig *config.InputConfig
|
pluginConfig *config.PluginConfig
|
||||||
|
|
||||||
prefix string
|
prefix string
|
||||||
}
|
}
|
||||||
@@ -69,31 +69,27 @@ func (ac *accumulator) AddFields(
|
|||||||
tags map[string]string,
|
tags map[string]string,
|
||||||
t ...time.Time,
|
t ...time.Time,
|
||||||
) {
|
) {
|
||||||
if len(fields) == 0 || len(measurement) == 0 {
|
if !ac.pluginConfig.Filter.ShouldTagsPass(tags) {
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ac.inputConfig.Filter.ShouldTagsPass(tags) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override measurement name if set
|
// Override measurement name if set
|
||||||
if len(ac.inputConfig.NameOverride) != 0 {
|
if len(ac.pluginConfig.NameOverride) != 0 {
|
||||||
measurement = ac.inputConfig.NameOverride
|
measurement = ac.pluginConfig.NameOverride
|
||||||
}
|
}
|
||||||
// Apply measurement prefix and suffix if set
|
// Apply measurement prefix and suffix if set
|
||||||
if len(ac.inputConfig.MeasurementPrefix) != 0 {
|
if len(ac.pluginConfig.MeasurementPrefix) != 0 {
|
||||||
measurement = ac.inputConfig.MeasurementPrefix + measurement
|
measurement = ac.pluginConfig.MeasurementPrefix + measurement
|
||||||
}
|
}
|
||||||
if len(ac.inputConfig.MeasurementSuffix) != 0 {
|
if len(ac.pluginConfig.MeasurementSuffix) != 0 {
|
||||||
measurement = measurement + ac.inputConfig.MeasurementSuffix
|
measurement = measurement + ac.pluginConfig.MeasurementSuffix
|
||||||
}
|
}
|
||||||
|
|
||||||
if tags == nil {
|
if tags == nil {
|
||||||
tags = make(map[string]string)
|
tags = make(map[string]string)
|
||||||
}
|
}
|
||||||
// Apply plugin-wide tags if set
|
// Apply plugin-wide tags if set
|
||||||
for k, v := range ac.inputConfig.Tags {
|
for k, v := range ac.pluginConfig.Tags {
|
||||||
if _, ok := tags[k]; !ok {
|
if _, ok := tags[k]; !ok {
|
||||||
tags[k] = v
|
tags[k] = v
|
||||||
}
|
}
|
||||||
@@ -108,8 +104,8 @@ func (ac *accumulator) AddFields(
|
|||||||
result := make(map[string]interface{})
|
result := make(map[string]interface{})
|
||||||
for k, v := range fields {
|
for k, v := range fields {
|
||||||
// Filter out any filtered fields
|
// Filter out any filtered fields
|
||||||
if ac.inputConfig != nil {
|
if ac.pluginConfig != nil {
|
||||||
if !ac.inputConfig.Filter.ShouldPass(k) {
|
if !ac.pluginConfig.Filter.ShouldPass(k) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
92
agent.go
92
agent.go
@@ -10,8 +10,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/internal/config"
|
"github.com/influxdb/telegraf/internal/config"
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
)
|
)
|
||||||
@@ -85,33 +85,33 @@ func (a *Agent) Close() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// gatherParallel runs the inputs that are using the same reporting interval
|
// gatherParallel runs the plugins that are using the same reporting interval
|
||||||
// as the telegraf agent.
|
// as the telegraf agent.
|
||||||
func (a *Agent) gatherParallel(pointChan chan *client.Point) error {
|
func (a *Agent) gatherParallel(pointChan chan *client.Point) error {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
counter := 0
|
counter := 0
|
||||||
for _, input := range a.Config.Inputs {
|
for _, plugin := range a.Config.Plugins {
|
||||||
if input.Config.Interval != 0 {
|
if plugin.Config.Interval != 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
counter++
|
counter++
|
||||||
go func(input *config.RunningInput) {
|
go func(plugin *config.RunningPlugin) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
acc := NewAccumulator(input.Config, pointChan)
|
acc := NewAccumulator(plugin.Config, pointChan)
|
||||||
acc.SetDebug(a.Config.Agent.Debug)
|
acc.SetDebug(a.Config.Agent.Debug)
|
||||||
// acc.SetPrefix(input.Name + "_")
|
// acc.SetPrefix(plugin.Name + "_")
|
||||||
acc.SetDefaultTags(a.Config.Tags)
|
acc.SetDefaultTags(a.Config.Tags)
|
||||||
|
|
||||||
if err := input.Input.Gather(acc); err != nil {
|
if err := plugin.Plugin.Gather(acc); err != nil {
|
||||||
log.Printf("Error in input [%s]: %s", input.Name, err)
|
log.Printf("Error in plugin [%s]: %s", plugin.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}(input)
|
}(plugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
if counter == 0 {
|
if counter == 0 {
|
||||||
@@ -121,36 +121,36 @@ func (a *Agent) gatherParallel(pointChan chan *client.Point) error {
|
|||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
elapsed := time.Since(start)
|
elapsed := time.Since(start)
|
||||||
log.Printf("Gathered metrics, (%s interval), from %d inputs in %s\n",
|
log.Printf("Gathered metrics, (%s interval), from %d plugins in %s\n",
|
||||||
a.Config.Agent.Interval.Duration, counter, elapsed)
|
a.Config.Agent.Interval, counter, elapsed)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// gatherSeparate runs the inputs that have been configured with their own
|
// gatherSeparate runs the plugins that have been configured with their own
|
||||||
// reporting interval.
|
// reporting interval.
|
||||||
func (a *Agent) gatherSeparate(
|
func (a *Agent) gatherSeparate(
|
||||||
shutdown chan struct{},
|
shutdown chan struct{},
|
||||||
input *config.RunningInput,
|
plugin *config.RunningPlugin,
|
||||||
pointChan chan *client.Point,
|
pointChan chan *client.Point,
|
||||||
) error {
|
) error {
|
||||||
ticker := time.NewTicker(input.Config.Interval)
|
ticker := time.NewTicker(plugin.Config.Interval)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
var outerr error
|
var outerr error
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
acc := NewAccumulator(input.Config, pointChan)
|
acc := NewAccumulator(plugin.Config, pointChan)
|
||||||
acc.SetDebug(a.Config.Agent.Debug)
|
acc.SetDebug(a.Config.Agent.Debug)
|
||||||
// acc.SetPrefix(input.Name + "_")
|
// acc.SetPrefix(plugin.Name + "_")
|
||||||
acc.SetDefaultTags(a.Config.Tags)
|
acc.SetDefaultTags(a.Config.Tags)
|
||||||
|
|
||||||
if err := input.Input.Gather(acc); err != nil {
|
if err := plugin.Plugin.Gather(acc); err != nil {
|
||||||
log.Printf("Error in input [%s]: %s", input.Name, err)
|
log.Printf("Error in plugin [%s]: %s", plugin.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
elapsed := time.Since(start)
|
elapsed := time.Since(start)
|
||||||
log.Printf("Gathered metrics, (separate %s interval), from %s in %s\n",
|
log.Printf("Gathered metrics, (separate %s interval), from %s in %s\n",
|
||||||
input.Config.Interval, input.Name, elapsed)
|
plugin.Config.Interval, plugin.Name, elapsed)
|
||||||
|
|
||||||
if outerr != nil {
|
if outerr != nil {
|
||||||
return outerr
|
return outerr
|
||||||
@@ -165,7 +165,7 @@ func (a *Agent) gatherSeparate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test verifies that we can 'Gather' from all inputs with their configured
|
// Test verifies that we can 'Gather' from all plugins with their configured
|
||||||
// Config struct
|
// Config struct
|
||||||
func (a *Agent) Test() error {
|
func (a *Agent) Test() error {
|
||||||
shutdown := make(chan struct{})
|
shutdown := make(chan struct{})
|
||||||
@@ -184,27 +184,27 @@ func (a *Agent) Test() error {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for _, input := range a.Config.Inputs {
|
for _, plugin := range a.Config.Plugins {
|
||||||
acc := NewAccumulator(input.Config, pointChan)
|
acc := NewAccumulator(plugin.Config, pointChan)
|
||||||
acc.SetDebug(true)
|
acc.SetDebug(true)
|
||||||
// acc.SetPrefix(input.Name + "_")
|
// acc.SetPrefix(plugin.Name + "_")
|
||||||
|
|
||||||
fmt.Printf("* Plugin: %s, Collection 1\n", input.Name)
|
fmt.Printf("* Plugin: %s, Collection 1\n", plugin.Name)
|
||||||
if input.Config.Interval != 0 {
|
if plugin.Config.Interval != 0 {
|
||||||
fmt.Printf("* Internal: %s\n", input.Config.Interval)
|
fmt.Printf("* Internal: %s\n", plugin.Config.Interval)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := input.Input.Gather(acc); err != nil {
|
if err := plugin.Plugin.Gather(acc); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special instructions for some inputs. cpu, for example, needs to be
|
// Special instructions for some plugins. cpu, for example, needs to be
|
||||||
// run twice in order to return cpu usage percentages.
|
// run twice in order to return cpu usage percentages.
|
||||||
switch input.Name {
|
switch plugin.Name {
|
||||||
case "cpu", "mongodb":
|
case "cpu", "mongodb":
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
fmt.Printf("* Plugin: %s, Collection 2\n", input.Name)
|
fmt.Printf("* Plugin: %s, Collection 2\n", plugin.Name)
|
||||||
if err := input.Input.Gather(acc); err != nil {
|
if err := plugin.Plugin.Gather(acc); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -332,10 +332,10 @@ func (a *Agent) Run(shutdown chan struct{}) error {
|
|||||||
|
|
||||||
log.Printf("Agent Config: Interval:%s, Debug:%#v, Hostname:%#v, "+
|
log.Printf("Agent Config: Interval:%s, Debug:%#v, Hostname:%#v, "+
|
||||||
"Flush Interval:%s\n",
|
"Flush Interval:%s\n",
|
||||||
a.Config.Agent.Interval.Duration, a.Config.Agent.Debug,
|
a.Config.Agent.Interval, a.Config.Agent.Debug,
|
||||||
a.Config.Agent.Hostname, a.Config.Agent.FlushInterval.Duration)
|
a.Config.Agent.Hostname, a.Config.Agent.FlushInterval)
|
||||||
|
|
||||||
// channel shared between all input threads for accumulating points
|
// channel shared between all plugin threads for accumulating points
|
||||||
pointChan := make(chan *client.Point, 1000)
|
pointChan := make(chan *client.Point, 1000)
|
||||||
|
|
||||||
// Round collection to nearest interval by sleeping
|
// Round collection to nearest interval by sleeping
|
||||||
@@ -354,29 +354,29 @@ func (a *Agent) Run(shutdown chan struct{}) error {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for _, input := range a.Config.Inputs {
|
for _, plugin := range a.Config.Plugins {
|
||||||
|
|
||||||
// Start service of any ServicePlugins
|
// Start service of any ServicePlugins
|
||||||
switch p := input.Input.(type) {
|
switch p := plugin.Plugin.(type) {
|
||||||
case inputs.ServiceInput:
|
case plugins.ServicePlugin:
|
||||||
if err := p.Start(); err != nil {
|
if err := p.Start(); err != nil {
|
||||||
log.Printf("Service for input %s failed to start, exiting\n%s\n",
|
log.Printf("Service for plugin %s failed to start, exiting\n%s\n",
|
||||||
input.Name, err.Error())
|
plugin.Name, err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer p.Stop()
|
defer p.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special handling for inputs that have their own collection interval
|
// Special handling for plugins that have their own collection interval
|
||||||
// configured. Default intervals are handled below with gatherParallel
|
// configured. Default intervals are handled below with gatherParallel
|
||||||
if input.Config.Interval != 0 {
|
if plugin.Config.Interval != 0 {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(input *config.RunningInput) {
|
go func(plugin *config.RunningPlugin) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err := a.gatherSeparate(shutdown, input, pointChan); err != nil {
|
if err := a.gatherSeparate(shutdown, plugin, pointChan); err != nil {
|
||||||
log.Printf(err.Error())
|
log.Printf(err.Error())
|
||||||
}
|
}
|
||||||
}(input)
|
}(plugin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,96 +8,77 @@ import (
|
|||||||
"github.com/influxdb/telegraf/internal/config"
|
"github.com/influxdb/telegraf/internal/config"
|
||||||
|
|
||||||
// needing to load the plugins
|
// needing to load the plugins
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/all"
|
_ "github.com/influxdb/telegraf/plugins/all"
|
||||||
// needing to load the outputs
|
// needing to load the outputs
|
||||||
_ "github.com/influxdb/telegraf/plugins/outputs/all"
|
_ "github.com/influxdb/telegraf/outputs/all"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAgent_LoadPlugin(t *testing.T) {
|
func TestAgent_LoadPlugin(t *testing.T) {
|
||||||
c := config.NewConfig()
|
c := config.NewConfig()
|
||||||
c.InputFilters = []string{"mysql"}
|
c.PluginFilters = []string{"mysql"}
|
||||||
err := c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
||||||
assert.NoError(t, err)
|
|
||||||
a, _ := NewAgent(c)
|
a, _ := NewAgent(c)
|
||||||
assert.Equal(t, 1, len(a.Config.Inputs))
|
assert.Equal(t, 1, len(a.Config.Plugins))
|
||||||
|
|
||||||
c = config.NewConfig()
|
c = config.NewConfig()
|
||||||
c.InputFilters = []string{"foo"}
|
c.PluginFilters = []string{"foo"}
|
||||||
err = c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
||||||
assert.NoError(t, err)
|
|
||||||
a, _ = NewAgent(c)
|
a, _ = NewAgent(c)
|
||||||
assert.Equal(t, 0, len(a.Config.Inputs))
|
assert.Equal(t, 0, len(a.Config.Plugins))
|
||||||
|
|
||||||
c = config.NewConfig()
|
c = config.NewConfig()
|
||||||
c.InputFilters = []string{"mysql", "foo"}
|
c.PluginFilters = []string{"mysql", "foo"}
|
||||||
err = c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
||||||
assert.NoError(t, err)
|
|
||||||
a, _ = NewAgent(c)
|
a, _ = NewAgent(c)
|
||||||
assert.Equal(t, 1, len(a.Config.Inputs))
|
assert.Equal(t, 1, len(a.Config.Plugins))
|
||||||
|
|
||||||
c = config.NewConfig()
|
c = config.NewConfig()
|
||||||
c.InputFilters = []string{"mysql", "redis"}
|
c.PluginFilters = []string{"mysql", "redis"}
|
||||||
err = c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
||||||
assert.NoError(t, err)
|
|
||||||
a, _ = NewAgent(c)
|
a, _ = NewAgent(c)
|
||||||
assert.Equal(t, 2, len(a.Config.Inputs))
|
assert.Equal(t, 2, len(a.Config.Plugins))
|
||||||
|
|
||||||
c = config.NewConfig()
|
c = config.NewConfig()
|
||||||
c.InputFilters = []string{"mysql", "foo", "redis", "bar"}
|
c.PluginFilters = []string{"mysql", "foo", "redis", "bar"}
|
||||||
err = c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
||||||
assert.NoError(t, err)
|
|
||||||
a, _ = NewAgent(c)
|
a, _ = NewAgent(c)
|
||||||
assert.Equal(t, 2, len(a.Config.Inputs))
|
assert.Equal(t, 2, len(a.Config.Plugins))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAgent_LoadOutput(t *testing.T) {
|
func TestAgent_LoadOutput(t *testing.T) {
|
||||||
c := config.NewConfig()
|
c := config.NewConfig()
|
||||||
c.OutputFilters = []string{"influxdb"}
|
c.OutputFilters = []string{"influxdb"}
|
||||||
err := c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
||||||
assert.NoError(t, err)
|
|
||||||
a, _ := NewAgent(c)
|
a, _ := NewAgent(c)
|
||||||
assert.Equal(t, 2, len(a.Config.Outputs))
|
assert.Equal(t, 2, len(a.Config.Outputs))
|
||||||
|
|
||||||
c = config.NewConfig()
|
|
||||||
c.OutputFilters = []string{"kafka"}
|
|
||||||
err = c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
a, _ = NewAgent(c)
|
|
||||||
assert.Equal(t, 1, len(a.Config.Outputs))
|
|
||||||
|
|
||||||
c = config.NewConfig()
|
c = config.NewConfig()
|
||||||
c.OutputFilters = []string{}
|
c.OutputFilters = []string{}
|
||||||
err = c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
||||||
assert.NoError(t, err)
|
|
||||||
a, _ = NewAgent(c)
|
a, _ = NewAgent(c)
|
||||||
assert.Equal(t, 3, len(a.Config.Outputs))
|
assert.Equal(t, 3, len(a.Config.Outputs))
|
||||||
|
|
||||||
c = config.NewConfig()
|
c = config.NewConfig()
|
||||||
c.OutputFilters = []string{"foo"}
|
c.OutputFilters = []string{"foo"}
|
||||||
err = c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
||||||
assert.NoError(t, err)
|
|
||||||
a, _ = NewAgent(c)
|
a, _ = NewAgent(c)
|
||||||
assert.Equal(t, 0, len(a.Config.Outputs))
|
assert.Equal(t, 0, len(a.Config.Outputs))
|
||||||
|
|
||||||
c = config.NewConfig()
|
c = config.NewConfig()
|
||||||
c.OutputFilters = []string{"influxdb", "foo"}
|
c.OutputFilters = []string{"influxdb", "foo"}
|
||||||
err = c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
||||||
assert.NoError(t, err)
|
|
||||||
a, _ = NewAgent(c)
|
a, _ = NewAgent(c)
|
||||||
assert.Equal(t, 2, len(a.Config.Outputs))
|
assert.Equal(t, 2, len(a.Config.Outputs))
|
||||||
|
|
||||||
c = config.NewConfig()
|
c = config.NewConfig()
|
||||||
c.OutputFilters = []string{"influxdb", "kafka"}
|
c.OutputFilters = []string{"influxdb", "kafka"}
|
||||||
err = c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, 3, len(c.Outputs))
|
|
||||||
a, _ = NewAgent(c)
|
a, _ = NewAgent(c)
|
||||||
assert.Equal(t, 3, len(a.Config.Outputs))
|
assert.Equal(t, 3, len(a.Config.Outputs))
|
||||||
|
|
||||||
c = config.NewConfig()
|
c = config.NewConfig()
|
||||||
c.OutputFilters = []string{"influxdb", "foo", "kafka", "bar"}
|
c.OutputFilters = []string{"influxdb", "foo", "kafka", "bar"}
|
||||||
err = c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
c.LoadConfig("./internal/config/testdata/telegraf-agent.toml")
|
||||||
assert.NoError(t, err)
|
|
||||||
a, _ = NewAgent(c)
|
a, _ = NewAgent(c)
|
||||||
assert.Equal(t, 3, len(a.Config.Outputs))
|
assert.Equal(t, 3, len(a.Config.Outputs))
|
||||||
}
|
}
|
||||||
|
|||||||
670
build.py
670
build.py
@@ -1,670 +0,0 @@
|
|||||||
#!/usr/bin/env python2.7
|
|
||||||
#
|
|
||||||
# This is the Telegraf build script.
|
|
||||||
#
|
|
||||||
# Current caveats:
|
|
||||||
# - Does not checkout the correct commit/branch (for now, you will need to do so manually)
|
|
||||||
# - Has external dependencies for packaging (fpm) and uploading (boto)
|
|
||||||
#
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import time
|
|
||||||
import datetime
|
|
||||||
import shutil
|
|
||||||
import tempfile
|
|
||||||
import hashlib
|
|
||||||
import re
|
|
||||||
|
|
||||||
try:
|
|
||||||
import boto
|
|
||||||
from boto.s3.key import Key
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# PACKAGING VARIABLES
|
|
||||||
INSTALL_ROOT_DIR = "/usr/bin"
|
|
||||||
LOG_DIR = "/var/log/telegraf"
|
|
||||||
SCRIPT_DIR = "/usr/lib/telegraf/scripts"
|
|
||||||
CONFIG_DIR = "/etc/telegraf"
|
|
||||||
LOGROTATE_DIR = "/etc/logrotate.d"
|
|
||||||
|
|
||||||
INIT_SCRIPT = "scripts/init.sh"
|
|
||||||
SYSTEMD_SCRIPT = "scripts/telegraf.service"
|
|
||||||
LOGROTATE_SCRIPT = "etc/logrotate.d/telegraf"
|
|
||||||
DEFAULT_CONFIG = "etc/telegraf.conf"
|
|
||||||
POSTINST_SCRIPT = "scripts/post-install.sh"
|
|
||||||
PREINST_SCRIPT = "scripts/pre-install.sh"
|
|
||||||
|
|
||||||
# META-PACKAGE VARIABLES
|
|
||||||
PACKAGE_LICENSE = "MIT"
|
|
||||||
PACKAGE_URL = "https://github.com/influxdata/telegraf"
|
|
||||||
MAINTAINER = "support@influxdb.com"
|
|
||||||
VENDOR = "InfluxData"
|
|
||||||
DESCRIPTION = "Plugin-driven server agent for reporting metrics into InfluxDB."
|
|
||||||
|
|
||||||
# SCRIPT START
|
|
||||||
prereqs = [ 'git', 'go' ]
|
|
||||||
optional_prereqs = [ 'gvm', 'fpm', 'rpmbuild' ]
|
|
||||||
|
|
||||||
fpm_common_args = "-f -s dir --log error \
|
|
||||||
--vendor {} \
|
|
||||||
--url {} \
|
|
||||||
--license {} \
|
|
||||||
--maintainer {} \
|
|
||||||
--config-files {} \
|
|
||||||
--config-files {} \
|
|
||||||
--after-install {} \
|
|
||||||
--before-install {} \
|
|
||||||
--description \"{}\"".format(
|
|
||||||
VENDOR,
|
|
||||||
PACKAGE_URL,
|
|
||||||
PACKAGE_LICENSE,
|
|
||||||
MAINTAINER,
|
|
||||||
CONFIG_DIR + '/telegraf.conf',
|
|
||||||
LOGROTATE_DIR + '/telegraf',
|
|
||||||
POSTINST_SCRIPT,
|
|
||||||
PREINST_SCRIPT,
|
|
||||||
DESCRIPTION)
|
|
||||||
|
|
||||||
targets = {
|
|
||||||
'telegraf' : './cmd/telegraf/telegraf.go',
|
|
||||||
}
|
|
||||||
|
|
||||||
supported_builds = {
|
|
||||||
# TODO(rossmcdonald): Add support for multiple GOARM values
|
|
||||||
'darwin': [ "amd64", "386" ],
|
|
||||||
# 'windows': [ "amd64", "386", "arm", "arm64" ],
|
|
||||||
'linux': [ "amd64", "386", "arm" ]
|
|
||||||
}
|
|
||||||
supported_go = [ '1.5.1' ]
|
|
||||||
supported_packages = {
|
|
||||||
"darwin": [ "tar", "zip" ],
|
|
||||||
"linux": [ "deb", "rpm", "tar", "zip" ],
|
|
||||||
"windows": [ "tar", "zip" ],
|
|
||||||
}
|
|
||||||
|
|
||||||
def run(command, allow_failure=False, shell=False):
|
|
||||||
out = None
|
|
||||||
try:
|
|
||||||
if shell:
|
|
||||||
out = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=shell)
|
|
||||||
else:
|
|
||||||
out = subprocess.check_output(command.split(), stderr=subprocess.STDOUT)
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
print ""
|
|
||||||
print ""
|
|
||||||
print "Executed command failed!"
|
|
||||||
print "-- Command run was: {}".format(command)
|
|
||||||
print "-- Failure was: {}".format(e.output)
|
|
||||||
if allow_failure:
|
|
||||||
print "Continuing..."
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
print ""
|
|
||||||
print "Stopping."
|
|
||||||
sys.exit(1)
|
|
||||||
except OSError as e:
|
|
||||||
print ""
|
|
||||||
print ""
|
|
||||||
print "Invalid command!"
|
|
||||||
print "-- Command run was: {}".format(command)
|
|
||||||
print "-- Failure was: {}".format(e)
|
|
||||||
if allow_failure:
|
|
||||||
print "Continuing..."
|
|
||||||
return out
|
|
||||||
else:
|
|
||||||
print ""
|
|
||||||
print "Stopping."
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
return out
|
|
||||||
|
|
||||||
def create_temp_dir():
|
|
||||||
return tempfile.mkdtemp(prefix="telegraf-build.")
|
|
||||||
|
|
||||||
def get_current_version():
|
|
||||||
command = "git describe --always --tags --abbrev=0"
|
|
||||||
out = run(command)
|
|
||||||
return out.strip()
|
|
||||||
|
|
||||||
def get_current_commit(short=False):
|
|
||||||
command = None
|
|
||||||
if short:
|
|
||||||
command = "git log --pretty=format:'%h' -n 1"
|
|
||||||
else:
|
|
||||||
command = "git rev-parse HEAD"
|
|
||||||
out = run(command)
|
|
||||||
return out.strip('\'\n\r ')
|
|
||||||
|
|
||||||
def get_current_branch():
|
|
||||||
command = "git rev-parse --abbrev-ref HEAD"
|
|
||||||
out = run(command)
|
|
||||||
return out.strip()
|
|
||||||
|
|
||||||
def get_system_arch():
|
|
||||||
arch = os.uname()[4]
|
|
||||||
if arch == "x86_64":
|
|
||||||
arch = "amd64"
|
|
||||||
return arch
|
|
||||||
|
|
||||||
def get_system_platform():
|
|
||||||
if sys.platform.startswith("linux"):
|
|
||||||
return "linux"
|
|
||||||
else:
|
|
||||||
return sys.platform
|
|
||||||
|
|
||||||
def get_go_version():
|
|
||||||
out = run("go version")
|
|
||||||
matches = re.search('go version go(\S+)', out)
|
|
||||||
if matches is not None:
|
|
||||||
return matches.groups()[0].strip()
|
|
||||||
return None
|
|
||||||
|
|
||||||
def check_path_for(b):
|
|
||||||
def is_exe(fpath):
|
|
||||||
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
|
|
||||||
|
|
||||||
for path in os.environ["PATH"].split(os.pathsep):
|
|
||||||
path = path.strip('"')
|
|
||||||
full_path = os.path.join(path, b)
|
|
||||||
if os.path.isfile(full_path) and os.access(full_path, os.X_OK):
|
|
||||||
return full_path
|
|
||||||
|
|
||||||
def check_environ(build_dir = None):
|
|
||||||
print "\nChecking environment:"
|
|
||||||
for v in [ "GOPATH", "GOBIN", "GOROOT" ]:
|
|
||||||
print "\t- {} -> {}".format(v, os.environ.get(v))
|
|
||||||
|
|
||||||
cwd = os.getcwd()
|
|
||||||
if build_dir == None and os.environ.get("GOPATH") and os.environ.get("GOPATH") not in cwd:
|
|
||||||
print "\n!! WARNING: Your current directory is not under your GOPATH. This may lead to build failures."
|
|
||||||
|
|
||||||
def check_prereqs():
|
|
||||||
print "\nChecking for dependencies:"
|
|
||||||
for req in prereqs:
|
|
||||||
print "\t- {} ->".format(req),
|
|
||||||
path = check_path_for(req)
|
|
||||||
if path:
|
|
||||||
print "{}".format(path)
|
|
||||||
else:
|
|
||||||
print "?"
|
|
||||||
for req in optional_prereqs:
|
|
||||||
print "\t- {} (optional) ->".format(req),
|
|
||||||
path = check_path_for(req)
|
|
||||||
if path:
|
|
||||||
print "{}".format(path)
|
|
||||||
else:
|
|
||||||
print "?"
|
|
||||||
print ""
|
|
||||||
|
|
||||||
def upload_packages(packages, nightly=False):
|
|
||||||
print "Uploading packages to S3..."
|
|
||||||
print ""
|
|
||||||
c = boto.connect_s3()
|
|
||||||
# TODO(rossmcdonald) - Set to different S3 bucket for release vs nightly
|
|
||||||
bucket = c.get_bucket('telegraf-nightly')
|
|
||||||
for p in packages:
|
|
||||||
name = os.path.basename(p)
|
|
||||||
if bucket.get_key(name) is None or nightly:
|
|
||||||
print "\t - Uploading {}...".format(name),
|
|
||||||
k = Key(bucket)
|
|
||||||
k.key = name
|
|
||||||
if nightly:
|
|
||||||
n = k.set_contents_from_filename(p, replace=True)
|
|
||||||
else:
|
|
||||||
n = k.set_contents_from_filename(p, replace=False)
|
|
||||||
k.make_public()
|
|
||||||
print "[ DONE ]"
|
|
||||||
else:
|
|
||||||
print "\t - Not uploading {}, already exists.".format(p)
|
|
||||||
print ""
|
|
||||||
|
|
||||||
def run_tests(race, parallel, timeout, no_vet):
|
|
||||||
get_command = "go get -d -t ./..."
|
|
||||||
print "Retrieving Go dependencies...",
|
|
||||||
sys.stdout.flush()
|
|
||||||
run(get_command)
|
|
||||||
print "done."
|
|
||||||
print "Running tests:"
|
|
||||||
print "\tRace: ", race
|
|
||||||
if parallel is not None:
|
|
||||||
print "\tParallel:", parallel
|
|
||||||
if timeout is not None:
|
|
||||||
print "\tTimeout:", timeout
|
|
||||||
sys.stdout.flush()
|
|
||||||
p = subprocess.Popen(["go", "fmt", "./..."], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
out, err = p.communicate()
|
|
||||||
if len(out) > 0 or len(err) > 0:
|
|
||||||
print "Code not formatted. Please use 'go fmt ./...' to fix formatting errors."
|
|
||||||
print out
|
|
||||||
print err
|
|
||||||
return False
|
|
||||||
if not no_vet:
|
|
||||||
p = subprocess.Popen(["go", "tool", "vet", "-composites=false", "./"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
out, err = p.communicate()
|
|
||||||
if len(out) > 0 or len(err) > 0:
|
|
||||||
print "Go vet failed. Please run 'go vet ./...' and fix any errors."
|
|
||||||
print out
|
|
||||||
print err
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
print "Skipping go vet ..."
|
|
||||||
sys.stdout.flush()
|
|
||||||
test_command = "go test -v"
|
|
||||||
if race:
|
|
||||||
test_command += " -race"
|
|
||||||
if parallel is not None:
|
|
||||||
test_command += " -parallel {}".format(parallel)
|
|
||||||
if timeout is not None:
|
|
||||||
test_command += " -timeout {}".format(timeout)
|
|
||||||
test_command += " ./..."
|
|
||||||
code = os.system(test_command)
|
|
||||||
if code != 0:
|
|
||||||
print "Tests Failed"
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
print "Tests Passed"
|
|
||||||
return True
|
|
||||||
|
|
||||||
def build(version=None,
|
|
||||||
branch=None,
|
|
||||||
commit=None,
|
|
||||||
platform=None,
|
|
||||||
arch=None,
|
|
||||||
nightly=False,
|
|
||||||
rc=None,
|
|
||||||
race=False,
|
|
||||||
clean=False,
|
|
||||||
outdir=".",
|
|
||||||
goarm_version="6"):
|
|
||||||
print "-------------------------"
|
|
||||||
print ""
|
|
||||||
print "Build plan:"
|
|
||||||
print "\t- version: {}".format(version)
|
|
||||||
if rc:
|
|
||||||
print "\t- release candidate: {}".format(rc)
|
|
||||||
print "\t- commit: {}".format(commit)
|
|
||||||
print "\t- branch: {}".format(branch)
|
|
||||||
print "\t- platform: {}".format(platform)
|
|
||||||
print "\t- arch: {}".format(arch)
|
|
||||||
if arch == 'arm' and goarm_version:
|
|
||||||
print "\t- ARM version: {}".format(goarm_version)
|
|
||||||
print "\t- nightly? {}".format(str(nightly).lower())
|
|
||||||
print "\t- race enabled? {}".format(str(race).lower())
|
|
||||||
print ""
|
|
||||||
|
|
||||||
if not os.path.exists(outdir):
|
|
||||||
os.makedirs(outdir)
|
|
||||||
elif clean and outdir != '/':
|
|
||||||
print "Cleaning build directory..."
|
|
||||||
shutil.rmtree(outdir)
|
|
||||||
os.makedirs(outdir)
|
|
||||||
|
|
||||||
if rc:
|
|
||||||
# If a release candidate, update the version information accordingly
|
|
||||||
version = "{}rc{}".format(version, rc)
|
|
||||||
|
|
||||||
print "Starting build..."
|
|
||||||
for b, c in targets.iteritems():
|
|
||||||
print "\t- Building '{}'...".format(os.path.join(outdir, b)),
|
|
||||||
build_command = ""
|
|
||||||
build_command += "GOOS={} GOARCH={} ".format(platform, arch)
|
|
||||||
if arch == "arm" and goarm_version:
|
|
||||||
if goarm_version not in ["5", "6", "7", "arm64"]:
|
|
||||||
print "!! Invalid ARM build version: {}".format(goarm_version)
|
|
||||||
build_command += "GOARM={} ".format(goarm_version)
|
|
||||||
build_command += "go build -o {} ".format(os.path.join(outdir, b))
|
|
||||||
if race:
|
|
||||||
build_command += "-race "
|
|
||||||
go_version = get_go_version()
|
|
||||||
if "1.4" in go_version:
|
|
||||||
build_command += "-ldflags=\"-X main.buildTime '{}' ".format(datetime.datetime.utcnow().isoformat())
|
|
||||||
build_command += "-X main.Version {} ".format(version)
|
|
||||||
build_command += "-X main.Branch {} ".format(branch)
|
|
||||||
build_command += "-X main.Commit {}\" ".format(get_current_commit())
|
|
||||||
else:
|
|
||||||
build_command += "-ldflags=\"-X main.buildTime='{}' ".format(datetime.datetime.utcnow().isoformat())
|
|
||||||
build_command += "-X main.Version={} ".format(version)
|
|
||||||
build_command += "-X main.Branch={} ".format(branch)
|
|
||||||
build_command += "-X main.Commit={}\" ".format(get_current_commit())
|
|
||||||
build_command += c
|
|
||||||
run(build_command, shell=True)
|
|
||||||
print "[ DONE ]"
|
|
||||||
print ""
|
|
||||||
|
|
||||||
def create_dir(path):
|
|
||||||
try:
|
|
||||||
os.makedirs(path)
|
|
||||||
except OSError as e:
|
|
||||||
print e
|
|
||||||
|
|
||||||
def rename_file(fr, to):
|
|
||||||
try:
|
|
||||||
os.rename(fr, to)
|
|
||||||
except OSError as e:
|
|
||||||
print e
|
|
||||||
# Return the original filename
|
|
||||||
return fr
|
|
||||||
else:
|
|
||||||
# Return the new filename
|
|
||||||
return to
|
|
||||||
|
|
||||||
def copy_file(fr, to):
|
|
||||||
try:
|
|
||||||
shutil.copy(fr, to)
|
|
||||||
except OSError as e:
|
|
||||||
print e
|
|
||||||
|
|
||||||
def create_package_fs(build_root):
|
|
||||||
print "\t- Creating a filesystem hierarchy from directory: {}".format(build_root)
|
|
||||||
# Using [1:] for the path names due to them being absolute
|
|
||||||
# (will overwrite previous paths, per 'os.path.join' documentation)
|
|
||||||
dirs = [ INSTALL_ROOT_DIR[1:], LOG_DIR[1:], SCRIPT_DIR[1:], CONFIG_DIR[1:], LOGROTATE_DIR[1:] ]
|
|
||||||
for d in dirs:
|
|
||||||
create_dir(os.path.join(build_root, d))
|
|
||||||
os.chmod(os.path.join(build_root, d), 0755)
|
|
||||||
|
|
||||||
def package_scripts(build_root):
|
|
||||||
print "\t- Copying scripts and sample configuration to build directory"
|
|
||||||
shutil.copyfile(INIT_SCRIPT, os.path.join(build_root, SCRIPT_DIR[1:], INIT_SCRIPT.split('/')[1]))
|
|
||||||
os.chmod(os.path.join(build_root, SCRIPT_DIR[1:], INIT_SCRIPT.split('/')[1]), 0644)
|
|
||||||
shutil.copyfile(SYSTEMD_SCRIPT, os.path.join(build_root, SCRIPT_DIR[1:], SYSTEMD_SCRIPT.split('/')[1]))
|
|
||||||
os.chmod(os.path.join(build_root, SCRIPT_DIR[1:], SYSTEMD_SCRIPT.split('/')[1]), 0644)
|
|
||||||
shutil.copyfile(LOGROTATE_SCRIPT, os.path.join(build_root, LOGROTATE_DIR[1:], "telegraf"))
|
|
||||||
os.chmod(os.path.join(build_root, LOGROTATE_DIR[1:], "telegraf"), 0644)
|
|
||||||
shutil.copyfile(DEFAULT_CONFIG, os.path.join(build_root, CONFIG_DIR[1:], "telegraf.conf"))
|
|
||||||
os.chmod(os.path.join(build_root, CONFIG_DIR[1:], "telegraf.conf"), 0644)
|
|
||||||
|
|
||||||
def go_get(update=False):
|
|
||||||
get_command = None
|
|
||||||
if update:
|
|
||||||
get_command = "go get -u -f -d ./..."
|
|
||||||
else:
|
|
||||||
get_command = "go get -d ./..."
|
|
||||||
print "Retrieving Go dependencies...",
|
|
||||||
run(get_command)
|
|
||||||
print "done.\n"
|
|
||||||
|
|
||||||
def generate_md5_from_file(path):
|
|
||||||
m = hashlib.md5()
|
|
||||||
with open(path, 'rb') as f:
|
|
||||||
for chunk in iter(lambda: f.read(4096), b""):
|
|
||||||
m.update(chunk)
|
|
||||||
return m.hexdigest()
|
|
||||||
|
|
||||||
def build_packages(build_output, version, nightly=False, rc=None, iteration=1):
|
|
||||||
outfiles = []
|
|
||||||
tmp_build_dir = create_temp_dir()
|
|
||||||
try:
|
|
||||||
print "-------------------------"
|
|
||||||
print ""
|
|
||||||
print "Packaging..."
|
|
||||||
for p in build_output:
|
|
||||||
# Create top-level folder displaying which platform (linux, etc)
|
|
||||||
create_dir(os.path.join(tmp_build_dir, p))
|
|
||||||
for a in build_output[p]:
|
|
||||||
current_location = build_output[p][a]
|
|
||||||
# Create second-level directory displaying the architecture (amd64, etc)p
|
|
||||||
build_root = os.path.join(tmp_build_dir, p, a)
|
|
||||||
# Create directory tree to mimic file system of package
|
|
||||||
create_dir(build_root)
|
|
||||||
create_package_fs(build_root)
|
|
||||||
# Copy in packaging and miscellaneous scripts
|
|
||||||
package_scripts(build_root)
|
|
||||||
# Copy newly-built binaries to packaging directory
|
|
||||||
for b in targets:
|
|
||||||
if p == 'windows':
|
|
||||||
b = b + '.exe'
|
|
||||||
fr = os.path.join(current_location, b)
|
|
||||||
to = os.path.join(build_root, INSTALL_ROOT_DIR[1:], b)
|
|
||||||
print "\t- [{}][{}] - Moving from '{}' to '{}'".format(p, a, fr, to)
|
|
||||||
copy_file(fr, to)
|
|
||||||
# Package the directory structure
|
|
||||||
for package_type in supported_packages[p]:
|
|
||||||
print "\t- Packaging directory '{}' as '{}'...".format(build_root, package_type),
|
|
||||||
name = "telegraf"
|
|
||||||
package_version = version
|
|
||||||
package_iteration = iteration
|
|
||||||
if package_type in ['zip', 'tar']:
|
|
||||||
if nightly:
|
|
||||||
name = '{}-nightly_{}_{}'.format(name, p, a)
|
|
||||||
else:
|
|
||||||
name = '{}-{}_{}_{}'.format(name, version, p, a)
|
|
||||||
if package_type == 'tar':
|
|
||||||
# Add `tar.gz` to path to reduce package size
|
|
||||||
current_location = os.path.join(current_location, name + '.tar.gz')
|
|
||||||
if rc is not None:
|
|
||||||
package_iteration = "0.rc{}".format(rc)
|
|
||||||
fpm_command = "fpm {} --name {} -a {} -t {} --version {} --iteration {} -C {} -p {} ".format(
|
|
||||||
fpm_common_args,
|
|
||||||
name,
|
|
||||||
a,
|
|
||||||
package_type,
|
|
||||||
package_version,
|
|
||||||
package_iteration,
|
|
||||||
build_root,
|
|
||||||
current_location)
|
|
||||||
if package_type == "rpm":
|
|
||||||
fpm_command += "--depends coreutils "
|
|
||||||
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))
|
|
||||||
print "[ DONE ]"
|
|
||||||
# Display MD5 hash for generated package
|
|
||||||
print "\t\tMD5 = {}".format(generate_md5_from_file(outfile))
|
|
||||||
print ""
|
|
||||||
return outfiles
|
|
||||||
finally:
|
|
||||||
# Cleanup
|
|
||||||
shutil.rmtree(tmp_build_dir)
|
|
||||||
|
|
||||||
def print_usage():
|
|
||||||
print "Usage: ./build.py [options]"
|
|
||||||
print ""
|
|
||||||
print "Options:"
|
|
||||||
print "\t --outdir=<path> \n\t\t- Send build output to a specified path. Defaults to ./build."
|
|
||||||
print "\t --arch=<arch> \n\t\t- Build for specified architecture. Acceptable values: x86_64|amd64, 386, arm, or all"
|
|
||||||
print "\t --goarm=<arm version> \n\t\t- Build for specified ARM version (when building for ARM). Default value is: 6"
|
|
||||||
print "\t --platform=<platform> \n\t\t- Build for specified platform. Acceptable values: linux, windows, darwin, or all"
|
|
||||||
print "\t --version=<version> \n\t\t- Version information to apply to build metadata. If not specified, will be pulled from repo tag."
|
|
||||||
print "\t --commit=<commit> \n\t\t- Use specific commit for build (currently a NOOP)."
|
|
||||||
print "\t --branch=<branch> \n\t\t- Build from a specific branch (currently a NOOP)."
|
|
||||||
print "\t --rc=<rc number> \n\t\t- Whether or not the build is a release candidate (affects version information)."
|
|
||||||
print "\t --iteration=<iteration number> \n\t\t- The iteration to display on the package output (defaults to 0 for RC's, and 1 otherwise)."
|
|
||||||
print "\t --race \n\t\t- Whether the produced build should have race detection enabled."
|
|
||||||
print "\t --package \n\t\t- Whether the produced builds should be packaged for the target platform(s)."
|
|
||||||
print "\t --nightly \n\t\t- Whether the produced build is a nightly (affects version information)."
|
|
||||||
print "\t --update \n\t\t- Whether dependencies should be updated prior to building."
|
|
||||||
print "\t --test \n\t\t- Run Go tests. Will not produce a build."
|
|
||||||
print "\t --parallel \n\t\t- Run Go tests in parallel up to the count specified."
|
|
||||||
print "\t --timeout \n\t\t- Timeout for Go tests. Defaults to 480s."
|
|
||||||
print "\t --clean \n\t\t- Clean the build output directory prior to creating build."
|
|
||||||
print ""
|
|
||||||
|
|
||||||
def print_package_summary(packages):
|
|
||||||
print packages
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# Command-line arguments
|
|
||||||
outdir = "build"
|
|
||||||
commit = None
|
|
||||||
target_platform = None
|
|
||||||
target_arch = None
|
|
||||||
nightly = False
|
|
||||||
race = False
|
|
||||||
branch = None
|
|
||||||
version = get_current_version()
|
|
||||||
rc = None
|
|
||||||
package = False
|
|
||||||
update = False
|
|
||||||
clean = False
|
|
||||||
upload = False
|
|
||||||
test = False
|
|
||||||
parallel = None
|
|
||||||
timeout = None
|
|
||||||
iteration = 1
|
|
||||||
no_vet = False
|
|
||||||
goarm_version = "6"
|
|
||||||
|
|
||||||
for arg in sys.argv[1:]:
|
|
||||||
if '--outdir' in arg:
|
|
||||||
# Output directory. If none is specified, then builds will be placed in the same directory.
|
|
||||||
output_dir = arg.split("=")[1]
|
|
||||||
if '--commit' in arg:
|
|
||||||
# Commit to build from. If none is specified, then it will build from the most recent commit.
|
|
||||||
commit = arg.split("=")[1]
|
|
||||||
if '--branch' in arg:
|
|
||||||
# Branch to build from. If none is specified, then it will build from the current branch.
|
|
||||||
branch = arg.split("=")[1]
|
|
||||||
elif '--arch' in arg:
|
|
||||||
# Target architecture. If none is specified, then it will build for the current arch.
|
|
||||||
target_arch = arg.split("=")[1]
|
|
||||||
elif '--platform' in arg:
|
|
||||||
# Target platform. If none is specified, then it will build for the current platform.
|
|
||||||
target_platform = arg.split("=")[1]
|
|
||||||
elif '--version' in arg:
|
|
||||||
# Version to assign to this build (0.9.5, etc)
|
|
||||||
version = arg.split("=")[1]
|
|
||||||
elif '--rc' in arg:
|
|
||||||
# Signifies that this is a release candidate build.
|
|
||||||
rc = arg.split("=")[1]
|
|
||||||
elif '--race' in arg:
|
|
||||||
# Signifies that race detection should be enabled.
|
|
||||||
race = True
|
|
||||||
elif '--package' in arg:
|
|
||||||
# Signifies that packages should be built.
|
|
||||||
package = True
|
|
||||||
elif '--nightly' in arg:
|
|
||||||
# Signifies that this is a nightly build.
|
|
||||||
nightly = True
|
|
||||||
elif '--update' in arg:
|
|
||||||
# Signifies that dependencies should be updated.
|
|
||||||
update = True
|
|
||||||
elif '--upload' in arg:
|
|
||||||
# Signifies that the resulting packages should be uploaded to S3
|
|
||||||
upload = True
|
|
||||||
elif '--test' in arg:
|
|
||||||
# Run tests and exit
|
|
||||||
test = True
|
|
||||||
elif '--parallel' in arg:
|
|
||||||
# Set parallel for tests.
|
|
||||||
parallel = int(arg.split("=")[1])
|
|
||||||
elif '--timeout' in arg:
|
|
||||||
# Set timeout for tests.
|
|
||||||
timeout = arg.split("=")[1]
|
|
||||||
elif '--clean' in arg:
|
|
||||||
# Signifies that the outdir should be deleted before building
|
|
||||||
clean = True
|
|
||||||
elif '--iteration' in arg:
|
|
||||||
iteration = arg.split("=")[1]
|
|
||||||
elif '--no-vet' in arg:
|
|
||||||
no_vet = True
|
|
||||||
elif '--goarm' in arg:
|
|
||||||
# Signifies GOARM flag to pass to build command when compiling for ARM
|
|
||||||
goarm_version = arg.split("=")[1]
|
|
||||||
elif '--help' in arg:
|
|
||||||
print_usage()
|
|
||||||
return 0
|
|
||||||
else:
|
|
||||||
print "!! Unknown argument: {}".format(arg)
|
|
||||||
print_usage()
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if nightly:
|
|
||||||
if rc:
|
|
||||||
print "!! Cannot be both nightly and a release candidate! Stopping."
|
|
||||||
return 1
|
|
||||||
# In order to support nightly builds on the repository, we are adding the epoch timestamp
|
|
||||||
# to the version so that version numbers are always greater than the previous nightly.
|
|
||||||
version = "{}.n{}".format(version, int(time.time()))
|
|
||||||
|
|
||||||
# Pre-build checks
|
|
||||||
check_environ()
|
|
||||||
check_prereqs()
|
|
||||||
|
|
||||||
if not commit:
|
|
||||||
commit = get_current_commit(short=True)
|
|
||||||
if not branch:
|
|
||||||
branch = get_current_branch()
|
|
||||||
if not target_arch:
|
|
||||||
if 'arm' in get_system_arch():
|
|
||||||
# Prevent uname from reporting ARM arch (eg 'armv7l')
|
|
||||||
target_arch = "arm"
|
|
||||||
else:
|
|
||||||
target_arch = get_system_arch()
|
|
||||||
if not target_platform:
|
|
||||||
target_platform = get_system_platform()
|
|
||||||
if rc or nightly:
|
|
||||||
# If a release candidate or nightly, set iteration to 0 (instead of 1)
|
|
||||||
iteration = 0
|
|
||||||
|
|
||||||
build_output = {}
|
|
||||||
# TODO(rossmcdonald): Prepare git repo for build (checking out correct branch/commit, etc.)
|
|
||||||
# prepare(branch=branch, commit=commit)
|
|
||||||
if test:
|
|
||||||
if not run_tests(race, parallel, timeout, no_vet):
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
go_get(update=update)
|
|
||||||
|
|
||||||
platforms = []
|
|
||||||
single_build = True
|
|
||||||
if target_platform == 'all':
|
|
||||||
platforms = supported_builds.keys()
|
|
||||||
single_build = False
|
|
||||||
else:
|
|
||||||
platforms = [target_platform]
|
|
||||||
|
|
||||||
for platform in platforms:
|
|
||||||
build_output.update( { platform : {} } )
|
|
||||||
archs = []
|
|
||||||
if target_arch == "all":
|
|
||||||
single_build = False
|
|
||||||
archs = supported_builds.get(platform)
|
|
||||||
else:
|
|
||||||
archs = [target_arch]
|
|
||||||
for arch in archs:
|
|
||||||
od = outdir
|
|
||||||
if not single_build:
|
|
||||||
od = os.path.join(outdir, platform, arch)
|
|
||||||
build(version=version,
|
|
||||||
branch=branch,
|
|
||||||
commit=commit,
|
|
||||||
platform=platform,
|
|
||||||
arch=arch,
|
|
||||||
nightly=nightly,
|
|
||||||
rc=rc,
|
|
||||||
race=race,
|
|
||||||
clean=clean,
|
|
||||||
outdir=od,
|
|
||||||
goarm_version=goarm_version)
|
|
||||||
build_output.get(platform).update( { arch : od } )
|
|
||||||
|
|
||||||
# Build packages
|
|
||||||
if package:
|
|
||||||
if not check_path_for("fpm"):
|
|
||||||
print "!! Cannot package without command 'fpm'. Stopping."
|
|
||||||
return 1
|
|
||||||
packages = build_packages(build_output, version, nightly=nightly, rc=rc, iteration=iteration)
|
|
||||||
# TODO(rossmcdonald): Add nice output for print_package_summary()
|
|
||||||
# print_package_summary(packages)
|
|
||||||
# Optionally upload to S3
|
|
||||||
if upload:
|
|
||||||
upload_packages(packages, nightly=nightly)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main())
|
|
||||||
|
|
||||||
@@ -4,12 +4,14 @@ machine:
|
|||||||
post:
|
post:
|
||||||
- sudo service zookeeper stop
|
- sudo service zookeeper stop
|
||||||
- go version
|
- go version
|
||||||
- go version | grep 1.5.2 || sudo rm -rf /usr/local/go
|
- go version | grep 1.5.1 || sudo rm -rf /usr/local/go
|
||||||
- wget https://storage.googleapis.com/golang/go1.5.2.linux-amd64.tar.gz
|
- wget https://storage.googleapis.com/golang/go1.5.1.linux-amd64.tar.gz
|
||||||
- sudo tar -C /usr/local -xzf go1.5.2.linux-amd64.tar.gz
|
- sudo tar -C /usr/local -xzf go1.5.1.linux-amd64.tar.gz
|
||||||
- go version
|
- go version
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
cache_directories:
|
||||||
|
- "~/telegraf-build/src"
|
||||||
override:
|
override:
|
||||||
- docker info
|
- docker info
|
||||||
|
|
||||||
|
|||||||
@@ -10,96 +10,41 @@ import (
|
|||||||
|
|
||||||
"github.com/influxdb/telegraf"
|
"github.com/influxdb/telegraf"
|
||||||
"github.com/influxdb/telegraf/internal/config"
|
"github.com/influxdb/telegraf/internal/config"
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/all"
|
_ "github.com/influxdb/telegraf/outputs/all"
|
||||||
_ "github.com/influxdb/telegraf/plugins/outputs/all"
|
_ "github.com/influxdb/telegraf/plugins/all"
|
||||||
)
|
)
|
||||||
|
|
||||||
var fDebug = flag.Bool("debug", false,
|
var fDebug = flag.Bool("debug", false,
|
||||||
"show metrics as they're generated to stdout")
|
"show metrics as they're generated to stdout")
|
||||||
var fTest = flag.Bool("test", false, "gather metrics, print them out, and exit")
|
var fTest = flag.Bool("test", false, "gather metrics, print them out, and exit")
|
||||||
var fConfig = flag.String("config", "", "configuration file to load")
|
var fConfig = flag.String("config", "", "configuration file to load")
|
||||||
var fConfigDirectory = flag.String("config-directory", "",
|
var fConfigDirectory = flag.String("configdirectory", "",
|
||||||
"directory containing additional *.conf files")
|
"directory containing additional *.conf files")
|
||||||
var fVersion = flag.Bool("version", false, "display the version")
|
var fVersion = flag.Bool("version", false, "display the version")
|
||||||
var fSampleConfig = flag.Bool("sample-config", false,
|
var fSampleConfig = flag.Bool("sample-config", false,
|
||||||
"print out full sample configuration")
|
"print out full sample configuration")
|
||||||
var fPidfile = flag.String("pidfile", "", "file to write our pid to")
|
var fPidfile = flag.String("pidfile", "", "file to write our pid to")
|
||||||
var fInputFilters = flag.String("input-filter", "",
|
var fPLuginFilters = flag.String("filter", "",
|
||||||
"filter the plugins to enable, separator is :")
|
"filter the plugins to enable, separator is :")
|
||||||
var fOutputFilters = flag.String("output-filter", "",
|
var fOutputFilters = flag.String("outputfilter", "",
|
||||||
"filter the outputs to enable, separator is :")
|
"filter the outputs to enable, separator is :")
|
||||||
var fUsage = flag.String("usage", "",
|
var fUsage = flag.String("usage", "",
|
||||||
"print usage for a plugin, ie, 'telegraf -usage mysql'")
|
"print usage for a plugin, ie, 'telegraf -usage mysql'")
|
||||||
|
|
||||||
var fInputFiltersLegacy = flag.String("filter", "",
|
|
||||||
"filter the plugins to enable, separator is :")
|
|
||||||
var fOutputFiltersLegacy = flag.String("outputfilter", "",
|
|
||||||
"filter the outputs to enable, separator is :")
|
|
||||||
var fConfigDirectoryLegacy = flag.String("configdirectory", "",
|
|
||||||
"directory containing additional *.conf files")
|
|
||||||
|
|
||||||
// Telegraf version
|
// Telegraf version
|
||||||
// -ldflags "-X main.Version=`git describe --always --tags`"
|
// -ldflags "-X main.Version=`git describe --always --tags`"
|
||||||
var Version string
|
var Version string
|
||||||
|
|
||||||
const usage = `Telegraf, The plugin-driven server agent for collecting and reporting metrics.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
telegraf <flags>
|
|
||||||
|
|
||||||
The flags are:
|
|
||||||
|
|
||||||
-config <file> configuration file to load
|
|
||||||
-test gather metrics once, print them to stdout, and exit
|
|
||||||
-sample-config print out full sample configuration to stdout
|
|
||||||
-config-directory directory containing additional *.conf files
|
|
||||||
-input-filter filter the input plugins to enable, separator is :
|
|
||||||
-output-filter filter the output plugins to enable, separator is :
|
|
||||||
-usage print usage for a plugin, ie, 'telegraf -usage mysql'
|
|
||||||
-version print the version to stdout
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
# generate a telegraf config file:
|
|
||||||
telegraf -sample-config > telegraf.conf
|
|
||||||
|
|
||||||
# generate config with only cpu input & influxdb output plugins defined
|
|
||||||
telegraf -sample-config -input-filter cpu -output-filter influxdb
|
|
||||||
|
|
||||||
# run a single telegraf collection, outputing metrics to stdout
|
|
||||||
telegraf -config telegraf.conf -test
|
|
||||||
|
|
||||||
# run telegraf with all plugins defined in config file
|
|
||||||
telegraf -config telegraf.conf
|
|
||||||
|
|
||||||
# run telegraf, enabling the cpu & memory input, and influxdb output plugins
|
|
||||||
telegraf -config telegraf.conf -input-filter cpu:mem -output-filter influxdb
|
|
||||||
`
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Usage = usageExit
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if flag.NFlag() == 0 {
|
var pluginFilters []string
|
||||||
usageExit()
|
if *fPLuginFilters != "" {
|
||||||
}
|
pluginsFilter := strings.TrimSpace(*fPLuginFilters)
|
||||||
|
pluginFilters = strings.Split(":"+pluginsFilter+":", ":")
|
||||||
var inputFilters []string
|
|
||||||
if *fInputFiltersLegacy != "" {
|
|
||||||
inputFilter := strings.TrimSpace(*fInputFiltersLegacy)
|
|
||||||
inputFilters = strings.Split(":"+inputFilter+":", ":")
|
|
||||||
}
|
|
||||||
if *fInputFilters != "" {
|
|
||||||
inputFilter := strings.TrimSpace(*fInputFilters)
|
|
||||||
inputFilters = strings.Split(":"+inputFilter+":", ":")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var outputFilters []string
|
var outputFilters []string
|
||||||
if *fOutputFiltersLegacy != "" {
|
|
||||||
outputFilter := strings.TrimSpace(*fOutputFiltersLegacy)
|
|
||||||
outputFilters = strings.Split(":"+outputFilter+":", ":")
|
|
||||||
}
|
|
||||||
if *fOutputFilters != "" {
|
if *fOutputFilters != "" {
|
||||||
outputFilter := strings.TrimSpace(*fOutputFilters)
|
outputFilter := strings.TrimSpace(*fOutputFilters)
|
||||||
outputFilters = strings.Split(":"+outputFilter+":", ":")
|
outputFilters = strings.Split(":"+outputFilter+":", ":")
|
||||||
@@ -112,12 +57,12 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if *fSampleConfig {
|
if *fSampleConfig {
|
||||||
config.PrintSampleConfig(inputFilters, outputFilters)
|
config.PrintSampleConfig(pluginFilters, outputFilters)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if *fUsage != "" {
|
if *fUsage != "" {
|
||||||
if err := config.PrintInputConfig(*fUsage); err != nil {
|
if err := config.PrintPluginConfig(*fUsage); err != nil {
|
||||||
if err2 := config.PrintOutputConfig(*fUsage); err2 != nil {
|
if err2 := config.PrintOutputConfig(*fUsage); err2 != nil {
|
||||||
log.Fatalf("%s and %s", err, err2)
|
log.Fatalf("%s and %s", err, err2)
|
||||||
}
|
}
|
||||||
@@ -133,7 +78,7 @@ func main() {
|
|||||||
if *fConfig != "" {
|
if *fConfig != "" {
|
||||||
c = config.NewConfig()
|
c = config.NewConfig()
|
||||||
c.OutputFilters = outputFilters
|
c.OutputFilters = outputFilters
|
||||||
c.InputFilters = inputFilters
|
c.PluginFilters = pluginFilters
|
||||||
err = c.LoadConfig(*fConfig)
|
err = c.LoadConfig(*fConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@@ -144,13 +89,6 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if *fConfigDirectoryLegacy != "" {
|
|
||||||
err = c.LoadDirectory(*fConfigDirectoryLegacy)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if *fConfigDirectory != "" {
|
if *fConfigDirectory != "" {
|
||||||
err = c.LoadDirectory(*fConfigDirectory)
|
err = c.LoadDirectory(*fConfigDirectory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -160,7 +98,7 @@ func main() {
|
|||||||
if len(c.Outputs) == 0 {
|
if len(c.Outputs) == 0 {
|
||||||
log.Fatalf("Error: no outputs found, did you provide a valid config file?")
|
log.Fatalf("Error: no outputs found, did you provide a valid config file?")
|
||||||
}
|
}
|
||||||
if len(c.Inputs) == 0 {
|
if len(c.Plugins) == 0 {
|
||||||
log.Fatalf("Error: no plugins found, did you provide a valid config file?")
|
log.Fatalf("Error: no plugins found, did you provide a valid config file?")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,7 +134,7 @@ func main() {
|
|||||||
|
|
||||||
log.Printf("Starting Telegraf (version %s)\n", Version)
|
log.Printf("Starting Telegraf (version %s)\n", Version)
|
||||||
log.Printf("Loaded outputs: %s", strings.Join(c.OutputNames(), " "))
|
log.Printf("Loaded outputs: %s", strings.Join(c.OutputNames(), " "))
|
||||||
log.Printf("Loaded plugins: %s", strings.Join(c.InputNames(), " "))
|
log.Printf("Loaded plugins: %s", strings.Join(c.PluginNames(), " "))
|
||||||
log.Printf("Tags enabled: %s", c.ListTags())
|
log.Printf("Tags enabled: %s", c.ListTags())
|
||||||
|
|
||||||
if *fPidfile != "" {
|
if *fPidfile != "" {
|
||||||
@@ -212,8 +150,3 @@ func main() {
|
|||||||
|
|
||||||
ag.Run(shutdown)
|
ag.Run(shutdown)
|
||||||
}
|
}
|
||||||
|
|
||||||
func usageExit() {
|
|
||||||
fmt.Println(usage)
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Telegraf configuration
|
# Telegraf configuration
|
||||||
|
|
||||||
# Telegraf is entirely plugin driven. All metrics are gathered from the
|
# Telegraf is entirely plugin driven. All metrics are gathered from the
|
||||||
# declared inputs.
|
# declared plugins.
|
||||||
|
|
||||||
# Even if a plugin has no configuration, it must be declared in here
|
# Even if a plugin has no configuration, it must be declared in here
|
||||||
# to be active. Declaring a plugin means just specifying the name
|
# to be active. Declaring a plugin means just specifying the name
|
||||||
@@ -49,6 +49,8 @@
|
|||||||
# OUTPUTS #
|
# OUTPUTS #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
[outputs]
|
||||||
|
|
||||||
# Configuration for influxdb server to send metrics to
|
# Configuration for influxdb server to send metrics to
|
||||||
[[outputs.influxdb]]
|
[[outputs.influxdb]]
|
||||||
# The full HTTP or UDP endpoint URL for your InfluxDB instance.
|
# The full HTTP or UDP endpoint URL for your InfluxDB instance.
|
||||||
@@ -74,11 +76,13 @@
|
|||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# INPUTS #
|
# PLUGINS #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
[plugins]
|
||||||
|
|
||||||
# Read metrics about cpu usage
|
# Read metrics about cpu usage
|
||||||
[[inputs.cpu]]
|
[[plugins.cpu]]
|
||||||
# Whether to report per-cpu stats or not
|
# Whether to report per-cpu stats or not
|
||||||
percpu = true
|
percpu = true
|
||||||
# Whether to report total system cpu stats or not
|
# Whether to report total system cpu stats or not
|
||||||
@@ -87,33 +91,33 @@
|
|||||||
drop = ["cpu_time"]
|
drop = ["cpu_time"]
|
||||||
|
|
||||||
# Read metrics about disk usage by mount point
|
# Read metrics about disk usage by mount point
|
||||||
[[inputs.disk]]
|
[[plugins.disk]]
|
||||||
# By default, telegraf gather stats for all mountpoints.
|
# By default, telegraf gather stats for all mountpoints.
|
||||||
# Setting mountpoints will restrict the stats to the specified mountpoints.
|
# Setting mountpoints will restrict the stats to the specified mountpoints.
|
||||||
# Mountpoints=["/"]
|
# Mountpoints=["/"]
|
||||||
|
|
||||||
# Read metrics about disk IO by device
|
# Read metrics about disk IO by device
|
||||||
[[inputs.diskio]]
|
[[plugins.diskio]]
|
||||||
# By default, telegraf will gather stats for all devices including
|
# By default, telegraf will gather stats for all devices including
|
||||||
# disk partitions.
|
# disk partitions.
|
||||||
# Setting devices will restrict the stats to the specified devices.
|
# Setting devices will restrict the stats to the specified devcies.
|
||||||
# Devices=["sda","sdb"]
|
# Devices=["sda","sdb"]
|
||||||
# Uncomment the following line if you do not need disk serial numbers.
|
# Uncomment the following line if you do not need disk serial numbers.
|
||||||
# SkipSerialNumber = true
|
# SkipSerialNumber = true
|
||||||
|
|
||||||
# Read metrics about memory usage
|
# Read metrics about memory usage
|
||||||
[[inputs.mem]]
|
[[plugins.mem]]
|
||||||
# no configuration
|
# no configuration
|
||||||
|
|
||||||
# Read metrics about swap memory usage
|
# Read metrics about swap memory usage
|
||||||
[[inputs.swap]]
|
[[plugins.swap]]
|
||||||
# no configuration
|
# no configuration
|
||||||
|
|
||||||
# Read metrics about system load & uptime
|
# Read metrics about system load & uptime
|
||||||
[[inputs.system]]
|
[[plugins.system]]
|
||||||
# no configuration
|
# no configuration
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# SERVICE INPUTS #
|
# SERVICE PLUGINS #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/internal"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
|
|
||||||
"github.com/naoina/toml"
|
"github.com/naoina/toml"
|
||||||
"github.com/naoina/toml/ast"
|
"github.com/naoina/toml/ast"
|
||||||
@@ -25,11 +25,11 @@ import (
|
|||||||
// specified
|
// specified
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Tags map[string]string
|
Tags map[string]string
|
||||||
InputFilters []string
|
PluginFilters []string
|
||||||
OutputFilters []string
|
OutputFilters []string
|
||||||
|
|
||||||
Agent *AgentConfig
|
Agent *AgentConfig
|
||||||
Inputs []*RunningInput
|
Plugins []*RunningPlugin
|
||||||
Outputs []*RunningOutput
|
Outputs []*RunningOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,9 +45,9 @@ func NewConfig() *Config {
|
|||||||
},
|
},
|
||||||
|
|
||||||
Tags: make(map[string]string),
|
Tags: make(map[string]string),
|
||||||
Inputs: make([]*RunningInput, 0),
|
Plugins: make([]*RunningPlugin, 0),
|
||||||
Outputs: make([]*RunningOutput, 0),
|
Outputs: make([]*RunningOutput, 0),
|
||||||
InputFilters: make([]string, 0),
|
PluginFilters: make([]string, 0),
|
||||||
OutputFilters: make([]string, 0),
|
OutputFilters: make([]string, 0),
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
@@ -93,10 +93,10 @@ type RunningOutput struct {
|
|||||||
Config *OutputConfig
|
Config *OutputConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
type RunningInput struct {
|
type RunningPlugin struct {
|
||||||
Name string
|
Name string
|
||||||
Input inputs.Input
|
Plugin plugins.Plugin
|
||||||
Config *InputConfig
|
Config *PluginConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter containing drop/pass and tagdrop/tagpass rules
|
// Filter containing drop/pass and tagdrop/tagpass rules
|
||||||
@@ -110,8 +110,8 @@ type Filter struct {
|
|||||||
IsActive bool
|
IsActive bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// InputConfig containing a name, interval, and filter
|
// PluginConfig containing a name, interval, and filter
|
||||||
type InputConfig struct {
|
type PluginConfig struct {
|
||||||
Name string
|
Name string
|
||||||
NameOverride string
|
NameOverride string
|
||||||
MeasurementPrefix string
|
MeasurementPrefix string
|
||||||
@@ -204,16 +204,16 @@ func (f Filter) ShouldTagsPass(tags map[string]string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inputs returns a list of strings of the configured inputs.
|
// Plugins returns a list of strings of the configured plugins.
|
||||||
func (c *Config) InputNames() []string {
|
func (c *Config) PluginNames() []string {
|
||||||
var name []string
|
var name []string
|
||||||
for _, input := range c.Inputs {
|
for _, plugin := range c.Plugins {
|
||||||
name = append(name, input.Name)
|
name = append(name, plugin.Name)
|
||||||
}
|
}
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outputs returns a list of strings of the configured inputs.
|
// Outputs returns a list of strings of the configured plugins.
|
||||||
func (c *Config) OutputNames() []string {
|
func (c *Config) OutputNames() []string {
|
||||||
var name []string
|
var name []string
|
||||||
for _, output := range c.Outputs {
|
for _, output := range c.Outputs {
|
||||||
@@ -239,7 +239,7 @@ func (c *Config) ListTags() string {
|
|||||||
var header = `# Telegraf configuration
|
var header = `# Telegraf configuration
|
||||||
|
|
||||||
# Telegraf is entirely plugin driven. All metrics are gathered from the
|
# Telegraf is entirely plugin driven. All metrics are gathered from the
|
||||||
# declared inputs.
|
# declared plugins.
|
||||||
|
|
||||||
# Even if a plugin has no configuration, it must be declared in here
|
# Even if a plugin has no configuration, it must be declared in here
|
||||||
# to be active. Declaring a plugin means just specifying the name
|
# to be active. Declaring a plugin means just specifying the name
|
||||||
@@ -263,7 +263,7 @@ var header = `# Telegraf configuration
|
|||||||
|
|
||||||
# Configuration for telegraf agent
|
# Configuration for telegraf agent
|
||||||
[agent]
|
[agent]
|
||||||
# Default data collection interval for all inputs
|
# Default data collection interval for all plugins
|
||||||
interval = "10s"
|
interval = "10s"
|
||||||
# Rounds collection interval to 'interval'
|
# Rounds collection interval to 'interval'
|
||||||
# ie, if interval="10s" then always collect on :00, :10, :20, etc.
|
# ie, if interval="10s" then always collect on :00, :10, :20, etc.
|
||||||
@@ -287,20 +287,22 @@ var header = `# Telegraf configuration
|
|||||||
# OUTPUTS #
|
# OUTPUTS #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
[outputs]
|
||||||
`
|
`
|
||||||
|
|
||||||
var pluginHeader = `
|
var pluginHeader = `
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# INPUTS #
|
# PLUGINS #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
[plugins]
|
||||||
`
|
`
|
||||||
|
|
||||||
var serviceInputHeader = `
|
var servicePluginHeader = `
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# SERVICE INPUTS #
|
# SERVICE PLUGINS #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
`
|
`
|
||||||
|
|
||||||
@@ -324,35 +326,35 @@ func PrintSampleConfig(pluginFilters []string, outputFilters []string) {
|
|||||||
printConfig(oname, output, "outputs")
|
printConfig(oname, output, "outputs")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter inputs
|
// Filter plugins
|
||||||
var pnames []string
|
var pnames []string
|
||||||
for pname := range inputs.Inputs {
|
for pname := range plugins.Plugins {
|
||||||
if len(pluginFilters) == 0 || sliceContains(pname, pluginFilters) {
|
if len(pluginFilters) == 0 || sliceContains(pname, pluginFilters) {
|
||||||
pnames = append(pnames, pname)
|
pnames = append(pnames, pname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.Strings(pnames)
|
sort.Strings(pnames)
|
||||||
|
|
||||||
// Print Inputs
|
// Print Plugins
|
||||||
fmt.Printf(pluginHeader)
|
fmt.Printf(pluginHeader)
|
||||||
servInputs := make(map[string]inputs.ServiceInput)
|
servPlugins := make(map[string]plugins.ServicePlugin)
|
||||||
for _, pname := range pnames {
|
for _, pname := range pnames {
|
||||||
creator := inputs.Inputs[pname]
|
creator := plugins.Plugins[pname]
|
||||||
input := creator()
|
plugin := creator()
|
||||||
|
|
||||||
switch p := input.(type) {
|
switch p := plugin.(type) {
|
||||||
case inputs.ServiceInput:
|
case plugins.ServicePlugin:
|
||||||
servInputs[pname] = p
|
servPlugins[pname] = p
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
printConfig(pname, input, "inputs")
|
printConfig(pname, plugin, "plugins")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print Service Inputs
|
// Print Service Plugins
|
||||||
fmt.Printf(serviceInputHeader)
|
fmt.Printf(servicePluginHeader)
|
||||||
for name, input := range servInputs {
|
for name, plugin := range servPlugins {
|
||||||
printConfig(name, input, "inputs")
|
printConfig(name, plugin, "plugins")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,12 +382,12 @@ func sliceContains(name string, list []string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintInputConfig prints the config usage of a single input.
|
// PrintPluginConfig prints the config usage of a single plugin.
|
||||||
func PrintInputConfig(name string) error {
|
func PrintPluginConfig(name string) error {
|
||||||
if creator, ok := inputs.Inputs[name]; ok {
|
if creator, ok := plugins.Plugins[name]; ok {
|
||||||
printConfig(name, creator(), "inputs")
|
printConfig(name, creator(), "plugins")
|
||||||
} else {
|
} else {
|
||||||
return errors.New(fmt.Sprintf("Input %s not found", name))
|
return errors.New(fmt.Sprintf("Plugin %s not found", name))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -451,15 +453,33 @@ func (c *Config) LoadConfig(path string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "outputs":
|
case "outputs":
|
||||||
|
for outputName, outputVal := range subTable.Fields {
|
||||||
|
switch outputSubTable := outputVal.(type) {
|
||||||
|
case *ast.Table:
|
||||||
|
if err = c.addOutput(outputName, outputSubTable); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case []*ast.Table:
|
||||||
|
for _, t := range outputSubTable {
|
||||||
|
if err = c.addOutput(outputName, t); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Unsupported config format: %s",
|
||||||
|
outputName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "plugins":
|
||||||
for pluginName, pluginVal := range subTable.Fields {
|
for pluginName, pluginVal := range subTable.Fields {
|
||||||
switch pluginSubTable := pluginVal.(type) {
|
switch pluginSubTable := pluginVal.(type) {
|
||||||
case *ast.Table:
|
case *ast.Table:
|
||||||
if err = c.addOutput(pluginName, pluginSubTable); err != nil {
|
if err = c.addPlugin(pluginName, pluginSubTable); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case []*ast.Table:
|
case []*ast.Table:
|
||||||
for _, t := range pluginSubTable {
|
for _, t := range pluginSubTable {
|
||||||
if err = c.addOutput(pluginName, t); err != nil {
|
if err = c.addPlugin(pluginName, t); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -468,28 +488,10 @@ func (c *Config) LoadConfig(path string) error {
|
|||||||
pluginName)
|
pluginName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "inputs", "plugins":
|
// Assume it's a plugin for legacy config file support if no other
|
||||||
for pluginName, pluginVal := range subTable.Fields {
|
|
||||||
switch pluginSubTable := pluginVal.(type) {
|
|
||||||
case *ast.Table:
|
|
||||||
if err = c.addInput(pluginName, pluginSubTable); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case []*ast.Table:
|
|
||||||
for _, t := range pluginSubTable {
|
|
||||||
if err = c.addInput(pluginName, t); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Unsupported config format: %s",
|
|
||||||
pluginName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Assume it's an input input for legacy config file support if no other
|
|
||||||
// identifiers are present
|
// identifiers are present
|
||||||
default:
|
default:
|
||||||
if err = c.addInput(name, subTable); err != nil {
|
if err = c.addPlugin(name, subTable); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -525,41 +527,41 @@ func (c *Config) addOutput(name string, table *ast.Table) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) addInput(name string, table *ast.Table) error {
|
func (c *Config) addPlugin(name string, table *ast.Table) error {
|
||||||
if len(c.InputFilters) > 0 && !sliceContains(name, c.InputFilters) {
|
if len(c.PluginFilters) > 0 && !sliceContains(name, c.PluginFilters) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Legacy support renaming io input to diskio
|
// Legacy support renaming io plugin to diskio
|
||||||
if name == "io" {
|
if name == "io" {
|
||||||
name = "diskio"
|
name = "diskio"
|
||||||
}
|
}
|
||||||
|
|
||||||
creator, ok := inputs.Inputs[name]
|
creator, ok := plugins.Plugins[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Undefined but requested input: %s", name)
|
return fmt.Errorf("Undefined but requested plugin: %s", name)
|
||||||
}
|
}
|
||||||
input := creator()
|
plugin := creator()
|
||||||
|
|
||||||
pluginConfig, err := buildInput(name, table)
|
pluginConfig, err := buildPlugin(name, table)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := toml.UnmarshalTable(table, input); err != nil {
|
if err := toml.UnmarshalTable(table, plugin); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
rp := &RunningInput{
|
rp := &RunningPlugin{
|
||||||
Name: name,
|
Name: name,
|
||||||
Input: input,
|
Plugin: plugin,
|
||||||
Config: pluginConfig,
|
Config: pluginConfig,
|
||||||
}
|
}
|
||||||
c.Inputs = append(c.Inputs, rp)
|
c.Plugins = append(c.Plugins, rp)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildFilter builds a Filter (tagpass/tagdrop/pass/drop) to
|
// buildFilter builds a Filter (tagpass/tagdrop/pass/drop) to
|
||||||
// be inserted into the OutputConfig/InputConfig to be used for prefix
|
// be inserted into the OutputConfig/PluginConfig to be used for prefix
|
||||||
// filtering on tags and measurements
|
// filtering on tags and measurements
|
||||||
func buildFilter(tbl *ast.Table) Filter {
|
func buildFilter(tbl *ast.Table) Filter {
|
||||||
f := Filter{}
|
f := Filter{}
|
||||||
@@ -635,11 +637,11 @@ func buildFilter(tbl *ast.Table) Filter {
|
|||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildInput parses input specific items from the ast.Table,
|
// buildPlugin parses plugin specific items from the ast.Table,
|
||||||
// builds the filter and returns a
|
// builds the filter and returns a
|
||||||
// InputConfig to be inserted into RunningInput
|
// PluginConfig to be inserted into RunningPlugin
|
||||||
func buildInput(name string, tbl *ast.Table) (*InputConfig, error) {
|
func buildPlugin(name string, tbl *ast.Table) (*PluginConfig, error) {
|
||||||
cp := &InputConfig{Name: name}
|
cp := &PluginConfig{Name: name}
|
||||||
if node, ok := tbl.Fields["interval"]; ok {
|
if node, ok := tbl.Fields["interval"]; ok {
|
||||||
if kv, ok := node.(*ast.KeyValue); ok {
|
if kv, ok := node.(*ast.KeyValue); ok {
|
||||||
if str, ok := kv.Value.(*ast.String); ok {
|
if str, ok := kv.Value.(*ast.String); ok {
|
||||||
@@ -681,7 +683,7 @@ func buildInput(name string, tbl *ast.Table) (*InputConfig, error) {
|
|||||||
if node, ok := tbl.Fields["tags"]; ok {
|
if node, ok := tbl.Fields["tags"]; ok {
|
||||||
if subtbl, ok := node.(*ast.Table); ok {
|
if subtbl, ok := node.(*ast.Table); ok {
|
||||||
if err := toml.UnmarshalTable(subtbl, cp.Tags); err != nil {
|
if err := toml.UnmarshalTable(subtbl, cp.Tags); err != nil {
|
||||||
log.Printf("Could not parse tags for input %s\n", name)
|
log.Printf("Could not parse tags for plugin %s\n", name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -696,7 +698,7 @@ func buildInput(name string, tbl *ast.Table) (*InputConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// buildOutput parses output specific items from the ast.Table, builds the filter and returns an
|
// buildOutput parses output specific items from the ast.Table, builds the filter and returns an
|
||||||
// OutputConfig to be inserted into RunningInput
|
// OutputConfig to be inserted into RunningPlugin
|
||||||
// Note: error exists in the return for future calls that might require error
|
// Note: error exists in the return for future calls that might require error
|
||||||
func buildOutput(name string, tbl *ast.Table) (*OutputConfig, error) {
|
func buildOutput(name string, tbl *ast.Table) (*OutputConfig, error) {
|
||||||
oc := &OutputConfig{
|
oc := &OutputConfig{
|
||||||
|
|||||||
@@ -4,21 +4,21 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
"github.com/influxdb/telegraf/plugins/inputs/exec"
|
"github.com/influxdb/telegraf/plugins/exec"
|
||||||
"github.com/influxdb/telegraf/plugins/inputs/memcached"
|
"github.com/influxdb/telegraf/plugins/memcached"
|
||||||
"github.com/influxdb/telegraf/plugins/inputs/procstat"
|
"github.com/influxdb/telegraf/plugins/procstat"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestConfig_LoadSingleInput(t *testing.T) {
|
func TestConfig_LoadSinglePlugin(t *testing.T) {
|
||||||
c := NewConfig()
|
c := NewConfig()
|
||||||
c.LoadConfig("./testdata/single_plugin.toml")
|
c.LoadConfig("./testdata/single_plugin.toml")
|
||||||
|
|
||||||
memcached := inputs.Inputs["memcached"]().(*memcached.Memcached)
|
memcached := plugins.Plugins["memcached"]().(*memcached.Memcached)
|
||||||
memcached.Servers = []string{"localhost"}
|
memcached.Servers = []string{"localhost"}
|
||||||
|
|
||||||
mConfig := &InputConfig{
|
mConfig := &PluginConfig{
|
||||||
Name: "memcached",
|
Name: "memcached",
|
||||||
Filter: Filter{
|
Filter: Filter{
|
||||||
Drop: []string{"other", "stuff"},
|
Drop: []string{"other", "stuff"},
|
||||||
@@ -39,11 +39,10 @@ func TestConfig_LoadSingleInput(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Interval: 5 * time.Second,
|
Interval: 5 * time.Second,
|
||||||
}
|
}
|
||||||
mConfig.Tags = make(map[string]string)
|
|
||||||
|
|
||||||
assert.Equal(t, memcached, c.Inputs[0].Input,
|
assert.Equal(t, memcached, c.Plugins[0].Plugin,
|
||||||
"Testdata did not produce a correct memcached struct.")
|
"Testdata did not produce a correct memcached struct.")
|
||||||
assert.Equal(t, mConfig, c.Inputs[0].Config,
|
assert.Equal(t, mConfig, c.Plugins[0].Config,
|
||||||
"Testdata did not produce correct memcached metadata.")
|
"Testdata did not produce correct memcached metadata.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,10 +57,10 @@ func TestConfig_LoadDirectory(t *testing.T) {
|
|||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
memcached := inputs.Inputs["memcached"]().(*memcached.Memcached)
|
memcached := plugins.Plugins["memcached"]().(*memcached.Memcached)
|
||||||
memcached.Servers = []string{"localhost"}
|
memcached.Servers = []string{"localhost"}
|
||||||
|
|
||||||
mConfig := &InputConfig{
|
mConfig := &PluginConfig{
|
||||||
Name: "memcached",
|
Name: "memcached",
|
||||||
Filter: Filter{
|
Filter: Filter{
|
||||||
Drop: []string{"other", "stuff"},
|
Drop: []string{"other", "stuff"},
|
||||||
@@ -82,40 +81,45 @@ func TestConfig_LoadDirectory(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Interval: 5 * time.Second,
|
Interval: 5 * time.Second,
|
||||||
}
|
}
|
||||||
mConfig.Tags = make(map[string]string)
|
assert.Equal(t, memcached, c.Plugins[0].Plugin,
|
||||||
|
|
||||||
assert.Equal(t, memcached, c.Inputs[0].Input,
|
|
||||||
"Testdata did not produce a correct memcached struct.")
|
"Testdata did not produce a correct memcached struct.")
|
||||||
assert.Equal(t, mConfig, c.Inputs[0].Config,
|
assert.Equal(t, mConfig, c.Plugins[0].Config,
|
||||||
"Testdata did not produce correct memcached metadata.")
|
"Testdata did not produce correct memcached metadata.")
|
||||||
|
|
||||||
ex := inputs.Inputs["exec"]().(*exec.Exec)
|
ex := plugins.Plugins["exec"]().(*exec.Exec)
|
||||||
ex.Command = "/usr/bin/myothercollector --foo=bar"
|
ex.Commands = []*exec.Command{
|
||||||
eConfig := &InputConfig{
|
&exec.Command{
|
||||||
Name: "exec",
|
Command: "/usr/bin/myothercollector --foo=bar",
|
||||||
MeasurementSuffix: "_myothercollector",
|
Name: "myothercollector",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
eConfig.Tags = make(map[string]string)
|
eConfig := &PluginConfig{Name: "exec"}
|
||||||
assert.Equal(t, ex, c.Inputs[1].Input,
|
assert.Equal(t, ex, c.Plugins[1].Plugin,
|
||||||
"Merged Testdata did not produce a correct exec struct.")
|
"Merged Testdata did not produce a correct exec struct.")
|
||||||
assert.Equal(t, eConfig, c.Inputs[1].Config,
|
assert.Equal(t, eConfig, c.Plugins[1].Config,
|
||||||
"Merged Testdata did not produce correct exec metadata.")
|
"Merged Testdata did not produce correct exec metadata.")
|
||||||
|
|
||||||
memcached.Servers = []string{"192.168.1.1"}
|
memcached.Servers = []string{"192.168.1.1"}
|
||||||
assert.Equal(t, memcached, c.Inputs[2].Input,
|
assert.Equal(t, memcached, c.Plugins[2].Plugin,
|
||||||
"Testdata did not produce a correct memcached struct.")
|
"Testdata did not produce a correct memcached struct.")
|
||||||
assert.Equal(t, mConfig, c.Inputs[2].Config,
|
assert.Equal(t, mConfig, c.Plugins[2].Config,
|
||||||
"Testdata did not produce correct memcached metadata.")
|
"Testdata did not produce correct memcached metadata.")
|
||||||
|
|
||||||
pstat := inputs.Inputs["procstat"]().(*procstat.Procstat)
|
pstat := plugins.Plugins["procstat"]().(*procstat.Procstat)
|
||||||
pstat.PidFile = "/var/run/grafana-server.pid"
|
pstat.Specifications = []*procstat.Specification{
|
||||||
|
&procstat.Specification{
|
||||||
|
PidFile: "/var/run/grafana-server.pid",
|
||||||
|
},
|
||||||
|
&procstat.Specification{
|
||||||
|
PidFile: "/var/run/influxdb/influxd.pid",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
pConfig := &InputConfig{Name: "procstat"}
|
pConfig := &PluginConfig{Name: "procstat"}
|
||||||
pConfig.Tags = make(map[string]string)
|
|
||||||
|
|
||||||
assert.Equal(t, pstat, c.Inputs[3].Input,
|
assert.Equal(t, pstat, c.Plugins[3].Plugin,
|
||||||
"Merged Testdata did not produce a correct procstat struct.")
|
"Merged Testdata did not produce a correct procstat struct.")
|
||||||
assert.Equal(t, pConfig, c.Inputs[3].Config,
|
assert.Equal(t, pConfig, c.Plugins[3].Config,
|
||||||
"Merged Testdata did not produce correct procstat metadata.")
|
"Merged Testdata did not produce correct procstat metadata.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
internal/config/testdata/single_plugin.toml
vendored
6
internal/config/testdata/single_plugin.toml
vendored
@@ -1,9 +1,9 @@
|
|||||||
[[inputs.memcached]]
|
[[plugins.memcached]]
|
||||||
servers = ["localhost"]
|
servers = ["localhost"]
|
||||||
pass = ["some", "strings"]
|
pass = ["some", "strings"]
|
||||||
drop = ["other", "stuff"]
|
drop = ["other", "stuff"]
|
||||||
interval = "5s"
|
interval = "5s"
|
||||||
[inputs.memcached.tagpass]
|
[plugins.memcached.tagpass]
|
||||||
goodtag = ["mytag"]
|
goodtag = ["mytag"]
|
||||||
[inputs.memcached.tagdrop]
|
[plugins.memcached.tagdrop]
|
||||||
badtag = ["othertag"]
|
badtag = ["othertag"]
|
||||||
|
|||||||
8
internal/config/testdata/subconfig/exec.conf
vendored
8
internal/config/testdata/subconfig/exec.conf
vendored
@@ -1,4 +1,8 @@
|
|||||||
[[inputs.exec]]
|
[[plugins.exec]]
|
||||||
|
# specify commands via an array of tables
|
||||||
|
[[plugins.exec.commands]]
|
||||||
# the command to run
|
# the command to run
|
||||||
command = "/usr/bin/myothercollector --foo=bar"
|
command = "/usr/bin/myothercollector --foo=bar"
|
||||||
name_suffix = "_myothercollector"
|
|
||||||
|
# name of the command (used as a prefix for measurements)
|
||||||
|
name = "myothercollector"
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
[[inputs.memcached]]
|
[[plugins.memcached]]
|
||||||
servers = ["192.168.1.1"]
|
servers = ["192.168.1.1"]
|
||||||
pass = ["some", "strings"]
|
pass = ["some", "strings"]
|
||||||
drop = ["other", "stuff"]
|
drop = ["other", "stuff"]
|
||||||
interval = "5s"
|
interval = "5s"
|
||||||
[inputs.memcached.tagpass]
|
[plugins.memcached.tagpass]
|
||||||
goodtag = ["mytag"]
|
goodtag = ["mytag"]
|
||||||
[inputs.memcached.tagdrop]
|
[plugins.memcached.tagdrop]
|
||||||
badtag = ["othertag"]
|
badtag = ["othertag"]
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
[[inputs.procstat]]
|
[[plugins.procstat]]
|
||||||
|
[[plugins.procstat.specifications]]
|
||||||
pid_file = "/var/run/grafana-server.pid"
|
pid_file = "/var/run/grafana-server.pid"
|
||||||
|
[[plugins.procstat.specifications]]
|
||||||
|
pid_file = "/var/run/influxdb/influxd.pid"
|
||||||
|
|||||||
121
internal/config/testdata/telegraf-agent.toml
vendored
121
internal/config/testdata/telegraf-agent.toml
vendored
@@ -1,7 +1,7 @@
|
|||||||
# Telegraf configuration
|
# Telegraf configuration
|
||||||
|
|
||||||
# Telegraf is entirely plugin driven. All metrics are gathered from the
|
# Telegraf is entirely plugin driven. All metrics are gathered from the
|
||||||
# declared inputs.
|
# declared plugins.
|
||||||
|
|
||||||
# Even if a plugin has no configuration, it must be declared in here
|
# Even if a plugin has no configuration, it must be declared in here
|
||||||
# to be active. Declaring a plugin means just specifying the name
|
# to be active. Declaring a plugin means just specifying the name
|
||||||
@@ -21,13 +21,20 @@
|
|||||||
|
|
||||||
# Tags can also be specified via a normal map, but only one form at a time:
|
# Tags can also be specified via a normal map, but only one form at a time:
|
||||||
[tags]
|
[tags]
|
||||||
dc = "us-east-1"
|
# dc = "us-east-1"
|
||||||
|
|
||||||
# Configuration for telegraf agent
|
# Configuration for telegraf agent
|
||||||
[agent]
|
[agent]
|
||||||
# Default data collection interval for all plugins
|
# Default data collection interval for all plugins
|
||||||
interval = "10s"
|
interval = "10s"
|
||||||
|
|
||||||
|
# If utc = false, uses local time (utc is highly recommended)
|
||||||
|
utc = true
|
||||||
|
|
||||||
|
# Precision of writes, valid values are n, u, ms, s, m, and h
|
||||||
|
# note: using second precision greatly helps InfluxDB compression
|
||||||
|
precision = "s"
|
||||||
|
|
||||||
# run telegraf in debug mode
|
# run telegraf in debug mode
|
||||||
debug = false
|
debug = false
|
||||||
|
|
||||||
@@ -39,6 +46,8 @@
|
|||||||
# OUTPUTS #
|
# OUTPUTS #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
[outputs]
|
||||||
|
|
||||||
# Configuration for influxdb server to send metrics to
|
# Configuration for influxdb server to send metrics to
|
||||||
[[outputs.influxdb]]
|
[[outputs.influxdb]]
|
||||||
# The full HTTP endpoint URL for your InfluxDB instance
|
# The full HTTP endpoint URL for your InfluxDB instance
|
||||||
@@ -49,6 +58,17 @@
|
|||||||
# The target database for metrics. This database must already exist
|
# The target database for metrics. This database must already exist
|
||||||
database = "telegraf" # required.
|
database = "telegraf" # required.
|
||||||
|
|
||||||
|
# Connection timeout (for the connection with InfluxDB), formatted as a string.
|
||||||
|
# Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||||
|
# If not provided, will default to 0 (no timeout)
|
||||||
|
# timeout = "5s"
|
||||||
|
|
||||||
|
# username = "telegraf"
|
||||||
|
# password = "metricsmetricsmetricsmetrics"
|
||||||
|
|
||||||
|
# Set the user agent for the POSTs (can be useful for log differentiation)
|
||||||
|
# user_agent = "telegraf"
|
||||||
|
|
||||||
[[outputs.influxdb]]
|
[[outputs.influxdb]]
|
||||||
urls = ["udp://localhost:8089"]
|
urls = ["udp://localhost:8089"]
|
||||||
database = "udp-telegraf"
|
database = "udp-telegraf"
|
||||||
@@ -68,13 +88,15 @@
|
|||||||
# PLUGINS #
|
# PLUGINS #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
[plugins]
|
||||||
|
|
||||||
# Read Apache status information (mod_status)
|
# Read Apache status information (mod_status)
|
||||||
[[inputs.apache]]
|
[[plugins.apache]]
|
||||||
# An array of Apache status URI to gather stats.
|
# An array of Apache status URI to gather stats.
|
||||||
urls = ["http://localhost/server-status?auto"]
|
urls = ["http://localhost/server-status?auto"]
|
||||||
|
|
||||||
# Read metrics about cpu usage
|
# Read metrics about cpu usage
|
||||||
[[inputs.cpu]]
|
[[plugins.cpu]]
|
||||||
# Whether to report per-cpu stats or not
|
# Whether to report per-cpu stats or not
|
||||||
percpu = true
|
percpu = true
|
||||||
# Whether to report total system cpu stats or not
|
# Whether to report total system cpu stats or not
|
||||||
@@ -83,11 +105,11 @@
|
|||||||
drop = ["cpu_time"]
|
drop = ["cpu_time"]
|
||||||
|
|
||||||
# Read metrics about disk usage by mount point
|
# Read metrics about disk usage by mount point
|
||||||
[[inputs.diskio]]
|
[[plugins.diskio]]
|
||||||
# no configuration
|
# no configuration
|
||||||
|
|
||||||
# Read metrics from one or many disque servers
|
# Read metrics from one or many disque servers
|
||||||
[[inputs.disque]]
|
[[plugins.disque]]
|
||||||
# An array of URI to gather stats about. Specify an ip or hostname
|
# An array of URI to gather stats about. Specify an ip or hostname
|
||||||
# with optional port and password. ie disque://localhost, disque://10.10.3.33:18832,
|
# with optional port and password. ie disque://localhost, disque://10.10.3.33:18832,
|
||||||
# 10.0.0.1:10000, etc.
|
# 10.0.0.1:10000, etc.
|
||||||
@@ -96,7 +118,7 @@
|
|||||||
servers = ["localhost"]
|
servers = ["localhost"]
|
||||||
|
|
||||||
# Read stats from one or more Elasticsearch servers or clusters
|
# Read stats from one or more Elasticsearch servers or clusters
|
||||||
[[inputs.elasticsearch]]
|
[[plugins.elasticsearch]]
|
||||||
# specify a list of one or more Elasticsearch servers
|
# specify a list of one or more Elasticsearch servers
|
||||||
servers = ["http://localhost:9200"]
|
servers = ["http://localhost:9200"]
|
||||||
|
|
||||||
@@ -105,13 +127,17 @@
|
|||||||
local = true
|
local = true
|
||||||
|
|
||||||
# Read flattened metrics from one or more commands that output JSON to stdout
|
# Read flattened metrics from one or more commands that output JSON to stdout
|
||||||
[[inputs.exec]]
|
[[plugins.exec]]
|
||||||
|
# specify commands via an array of tables
|
||||||
|
[[exec.commands]]
|
||||||
# the command to run
|
# the command to run
|
||||||
command = "/usr/bin/mycollector --foo=bar"
|
command = "/usr/bin/mycollector --foo=bar"
|
||||||
name_suffix = "_mycollector"
|
|
||||||
|
# name of the command (used as a prefix for measurements)
|
||||||
|
name = "mycollector"
|
||||||
|
|
||||||
# Read metrics of haproxy, via socket or csv stats page
|
# Read metrics of haproxy, via socket or csv stats page
|
||||||
[[inputs.haproxy]]
|
[[plugins.haproxy]]
|
||||||
# An array of address to gather stats about. Specify an ip on hostname
|
# An array of address to gather stats about. Specify an ip on hostname
|
||||||
# with optional port. ie localhost, 10.10.3.33:1936, etc.
|
# with optional port. ie localhost, 10.10.3.33:1936, etc.
|
||||||
#
|
#
|
||||||
@@ -121,30 +147,33 @@
|
|||||||
# servers = ["socket:/run/haproxy/admin.sock"]
|
# servers = ["socket:/run/haproxy/admin.sock"]
|
||||||
|
|
||||||
# Read flattened metrics from one or more JSON HTTP endpoints
|
# Read flattened metrics from one or more JSON HTTP endpoints
|
||||||
[[inputs.httpjson]]
|
[[plugins.httpjson]]
|
||||||
# a name for the service being polled
|
# Specify services via an array of tables
|
||||||
name = "webserver_stats"
|
[[httpjson.services]]
|
||||||
|
|
||||||
# URL of each server in the service's cluster
|
# a name for the service being polled
|
||||||
servers = [
|
name = "webserver_stats"
|
||||||
"http://localhost:9999/stats/",
|
|
||||||
"http://localhost:9998/stats/",
|
|
||||||
]
|
|
||||||
|
|
||||||
# HTTP method to use (case-sensitive)
|
# URL of each server in the service's cluster
|
||||||
method = "GET"
|
servers = [
|
||||||
|
"http://localhost:9999/stats/",
|
||||||
|
"http://localhost:9998/stats/",
|
||||||
|
]
|
||||||
|
|
||||||
# HTTP parameters (all values must be strings)
|
# HTTP method to use (case-sensitive)
|
||||||
[httpjson.parameters]
|
method = "GET"
|
||||||
event_type = "cpu_spike"
|
|
||||||
threshold = "0.75"
|
# HTTP parameters (all values must be strings)
|
||||||
|
[httpjson.services.parameters]
|
||||||
|
event_type = "cpu_spike"
|
||||||
|
threshold = "0.75"
|
||||||
|
|
||||||
# Read metrics about disk IO by device
|
# Read metrics about disk IO by device
|
||||||
[[inputs.diskio]]
|
[[plugins.io]]
|
||||||
# no configuration
|
# no configuration
|
||||||
|
|
||||||
# read metrics from a Kafka topic
|
# read metrics from a Kafka topic
|
||||||
[[inputs.kafka_consumer]]
|
[[plugins.kafka_consumer]]
|
||||||
# topic(s) to consume
|
# topic(s) to consume
|
||||||
topics = ["telegraf"]
|
topics = ["telegraf"]
|
||||||
# an array of Zookeeper connection strings
|
# an array of Zookeeper connection strings
|
||||||
@@ -157,7 +186,7 @@
|
|||||||
offset = "oldest"
|
offset = "oldest"
|
||||||
|
|
||||||
# Read metrics from a LeoFS Server via SNMP
|
# Read metrics from a LeoFS Server via SNMP
|
||||||
[[inputs.leofs]]
|
[[plugins.leofs]]
|
||||||
# An array of URI to gather stats about LeoFS.
|
# An array of URI to gather stats about LeoFS.
|
||||||
# Specify an ip or hostname with port. ie 127.0.0.1:4020
|
# Specify an ip or hostname with port. ie 127.0.0.1:4020
|
||||||
#
|
#
|
||||||
@@ -165,7 +194,7 @@
|
|||||||
servers = ["127.0.0.1:4021"]
|
servers = ["127.0.0.1:4021"]
|
||||||
|
|
||||||
# Read metrics from local Lustre service on OST, MDS
|
# Read metrics from local Lustre service on OST, MDS
|
||||||
[[inputs.lustre2]]
|
[[plugins.lustre2]]
|
||||||
# An array of /proc globs to search for Lustre stats
|
# An array of /proc globs to search for Lustre stats
|
||||||
# If not specified, the default will work on Lustre 2.5.x
|
# If not specified, the default will work on Lustre 2.5.x
|
||||||
#
|
#
|
||||||
@@ -173,11 +202,11 @@
|
|||||||
# mds_procfiles = ["/proc/fs/lustre/mdt/*/md_stats"]
|
# mds_procfiles = ["/proc/fs/lustre/mdt/*/md_stats"]
|
||||||
|
|
||||||
# Read metrics about memory usage
|
# Read metrics about memory usage
|
||||||
[[inputs.mem]]
|
[[plugins.mem]]
|
||||||
# no configuration
|
# no configuration
|
||||||
|
|
||||||
# Read metrics from one or many memcached servers
|
# Read metrics from one or many memcached servers
|
||||||
[[inputs.memcached]]
|
[[plugins.memcached]]
|
||||||
# An array of address to gather stats about. Specify an ip on hostname
|
# An array of address to gather stats about. Specify an ip on hostname
|
||||||
# with optional port. ie localhost, 10.0.0.1:11211, etc.
|
# with optional port. ie localhost, 10.0.0.1:11211, etc.
|
||||||
#
|
#
|
||||||
@@ -185,7 +214,7 @@
|
|||||||
servers = ["localhost"]
|
servers = ["localhost"]
|
||||||
|
|
||||||
# Read metrics from one or many MongoDB servers
|
# Read metrics from one or many MongoDB servers
|
||||||
[[inputs.mongodb]]
|
[[plugins.mongodb]]
|
||||||
# An array of URI to gather stats about. Specify an ip or hostname
|
# An array of URI to gather stats about. Specify an ip or hostname
|
||||||
# with optional port add password. ie mongodb://user:auth_key@10.10.3.30:27017,
|
# with optional port add password. ie mongodb://user:auth_key@10.10.3.30:27017,
|
||||||
# mongodb://10.10.3.33:18832, 10.0.0.1:10000, etc.
|
# mongodb://10.10.3.33:18832, 10.0.0.1:10000, etc.
|
||||||
@@ -194,7 +223,7 @@
|
|||||||
servers = ["127.0.0.1:27017"]
|
servers = ["127.0.0.1:27017"]
|
||||||
|
|
||||||
# Read metrics from one or many mysql servers
|
# Read metrics from one or many mysql servers
|
||||||
[[inputs.mysql]]
|
[[plugins.mysql]]
|
||||||
# specify servers via a url matching:
|
# specify servers via a url matching:
|
||||||
# [username[:password]@][protocol[(address)]]/[?tls=[true|false|skip-verify]]
|
# [username[:password]@][protocol[(address)]]/[?tls=[true|false|skip-verify]]
|
||||||
# e.g.
|
# e.g.
|
||||||
@@ -205,7 +234,7 @@
|
|||||||
servers = ["localhost"]
|
servers = ["localhost"]
|
||||||
|
|
||||||
# Read metrics about network interface usage
|
# Read metrics about network interface usage
|
||||||
[[inputs.net]]
|
[[plugins.net]]
|
||||||
# By default, telegraf gathers stats from any up interface (excluding loopback)
|
# By default, telegraf gathers stats from any up interface (excluding loopback)
|
||||||
# Setting interfaces will tell it to gather these explicit interfaces,
|
# Setting interfaces will tell it to gather these explicit interfaces,
|
||||||
# regardless of status.
|
# regardless of status.
|
||||||
@@ -213,12 +242,12 @@
|
|||||||
# interfaces = ["eth0", ... ]
|
# interfaces = ["eth0", ... ]
|
||||||
|
|
||||||
# Read Nginx's basic status information (ngx_http_stub_status_module)
|
# Read Nginx's basic status information (ngx_http_stub_status_module)
|
||||||
[[inputs.nginx]]
|
[[plugins.nginx]]
|
||||||
# An array of Nginx stub_status URI to gather stats.
|
# An array of Nginx stub_status URI to gather stats.
|
||||||
urls = ["http://localhost/status"]
|
urls = ["http://localhost/status"]
|
||||||
|
|
||||||
# Ping given url(s) and return statistics
|
# Ping given url(s) and return statistics
|
||||||
[[inputs.ping]]
|
[[plugins.ping]]
|
||||||
# urls to ping
|
# urls to ping
|
||||||
urls = ["www.google.com"] # required
|
urls = ["www.google.com"] # required
|
||||||
# number of pings to send (ping -c <COUNT>)
|
# number of pings to send (ping -c <COUNT>)
|
||||||
@@ -231,7 +260,10 @@
|
|||||||
interface = ""
|
interface = ""
|
||||||
|
|
||||||
# Read metrics from one or many postgresql servers
|
# Read metrics from one or many postgresql servers
|
||||||
[[inputs.postgresql]]
|
[[plugins.postgresql]]
|
||||||
|
# specify servers via an array of tables
|
||||||
|
[[postgresql.servers]]
|
||||||
|
|
||||||
# specify address via a url matching:
|
# specify address via a url matching:
|
||||||
# postgres://[pqgotest[:password]]@localhost[/dbname]?sslmode=[disable|verify-ca|verify-full]
|
# postgres://[pqgotest[:password]]@localhost[/dbname]?sslmode=[disable|verify-ca|verify-full]
|
||||||
# or a simple string:
|
# or a simple string:
|
||||||
@@ -258,13 +290,14 @@
|
|||||||
# address = "influx@remoteserver"
|
# address = "influx@remoteserver"
|
||||||
|
|
||||||
# Read metrics from one or many prometheus clients
|
# Read metrics from one or many prometheus clients
|
||||||
[[inputs.prometheus]]
|
[[plugins.prometheus]]
|
||||||
# An array of urls to scrape metrics from.
|
# An array of urls to scrape metrics from.
|
||||||
urls = ["http://localhost:9100/metrics"]
|
urls = ["http://localhost:9100/metrics"]
|
||||||
|
|
||||||
# Read metrics from one or many RabbitMQ servers via the management API
|
# Read metrics from one or many RabbitMQ servers via the management API
|
||||||
[[inputs.rabbitmq]]
|
[[plugins.rabbitmq]]
|
||||||
# Specify servers via an array of tables
|
# Specify servers via an array of tables
|
||||||
|
[[rabbitmq.servers]]
|
||||||
# name = "rmq-server-1" # optional tag
|
# name = "rmq-server-1" # optional tag
|
||||||
# url = "http://localhost:15672"
|
# url = "http://localhost:15672"
|
||||||
# username = "guest"
|
# username = "guest"
|
||||||
@@ -275,7 +308,7 @@
|
|||||||
# nodes = ["rabbit@node1", "rabbit@node2"]
|
# nodes = ["rabbit@node1", "rabbit@node2"]
|
||||||
|
|
||||||
# Read metrics from one or many redis servers
|
# Read metrics from one or many redis servers
|
||||||
[[inputs.redis]]
|
[[plugins.redis]]
|
||||||
# An array of URI to gather stats about. Specify an ip or hostname
|
# An array of URI to gather stats about. Specify an ip or hostname
|
||||||
# with optional port add password. ie redis://localhost, redis://10.10.3.33:18832,
|
# with optional port add password. ie redis://localhost, redis://10.10.3.33:18832,
|
||||||
# 10.0.0.1:10000, etc.
|
# 10.0.0.1:10000, etc.
|
||||||
@@ -284,7 +317,7 @@
|
|||||||
servers = ["localhost"]
|
servers = ["localhost"]
|
||||||
|
|
||||||
# Read metrics from one or many RethinkDB servers
|
# Read metrics from one or many RethinkDB servers
|
||||||
[[inputs.rethinkdb]]
|
[[plugins.rethinkdb]]
|
||||||
# An array of URI to gather stats about. Specify an ip or hostname
|
# An array of URI to gather stats about. Specify an ip or hostname
|
||||||
# with optional port add password. ie rethinkdb://user:auth_key@10.10.3.30:28105,
|
# with optional port add password. ie rethinkdb://user:auth_key@10.10.3.30:28105,
|
||||||
# rethinkdb://10.10.3.33:18832, 10.0.0.1:10000, etc.
|
# rethinkdb://10.10.3.33:18832, 10.0.0.1:10000, etc.
|
||||||
@@ -293,9 +326,9 @@
|
|||||||
servers = ["127.0.0.1:28015"]
|
servers = ["127.0.0.1:28015"]
|
||||||
|
|
||||||
# Read metrics about swap memory usage
|
# Read metrics about swap memory usage
|
||||||
[[inputs.swap]]
|
[[plugins.swap]]
|
||||||
# no configuration
|
# no configuration
|
||||||
|
|
||||||
# Read metrics about system load & uptime
|
# Read metrics about system load & uptime
|
||||||
[[inputs.system]]
|
[[plugins.system]]
|
||||||
# no configuration
|
# no configuration
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func (f *JSONFlattener) FlattenJSON(
|
|||||||
}
|
}
|
||||||
case float64:
|
case float64:
|
||||||
f.Fields[fieldname] = t
|
f.Fields[fieldname] = t
|
||||||
case bool, string, []interface{}, nil:
|
case bool, string, []interface{}:
|
||||||
// ignored types
|
// ignored types
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
|
|||||||
16
outputs/all/all.go
Normal file
16
outputs/all/all.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package all
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/influxdb/telegraf/outputs/amon"
|
||||||
|
_ "github.com/influxdb/telegraf/outputs/amqp"
|
||||||
|
_ "github.com/influxdb/telegraf/outputs/datadog"
|
||||||
|
_ "github.com/influxdb/telegraf/outputs/influxdb"
|
||||||
|
_ "github.com/influxdb/telegraf/outputs/kafka"
|
||||||
|
_ "github.com/influxdb/telegraf/outputs/kinesis"
|
||||||
|
_ "github.com/influxdb/telegraf/outputs/librato"
|
||||||
|
_ "github.com/influxdb/telegraf/outputs/mqtt"
|
||||||
|
_ "github.com/influxdb/telegraf/outputs/nsq"
|
||||||
|
_ "github.com/influxdb/telegraf/outputs/opentsdb"
|
||||||
|
_ "github.com/influxdb/telegraf/outputs/prometheus_client"
|
||||||
|
_ "github.com/influxdb/telegraf/outputs/riemann"
|
||||||
|
)
|
||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/internal"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Amon struct {
|
type Amon struct {
|
||||||
@@ -18,7 +18,7 @@ func TestBuildPoint(t *testing.T) {
|
|||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
testutil.TestPoint(float64(0.0), "testpt"),
|
testutil.TestPoint(float64(0.0)),
|
||||||
Point{
|
Point{
|
||||||
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
||||||
0.0,
|
0.0,
|
||||||
@@ -26,7 +26,7 @@ func TestBuildPoint(t *testing.T) {
|
|||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testutil.TestPoint(float64(1.0), "testpt"),
|
testutil.TestPoint(float64(1.0)),
|
||||||
Point{
|
Point{
|
||||||
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
||||||
1.0,
|
1.0,
|
||||||
@@ -34,7 +34,7 @@ func TestBuildPoint(t *testing.T) {
|
|||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testutil.TestPoint(int(10), "testpt"),
|
testutil.TestPoint(int(10)),
|
||||||
Point{
|
Point{
|
||||||
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
||||||
10.0,
|
10.0,
|
||||||
@@ -42,7 +42,7 @@ func TestBuildPoint(t *testing.T) {
|
|||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testutil.TestPoint(int32(112345), "testpt"),
|
testutil.TestPoint(int32(112345)),
|
||||||
Point{
|
Point{
|
||||||
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
||||||
112345.0,
|
112345.0,
|
||||||
@@ -50,7 +50,7 @@ func TestBuildPoint(t *testing.T) {
|
|||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testutil.TestPoint(int64(112345), "testpt"),
|
testutil.TestPoint(int64(112345)),
|
||||||
Point{
|
Point{
|
||||||
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
||||||
112345.0,
|
112345.0,
|
||||||
@@ -58,7 +58,7 @@ func TestBuildPoint(t *testing.T) {
|
|||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testutil.TestPoint(float32(11234.5), "testpt"),
|
testutil.TestPoint(float32(11234.5)),
|
||||||
Point{
|
Point{
|
||||||
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
||||||
11234.5,
|
11234.5,
|
||||||
@@ -66,7 +66,7 @@ func TestBuildPoint(t *testing.T) {
|
|||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testutil.TestPoint("11234.5", "testpt"),
|
testutil.TestPoint("11234.5"),
|
||||||
Point{
|
Point{
|
||||||
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
|
||||||
11234.5,
|
11234.5,
|
||||||
@@ -75,16 +75,15 @@ func TestBuildPoint(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tagtests {
|
for _, tt := range tagtests {
|
||||||
pt, err := buildPoints(tt.ptIn)
|
pt, err := buildPoint(tt.ptIn)
|
||||||
if err != nil && tt.err == nil {
|
if err != nil && tt.err == nil {
|
||||||
t.Errorf("%s: unexpected error, %+v\n", tt.ptIn.Name(), err)
|
t.Errorf("%s: unexpected error, %+v\n", tt.ptIn.Name(), err)
|
||||||
}
|
}
|
||||||
if tt.err != nil && err == nil {
|
if tt.err != nil && err == nil {
|
||||||
t.Errorf("%s: expected an error (%s) but none returned", tt.ptIn.Name(), tt.err.Error())
|
t.Errorf("%s: expected an error (%s) but none returned", tt.ptIn.Name(), tt.err.Error())
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(pt["value"], tt.outPt) && tt.err == nil {
|
if !reflect.DeepEqual(pt, tt.outPt) && tt.err == nil {
|
||||||
t.Errorf("%s: \nexpected %+v\ngot %+v\n",
|
t.Errorf("%s: \nexpected %+v\ngot %+v\n", tt.ptIn.Name(), tt.outPt, pt)
|
||||||
tt.ptIn.Name(), tt.outPt, pt["value"])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
"github.com/streadway/amqp"
|
"github.com/streadway/amqp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/internal"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Datadog struct {
|
type Datadog struct {
|
||||||
@@ -162,16 +162,15 @@ func TestBuildPoint(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tagtests {
|
for _, tt := range tagtests {
|
||||||
pt, err := buildPoints(tt.ptIn)
|
pt, err := buildPoint(tt.ptIn)
|
||||||
if err != nil && tt.err == nil {
|
if err != nil && tt.err == nil {
|
||||||
t.Errorf("%s: unexpected error, %+v\n", tt.ptIn.Name(), err)
|
t.Errorf("%s: unexpected error, %+v\n", tt.ptIn.Name(), err)
|
||||||
}
|
}
|
||||||
if tt.err != nil && err == nil {
|
if tt.err != nil && err == nil {
|
||||||
t.Errorf("%s: expected an error (%s) but none returned", tt.ptIn.Name(), tt.err.Error())
|
t.Errorf("%s: expected an error (%s) but none returned", tt.ptIn.Name(), tt.err.Error())
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(pt["value"], tt.outPt) && tt.err == nil {
|
if !reflect.DeepEqual(pt, tt.outPt) && tt.err == nil {
|
||||||
t.Errorf("%s: \nexpected %+v\ngot %+v\n",
|
t.Errorf("%s: \nexpected %+v\ngot %+v\n", tt.ptIn.Name(), tt.outPt, pt)
|
||||||
tt.ptIn.Name(), tt.outPt, pt["value"])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/internal"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type InfluxDB struct {
|
type InfluxDB struct {
|
||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/Shopify/sarama"
|
"github.com/Shopify/sarama"
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Kafka struct {
|
type Kafka struct {
|
||||||
@@ -16,7 +16,7 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/service/kinesis"
|
"github.com/aws/aws-sdk-go/service/kinesis"
|
||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type KinesisOutput struct {
|
type KinesisOutput struct {
|
||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/internal"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Librato struct {
|
type Librato struct {
|
||||||
@@ -142,20 +142,15 @@ func TestBuildGauge(t *testing.T) {
|
|||||||
|
|
||||||
l := NewLibrato(fakeUrl)
|
l := NewLibrato(fakeUrl)
|
||||||
for _, gt := range gaugeTests {
|
for _, gt := range gaugeTests {
|
||||||
gauges, err := l.buildGauges(gt.ptIn)
|
gauge, err := l.buildGauge(gt.ptIn)
|
||||||
if err != nil && gt.err == nil {
|
if err != nil && gt.err == nil {
|
||||||
t.Errorf("%s: unexpected error, %+v\n", gt.ptIn.Name(), err)
|
t.Errorf("%s: unexpected error, %+v\n", gt.ptIn.Name(), err)
|
||||||
}
|
}
|
||||||
if gt.err != nil && err == nil {
|
if gt.err != nil && err == nil {
|
||||||
t.Errorf("%s: expected an error (%s) but none returned",
|
t.Errorf("%s: expected an error (%s) but none returned", gt.ptIn.Name(), gt.err.Error())
|
||||||
gt.ptIn.Name(), gt.err.Error())
|
|
||||||
}
|
}
|
||||||
if len(gauges) == 0 {
|
if !reflect.DeepEqual(gauge, gt.outGauge) && gt.err == nil {
|
||||||
continue
|
t.Errorf("%s: \nexpected %+v\ngot %+v\n", gt.ptIn.Name(), gt.outGauge, gauge)
|
||||||
}
|
|
||||||
if gt.err == nil && !reflect.DeepEqual(gauges[0], gt.outGauge) {
|
|
||||||
t.Errorf("%s: \nexpected %+v\ngot %+v\n",
|
|
||||||
gt.ptIn.Name(), gt.outGauge, gauges[0])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,18 +198,15 @@ func TestBuildGaugeWithSource(t *testing.T) {
|
|||||||
l := NewLibrato(fakeUrl)
|
l := NewLibrato(fakeUrl)
|
||||||
l.SourceTag = "hostname"
|
l.SourceTag = "hostname"
|
||||||
for _, gt := range gaugeTests {
|
for _, gt := range gaugeTests {
|
||||||
gauges, err := l.buildGauges(gt.ptIn)
|
gauge, err := l.buildGauge(gt.ptIn)
|
||||||
if err != nil && gt.err == nil {
|
if err != nil && gt.err == nil {
|
||||||
t.Errorf("%s: unexpected error, %+v\n", gt.ptIn.Name(), err)
|
t.Errorf("%s: unexpected error, %+v\n", gt.ptIn.Name(), err)
|
||||||
}
|
}
|
||||||
if gt.err != nil && err == nil {
|
if gt.err != nil && err == nil {
|
||||||
t.Errorf("%s: expected an error (%s) but none returned", gt.ptIn.Name(), gt.err.Error())
|
t.Errorf("%s: expected an error (%s) but none returned", gt.ptIn.Name(), gt.err.Error())
|
||||||
}
|
}
|
||||||
if len(gauges) == 0 {
|
if !reflect.DeepEqual(gauge, gt.outGauge) && gt.err == nil {
|
||||||
continue
|
t.Errorf("%s: \nexpected %+v\ngot %+v\n", gt.ptIn.Name(), gt.outGauge, gauge)
|
||||||
}
|
|
||||||
if gt.err == nil && !reflect.DeepEqual(gauges[0], gt.outGauge) {
|
|
||||||
t.Errorf("%s: \nexpected %+v\ngot %+v\n", gt.ptIn.Name(), gt.outGauge, gauges[0])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
paho "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
|
paho "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/internal"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
const MaxClientIdLen = 8
|
const MaxClientIdLen = 8
|
||||||
@@ -3,7 +3,7 @@ package nsq
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
"github.com/nsqio/go-nsq"
|
"github.com/nsqio/go-nsq"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OpenTSDB struct {
|
type OpenTSDB struct {
|
||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -3,11 +3,11 @@ package prometheus_client
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/plugins/inputs/prometheus"
|
"github.com/influxdb/telegraf/plugins/prometheus"
|
||||||
"github.com/influxdb/telegraf/testutil"
|
"github.com/influxdb/telegraf/testutil"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
var pTesting *PrometheusClient
|
var pTesting *PrometheusClient
|
||||||
@@ -48,8 +48,7 @@ func TestPrometheusWritePointEmptyTag(t *testing.T) {
|
|||||||
|
|
||||||
require.NoError(t, p.Gather(&acc))
|
require.NoError(t, p.Gather(&acc))
|
||||||
for _, e := range expected {
|
for _, e := range expected {
|
||||||
acc.AssertContainsFields(t, "prometheus_"+e.name,
|
assert.NoError(t, acc.ValidateValue(e.name, e.value))
|
||||||
map[string]interface{}{"value": e.value})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,8 +88,7 @@ func TestPrometheusWritePointTag(t *testing.T) {
|
|||||||
|
|
||||||
require.NoError(t, p.Gather(&acc))
|
require.NoError(t, p.Gather(&acc))
|
||||||
for _, e := range expected {
|
for _, e := range expected {
|
||||||
acc.AssertContainsFields(t, "prometheus_"+e.name,
|
assert.True(t, acc.CheckTaggedValue(e.name, e.value, tags))
|
||||||
map[string]interface{}{"value": e.value})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/amir/raidman"
|
"github.com/amir/raidman"
|
||||||
"github.com/influxdb/influxdb/client/v2"
|
"github.com/influxdb/influxdb/client/v2"
|
||||||
"github.com/influxdb/telegraf/plugins/outputs"
|
"github.com/influxdb/telegraf/outputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Riemann struct {
|
type Riemann struct {
|
||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -119,7 +119,7 @@ func (a *Aerospike) Description() string {
|
|||||||
return "Read stats from an aerospike server"
|
return "Read stats from an aerospike server"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Aerospike) Gather(acc inputs.Accumulator) error {
|
func (a *Aerospike) Gather(acc plugins.Accumulator) error {
|
||||||
if len(a.Servers) == 0 {
|
if len(a.Servers) == 0 {
|
||||||
return a.gatherServer("127.0.0.1:3000", acc)
|
return a.gatherServer("127.0.0.1:3000", acc)
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ func (a *Aerospike) Gather(acc inputs.Accumulator) error {
|
|||||||
return outerr
|
return outerr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Aerospike) gatherServer(host string, acc inputs.Accumulator) error {
|
func (a *Aerospike) gatherServer(host string, acc plugins.Accumulator) error {
|
||||||
aerospikeInfo, err := getMap(STATISTICS_COMMAND, host)
|
aerospikeInfo, err := getMap(STATISTICS_COMMAND, host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Aerospike info failed: %s", err)
|
return fmt.Errorf("Aerospike info failed: %s", err)
|
||||||
@@ -249,7 +249,7 @@ func get(key []byte, host string) (map[string]string, error) {
|
|||||||
|
|
||||||
func readAerospikeStats(
|
func readAerospikeStats(
|
||||||
stats map[string]string,
|
stats map[string]string,
|
||||||
acc inputs.Accumulator,
|
acc plugins.Accumulator,
|
||||||
host string,
|
host string,
|
||||||
namespace string,
|
namespace string,
|
||||||
) {
|
) {
|
||||||
@@ -336,7 +336,7 @@ func msgLenFromBytes(buf [6]byte) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("aerospike", func() inputs.Input {
|
plugins.Add("aerospike", func() plugins.Plugin {
|
||||||
return &Aerospike{}
|
return &Aerospike{}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
package aerospike
|
package aerospike
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
"github.com/influxdb/telegraf/testutil"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAerospikeStatistics(t *testing.T) {
|
func TestAerospikeStatistics(t *testing.T) {
|
||||||
@@ -32,7 +31,7 @@ func TestAerospikeStatistics(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, metric := range asMetrics {
|
for _, metric := range asMetrics {
|
||||||
assert.True(t, acc.HasIntField("aerospike", metric), metric)
|
assert.True(t, acc.HasIntValue(metric), metric)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -50,16 +49,13 @@ func TestReadAerospikeStatsNoNamespace(t *testing.T) {
|
|||||||
"stat_read_reqs": "12345",
|
"stat_read_reqs": "12345",
|
||||||
}
|
}
|
||||||
readAerospikeStats(stats, &acc, "host1", "")
|
readAerospikeStats(stats, &acc, "host1", "")
|
||||||
|
for k := range stats {
|
||||||
fields := map[string]interface{}{
|
if k == "stat-write-errs" {
|
||||||
"stat_write_errs": int64(12345),
|
k = "stat_write_errs"
|
||||||
"stat_read_reqs": int64(12345),
|
}
|
||||||
|
assert.True(t, acc.HasMeasurement(k))
|
||||||
|
assert.True(t, acc.CheckValue(k, int64(12345)))
|
||||||
}
|
}
|
||||||
tags := map[string]string{
|
|
||||||
"aerospike_host": "host1",
|
|
||||||
"namespace": "_service",
|
|
||||||
}
|
|
||||||
acc.AssertContainsTaggedFields(t, "aerospike", fields, tags)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadAerospikeStatsNamespace(t *testing.T) {
|
func TestReadAerospikeStatsNamespace(t *testing.T) {
|
||||||
@@ -70,15 +66,13 @@ func TestReadAerospikeStatsNamespace(t *testing.T) {
|
|||||||
}
|
}
|
||||||
readAerospikeStats(stats, &acc, "host1", "test")
|
readAerospikeStats(stats, &acc, "host1", "test")
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
|
||||||
"stat_write_errs": int64(12345),
|
|
||||||
"stat_read_reqs": int64(12345),
|
|
||||||
}
|
|
||||||
tags := map[string]string{
|
tags := map[string]string{
|
||||||
"aerospike_host": "host1",
|
"aerospike_host": "host1",
|
||||||
"namespace": "test",
|
"namespace": "test",
|
||||||
}
|
}
|
||||||
acc.AssertContainsTaggedFields(t, "aerospike", fields, tags)
|
for k := range stats {
|
||||||
|
assert.True(t, acc.ValidateTaggedValue(k, int64(12345), tags) == nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAerospikeUnmarshalList(t *testing.T) {
|
func TestAerospikeUnmarshalList(t *testing.T) {
|
||||||
37
plugins/all/all.go
Normal file
37
plugins/all/all.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package all
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/aerospike"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/apache"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/bcache"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/disque"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/elasticsearch"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/exec"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/haproxy"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/httpjson"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/influxdb"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/jolokia"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/kafka_consumer"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/leofs"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/lustre2"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/mailchimp"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/memcached"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/mongodb"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/mysql"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/nginx"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/phpfpm"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/ping"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/postgresql"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/procstat"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/prometheus"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/puppetagent"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/rabbitmq"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/redis"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/rethinkdb"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/statsd"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/system"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/trig"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/twemproxy"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/zfs"
|
||||||
|
_ "github.com/influxdb/telegraf/plugins/zookeeper"
|
||||||
|
)
|
||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Apache struct {
|
type Apache struct {
|
||||||
@@ -31,7 +31,7 @@ func (n *Apache) Description() string {
|
|||||||
return "Read Apache status information (mod_status)"
|
return "Read Apache status information (mod_status)"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Apache) Gather(acc inputs.Accumulator) error {
|
func (n *Apache) Gather(acc plugins.Accumulator) error {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var outerr error
|
var outerr error
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ var tr = &http.Transport{
|
|||||||
|
|
||||||
var client = &http.Client{Transport: tr}
|
var client = &http.Client{Transport: tr}
|
||||||
|
|
||||||
func (n *Apache) gatherUrl(addr *url.URL, acc inputs.Accumulator) error {
|
func (n *Apache) gatherUrl(addr *url.URL, acc plugins.Accumulator) error {
|
||||||
resp, err := client.Get(addr.String())
|
resp, err := client.Get(addr.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error making HTTP request to %s: %s", addr.String(), err)
|
return fmt.Errorf("error making HTTP request to %s: %s", addr.String(), err)
|
||||||
@@ -164,7 +164,7 @@ func getTags(addr *url.URL) map[string]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("apache", func() inputs.Input {
|
plugins.Add("apache", func() plugins.Plugin {
|
||||||
return &Apache{}
|
return &Apache{}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
"github.com/influxdb/telegraf/testutil"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -43,31 +44,37 @@ func TestHTTPApache(t *testing.T) {
|
|||||||
err := a.Gather(&acc)
|
err := a.Gather(&acc)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
testInt := []struct {
|
||||||
"TotalAccesses": float64(1.29811861e+08),
|
measurement string
|
||||||
"TotalkBytes": float64(5.213701865e+09),
|
value float64
|
||||||
"CPULoad": float64(6.51929),
|
}{
|
||||||
"Uptime": float64(941553),
|
{"TotalAccesses", 1.29811861e+08},
|
||||||
"ReqPerSec": float64(137.87),
|
{"TotalkBytes", 5.213701865e+09},
|
||||||
"BytesPerSec": float64(5.67024e+06),
|
{"CPULoad", 6.51929},
|
||||||
"BytesPerReq": float64(41127.4),
|
{"Uptime", 941553},
|
||||||
"BusyWorkers": float64(270),
|
{"ReqPerSec", 137.87},
|
||||||
"IdleWorkers": float64(630),
|
{"BytesPerSec", 5.67024e+06},
|
||||||
"ConnsTotal": float64(1451),
|
{"BytesPerReq", 41127.4},
|
||||||
"ConnsAsyncWriting": float64(32),
|
{"BusyWorkers", 270},
|
||||||
"ConnsAsyncKeepAlive": float64(945),
|
{"IdleWorkers", 630},
|
||||||
"ConnsAsyncClosing": float64(205),
|
{"ConnsTotal", 1451},
|
||||||
"scboard_waiting": float64(630),
|
{"ConnsAsyncWriting", 32},
|
||||||
"scboard_starting": float64(0),
|
{"ConnsAsyncKeepAlive", 945},
|
||||||
"scboard_reading": float64(157),
|
{"ConnsAsyncClosing", 205},
|
||||||
"scboard_sending": float64(113),
|
{"scboard_waiting", 630},
|
||||||
"scboard_keepalive": float64(0),
|
{"scboard_starting", 0},
|
||||||
"scboard_dnslookup": float64(0),
|
{"scboard_reading", 157},
|
||||||
"scboard_closing": float64(0),
|
{"scboard_sending", 113},
|
||||||
"scboard_logging": float64(0),
|
{"scboard_keepalive", 0},
|
||||||
"scboard_finishing": float64(0),
|
{"scboard_dnslookup", 0},
|
||||||
"scboard_idle_cleanup": float64(0),
|
{"scboard_closing", 0},
|
||||||
"scboard_open": float64(2850),
|
{"scboard_logging", 0},
|
||||||
|
{"scboard_finishing", 0},
|
||||||
|
{"scboard_idle_cleanup", 0},
|
||||||
|
{"scboard_open", 2850},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testInt {
|
||||||
|
assert.True(t, acc.CheckValue(test.measurement, test.value))
|
||||||
}
|
}
|
||||||
acc.AssertContainsFields(t, "apache", fields)
|
|
||||||
}
|
}
|
||||||
@@ -26,27 +26,27 @@ Measurement names:
|
|||||||
dirty_data
|
dirty_data
|
||||||
Amount of dirty data for this backing device in the cache. Continuously
|
Amount of dirty data for this backing device in the cache. Continuously
|
||||||
updated unlike the cache set's version, but may be slightly off.
|
updated unlike the cache set's version, but may be slightly off.
|
||||||
|
|
||||||
bypassed
|
bypassed
|
||||||
Amount of IO (both reads and writes) that has bypassed the cache
|
Amount of IO (both reads and writes) that has bypassed the cache
|
||||||
|
|
||||||
|
|
||||||
cache_bypass_hits
|
cache_bypass_hits
|
||||||
cache_bypass_misses
|
cache_bypass_misses
|
||||||
Hits and misses for IO that is intended to skip the cache are still counted,
|
Hits and misses for IO that is intended to skip the cache are still counted,
|
||||||
but broken out here.
|
but broken out here.
|
||||||
|
|
||||||
cache_hits
|
cache_hits
|
||||||
cache_misses
|
cache_misses
|
||||||
cache_hit_ratio
|
cache_hit_ratio
|
||||||
Hits and misses are counted per individual IO as bcache sees them; a
|
Hits and misses are counted per individual IO as bcache sees them; a
|
||||||
partial hit is counted as a miss.
|
partial hit is counted as a miss.
|
||||||
|
|
||||||
cache_miss_collisions
|
cache_miss_collisions
|
||||||
Counts instances where data was going to be inserted into the cache from a
|
Counts instances where data was going to be inserted into the cache from a
|
||||||
cache miss, but raced with a write and data was already present (usually 0
|
cache miss, but raced with a write and data was already present (usually 0
|
||||||
since the synchronization for cache misses was rewritten)
|
since the synchronization for cache misses was rewritten)
|
||||||
|
|
||||||
cache_readaheads
|
cache_readaheads
|
||||||
Count of times readahead occurred.
|
Count of times readahead occurred.
|
||||||
```
|
```
|
||||||
@@ -70,7 +70,7 @@ Using this configuration:
|
|||||||
When run with:
|
When run with:
|
||||||
|
|
||||||
```
|
```
|
||||||
./telegraf -config telegraf.conf -input-filter bcache -test
|
./telegraf -config telegraf.conf -filter bcache -test
|
||||||
```
|
```
|
||||||
|
|
||||||
It produces:
|
It produces:
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Bcache struct {
|
type Bcache struct {
|
||||||
@@ -69,7 +69,7 @@ func prettyToBytes(v string) uint64 {
|
|||||||
return uint64(result)
|
return uint64(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bcache) gatherBcache(bdev string, acc inputs.Accumulator) error {
|
func (b *Bcache) gatherBcache(bdev string, acc plugins.Accumulator) error {
|
||||||
tags := getTags(bdev)
|
tags := getTags(bdev)
|
||||||
metrics, err := filepath.Glob(bdev + "/stats_total/*")
|
metrics, err := filepath.Glob(bdev + "/stats_total/*")
|
||||||
if len(metrics) < 0 {
|
if len(metrics) < 0 {
|
||||||
@@ -104,7 +104,7 @@ func (b *Bcache) gatherBcache(bdev string, acc inputs.Accumulator) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bcache) Gather(acc inputs.Accumulator) error {
|
func (b *Bcache) Gather(acc plugins.Accumulator) error {
|
||||||
bcacheDevsChecked := make(map[string]bool)
|
bcacheDevsChecked := make(map[string]bool)
|
||||||
var restrictDevs bool
|
var restrictDevs bool
|
||||||
if len(b.BcacheDevs) != 0 {
|
if len(b.BcacheDevs) != 0 {
|
||||||
@@ -135,7 +135,7 @@ func (b *Bcache) Gather(acc inputs.Accumulator) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("bcache", func() inputs.Input {
|
plugins.Add("bcache", func() plugins.Plugin {
|
||||||
return &Bcache{}
|
return &Bcache{}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
"github.com/influxdb/telegraf/testutil"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -28,6 +29,11 @@ var (
|
|||||||
testBcacheBackingDevPath = os.TempDir() + "/telegraf/sys/devices/virtual/block/md10"
|
testBcacheBackingDevPath = os.TempDir() + "/telegraf/sys/devices/virtual/block/md10"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type metrics struct {
|
||||||
|
name string
|
||||||
|
value uint64
|
||||||
|
}
|
||||||
|
|
||||||
func TestBcacheGeneratesMetrics(t *testing.T) {
|
func TestBcacheGeneratesMetrics(t *testing.T) {
|
||||||
err := os.MkdirAll(testBcacheUuidPath, 0755)
|
err := os.MkdirAll(testBcacheUuidPath, 0755)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -47,52 +53,70 @@ func TestBcacheGeneratesMetrics(t *testing.T) {
|
|||||||
err = os.MkdirAll(testBcacheUuidPath+"/bdev0/stats_total", 0755)
|
err = os.MkdirAll(testBcacheUuidPath+"/bdev0/stats_total", 0755)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/dirty_data",
|
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/dirty_data", []byte(dirty_data), 0644)
|
||||||
[]byte(dirty_data), 0644)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/bypassed",
|
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/bypassed", []byte(bypassed), 0644)
|
||||||
[]byte(bypassed), 0644)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_bypass_hits",
|
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_bypass_hits", []byte(cache_bypass_hits), 0644)
|
||||||
[]byte(cache_bypass_hits), 0644)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_bypass_misses",
|
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_bypass_misses", []byte(cache_bypass_misses), 0644)
|
||||||
[]byte(cache_bypass_misses), 0644)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_hit_ratio",
|
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_hit_ratio", []byte(cache_hit_ratio), 0644)
|
||||||
[]byte(cache_hit_ratio), 0644)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_hits",
|
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_hits", []byte(cache_hits), 0644)
|
||||||
[]byte(cache_hits), 0644)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_miss_collisions",
|
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_miss_collisions", []byte(cache_miss_collisions), 0644)
|
||||||
[]byte(cache_miss_collisions), 0644)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_misses",
|
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_misses", []byte(cache_misses), 0644)
|
||||||
[]byte(cache_misses), 0644)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_readaheads",
|
err = ioutil.WriteFile(testBcacheUuidPath+"/bdev0/stats_total/cache_readaheads", []byte(cache_readaheads), 0644)
|
||||||
[]byte(cache_readaheads), 0644)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
intMetrics := []*metrics{
|
||||||
"dirty_data": uint64(1610612736),
|
{
|
||||||
"bypassed": uint64(5167704440832),
|
name: "dirty_data",
|
||||||
"cache_bypass_hits": uint64(146155333),
|
value: 1610612736,
|
||||||
"cache_bypass_misses": uint64(0),
|
},
|
||||||
"cache_hit_ratio": uint64(90),
|
{
|
||||||
"cache_hits": uint64(511469583),
|
name: "bypassed",
|
||||||
"cache_miss_collisions": uint64(157567),
|
value: 5167704440832,
|
||||||
"cache_misses": uint64(50616331),
|
},
|
||||||
"cache_readaheads": uint64(2),
|
{
|
||||||
|
name: "cache_bypass_hits",
|
||||||
|
value: 146155333,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cache_bypass_misses",
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cache_hit_ratio",
|
||||||
|
value: 90,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cache_hits",
|
||||||
|
value: 511469583,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cache_miss_collisions",
|
||||||
|
value: 157567,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cache_misses",
|
||||||
|
value: 50616331,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cache_readaheads",
|
||||||
|
value: 2,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
tags := map[string]string{
|
tags := map[string]string{
|
||||||
@@ -102,19 +126,27 @@ func TestBcacheGeneratesMetrics(t *testing.T) {
|
|||||||
|
|
||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
|
|
||||||
// all devs
|
//all devs
|
||||||
b := &Bcache{BcachePath: testBcachePath}
|
b := &Bcache{BcachePath: testBcachePath}
|
||||||
|
|
||||||
err = b.Gather(&acc)
|
err = b.Gather(&acc)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
acc.AssertContainsTaggedFields(t, "bcache", fields, tags)
|
|
||||||
|
|
||||||
// one exist dev
|
for _, metric := range intMetrics {
|
||||||
|
assert.True(t, acc.HasUIntValue(metric.name), metric.name)
|
||||||
|
assert.True(t, acc.CheckTaggedValue(metric.name, metric.value, tags))
|
||||||
|
}
|
||||||
|
|
||||||
|
//one exist dev
|
||||||
b = &Bcache{BcachePath: testBcachePath, BcacheDevs: []string{"bcache0"}}
|
b = &Bcache{BcachePath: testBcachePath, BcacheDevs: []string{"bcache0"}}
|
||||||
|
|
||||||
err = b.Gather(&acc)
|
err = b.Gather(&acc)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
acc.AssertContainsTaggedFields(t, "bcache", fields, tags)
|
|
||||||
|
for _, metric := range intMetrics {
|
||||||
|
assert.True(t, acc.HasUIntValue(metric.name), metric.name)
|
||||||
|
assert.True(t, acc.CheckTaggedValue(metric.name, metric.value, tags))
|
||||||
|
}
|
||||||
|
|
||||||
err = os.RemoveAll(os.TempDir() + "/telegraf")
|
err = os.RemoveAll(os.TempDir() + "/telegraf")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Disque struct {
|
type Disque struct {
|
||||||
@@ -61,7 +61,7 @@ var ErrProtocolError = errors.New("disque protocol error")
|
|||||||
|
|
||||||
// Reads stats from all configured servers accumulates stats.
|
// Reads stats from all configured servers accumulates stats.
|
||||||
// Returns one of the errors encountered while gather stats (if any).
|
// Returns one of the errors encountered while gather stats (if any).
|
||||||
func (g *Disque) Gather(acc inputs.Accumulator) error {
|
func (g *Disque) Gather(acc plugins.Accumulator) error {
|
||||||
if len(g.Servers) == 0 {
|
if len(g.Servers) == 0 {
|
||||||
url := &url.URL{
|
url := &url.URL{
|
||||||
Host: ":7711",
|
Host: ":7711",
|
||||||
@@ -98,7 +98,7 @@ func (g *Disque) Gather(acc inputs.Accumulator) error {
|
|||||||
|
|
||||||
const defaultPort = "7711"
|
const defaultPort = "7711"
|
||||||
|
|
||||||
func (g *Disque) gatherServer(addr *url.URL, acc inputs.Accumulator) error {
|
func (g *Disque) gatherServer(addr *url.URL, acc plugins.Accumulator) error {
|
||||||
if g.c == nil {
|
if g.c == nil {
|
||||||
|
|
||||||
_, _, err := net.SplitHostPort(addr.Host)
|
_, _, err := net.SplitHostPort(addr.Host)
|
||||||
@@ -198,7 +198,7 @@ func (g *Disque) gatherServer(addr *url.URL, acc inputs.Accumulator) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("disque", func() inputs.Input {
|
plugins.Add("disque", func() plugins.Plugin {
|
||||||
return &Disque{}
|
return &Disque{}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
"github.com/influxdb/telegraf/testutil"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -54,26 +55,42 @@ func TestDisqueGeneratesMetrics(t *testing.T) {
|
|||||||
err = r.Gather(&acc)
|
err = r.Gather(&acc)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
checkInt := []struct {
|
||||||
"uptime": uint64(1452705),
|
name string
|
||||||
"clients": uint64(31),
|
value uint64
|
||||||
"blocked_clients": uint64(13),
|
}{
|
||||||
"used_memory": uint64(1840104),
|
{"uptime", 1452705},
|
||||||
"used_memory_rss": uint64(3227648),
|
{"clients", 31},
|
||||||
"used_memory_peak": uint64(89603656),
|
{"blocked_clients", 13},
|
||||||
"total_connections_received": uint64(5062777),
|
{"used_memory", 1840104},
|
||||||
"total_commands_processed": uint64(12308396),
|
{"used_memory_rss", 3227648},
|
||||||
"instantaneous_ops_per_sec": uint64(18),
|
{"used_memory_peak", 89603656},
|
||||||
"latest_fork_usec": uint64(1644),
|
{"total_connections_received", 5062777},
|
||||||
"registered_jobs": uint64(360),
|
{"total_commands_processed", 12308396},
|
||||||
"registered_queues": uint64(12),
|
{"instantaneous_ops_per_sec", 18},
|
||||||
"mem_fragmentation_ratio": float64(1.75),
|
{"latest_fork_usec", 1644},
|
||||||
"used_cpu_sys": float64(19585.73),
|
{"registered_jobs", 360},
|
||||||
"used_cpu_user": float64(11255.96),
|
{"registered_queues", 12},
|
||||||
"used_cpu_sys_children": float64(1.75),
|
}
|
||||||
"used_cpu_user_children": float64(1.91),
|
|
||||||
|
for _, c := range checkInt {
|
||||||
|
assert.True(t, acc.CheckValue(c.name, c.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
checkFloat := []struct {
|
||||||
|
name string
|
||||||
|
value float64
|
||||||
|
}{
|
||||||
|
{"mem_fragmentation_ratio", 1.75},
|
||||||
|
{"used_cpu_sys", 19585.73},
|
||||||
|
{"used_cpu_user", 11255.96},
|
||||||
|
{"used_cpu_sys_children", 1.75},
|
||||||
|
{"used_cpu_user_children", 1.91},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range checkFloat {
|
||||||
|
assert.True(t, acc.CheckValue(c.name, c.value))
|
||||||
}
|
}
|
||||||
acc.AssertContainsFields(t, "disque", fields)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDisqueCanPullStatsFromMultipleServers(t *testing.T) {
|
func TestDisqueCanPullStatsFromMultipleServers(t *testing.T) {
|
||||||
@@ -120,26 +137,42 @@ func TestDisqueCanPullStatsFromMultipleServers(t *testing.T) {
|
|||||||
err = r.Gather(&acc)
|
err = r.Gather(&acc)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
checkInt := []struct {
|
||||||
"uptime": uint64(1452705),
|
name string
|
||||||
"clients": uint64(31),
|
value uint64
|
||||||
"blocked_clients": uint64(13),
|
}{
|
||||||
"used_memory": uint64(1840104),
|
{"uptime", 1452705},
|
||||||
"used_memory_rss": uint64(3227648),
|
{"clients", 31},
|
||||||
"used_memory_peak": uint64(89603656),
|
{"blocked_clients", 13},
|
||||||
"total_connections_received": uint64(5062777),
|
{"used_memory", 1840104},
|
||||||
"total_commands_processed": uint64(12308396),
|
{"used_memory_rss", 3227648},
|
||||||
"instantaneous_ops_per_sec": uint64(18),
|
{"used_memory_peak", 89603656},
|
||||||
"latest_fork_usec": uint64(1644),
|
{"total_connections_received", 5062777},
|
||||||
"registered_jobs": uint64(360),
|
{"total_commands_processed", 12308396},
|
||||||
"registered_queues": uint64(12),
|
{"instantaneous_ops_per_sec", 18},
|
||||||
"mem_fragmentation_ratio": float64(1.75),
|
{"latest_fork_usec", 1644},
|
||||||
"used_cpu_sys": float64(19585.73),
|
{"registered_jobs", 360},
|
||||||
"used_cpu_user": float64(11255.96),
|
{"registered_queues", 12},
|
||||||
"used_cpu_sys_children": float64(1.75),
|
}
|
||||||
"used_cpu_user_children": float64(1.91),
|
|
||||||
|
for _, c := range checkInt {
|
||||||
|
assert.True(t, acc.CheckValue(c.name, c.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
checkFloat := []struct {
|
||||||
|
name string
|
||||||
|
value float64
|
||||||
|
}{
|
||||||
|
{"mem_fragmentation_ratio", 1.75},
|
||||||
|
{"used_cpu_sys", 19585.73},
|
||||||
|
{"used_cpu_user", 11255.96},
|
||||||
|
{"used_cpu_sys_children", 1.75},
|
||||||
|
{"used_cpu_user_children", 1.91},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range checkFloat {
|
||||||
|
assert.True(t, acc.CheckValue(c.name, c.value))
|
||||||
}
|
}
|
||||||
acc.AssertContainsFields(t, "disque", fields)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const testOutput = `# Server
|
const testOutput = `# Server
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/internal"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
)
|
)
|
||||||
|
|
||||||
const statsPath = "/_nodes/stats"
|
const statsPath = "/_nodes/stats"
|
||||||
@@ -92,7 +92,7 @@ func (e *Elasticsearch) Description() string {
|
|||||||
|
|
||||||
// Gather reads the stats from Elasticsearch and writes it to the
|
// Gather reads the stats from Elasticsearch and writes it to the
|
||||||
// Accumulator.
|
// Accumulator.
|
||||||
func (e *Elasticsearch) Gather(acc inputs.Accumulator) error {
|
func (e *Elasticsearch) Gather(acc plugins.Accumulator) error {
|
||||||
for _, serv := range e.Servers {
|
for _, serv := range e.Servers {
|
||||||
var url string
|
var url string
|
||||||
if e.Local {
|
if e.Local {
|
||||||
@@ -110,7 +110,7 @@ func (e *Elasticsearch) Gather(acc inputs.Accumulator) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Elasticsearch) gatherNodeStats(url string, acc inputs.Accumulator) error {
|
func (e *Elasticsearch) gatherNodeStats(url string, acc plugins.Accumulator) error {
|
||||||
nodeStats := &struct {
|
nodeStats := &struct {
|
||||||
ClusterName string `json:"cluster_name"`
|
ClusterName string `json:"cluster_name"`
|
||||||
Nodes map[string]*node `json:"nodes"`
|
Nodes map[string]*node `json:"nodes"`
|
||||||
@@ -155,7 +155,7 @@ func (e *Elasticsearch) gatherNodeStats(url string, acc inputs.Accumulator) erro
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Elasticsearch) gatherClusterStats(url string, acc inputs.Accumulator) error {
|
func (e *Elasticsearch) gatherClusterStats(url string, acc plugins.Accumulator) error {
|
||||||
clusterStats := &clusterHealth{}
|
clusterStats := &clusterHealth{}
|
||||||
if err := e.gatherData(url, clusterStats); err != nil {
|
if err := e.gatherData(url, clusterStats); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -220,7 +220,7 @@ func (e *Elasticsearch) gatherData(url string, v interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("elasticsearch", func() inputs.Input {
|
plugins.Add("elasticsearch", func() plugins.Plugin {
|
||||||
return NewElasticsearch()
|
return NewElasticsearch()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
"github.com/influxdb/telegraf/testutil"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -52,15 +52,23 @@ func TestElasticsearch(t *testing.T) {
|
|||||||
"node_host": "test",
|
"node_host": "test",
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.AssertContainsTaggedFields(t, "elasticsearch_indices", indicesExpected, tags)
|
testTables := []map[string]float64{
|
||||||
acc.AssertContainsTaggedFields(t, "elasticsearch_os", osExpected, tags)
|
indicesExpected,
|
||||||
acc.AssertContainsTaggedFields(t, "elasticsearch_process", processExpected, tags)
|
osExpected,
|
||||||
acc.AssertContainsTaggedFields(t, "elasticsearch_jvm", jvmExpected, tags)
|
processExpected,
|
||||||
acc.AssertContainsTaggedFields(t, "elasticsearch_thread_pool", threadPoolExpected, tags)
|
jvmExpected,
|
||||||
acc.AssertContainsTaggedFields(t, "elasticsearch_fs", fsExpected, tags)
|
threadPoolExpected,
|
||||||
acc.AssertContainsTaggedFields(t, "elasticsearch_transport", transportExpected, tags)
|
fsExpected,
|
||||||
acc.AssertContainsTaggedFields(t, "elasticsearch_http", httpExpected, tags)
|
transportExpected,
|
||||||
acc.AssertContainsTaggedFields(t, "elasticsearch_breakers", breakersExpected, tags)
|
httpExpected,
|
||||||
|
breakersExpected,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testTable := range testTables {
|
||||||
|
for k, v := range testTable {
|
||||||
|
assert.NoError(t, acc.ValidateTaggedValue(k, v, tags))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGatherClusterStats(t *testing.T) {
|
func TestGatherClusterStats(t *testing.T) {
|
||||||
@@ -72,15 +80,29 @@ func TestGatherClusterStats(t *testing.T) {
|
|||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
require.NoError(t, es.Gather(&acc))
|
require.NoError(t, es.Gather(&acc))
|
||||||
|
|
||||||
acc.AssertContainsTaggedFields(t, "elasticsearch_cluster_health",
|
var clusterHealthTests = []struct {
|
||||||
clusterHealthExpected,
|
measurement string
|
||||||
map[string]string{"name": "elasticsearch_telegraf"})
|
fields map[string]interface{}
|
||||||
|
tags map[string]string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"cluster_health",
|
||||||
|
clusterHealthExpected,
|
||||||
|
map[string]string{"name": "elasticsearch_telegraf"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indices",
|
||||||
|
v1IndexExpected,
|
||||||
|
map[string]string{"index": "v1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indices",
|
||||||
|
v2IndexExpected,
|
||||||
|
map[string]string{"index": "v2"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
acc.AssertContainsTaggedFields(t, "elasticsearch_indices",
|
for _, exp := range clusterHealthTests {
|
||||||
v1IndexExpected,
|
assert.NoError(t, acc.ValidateTaggedFields(exp.measurement, exp.fields, exp.tags))
|
||||||
map[string]string{"index": "v1"})
|
}
|
||||||
|
|
||||||
acc.AssertContainsTaggedFields(t, "elasticsearch_indices",
|
|
||||||
v2IndexExpected,
|
|
||||||
map[string]string{"index": "v2"})
|
|
||||||
}
|
}
|
||||||
759
plugins/elasticsearch/testdata_test.go
Normal file
759
plugins/elasticsearch/testdata_test.go
Normal file
@@ -0,0 +1,759 @@
|
|||||||
|
package elasticsearch
|
||||||
|
|
||||||
|
const clusterResponse = `
|
||||||
|
{
|
||||||
|
"cluster_name": "elasticsearch_telegraf",
|
||||||
|
"status": "green",
|
||||||
|
"timed_out": false,
|
||||||
|
"number_of_nodes": 3,
|
||||||
|
"number_of_data_nodes": 3,
|
||||||
|
"active_primary_shards": 5,
|
||||||
|
"active_shards": 15,
|
||||||
|
"relocating_shards": 0,
|
||||||
|
"initializing_shards": 0,
|
||||||
|
"unassigned_shards": 0,
|
||||||
|
"indices": {
|
||||||
|
"v1": {
|
||||||
|
"status": "green",
|
||||||
|
"number_of_shards": 10,
|
||||||
|
"number_of_replicas": 1,
|
||||||
|
"active_primary_shards": 10,
|
||||||
|
"active_shards": 20,
|
||||||
|
"relocating_shards": 0,
|
||||||
|
"initializing_shards": 0,
|
||||||
|
"unassigned_shards": 0
|
||||||
|
},
|
||||||
|
"v2": {
|
||||||
|
"status": "red",
|
||||||
|
"number_of_shards": 10,
|
||||||
|
"number_of_replicas": 1,
|
||||||
|
"active_primary_shards": 0,
|
||||||
|
"active_shards": 0,
|
||||||
|
"relocating_shards": 0,
|
||||||
|
"initializing_shards": 0,
|
||||||
|
"unassigned_shards": 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
var clusterHealthExpected = map[string]interface{}{
|
||||||
|
"status": "green",
|
||||||
|
"timed_out": false,
|
||||||
|
"number_of_nodes": 3,
|
||||||
|
"number_of_data_nodes": 3,
|
||||||
|
"active_primary_shards": 5,
|
||||||
|
"active_shards": 15,
|
||||||
|
"relocating_shards": 0,
|
||||||
|
"initializing_shards": 0,
|
||||||
|
"unassigned_shards": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
var v1IndexExpected = map[string]interface{}{
|
||||||
|
"status": "green",
|
||||||
|
"number_of_shards": 10,
|
||||||
|
"number_of_replicas": 1,
|
||||||
|
"active_primary_shards": 10,
|
||||||
|
"active_shards": 20,
|
||||||
|
"relocating_shards": 0,
|
||||||
|
"initializing_shards": 0,
|
||||||
|
"unassigned_shards": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
var v2IndexExpected = map[string]interface{}{
|
||||||
|
"status": "red",
|
||||||
|
"number_of_shards": 10,
|
||||||
|
"number_of_replicas": 1,
|
||||||
|
"active_primary_shards": 0,
|
||||||
|
"active_shards": 0,
|
||||||
|
"relocating_shards": 0,
|
||||||
|
"initializing_shards": 0,
|
||||||
|
"unassigned_shards": 20,
|
||||||
|
}
|
||||||
|
|
||||||
|
const statsResponse = `
|
||||||
|
{
|
||||||
|
"cluster_name": "es-testcluster",
|
||||||
|
"nodes": {
|
||||||
|
"SDFsfSDFsdfFSDSDfSFDSDF": {
|
||||||
|
"timestamp": 1436365550135,
|
||||||
|
"name": "test.host.com",
|
||||||
|
"transport_address": "inet[/127.0.0.1:9300]",
|
||||||
|
"host": "test",
|
||||||
|
"ip": [
|
||||||
|
"inet[/127.0.0.1:9300]",
|
||||||
|
"NONE"
|
||||||
|
],
|
||||||
|
"attributes": {
|
||||||
|
"master": "true"
|
||||||
|
},
|
||||||
|
"indices": {
|
||||||
|
"docs": {
|
||||||
|
"count": 29652,
|
||||||
|
"deleted": 5229
|
||||||
|
},
|
||||||
|
"store": {
|
||||||
|
"size_in_bytes": 37715234,
|
||||||
|
"throttle_time_in_millis": 215
|
||||||
|
},
|
||||||
|
"indexing": {
|
||||||
|
"index_total": 84790,
|
||||||
|
"index_time_in_millis": 29680,
|
||||||
|
"index_current": 0,
|
||||||
|
"delete_total": 13879,
|
||||||
|
"delete_time_in_millis": 1139,
|
||||||
|
"delete_current": 0,
|
||||||
|
"noop_update_total": 0,
|
||||||
|
"is_throttled": false,
|
||||||
|
"throttle_time_in_millis": 0
|
||||||
|
},
|
||||||
|
"get": {
|
||||||
|
"total": 1,
|
||||||
|
"time_in_millis": 2,
|
||||||
|
"exists_total": 0,
|
||||||
|
"exists_time_in_millis": 0,
|
||||||
|
"missing_total": 1,
|
||||||
|
"missing_time_in_millis": 2,
|
||||||
|
"current": 0
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"open_contexts": 0,
|
||||||
|
"query_total": 1452,
|
||||||
|
"query_time_in_millis": 5695,
|
||||||
|
"query_current": 0,
|
||||||
|
"fetch_total": 414,
|
||||||
|
"fetch_time_in_millis": 146,
|
||||||
|
"fetch_current": 0
|
||||||
|
},
|
||||||
|
"merges": {
|
||||||
|
"current": 0,
|
||||||
|
"current_docs": 0,
|
||||||
|
"current_size_in_bytes": 0,
|
||||||
|
"total": 133,
|
||||||
|
"total_time_in_millis": 21060,
|
||||||
|
"total_docs": 203672,
|
||||||
|
"total_size_in_bytes": 142900226
|
||||||
|
},
|
||||||
|
"refresh": {
|
||||||
|
"total": 1076,
|
||||||
|
"total_time_in_millis": 20078
|
||||||
|
},
|
||||||
|
"flush": {
|
||||||
|
"total": 115,
|
||||||
|
"total_time_in_millis": 2401
|
||||||
|
},
|
||||||
|
"warmer": {
|
||||||
|
"current": 0,
|
||||||
|
"total": 2319,
|
||||||
|
"total_time_in_millis": 448
|
||||||
|
},
|
||||||
|
"filter_cache": {
|
||||||
|
"memory_size_in_bytes": 7384,
|
||||||
|
"evictions": 0
|
||||||
|
},
|
||||||
|
"id_cache": {
|
||||||
|
"memory_size_in_bytes": 0
|
||||||
|
},
|
||||||
|
"fielddata": {
|
||||||
|
"memory_size_in_bytes": 12996,
|
||||||
|
"evictions": 0
|
||||||
|
},
|
||||||
|
"percolate": {
|
||||||
|
"total": 0,
|
||||||
|
"time_in_millis": 0,
|
||||||
|
"current": 0,
|
||||||
|
"memory_size_in_bytes": -1,
|
||||||
|
"memory_size": "-1b",
|
||||||
|
"queries": 0
|
||||||
|
},
|
||||||
|
"completion": {
|
||||||
|
"size_in_bytes": 0
|
||||||
|
},
|
||||||
|
"segments": {
|
||||||
|
"count": 134,
|
||||||
|
"memory_in_bytes": 1285212,
|
||||||
|
"index_writer_memory_in_bytes": 0,
|
||||||
|
"index_writer_max_memory_in_bytes": 172368955,
|
||||||
|
"version_map_memory_in_bytes": 611844,
|
||||||
|
"fixed_bit_set_memory_in_bytes": 0
|
||||||
|
},
|
||||||
|
"translog": {
|
||||||
|
"operations": 17702,
|
||||||
|
"size_in_bytes": 17
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"total": 0,
|
||||||
|
"time_in_millis": 0,
|
||||||
|
"current": 0
|
||||||
|
},
|
||||||
|
"query_cache": {
|
||||||
|
"memory_size_in_bytes": 0,
|
||||||
|
"evictions": 0,
|
||||||
|
"hit_count": 0,
|
||||||
|
"miss_count": 0
|
||||||
|
},
|
||||||
|
"recovery": {
|
||||||
|
"current_as_source": 0,
|
||||||
|
"current_as_target": 0,
|
||||||
|
"throttle_time_in_millis": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"os": {
|
||||||
|
"timestamp": 1436460392944,
|
||||||
|
"load_average": [
|
||||||
|
0.01,
|
||||||
|
0.04,
|
||||||
|
0.05
|
||||||
|
],
|
||||||
|
"mem": {
|
||||||
|
"free_in_bytes": 477761536,
|
||||||
|
"used_in_bytes": 1621868544,
|
||||||
|
"free_percent": 74,
|
||||||
|
"used_percent": 25,
|
||||||
|
"actual_free_in_bytes": 1565470720,
|
||||||
|
"actual_used_in_bytes": 534159360
|
||||||
|
},
|
||||||
|
"swap": {
|
||||||
|
"used_in_bytes": 0,
|
||||||
|
"free_in_bytes": 487997440
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"process": {
|
||||||
|
"timestamp": 1436460392945,
|
||||||
|
"open_file_descriptors": 160,
|
||||||
|
"cpu": {
|
||||||
|
"percent": 2,
|
||||||
|
"sys_in_millis": 1870,
|
||||||
|
"user_in_millis": 13610,
|
||||||
|
"total_in_millis": 15480
|
||||||
|
},
|
||||||
|
"mem": {
|
||||||
|
"total_virtual_in_bytes": 4747890688
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jvm": {
|
||||||
|
"timestamp": 1436460392945,
|
||||||
|
"uptime_in_millis": 202245,
|
||||||
|
"mem": {
|
||||||
|
"heap_used_in_bytes": 52709568,
|
||||||
|
"heap_used_percent": 5,
|
||||||
|
"heap_committed_in_bytes": 259522560,
|
||||||
|
"heap_max_in_bytes": 1038876672,
|
||||||
|
"non_heap_used_in_bytes": 39634576,
|
||||||
|
"non_heap_committed_in_bytes": 40841216,
|
||||||
|
"pools": {
|
||||||
|
"young": {
|
||||||
|
"used_in_bytes": 32685760,
|
||||||
|
"max_in_bytes": 279183360,
|
||||||
|
"peak_used_in_bytes": 71630848,
|
||||||
|
"peak_max_in_bytes": 279183360
|
||||||
|
},
|
||||||
|
"survivor": {
|
||||||
|
"used_in_bytes": 8912880,
|
||||||
|
"max_in_bytes": 34865152,
|
||||||
|
"peak_used_in_bytes": 8912888,
|
||||||
|
"peak_max_in_bytes": 34865152
|
||||||
|
},
|
||||||
|
"old": {
|
||||||
|
"used_in_bytes": 11110928,
|
||||||
|
"max_in_bytes": 724828160,
|
||||||
|
"peak_used_in_bytes": 14354608,
|
||||||
|
"peak_max_in_bytes": 724828160
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"threads": {
|
||||||
|
"count": 44,
|
||||||
|
"peak_count": 45
|
||||||
|
},
|
||||||
|
"gc": {
|
||||||
|
"collectors": {
|
||||||
|
"young": {
|
||||||
|
"collection_count": 2,
|
||||||
|
"collection_time_in_millis": 98
|
||||||
|
},
|
||||||
|
"old": {
|
||||||
|
"collection_count": 1,
|
||||||
|
"collection_time_in_millis": 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buffer_pools": {
|
||||||
|
"direct": {
|
||||||
|
"count": 40,
|
||||||
|
"used_in_bytes": 6304239,
|
||||||
|
"total_capacity_in_bytes": 6304239
|
||||||
|
},
|
||||||
|
"mapped": {
|
||||||
|
"count": 0,
|
||||||
|
"used_in_bytes": 0,
|
||||||
|
"total_capacity_in_bytes": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"thread_pool": {
|
||||||
|
"percolate": {
|
||||||
|
"threads": 123,
|
||||||
|
"queue": 23,
|
||||||
|
"active": 13,
|
||||||
|
"rejected": 235,
|
||||||
|
"largest": 23,
|
||||||
|
"completed": 33
|
||||||
|
},
|
||||||
|
"fetch_shard_started": {
|
||||||
|
"threads": 3,
|
||||||
|
"queue": 1,
|
||||||
|
"active": 5,
|
||||||
|
"rejected": 6,
|
||||||
|
"largest": 4,
|
||||||
|
"completed": 54
|
||||||
|
},
|
||||||
|
"listener": {
|
||||||
|
"threads": 1,
|
||||||
|
"queue": 2,
|
||||||
|
"active": 4,
|
||||||
|
"rejected": 8,
|
||||||
|
"largest": 1,
|
||||||
|
"completed": 1
|
||||||
|
},
|
||||||
|
"index": {
|
||||||
|
"threads": 6,
|
||||||
|
"queue": 8,
|
||||||
|
"active": 4,
|
||||||
|
"rejected": 2,
|
||||||
|
"largest": 3,
|
||||||
|
"completed": 6
|
||||||
|
},
|
||||||
|
"refresh": {
|
||||||
|
"threads": 23,
|
||||||
|
"queue": 7,
|
||||||
|
"active": 3,
|
||||||
|
"rejected": 4,
|
||||||
|
"largest": 8,
|
||||||
|
"completed": 3
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"threads": 2,
|
||||||
|
"queue": 7,
|
||||||
|
"active": 2,
|
||||||
|
"rejected": 1,
|
||||||
|
"largest": 8,
|
||||||
|
"completed": 3
|
||||||
|
},
|
||||||
|
"generic": {
|
||||||
|
"threads": 1,
|
||||||
|
"queue": 4,
|
||||||
|
"active": 6,
|
||||||
|
"rejected": 3,
|
||||||
|
"largest": 2,
|
||||||
|
"completed": 27
|
||||||
|
},
|
||||||
|
"warmer": {
|
||||||
|
"threads": 2,
|
||||||
|
"queue": 7,
|
||||||
|
"active": 3,
|
||||||
|
"rejected": 2,
|
||||||
|
"largest": 3,
|
||||||
|
"completed": 1
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"threads": 5,
|
||||||
|
"queue": 7,
|
||||||
|
"active": 2,
|
||||||
|
"rejected": 7,
|
||||||
|
"largest": 2,
|
||||||
|
"completed": 4
|
||||||
|
},
|
||||||
|
"flush": {
|
||||||
|
"threads": 3,
|
||||||
|
"queue": 8,
|
||||||
|
"active": 0,
|
||||||
|
"rejected": 1,
|
||||||
|
"largest": 5,
|
||||||
|
"completed": 3
|
||||||
|
},
|
||||||
|
"optimize": {
|
||||||
|
"threads": 3,
|
||||||
|
"queue": 4,
|
||||||
|
"active": 1,
|
||||||
|
"rejected": 2,
|
||||||
|
"largest": 7,
|
||||||
|
"completed": 3
|
||||||
|
},
|
||||||
|
"fetch_shard_store": {
|
||||||
|
"threads": 1,
|
||||||
|
"queue": 7,
|
||||||
|
"active": 4,
|
||||||
|
"rejected": 2,
|
||||||
|
"largest": 4,
|
||||||
|
"completed": 1
|
||||||
|
},
|
||||||
|
"management": {
|
||||||
|
"threads": 2,
|
||||||
|
"queue": 3,
|
||||||
|
"active": 1,
|
||||||
|
"rejected": 6,
|
||||||
|
"largest": 2,
|
||||||
|
"completed": 22
|
||||||
|
},
|
||||||
|
"get": {
|
||||||
|
"threads": 1,
|
||||||
|
"queue": 8,
|
||||||
|
"active": 4,
|
||||||
|
"rejected": 3,
|
||||||
|
"largest": 2,
|
||||||
|
"completed": 1
|
||||||
|
},
|
||||||
|
"merge": {
|
||||||
|
"threads": 6,
|
||||||
|
"queue": 4,
|
||||||
|
"active": 5,
|
||||||
|
"rejected": 2,
|
||||||
|
"largest": 5,
|
||||||
|
"completed": 1
|
||||||
|
},
|
||||||
|
"bulk": {
|
||||||
|
"threads": 4,
|
||||||
|
"queue": 5,
|
||||||
|
"active": 7,
|
||||||
|
"rejected": 3,
|
||||||
|
"largest": 1,
|
||||||
|
"completed": 4
|
||||||
|
},
|
||||||
|
"snapshot": {
|
||||||
|
"threads": 8,
|
||||||
|
"queue": 5,
|
||||||
|
"active": 6,
|
||||||
|
"rejected": 2,
|
||||||
|
"largest": 1,
|
||||||
|
"completed": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fs": {
|
||||||
|
"timestamp": 1436460392946,
|
||||||
|
"total": {
|
||||||
|
"total_in_bytes": 19507089408,
|
||||||
|
"free_in_bytes": 16909316096,
|
||||||
|
"available_in_bytes": 15894814720
|
||||||
|
},
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"path": "/usr/share/elasticsearch/data/elasticsearch/nodes/0",
|
||||||
|
"mount": "/usr/share/elasticsearch/data",
|
||||||
|
"type": "ext4",
|
||||||
|
"total_in_bytes": 19507089408,
|
||||||
|
"free_in_bytes": 16909316096,
|
||||||
|
"available_in_bytes": 15894814720
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"transport": {
|
||||||
|
"server_open": 13,
|
||||||
|
"rx_count": 6,
|
||||||
|
"rx_size_in_bytes": 1380,
|
||||||
|
"tx_count": 6,
|
||||||
|
"tx_size_in_bytes": 1380
|
||||||
|
},
|
||||||
|
"http": {
|
||||||
|
"current_open": 3,
|
||||||
|
"total_opened": 3
|
||||||
|
},
|
||||||
|
"breakers": {
|
||||||
|
"fielddata": {
|
||||||
|
"limit_size_in_bytes": 623326003,
|
||||||
|
"limit_size": "594.4mb",
|
||||||
|
"estimated_size_in_bytes": 0,
|
||||||
|
"estimated_size": "0b",
|
||||||
|
"overhead": 1.03,
|
||||||
|
"tripped": 0
|
||||||
|
},
|
||||||
|
"request": {
|
||||||
|
"limit_size_in_bytes": 415550668,
|
||||||
|
"limit_size": "396.2mb",
|
||||||
|
"estimated_size_in_bytes": 0,
|
||||||
|
"estimated_size": "0b",
|
||||||
|
"overhead": 1.0,
|
||||||
|
"tripped": 0
|
||||||
|
},
|
||||||
|
"parent": {
|
||||||
|
"limit_size_in_bytes": 727213670,
|
||||||
|
"limit_size": "693.5mb",
|
||||||
|
"estimated_size_in_bytes": 0,
|
||||||
|
"estimated_size": "0b",
|
||||||
|
"overhead": 1.0,
|
||||||
|
"tripped": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
var indicesExpected = map[string]float64{
|
||||||
|
"indices_id_cache_memory_size_in_bytes": 0,
|
||||||
|
"indices_completion_size_in_bytes": 0,
|
||||||
|
"indices_suggest_total": 0,
|
||||||
|
"indices_suggest_time_in_millis": 0,
|
||||||
|
"indices_suggest_current": 0,
|
||||||
|
"indices_query_cache_memory_size_in_bytes": 0,
|
||||||
|
"indices_query_cache_evictions": 0,
|
||||||
|
"indices_query_cache_hit_count": 0,
|
||||||
|
"indices_query_cache_miss_count": 0,
|
||||||
|
"indices_store_size_in_bytes": 37715234,
|
||||||
|
"indices_store_throttle_time_in_millis": 215,
|
||||||
|
"indices_merges_current_docs": 0,
|
||||||
|
"indices_merges_current_size_in_bytes": 0,
|
||||||
|
"indices_merges_total": 133,
|
||||||
|
"indices_merges_total_time_in_millis": 21060,
|
||||||
|
"indices_merges_total_docs": 203672,
|
||||||
|
"indices_merges_total_size_in_bytes": 142900226,
|
||||||
|
"indices_merges_current": 0,
|
||||||
|
"indices_filter_cache_memory_size_in_bytes": 7384,
|
||||||
|
"indices_filter_cache_evictions": 0,
|
||||||
|
"indices_indexing_index_total": 84790,
|
||||||
|
"indices_indexing_index_time_in_millis": 29680,
|
||||||
|
"indices_indexing_index_current": 0,
|
||||||
|
"indices_indexing_noop_update_total": 0,
|
||||||
|
"indices_indexing_throttle_time_in_millis": 0,
|
||||||
|
"indices_indexing_delete_total": 13879,
|
||||||
|
"indices_indexing_delete_time_in_millis": 1139,
|
||||||
|
"indices_indexing_delete_current": 0,
|
||||||
|
"indices_get_exists_time_in_millis": 0,
|
||||||
|
"indices_get_missing_total": 1,
|
||||||
|
"indices_get_missing_time_in_millis": 2,
|
||||||
|
"indices_get_current": 0,
|
||||||
|
"indices_get_total": 1,
|
||||||
|
"indices_get_time_in_millis": 2,
|
||||||
|
"indices_get_exists_total": 0,
|
||||||
|
"indices_refresh_total": 1076,
|
||||||
|
"indices_refresh_total_time_in_millis": 20078,
|
||||||
|
"indices_percolate_current": 0,
|
||||||
|
"indices_percolate_memory_size_in_bytes": -1,
|
||||||
|
"indices_percolate_queries": 0,
|
||||||
|
"indices_percolate_total": 0,
|
||||||
|
"indices_percolate_time_in_millis": 0,
|
||||||
|
"indices_translog_operations": 17702,
|
||||||
|
"indices_translog_size_in_bytes": 17,
|
||||||
|
"indices_recovery_current_as_source": 0,
|
||||||
|
"indices_recovery_current_as_target": 0,
|
||||||
|
"indices_recovery_throttle_time_in_millis": 0,
|
||||||
|
"indices_docs_count": 29652,
|
||||||
|
"indices_docs_deleted": 5229,
|
||||||
|
"indices_flush_total_time_in_millis": 2401,
|
||||||
|
"indices_flush_total": 115,
|
||||||
|
"indices_fielddata_memory_size_in_bytes": 12996,
|
||||||
|
"indices_fielddata_evictions": 0,
|
||||||
|
"indices_search_fetch_current": 0,
|
||||||
|
"indices_search_open_contexts": 0,
|
||||||
|
"indices_search_query_total": 1452,
|
||||||
|
"indices_search_query_time_in_millis": 5695,
|
||||||
|
"indices_search_query_current": 0,
|
||||||
|
"indices_search_fetch_total": 414,
|
||||||
|
"indices_search_fetch_time_in_millis": 146,
|
||||||
|
"indices_warmer_current": 0,
|
||||||
|
"indices_warmer_total": 2319,
|
||||||
|
"indices_warmer_total_time_in_millis": 448,
|
||||||
|
"indices_segments_count": 134,
|
||||||
|
"indices_segments_memory_in_bytes": 1285212,
|
||||||
|
"indices_segments_index_writer_memory_in_bytes": 0,
|
||||||
|
"indices_segments_index_writer_max_memory_in_bytes": 172368955,
|
||||||
|
"indices_segments_version_map_memory_in_bytes": 611844,
|
||||||
|
"indices_segments_fixed_bit_set_memory_in_bytes": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
var osExpected = map[string]float64{
|
||||||
|
"os_swap_used_in_bytes": 0,
|
||||||
|
"os_swap_free_in_bytes": 487997440,
|
||||||
|
"os_timestamp": 1436460392944,
|
||||||
|
"os_mem_free_percent": 74,
|
||||||
|
"os_mem_used_percent": 25,
|
||||||
|
"os_mem_actual_free_in_bytes": 1565470720,
|
||||||
|
"os_mem_actual_used_in_bytes": 534159360,
|
||||||
|
"os_mem_free_in_bytes": 477761536,
|
||||||
|
"os_mem_used_in_bytes": 1621868544,
|
||||||
|
}
|
||||||
|
|
||||||
|
var processExpected = map[string]float64{
|
||||||
|
"process_mem_total_virtual_in_bytes": 4747890688,
|
||||||
|
"process_timestamp": 1436460392945,
|
||||||
|
"process_open_file_descriptors": 160,
|
||||||
|
"process_cpu_total_in_millis": 15480,
|
||||||
|
"process_cpu_percent": 2,
|
||||||
|
"process_cpu_sys_in_millis": 1870,
|
||||||
|
"process_cpu_user_in_millis": 13610,
|
||||||
|
}
|
||||||
|
|
||||||
|
var jvmExpected = map[string]float64{
|
||||||
|
"jvm_timestamp": 1436460392945,
|
||||||
|
"jvm_uptime_in_millis": 202245,
|
||||||
|
"jvm_mem_non_heap_used_in_bytes": 39634576,
|
||||||
|
"jvm_mem_non_heap_committed_in_bytes": 40841216,
|
||||||
|
"jvm_mem_pools_young_max_in_bytes": 279183360,
|
||||||
|
"jvm_mem_pools_young_peak_used_in_bytes": 71630848,
|
||||||
|
"jvm_mem_pools_young_peak_max_in_bytes": 279183360,
|
||||||
|
"jvm_mem_pools_young_used_in_bytes": 32685760,
|
||||||
|
"jvm_mem_pools_survivor_peak_used_in_bytes": 8912888,
|
||||||
|
"jvm_mem_pools_survivor_peak_max_in_bytes": 34865152,
|
||||||
|
"jvm_mem_pools_survivor_used_in_bytes": 8912880,
|
||||||
|
"jvm_mem_pools_survivor_max_in_bytes": 34865152,
|
||||||
|
"jvm_mem_pools_old_peak_max_in_bytes": 724828160,
|
||||||
|
"jvm_mem_pools_old_used_in_bytes": 11110928,
|
||||||
|
"jvm_mem_pools_old_max_in_bytes": 724828160,
|
||||||
|
"jvm_mem_pools_old_peak_used_in_bytes": 14354608,
|
||||||
|
"jvm_mem_heap_used_in_bytes": 52709568,
|
||||||
|
"jvm_mem_heap_used_percent": 5,
|
||||||
|
"jvm_mem_heap_committed_in_bytes": 259522560,
|
||||||
|
"jvm_mem_heap_max_in_bytes": 1038876672,
|
||||||
|
"jvm_threads_peak_count": 45,
|
||||||
|
"jvm_threads_count": 44,
|
||||||
|
"jvm_gc_collectors_young_collection_count": 2,
|
||||||
|
"jvm_gc_collectors_young_collection_time_in_millis": 98,
|
||||||
|
"jvm_gc_collectors_old_collection_count": 1,
|
||||||
|
"jvm_gc_collectors_old_collection_time_in_millis": 24,
|
||||||
|
"jvm_buffer_pools_direct_count": 40,
|
||||||
|
"jvm_buffer_pools_direct_used_in_bytes": 6304239,
|
||||||
|
"jvm_buffer_pools_direct_total_capacity_in_bytes": 6304239,
|
||||||
|
"jvm_buffer_pools_mapped_count": 0,
|
||||||
|
"jvm_buffer_pools_mapped_used_in_bytes": 0,
|
||||||
|
"jvm_buffer_pools_mapped_total_capacity_in_bytes": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
var threadPoolExpected = map[string]float64{
|
||||||
|
"thread_pool_merge_threads": 6,
|
||||||
|
"thread_pool_merge_queue": 4,
|
||||||
|
"thread_pool_merge_active": 5,
|
||||||
|
"thread_pool_merge_rejected": 2,
|
||||||
|
"thread_pool_merge_largest": 5,
|
||||||
|
"thread_pool_merge_completed": 1,
|
||||||
|
"thread_pool_bulk_threads": 4,
|
||||||
|
"thread_pool_bulk_queue": 5,
|
||||||
|
"thread_pool_bulk_active": 7,
|
||||||
|
"thread_pool_bulk_rejected": 3,
|
||||||
|
"thread_pool_bulk_largest": 1,
|
||||||
|
"thread_pool_bulk_completed": 4,
|
||||||
|
"thread_pool_warmer_threads": 2,
|
||||||
|
"thread_pool_warmer_queue": 7,
|
||||||
|
"thread_pool_warmer_active": 3,
|
||||||
|
"thread_pool_warmer_rejected": 2,
|
||||||
|
"thread_pool_warmer_largest": 3,
|
||||||
|
"thread_pool_warmer_completed": 1,
|
||||||
|
"thread_pool_get_largest": 2,
|
||||||
|
"thread_pool_get_completed": 1,
|
||||||
|
"thread_pool_get_threads": 1,
|
||||||
|
"thread_pool_get_queue": 8,
|
||||||
|
"thread_pool_get_active": 4,
|
||||||
|
"thread_pool_get_rejected": 3,
|
||||||
|
"thread_pool_index_threads": 6,
|
||||||
|
"thread_pool_index_queue": 8,
|
||||||
|
"thread_pool_index_active": 4,
|
||||||
|
"thread_pool_index_rejected": 2,
|
||||||
|
"thread_pool_index_largest": 3,
|
||||||
|
"thread_pool_index_completed": 6,
|
||||||
|
"thread_pool_suggest_threads": 2,
|
||||||
|
"thread_pool_suggest_queue": 7,
|
||||||
|
"thread_pool_suggest_active": 2,
|
||||||
|
"thread_pool_suggest_rejected": 1,
|
||||||
|
"thread_pool_suggest_largest": 8,
|
||||||
|
"thread_pool_suggest_completed": 3,
|
||||||
|
"thread_pool_fetch_shard_store_queue": 7,
|
||||||
|
"thread_pool_fetch_shard_store_active": 4,
|
||||||
|
"thread_pool_fetch_shard_store_rejected": 2,
|
||||||
|
"thread_pool_fetch_shard_store_largest": 4,
|
||||||
|
"thread_pool_fetch_shard_store_completed": 1,
|
||||||
|
"thread_pool_fetch_shard_store_threads": 1,
|
||||||
|
"thread_pool_management_threads": 2,
|
||||||
|
"thread_pool_management_queue": 3,
|
||||||
|
"thread_pool_management_active": 1,
|
||||||
|
"thread_pool_management_rejected": 6,
|
||||||
|
"thread_pool_management_largest": 2,
|
||||||
|
"thread_pool_management_completed": 22,
|
||||||
|
"thread_pool_percolate_queue": 23,
|
||||||
|
"thread_pool_percolate_active": 13,
|
||||||
|
"thread_pool_percolate_rejected": 235,
|
||||||
|
"thread_pool_percolate_largest": 23,
|
||||||
|
"thread_pool_percolate_completed": 33,
|
||||||
|
"thread_pool_percolate_threads": 123,
|
||||||
|
"thread_pool_listener_active": 4,
|
||||||
|
"thread_pool_listener_rejected": 8,
|
||||||
|
"thread_pool_listener_largest": 1,
|
||||||
|
"thread_pool_listener_completed": 1,
|
||||||
|
"thread_pool_listener_threads": 1,
|
||||||
|
"thread_pool_listener_queue": 2,
|
||||||
|
"thread_pool_search_rejected": 7,
|
||||||
|
"thread_pool_search_largest": 2,
|
||||||
|
"thread_pool_search_completed": 4,
|
||||||
|
"thread_pool_search_threads": 5,
|
||||||
|
"thread_pool_search_queue": 7,
|
||||||
|
"thread_pool_search_active": 2,
|
||||||
|
"thread_pool_fetch_shard_started_threads": 3,
|
||||||
|
"thread_pool_fetch_shard_started_queue": 1,
|
||||||
|
"thread_pool_fetch_shard_started_active": 5,
|
||||||
|
"thread_pool_fetch_shard_started_rejected": 6,
|
||||||
|
"thread_pool_fetch_shard_started_largest": 4,
|
||||||
|
"thread_pool_fetch_shard_started_completed": 54,
|
||||||
|
"thread_pool_refresh_rejected": 4,
|
||||||
|
"thread_pool_refresh_largest": 8,
|
||||||
|
"thread_pool_refresh_completed": 3,
|
||||||
|
"thread_pool_refresh_threads": 23,
|
||||||
|
"thread_pool_refresh_queue": 7,
|
||||||
|
"thread_pool_refresh_active": 3,
|
||||||
|
"thread_pool_optimize_threads": 3,
|
||||||
|
"thread_pool_optimize_queue": 4,
|
||||||
|
"thread_pool_optimize_active": 1,
|
||||||
|
"thread_pool_optimize_rejected": 2,
|
||||||
|
"thread_pool_optimize_largest": 7,
|
||||||
|
"thread_pool_optimize_completed": 3,
|
||||||
|
"thread_pool_snapshot_largest": 1,
|
||||||
|
"thread_pool_snapshot_completed": 0,
|
||||||
|
"thread_pool_snapshot_threads": 8,
|
||||||
|
"thread_pool_snapshot_queue": 5,
|
||||||
|
"thread_pool_snapshot_active": 6,
|
||||||
|
"thread_pool_snapshot_rejected": 2,
|
||||||
|
"thread_pool_generic_threads": 1,
|
||||||
|
"thread_pool_generic_queue": 4,
|
||||||
|
"thread_pool_generic_active": 6,
|
||||||
|
"thread_pool_generic_rejected": 3,
|
||||||
|
"thread_pool_generic_largest": 2,
|
||||||
|
"thread_pool_generic_completed": 27,
|
||||||
|
"thread_pool_flush_threads": 3,
|
||||||
|
"thread_pool_flush_queue": 8,
|
||||||
|
"thread_pool_flush_active": 0,
|
||||||
|
"thread_pool_flush_rejected": 1,
|
||||||
|
"thread_pool_flush_largest": 5,
|
||||||
|
"thread_pool_flush_completed": 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
var fsExpected = map[string]float64{
|
||||||
|
"fs_timestamp": 1436460392946,
|
||||||
|
"fs_total_free_in_bytes": 16909316096,
|
||||||
|
"fs_total_available_in_bytes": 15894814720,
|
||||||
|
"fs_total_total_in_bytes": 19507089408,
|
||||||
|
}
|
||||||
|
|
||||||
|
var transportExpected = map[string]float64{
|
||||||
|
"transport_server_open": 13,
|
||||||
|
"transport_rx_count": 6,
|
||||||
|
"transport_rx_size_in_bytes": 1380,
|
||||||
|
"transport_tx_count": 6,
|
||||||
|
"transport_tx_size_in_bytes": 1380,
|
||||||
|
}
|
||||||
|
|
||||||
|
var httpExpected = map[string]float64{
|
||||||
|
"http_current_open": 3,
|
||||||
|
"http_total_opened": 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
var breakersExpected = map[string]float64{
|
||||||
|
"breakers_fielddata_estimated_size_in_bytes": 0,
|
||||||
|
"breakers_fielddata_overhead": 1.03,
|
||||||
|
"breakers_fielddata_tripped": 0,
|
||||||
|
"breakers_fielddata_limit_size_in_bytes": 623326003,
|
||||||
|
"breakers_request_estimated_size_in_bytes": 0,
|
||||||
|
"breakers_request_overhead": 1.0,
|
||||||
|
"breakers_request_tripped": 0,
|
||||||
|
"breakers_request_limit_size_in_bytes": 415550668,
|
||||||
|
"breakers_parent_overhead": 1.0,
|
||||||
|
"breakers_parent_tripped": 0,
|
||||||
|
"breakers_parent_limit_size_in_bytes": 727213670,
|
||||||
|
"breakers_parent_estimated_size_in_bytes": 0,
|
||||||
|
}
|
||||||
@@ -9,19 +9,20 @@ import (
|
|||||||
"github.com/gonuts/go-shellquote"
|
"github.com/gonuts/go-shellquote"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/internal"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
)
|
)
|
||||||
|
|
||||||
const sampleConfig = `
|
const sampleConfig = `
|
||||||
# the command to run
|
# the command to run
|
||||||
command = "/usr/bin/mycollector --foo=bar"
|
command = "/usr/bin/mycollector --foo=bar"
|
||||||
|
|
||||||
# measurement name suffix (for separating different commands)
|
# name of the command (used as a prefix for measurements)
|
||||||
name_suffix = "_mycollector"
|
name = "mycollector"
|
||||||
`
|
`
|
||||||
|
|
||||||
type Exec struct {
|
type Exec struct {
|
||||||
Command string
|
Command string
|
||||||
|
Name string
|
||||||
|
|
||||||
runner Runner
|
runner Runner
|
||||||
}
|
}
|
||||||
@@ -61,7 +62,7 @@ func (e *Exec) Description() string {
|
|||||||
return "Read flattened metrics from one or more commands that output JSON to stdout"
|
return "Read flattened metrics from one or more commands that output JSON to stdout"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exec) Gather(acc inputs.Accumulator) error {
|
func (e *Exec) Gather(acc plugins.Accumulator) error {
|
||||||
out, err := e.runner.Run(e)
|
out, err := e.runner.Run(e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -80,12 +81,18 @@ func (e *Exec) Gather(acc inputs.Accumulator) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.AddFields("exec", f.Fields, nil)
|
var msrmnt_name string
|
||||||
|
if e.Name == "" {
|
||||||
|
msrmnt_name = "exec"
|
||||||
|
} else {
|
||||||
|
msrmnt_name = "exec_" + e.Name
|
||||||
|
}
|
||||||
|
acc.AddFields(msrmnt_name, f.Fields, nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("exec", func() inputs.Input {
|
plugins.Add("exec", func() plugins.Plugin {
|
||||||
return NewExec()
|
return NewExec()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
262
plugins/exec/exec_test.go
Normal file
262
plugins/exec/exec_test.go
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
package exec
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/influxdb/telegraf/testutil"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"math"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Midnight 9/22/2015
|
||||||
|
const baseTimeSeconds = 1442905200
|
||||||
|
|
||||||
|
const validJson = `
|
||||||
|
{
|
||||||
|
"status": "green",
|
||||||
|
"num_processes": 82,
|
||||||
|
"cpu": {
|
||||||
|
"status": "red",
|
||||||
|
"nil_status": null,
|
||||||
|
"used": 8234,
|
||||||
|
"free": 32
|
||||||
|
},
|
||||||
|
"percent": 0.81,
|
||||||
|
"users": [0, 1, 2, 3]
|
||||||
|
}`
|
||||||
|
|
||||||
|
const malformedJson = `
|
||||||
|
{
|
||||||
|
"status": "green",
|
||||||
|
`
|
||||||
|
|
||||||
|
type runnerMock struct {
|
||||||
|
out []byte
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
type clockMock struct {
|
||||||
|
now time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRunnerMock(out []byte, err error) Runner {
|
||||||
|
return &runnerMock{
|
||||||
|
out: out,
|
||||||
|
err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r runnerMock) Run(command *Command) ([]byte, error) {
|
||||||
|
if r.err != nil {
|
||||||
|
return nil, r.err
|
||||||
|
}
|
||||||
|
return r.out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newClockMock(now time.Time) Clock {
|
||||||
|
return &clockMock{now: now}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c clockMock) Now() time.Time {
|
||||||
|
return c.now
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExec(t *testing.T) {
|
||||||
|
runner := newRunnerMock([]byte(validJson), nil)
|
||||||
|
clock := newClockMock(time.Unix(baseTimeSeconds+20, 0))
|
||||||
|
command := Command{
|
||||||
|
Command: "testcommand arg1",
|
||||||
|
Name: "mycollector",
|
||||||
|
Interval: 10,
|
||||||
|
lastRunAt: time.Unix(baseTimeSeconds, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
e := &Exec{
|
||||||
|
runner: runner,
|
||||||
|
clock: clock,
|
||||||
|
Commands: []*Command{&command},
|
||||||
|
}
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
initialPoints := len(acc.Points)
|
||||||
|
err := e.Gather(&acc)
|
||||||
|
deltaPoints := len(acc.Points) - initialPoints
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
checkFloat := []struct {
|
||||||
|
name string
|
||||||
|
value float64
|
||||||
|
}{
|
||||||
|
{"mycollector_num_processes", 82},
|
||||||
|
{"mycollector_cpu_used", 8234},
|
||||||
|
{"mycollector_cpu_free", 32},
|
||||||
|
{"mycollector_percent", 0.81},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range checkFloat {
|
||||||
|
assert.True(t, acc.CheckValue(c.name, c.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, deltaPoints, 4, "non-numeric measurements should be ignored")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExecMalformed(t *testing.T) {
|
||||||
|
runner := newRunnerMock([]byte(malformedJson), nil)
|
||||||
|
clock := newClockMock(time.Unix(baseTimeSeconds+20, 0))
|
||||||
|
command := Command{
|
||||||
|
Command: "badcommand arg1",
|
||||||
|
Name: "mycollector",
|
||||||
|
Interval: 10,
|
||||||
|
lastRunAt: time.Unix(baseTimeSeconds, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
e := &Exec{
|
||||||
|
runner: runner,
|
||||||
|
clock: clock,
|
||||||
|
Commands: []*Command{&command},
|
||||||
|
}
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
initialPoints := len(acc.Points)
|
||||||
|
err := e.Gather(&acc)
|
||||||
|
deltaPoints := len(acc.Points) - initialPoints
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, deltaPoints, 0, "No new points should have been added")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommandError(t *testing.T) {
|
||||||
|
runner := newRunnerMock(nil, fmt.Errorf("exit status code 1"))
|
||||||
|
clock := newClockMock(time.Unix(baseTimeSeconds+20, 0))
|
||||||
|
command := Command{
|
||||||
|
Command: "badcommand",
|
||||||
|
Name: "mycollector",
|
||||||
|
Interval: 10,
|
||||||
|
lastRunAt: time.Unix(baseTimeSeconds, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
e := &Exec{
|
||||||
|
runner: runner,
|
||||||
|
clock: clock,
|
||||||
|
Commands: []*Command{&command},
|
||||||
|
}
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
initialPoints := len(acc.Points)
|
||||||
|
err := e.Gather(&acc)
|
||||||
|
deltaPoints := len(acc.Points) - initialPoints
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, deltaPoints, 0, "No new points should have been added")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExecNotEnoughTime(t *testing.T) {
|
||||||
|
runner := newRunnerMock([]byte(validJson), nil)
|
||||||
|
clock := newClockMock(time.Unix(baseTimeSeconds+5, 0))
|
||||||
|
command := Command{
|
||||||
|
Command: "testcommand arg1",
|
||||||
|
Name: "mycollector",
|
||||||
|
Interval: 10,
|
||||||
|
lastRunAt: time.Unix(baseTimeSeconds, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
e := &Exec{
|
||||||
|
runner: runner,
|
||||||
|
clock: clock,
|
||||||
|
Commands: []*Command{&command},
|
||||||
|
}
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
initialPoints := len(acc.Points)
|
||||||
|
err := e.Gather(&acc)
|
||||||
|
deltaPoints := len(acc.Points) - initialPoints
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, deltaPoints, 0, "No new points should have been added")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExecUninitializedLastRunAt(t *testing.T) {
|
||||||
|
runner := newRunnerMock([]byte(validJson), nil)
|
||||||
|
clock := newClockMock(time.Unix(baseTimeSeconds, 0))
|
||||||
|
command := Command{
|
||||||
|
Command: "testcommand arg1",
|
||||||
|
Name: "mycollector",
|
||||||
|
Interval: math.MaxInt32,
|
||||||
|
// Uninitialized lastRunAt should default to time.Unix(0, 0), so this should
|
||||||
|
// run no matter what the interval is
|
||||||
|
}
|
||||||
|
|
||||||
|
e := &Exec{
|
||||||
|
runner: runner,
|
||||||
|
clock: clock,
|
||||||
|
Commands: []*Command{&command},
|
||||||
|
}
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
initialPoints := len(acc.Points)
|
||||||
|
err := e.Gather(&acc)
|
||||||
|
deltaPoints := len(acc.Points) - initialPoints
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
checkFloat := []struct {
|
||||||
|
name string
|
||||||
|
value float64
|
||||||
|
}{
|
||||||
|
{"mycollector_num_processes", 82},
|
||||||
|
{"mycollector_cpu_used", 8234},
|
||||||
|
{"mycollector_cpu_free", 32},
|
||||||
|
{"mycollector_percent", 0.81},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range checkFloat {
|
||||||
|
assert.True(t, acc.CheckValue(c.name, c.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, deltaPoints, 4, "non-numeric measurements should be ignored")
|
||||||
|
}
|
||||||
|
func TestExecOneNotEnoughTimeAndOneEnoughTime(t *testing.T) {
|
||||||
|
runner := newRunnerMock([]byte(validJson), nil)
|
||||||
|
clock := newClockMock(time.Unix(baseTimeSeconds+5, 0))
|
||||||
|
notEnoughTimeCommand := Command{
|
||||||
|
Command: "testcommand arg1",
|
||||||
|
Name: "mycollector",
|
||||||
|
Interval: 10,
|
||||||
|
lastRunAt: time.Unix(baseTimeSeconds, 0),
|
||||||
|
}
|
||||||
|
enoughTimeCommand := Command{
|
||||||
|
Command: "testcommand arg1",
|
||||||
|
Name: "mycollector",
|
||||||
|
Interval: 3,
|
||||||
|
lastRunAt: time.Unix(baseTimeSeconds, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
e := &Exec{
|
||||||
|
runner: runner,
|
||||||
|
clock: clock,
|
||||||
|
Commands: []*Command{¬EnoughTimeCommand, &enoughTimeCommand},
|
||||||
|
}
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
initialPoints := len(acc.Points)
|
||||||
|
err := e.Gather(&acc)
|
||||||
|
deltaPoints := len(acc.Points) - initialPoints
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
checkFloat := []struct {
|
||||||
|
name string
|
||||||
|
value float64
|
||||||
|
}{
|
||||||
|
{"mycollector_num_processes", 82},
|
||||||
|
{"mycollector_cpu_used", 8234},
|
||||||
|
{"mycollector_cpu_free", 32},
|
||||||
|
{"mycollector_percent", 0.81},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range checkFloat {
|
||||||
|
assert.True(t, acc.CheckValue(c.name, c.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, deltaPoints, 4, "Only one command should have been run")
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ package haproxy
|
|||||||
import (
|
import (
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -91,7 +91,7 @@ var sampleConfig = `
|
|||||||
# If no servers are specified, then default to 127.0.0.1:1936
|
# If no servers are specified, then default to 127.0.0.1:1936
|
||||||
servers = ["http://myhaproxy.com:1936", "http://anotherhaproxy.com:1936"]
|
servers = ["http://myhaproxy.com:1936", "http://anotherhaproxy.com:1936"]
|
||||||
# Or you can also use local socket(not work yet)
|
# Or you can also use local socket(not work yet)
|
||||||
# servers = ["socket://run/haproxy/admin.sock"]
|
# servers = ["socket:/run/haproxy/admin.sock"]
|
||||||
`
|
`
|
||||||
|
|
||||||
func (r *haproxy) SampleConfig() string {
|
func (r *haproxy) SampleConfig() string {
|
||||||
@@ -104,7 +104,7 @@ func (r *haproxy) Description() string {
|
|||||||
|
|
||||||
// Reads stats from all configured servers accumulates stats.
|
// Reads stats from all configured servers accumulates stats.
|
||||||
// Returns one of the errors encountered while gather stats (if any).
|
// Returns one of the errors encountered while gather stats (if any).
|
||||||
func (g *haproxy) Gather(acc inputs.Accumulator) error {
|
func (g *haproxy) Gather(acc plugins.Accumulator) error {
|
||||||
if len(g.Servers) == 0 {
|
if len(g.Servers) == 0 {
|
||||||
return g.gatherServer("http://127.0.0.1:1936", acc)
|
return g.gatherServer("http://127.0.0.1:1936", acc)
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ func (g *haproxy) Gather(acc inputs.Accumulator) error {
|
|||||||
return outerr
|
return outerr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *haproxy) gatherServer(addr string, acc inputs.Accumulator) error {
|
func (g *haproxy) gatherServer(addr string, acc plugins.Accumulator) error {
|
||||||
if g.client == nil {
|
if g.client == nil {
|
||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
@@ -156,7 +156,7 @@ func (g *haproxy) gatherServer(addr string, acc inputs.Accumulator) error {
|
|||||||
return importCsvResult(res.Body, acc, u.Host)
|
return importCsvResult(res.Body, acc, u.Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
func importCsvResult(r io.Reader, acc inputs.Accumulator, host string) error {
|
func importCsvResult(r io.Reader, acc plugins.Accumulator, host string) error {
|
||||||
csv := csv.NewReader(r)
|
csv := csv.NewReader(r)
|
||||||
result, err := csv.ReadAll()
|
result, err := csv.ReadAll()
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@@ -358,7 +358,7 @@ func importCsvResult(r io.Reader, acc inputs.Accumulator, host string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("haproxy", func() inputs.Input {
|
plugins.Add("haproxy", func() plugins.Plugin {
|
||||||
return &haproxy{}
|
return &haproxy{}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -47,39 +47,52 @@ func TestHaproxyGeneratesMetricsWithAuthentication(t *testing.T) {
|
|||||||
"sv": "host0",
|
"sv": "host0",
|
||||||
}
|
}
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
assert.NoError(t, acc.ValidateTaggedValue("stot", uint64(171014), tags))
|
||||||
"active_servers": uint64(1),
|
|
||||||
"backup_servers": uint64(0),
|
checkInt := []struct {
|
||||||
"bin": uint64(510913516),
|
name string
|
||||||
"bout": uint64(2193856571),
|
value uint64
|
||||||
"check_duration": uint64(10),
|
}{
|
||||||
"cli_abort": uint64(73),
|
|
||||||
"ctime": uint64(2),
|
{"qmax", 81},
|
||||||
"downtime": uint64(0),
|
{"scur", 288},
|
||||||
"dresp": uint64(0),
|
{"smax", 713},
|
||||||
"econ": uint64(0),
|
{"bin", 5557055817},
|
||||||
"eresp": uint64(1),
|
{"bout", 24096715169},
|
||||||
"http_response.1xx": uint64(0),
|
{"dreq", 1102},
|
||||||
"http_response.2xx": uint64(119534),
|
{"dresp", 80},
|
||||||
"http_response.3xx": uint64(48051),
|
{"ereq", 95740},
|
||||||
"http_response.4xx": uint64(2345),
|
{"econ", 0},
|
||||||
"http_response.5xx": uint64(1056),
|
{"eresp", 0},
|
||||||
"lbtot": uint64(171013),
|
{"wretr", 17},
|
||||||
"qcur": uint64(0),
|
{"wredis", 19},
|
||||||
"qmax": uint64(0),
|
{"active_servers", 1},
|
||||||
"qtime": uint64(0),
|
{"backup_servers", 0},
|
||||||
"rate": uint64(3),
|
{"downtime", 0},
|
||||||
"rate_max": uint64(12),
|
{"throttle", 13},
|
||||||
"rtime": uint64(312),
|
{"lbtot", 114},
|
||||||
"scur": uint64(1),
|
{"rate", 18},
|
||||||
"smax": uint64(32),
|
{"rate_max", 102},
|
||||||
"srv_abort": uint64(1),
|
{"check_duration", 1},
|
||||||
"stot": uint64(171014),
|
{"http_response.1xx", 0},
|
||||||
"ttime": uint64(2341),
|
{"http_response.2xx", 1314093},
|
||||||
"wredis": uint64(0),
|
{"http_response.3xx", 537036},
|
||||||
"wretr": uint64(1),
|
{"http_response.4xx", 123452},
|
||||||
|
{"http_response.5xx", 11966},
|
||||||
|
{"req_rate", 35},
|
||||||
|
{"req_rate_max", 140},
|
||||||
|
{"req_tot", 1987928},
|
||||||
|
{"cli_abort", 0},
|
||||||
|
{"srv_abort", 0},
|
||||||
|
{"qtime", 0},
|
||||||
|
{"ctime", 2},
|
||||||
|
{"rtime", 23},
|
||||||
|
{"ttime", 545},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range checkInt {
|
||||||
|
assert.Equal(t, true, acc.CheckValue(c.name, c.value))
|
||||||
}
|
}
|
||||||
acc.AssertContainsTaggedFields(t, "haproxy", fields, tags)
|
|
||||||
|
|
||||||
//Here, we should get error because we don't pass authentication data
|
//Here, we should get error because we don't pass authentication data
|
||||||
r = &haproxy{
|
r = &haproxy{
|
||||||
@@ -111,39 +124,10 @@ func TestHaproxyGeneratesMetricsWithoutAuthentication(t *testing.T) {
|
|||||||
"sv": "host0",
|
"sv": "host0",
|
||||||
}
|
}
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
assert.NoError(t, acc.ValidateTaggedValue("stot", uint64(171014), tags))
|
||||||
"active_servers": uint64(1),
|
assert.NoError(t, acc.ValidateTaggedValue("scur", uint64(1), tags))
|
||||||
"backup_servers": uint64(0),
|
assert.NoError(t, acc.ValidateTaggedValue("rate", uint64(3), tags))
|
||||||
"bin": uint64(510913516),
|
assert.Equal(t, true, acc.CheckValue("bin", uint64(5557055817)))
|
||||||
"bout": uint64(2193856571),
|
|
||||||
"check_duration": uint64(10),
|
|
||||||
"cli_abort": uint64(73),
|
|
||||||
"ctime": uint64(2),
|
|
||||||
"downtime": uint64(0),
|
|
||||||
"dresp": uint64(0),
|
|
||||||
"econ": uint64(0),
|
|
||||||
"eresp": uint64(1),
|
|
||||||
"http_response.1xx": uint64(0),
|
|
||||||
"http_response.2xx": uint64(119534),
|
|
||||||
"http_response.3xx": uint64(48051),
|
|
||||||
"http_response.4xx": uint64(2345),
|
|
||||||
"http_response.5xx": uint64(1056),
|
|
||||||
"lbtot": uint64(171013),
|
|
||||||
"qcur": uint64(0),
|
|
||||||
"qmax": uint64(0),
|
|
||||||
"qtime": uint64(0),
|
|
||||||
"rate": uint64(3),
|
|
||||||
"rate_max": uint64(12),
|
|
||||||
"rtime": uint64(312),
|
|
||||||
"scur": uint64(1),
|
|
||||||
"smax": uint64(32),
|
|
||||||
"srv_abort": uint64(1),
|
|
||||||
"stot": uint64(171014),
|
|
||||||
"ttime": uint64(2341),
|
|
||||||
"wredis": uint64(0),
|
|
||||||
"wretr": uint64(1),
|
|
||||||
}
|
|
||||||
acc.AssertContainsTaggedFields(t, "haproxy", fields, tags)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//When not passing server config, we default to localhost
|
//When not passing server config, we default to localhost
|
||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/internal"
|
"github.com/influxdb/telegraf/internal"
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HttpJson struct {
|
type HttpJson struct {
|
||||||
@@ -63,7 +63,7 @@ var sampleConfig = `
|
|||||||
# ]
|
# ]
|
||||||
|
|
||||||
# HTTP parameters (all values must be strings)
|
# HTTP parameters (all values must be strings)
|
||||||
[inputs.httpjson.parameters]
|
[plugins.httpjson.parameters]
|
||||||
event_type = "cpu_spike"
|
event_type = "cpu_spike"
|
||||||
threshold = "0.75"
|
threshold = "0.75"
|
||||||
`
|
`
|
||||||
@@ -77,7 +77,7 @@ func (h *HttpJson) Description() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Gathers data for all servers.
|
// Gathers data for all servers.
|
||||||
func (h *HttpJson) Gather(acc inputs.Accumulator) error {
|
func (h *HttpJson) Gather(acc plugins.Accumulator) error {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
errorChannel := make(chan error, len(h.Servers))
|
errorChannel := make(chan error, len(h.Servers))
|
||||||
@@ -116,7 +116,7 @@ func (h *HttpJson) Gather(acc inputs.Accumulator) error {
|
|||||||
// Returns:
|
// Returns:
|
||||||
// error: Any error that may have occurred
|
// error: Any error that may have occurred
|
||||||
func (h *HttpJson) gatherServer(
|
func (h *HttpJson) gatherServer(
|
||||||
acc inputs.Accumulator,
|
acc plugins.Accumulator,
|
||||||
serverURL string,
|
serverURL string,
|
||||||
) error {
|
) error {
|
||||||
resp, err := h.sendRequest(serverURL)
|
resp, err := h.sendRequest(serverURL)
|
||||||
@@ -153,7 +153,7 @@ func (h *HttpJson) gatherServer(
|
|||||||
} else {
|
} else {
|
||||||
msrmnt_name = "httpjson_" + h.Name
|
msrmnt_name = "httpjson_" + h.Name
|
||||||
}
|
}
|
||||||
acc.AddFields(msrmnt_name, f.Fields, tags)
|
acc.AddFields(msrmnt_name, f.Fields, nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,6 +182,7 @@ func (h *HttpJson) sendRequest(serverURL string) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
defer req.Body.Close()
|
||||||
|
|
||||||
resp, err := h.client.MakeRequest(req)
|
resp, err := h.client.MakeRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -210,7 +211,7 @@ func (h *HttpJson) sendRequest(serverURL string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("httpjson", func() inputs.Input {
|
plugins.Add("httpjson", func() plugins.Plugin {
|
||||||
return &HttpJson{client: RealHTTPClient{client: &http.Client{}}}
|
return &HttpJson{client: RealHTTPClient{client: &http.Client{}}}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package httpjson
|
package httpjson
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -34,11 +35,6 @@ const validJSONTags = `
|
|||||||
"build": "123"
|
"build": "123"
|
||||||
}`
|
}`
|
||||||
|
|
||||||
var expectedFields = map[string]interface{}{
|
|
||||||
"parent_child": float64(3),
|
|
||||||
"integer": float64(4),
|
|
||||||
}
|
|
||||||
|
|
||||||
const invalidJSON = "I don't think this is JSON"
|
const invalidJSON = "I don't think this is JSON"
|
||||||
|
|
||||||
const empty = ""
|
const empty = ""
|
||||||
@@ -80,36 +76,37 @@ func (c mockHTTPClient) MakeRequest(req *http.Request) (*http.Response, error) {
|
|||||||
//
|
//
|
||||||
// Returns:
|
// Returns:
|
||||||
// *HttpJson: Pointer to an HttpJson object that uses the generated mock HTTP client
|
// *HttpJson: Pointer to an HttpJson object that uses the generated mock HTTP client
|
||||||
func genMockHttpJson(response string, statusCode int) []*HttpJson {
|
func genMockHttpJson(response string, statusCode int) *HttpJson {
|
||||||
return []*HttpJson{
|
return &HttpJson{
|
||||||
&HttpJson{
|
client: mockHTTPClient{responseBody: response, statusCode: statusCode},
|
||||||
client: mockHTTPClient{responseBody: response, statusCode: statusCode},
|
Services: []Service{
|
||||||
Servers: []string{
|
Service{
|
||||||
"http://server1.example.com/metrics/",
|
Servers: []string{
|
||||||
"http://server2.example.com/metrics/",
|
"http://server1.example.com/metrics/",
|
||||||
|
"http://server2.example.com/metrics/",
|
||||||
|
},
|
||||||
|
Name: "my_webapp",
|
||||||
|
Method: "GET",
|
||||||
|
Parameters: map[string]string{
|
||||||
|
"httpParam1": "12",
|
||||||
|
"httpParam2": "the second parameter",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Name: "my_webapp",
|
Service{
|
||||||
Method: "GET",
|
Servers: []string{
|
||||||
Parameters: map[string]string{
|
"http://server3.example.com/metrics/",
|
||||||
"httpParam1": "12",
|
"http://server4.example.com/metrics/",
|
||||||
"httpParam2": "the second parameter",
|
},
|
||||||
},
|
Name: "other_webapp",
|
||||||
},
|
Method: "POST",
|
||||||
&HttpJson{
|
Parameters: map[string]string{
|
||||||
client: mockHTTPClient{responseBody: response, statusCode: statusCode},
|
"httpParam1": "12",
|
||||||
Servers: []string{
|
"httpParam2": "the second parameter",
|
||||||
"http://server3.example.com/metrics/",
|
},
|
||||||
"http://server4.example.com/metrics/",
|
TagKeys: []string{
|
||||||
},
|
"role",
|
||||||
Name: "other_webapp",
|
"build",
|
||||||
Method: "POST",
|
},
|
||||||
Parameters: map[string]string{
|
|
||||||
"httpParam1": "12",
|
|
||||||
"httpParam2": "the second parameter",
|
|
||||||
},
|
|
||||||
TagKeys: []string{
|
|
||||||
"role",
|
|
||||||
"build",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -119,15 +116,28 @@ func genMockHttpJson(response string, statusCode int) []*HttpJson {
|
|||||||
func TestHttpJson200(t *testing.T) {
|
func TestHttpJson200(t *testing.T) {
|
||||||
httpjson := genMockHttpJson(validJSON, 200)
|
httpjson := genMockHttpJson(validJSON, 200)
|
||||||
|
|
||||||
for _, service := range httpjson {
|
var acc testutil.Accumulator
|
||||||
var acc testutil.Accumulator
|
err := httpjson.Gather(&acc)
|
||||||
err := service.Gather(&acc)
|
require.NoError(t, err)
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 4, acc.NFields())
|
assert.Equal(t, 8, len(acc.Points))
|
||||||
|
|
||||||
|
for _, service := range httpjson.Services {
|
||||||
for _, srv := range service.Servers {
|
for _, srv := range service.Servers {
|
||||||
tags := map[string]string{"server": srv}
|
require.NoError(t,
|
||||||
mname := "httpjson_" + service.Name
|
acc.ValidateTaggedValue(
|
||||||
acc.AssertContainsTaggedFields(t, mname, expectedFields, tags)
|
fmt.Sprintf("%s_parent_child", service.Name),
|
||||||
|
3.0,
|
||||||
|
map[string]string{"server": srv},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
require.NoError(t,
|
||||||
|
acc.ValidateTaggedValue(
|
||||||
|
fmt.Sprintf("%s_integer", service.Name),
|
||||||
|
4.0,
|
||||||
|
map[string]string{"server": srv},
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,22 +147,28 @@ func TestHttpJson500(t *testing.T) {
|
|||||||
httpjson := genMockHttpJson(validJSON, 500)
|
httpjson := genMockHttpJson(validJSON, 500)
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
err := httpjson[0].Gather(&acc)
|
err := httpjson.Gather(&acc)
|
||||||
|
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
assert.Equal(t, 0, acc.NFields())
|
// 4 error lines for (2 urls) * (2 services)
|
||||||
|
assert.Equal(t, len(strings.Split(err.Error(), "\n")), 4)
|
||||||
|
assert.Equal(t, 0, len(acc.Points))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test response to HTTP 405
|
// Test response to HTTP 405
|
||||||
func TestHttpJsonBadMethod(t *testing.T) {
|
func TestHttpJsonBadMethod(t *testing.T) {
|
||||||
httpjson := genMockHttpJson(validJSON, 200)
|
httpjson := genMockHttpJson(validJSON, 200)
|
||||||
httpjson[0].Method = "NOT_A_REAL_METHOD"
|
httpjson.Services[0].Method = "NOT_A_REAL_METHOD"
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
err := httpjson[0].Gather(&acc)
|
err := httpjson.Gather(&acc)
|
||||||
|
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
assert.Equal(t, 0, acc.NFields())
|
// 2 error lines for (2 urls) * (1 falied service)
|
||||||
|
assert.Equal(t, len(strings.Split(err.Error(), "\n")), 2)
|
||||||
|
|
||||||
|
// (2 measurements) * (2 servers) * (1 successful service)
|
||||||
|
assert.Equal(t, 4, len(acc.Points))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test response to malformed JSON
|
// Test response to malformed JSON
|
||||||
@@ -160,10 +176,12 @@ func TestHttpJsonBadJson(t *testing.T) {
|
|||||||
httpjson := genMockHttpJson(invalidJSON, 200)
|
httpjson := genMockHttpJson(invalidJSON, 200)
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
err := httpjson[0].Gather(&acc)
|
err := httpjson.Gather(&acc)
|
||||||
|
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
assert.Equal(t, 0, acc.NFields())
|
// 4 error lines for (2 urls) * (2 services)
|
||||||
|
assert.Equal(t, len(strings.Split(err.Error(), "\n")), 4)
|
||||||
|
assert.Equal(t, 0, len(acc.Points))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test response to empty string as response objectgT
|
// Test response to empty string as response objectgT
|
||||||
@@ -171,27 +189,34 @@ func TestHttpJsonEmptyResponse(t *testing.T) {
|
|||||||
httpjson := genMockHttpJson(empty, 200)
|
httpjson := genMockHttpJson(empty, 200)
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
err := httpjson[0].Gather(&acc)
|
err := httpjson.Gather(&acc)
|
||||||
|
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
assert.Equal(t, 0, acc.NFields())
|
// 4 error lines for (2 urls) * (2 services)
|
||||||
|
assert.Equal(t, len(strings.Split(err.Error(), "\n")), 4)
|
||||||
|
assert.Equal(t, 0, len(acc.Points))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that the proper values are ignored or collected
|
// Test that the proper values are ignored or collected
|
||||||
func TestHttpJson200Tags(t *testing.T) {
|
func TestHttpJson200Tags(t *testing.T) {
|
||||||
httpjson := genMockHttpJson(validJSONTags, 200)
|
httpjson := genMockHttpJson(validJSONTags, 200)
|
||||||
|
|
||||||
for _, service := range httpjson {
|
var acc testutil.Accumulator
|
||||||
|
err := httpjson.Gather(&acc)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, 4, len(acc.Points))
|
||||||
|
|
||||||
|
for _, service := range httpjson.Services {
|
||||||
if service.Name == "other_webapp" {
|
if service.Name == "other_webapp" {
|
||||||
var acc testutil.Accumulator
|
|
||||||
err := service.Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 2, acc.NFields())
|
|
||||||
for _, srv := range service.Servers {
|
for _, srv := range service.Servers {
|
||||||
tags := map[string]string{"server": srv, "role": "master", "build": "123"}
|
require.NoError(t,
|
||||||
fields := map[string]interface{}{"value": float64(15)}
|
acc.ValidateTaggedValue(
|
||||||
mname := "httpjson_" + service.Name
|
fmt.Sprintf("%s_value", service.Name),
|
||||||
acc.AssertContainsTaggedFields(t, mname, fields, tags)
|
15.0,
|
||||||
|
map[string]string{"server": srv, "role": "master", "build": "123"},
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ The influxdb plugin collects InfluxDB-formatted data from JSON endpoints.
|
|||||||
With a configuration of:
|
With a configuration of:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[[inputs.influxdb]]
|
[[plugins.influxdb]]
|
||||||
urls = [
|
urls = [
|
||||||
"http://127.0.0.1:8086/debug/vars",
|
"http://127.0.0.1:8086/debug/vars",
|
||||||
"http://192.168.2.1:8086/debug/vars"
|
"http://192.168.2.1:8086/debug/vars"
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
)
|
)
|
||||||
|
|
||||||
type InfluxDB struct {
|
type InfluxDB struct {
|
||||||
@@ -32,7 +32,7 @@ func (*InfluxDB) SampleConfig() string {
|
|||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *InfluxDB) Gather(acc inputs.Accumulator) error {
|
func (i *InfluxDB) Gather(acc plugins.Accumulator) error {
|
||||||
errorChannel := make(chan error, len(i.URLs))
|
errorChannel := make(chan error, len(i.URLs))
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
@@ -77,7 +77,7 @@ type point struct {
|
|||||||
// Returns:
|
// Returns:
|
||||||
// error: Any error that may have occurred
|
// error: Any error that may have occurred
|
||||||
func (i *InfluxDB) gatherURL(
|
func (i *InfluxDB) gatherURL(
|
||||||
acc inputs.Accumulator,
|
acc plugins.Accumulator,
|
||||||
url string,
|
url string,
|
||||||
) error {
|
) error {
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
@@ -140,7 +140,7 @@ func (i *InfluxDB) gatherURL(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("influxdb", func() inputs.Input {
|
plugins.Add("influxdb", func() plugins.Plugin {
|
||||||
return &InfluxDB{}
|
return &InfluxDB{}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/plugins/inputs/influxdb"
|
"github.com/influxdb/telegraf/plugins/influxdb"
|
||||||
"github.com/influxdb/telegraf/testutil"
|
"github.com/influxdb/telegraf/testutil"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@@ -72,26 +72,29 @@ func TestBasic(t *testing.T) {
|
|||||||
require.NoError(t, plugin.Gather(&acc))
|
require.NoError(t, plugin.Gather(&acc))
|
||||||
|
|
||||||
require.Len(t, acc.Points, 2)
|
require.Len(t, acc.Points, 2)
|
||||||
fields := map[string]interface{}{
|
require.NoError(t, acc.ValidateTaggedFieldsValue(
|
||||||
// JSON will truncate floats to integer representations.
|
"foo",
|
||||||
// Since there's no distinction in JSON, we can't assume it's an int.
|
map[string]interface{}{
|
||||||
"i": -1.0,
|
// JSON will truncate floats to integer representations.
|
||||||
"f": 0.5,
|
// Since there's no distinction in JSON, we can't assume it's an int.
|
||||||
"b": true,
|
"i": -1.0,
|
||||||
"s": "string",
|
"f": 0.5,
|
||||||
}
|
"b": true,
|
||||||
tags := map[string]string{
|
"s": "string",
|
||||||
"id": "ex1",
|
},
|
||||||
"url": fakeServer.URL + "/endpoint",
|
map[string]string{
|
||||||
}
|
"id": "ex1",
|
||||||
acc.AssertContainsTaggedFields(t, "foo", fields, tags)
|
"url": fakeServer.URL + "/endpoint",
|
||||||
|
},
|
||||||
fields = map[string]interface{}{
|
))
|
||||||
"x": "x",
|
require.NoError(t, acc.ValidateTaggedFieldsValue(
|
||||||
}
|
"bar",
|
||||||
tags = map[string]string{
|
map[string]interface{}{
|
||||||
"id": "ex2",
|
"x": "x",
|
||||||
"url": fakeServer.URL + "/endpoint",
|
},
|
||||||
}
|
map[string]string{
|
||||||
acc.AssertContainsTaggedFields(t, "bar", fields, tags)
|
"id": "ex2",
|
||||||
|
"url": fakeServer.URL + "/endpoint",
|
||||||
|
},
|
||||||
|
))
|
||||||
}
|
}
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package all
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/aerospike"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/apache"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/bcache"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/disque"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/elasticsearch"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/exec"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/haproxy"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/httpjson"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/influxdb"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/jolokia"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/kafka_consumer"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/leofs"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/lustre2"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/mailchimp"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/memcached"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/mongodb"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/mysql"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/nginx"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/phpfpm"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/ping"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/postgresql"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/procstat"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/prometheus"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/puppetagent"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/rabbitmq"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/redis"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/rethinkdb"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/statsd"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/system"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/trig"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/twemproxy"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/zfs"
|
|
||||||
_ "github.com/influxdb/telegraf/plugins/inputs/zookeeper"
|
|
||||||
)
|
|
||||||
@@ -1,759 +0,0 @@
|
|||||||
package elasticsearch
|
|
||||||
|
|
||||||
const clusterResponse = `
|
|
||||||
{
|
|
||||||
"cluster_name": "elasticsearch_telegraf",
|
|
||||||
"status": "green",
|
|
||||||
"timed_out": false,
|
|
||||||
"number_of_nodes": 3,
|
|
||||||
"number_of_data_nodes": 3,
|
|
||||||
"active_primary_shards": 5,
|
|
||||||
"active_shards": 15,
|
|
||||||
"relocating_shards": 0,
|
|
||||||
"initializing_shards": 0,
|
|
||||||
"unassigned_shards": 0,
|
|
||||||
"indices": {
|
|
||||||
"v1": {
|
|
||||||
"status": "green",
|
|
||||||
"number_of_shards": 10,
|
|
||||||
"number_of_replicas": 1,
|
|
||||||
"active_primary_shards": 10,
|
|
||||||
"active_shards": 20,
|
|
||||||
"relocating_shards": 0,
|
|
||||||
"initializing_shards": 0,
|
|
||||||
"unassigned_shards": 0
|
|
||||||
},
|
|
||||||
"v2": {
|
|
||||||
"status": "red",
|
|
||||||
"number_of_shards": 10,
|
|
||||||
"number_of_replicas": 1,
|
|
||||||
"active_primary_shards": 0,
|
|
||||||
"active_shards": 0,
|
|
||||||
"relocating_shards": 0,
|
|
||||||
"initializing_shards": 0,
|
|
||||||
"unassigned_shards": 20
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
var clusterHealthExpected = map[string]interface{}{
|
|
||||||
"status": "green",
|
|
||||||
"timed_out": false,
|
|
||||||
"number_of_nodes": 3,
|
|
||||||
"number_of_data_nodes": 3,
|
|
||||||
"active_primary_shards": 5,
|
|
||||||
"active_shards": 15,
|
|
||||||
"relocating_shards": 0,
|
|
||||||
"initializing_shards": 0,
|
|
||||||
"unassigned_shards": 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
var v1IndexExpected = map[string]interface{}{
|
|
||||||
"status": "green",
|
|
||||||
"number_of_shards": 10,
|
|
||||||
"number_of_replicas": 1,
|
|
||||||
"active_primary_shards": 10,
|
|
||||||
"active_shards": 20,
|
|
||||||
"relocating_shards": 0,
|
|
||||||
"initializing_shards": 0,
|
|
||||||
"unassigned_shards": 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
var v2IndexExpected = map[string]interface{}{
|
|
||||||
"status": "red",
|
|
||||||
"number_of_shards": 10,
|
|
||||||
"number_of_replicas": 1,
|
|
||||||
"active_primary_shards": 0,
|
|
||||||
"active_shards": 0,
|
|
||||||
"relocating_shards": 0,
|
|
||||||
"initializing_shards": 0,
|
|
||||||
"unassigned_shards": 20,
|
|
||||||
}
|
|
||||||
|
|
||||||
const statsResponse = `
|
|
||||||
{
|
|
||||||
"cluster_name": "es-testcluster",
|
|
||||||
"nodes": {
|
|
||||||
"SDFsfSDFsdfFSDSDfSFDSDF": {
|
|
||||||
"timestamp": 1436365550135,
|
|
||||||
"name": "test.host.com",
|
|
||||||
"transport_address": "inet[/127.0.0.1:9300]",
|
|
||||||
"host": "test",
|
|
||||||
"ip": [
|
|
||||||
"inet[/127.0.0.1:9300]",
|
|
||||||
"NONE"
|
|
||||||
],
|
|
||||||
"attributes": {
|
|
||||||
"master": "true"
|
|
||||||
},
|
|
||||||
"indices": {
|
|
||||||
"docs": {
|
|
||||||
"count": 29652,
|
|
||||||
"deleted": 5229
|
|
||||||
},
|
|
||||||
"store": {
|
|
||||||
"size_in_bytes": 37715234,
|
|
||||||
"throttle_time_in_millis": 215
|
|
||||||
},
|
|
||||||
"indexing": {
|
|
||||||
"index_total": 84790,
|
|
||||||
"index_time_in_millis": 29680,
|
|
||||||
"index_current": 0,
|
|
||||||
"delete_total": 13879,
|
|
||||||
"delete_time_in_millis": 1139,
|
|
||||||
"delete_current": 0,
|
|
||||||
"noop_update_total": 0,
|
|
||||||
"is_throttled": false,
|
|
||||||
"throttle_time_in_millis": 0
|
|
||||||
},
|
|
||||||
"get": {
|
|
||||||
"total": 1,
|
|
||||||
"time_in_millis": 2,
|
|
||||||
"exists_total": 0,
|
|
||||||
"exists_time_in_millis": 0,
|
|
||||||
"missing_total": 1,
|
|
||||||
"missing_time_in_millis": 2,
|
|
||||||
"current": 0
|
|
||||||
},
|
|
||||||
"search": {
|
|
||||||
"open_contexts": 0,
|
|
||||||
"query_total": 1452,
|
|
||||||
"query_time_in_millis": 5695,
|
|
||||||
"query_current": 0,
|
|
||||||
"fetch_total": 414,
|
|
||||||
"fetch_time_in_millis": 146,
|
|
||||||
"fetch_current": 0
|
|
||||||
},
|
|
||||||
"merges": {
|
|
||||||
"current": 0,
|
|
||||||
"current_docs": 0,
|
|
||||||
"current_size_in_bytes": 0,
|
|
||||||
"total": 133,
|
|
||||||
"total_time_in_millis": 21060,
|
|
||||||
"total_docs": 203672,
|
|
||||||
"total_size_in_bytes": 142900226
|
|
||||||
},
|
|
||||||
"refresh": {
|
|
||||||
"total": 1076,
|
|
||||||
"total_time_in_millis": 20078
|
|
||||||
},
|
|
||||||
"flush": {
|
|
||||||
"total": 115,
|
|
||||||
"total_time_in_millis": 2401
|
|
||||||
},
|
|
||||||
"warmer": {
|
|
||||||
"current": 0,
|
|
||||||
"total": 2319,
|
|
||||||
"total_time_in_millis": 448
|
|
||||||
},
|
|
||||||
"filter_cache": {
|
|
||||||
"memory_size_in_bytes": 7384,
|
|
||||||
"evictions": 0
|
|
||||||
},
|
|
||||||
"id_cache": {
|
|
||||||
"memory_size_in_bytes": 0
|
|
||||||
},
|
|
||||||
"fielddata": {
|
|
||||||
"memory_size_in_bytes": 12996,
|
|
||||||
"evictions": 0
|
|
||||||
},
|
|
||||||
"percolate": {
|
|
||||||
"total": 0,
|
|
||||||
"time_in_millis": 0,
|
|
||||||
"current": 0,
|
|
||||||
"memory_size_in_bytes": -1,
|
|
||||||
"memory_size": "-1b",
|
|
||||||
"queries": 0
|
|
||||||
},
|
|
||||||
"completion": {
|
|
||||||
"size_in_bytes": 0
|
|
||||||
},
|
|
||||||
"segments": {
|
|
||||||
"count": 134,
|
|
||||||
"memory_in_bytes": 1285212,
|
|
||||||
"index_writer_memory_in_bytes": 0,
|
|
||||||
"index_writer_max_memory_in_bytes": 172368955,
|
|
||||||
"version_map_memory_in_bytes": 611844,
|
|
||||||
"fixed_bit_set_memory_in_bytes": 0
|
|
||||||
},
|
|
||||||
"translog": {
|
|
||||||
"operations": 17702,
|
|
||||||
"size_in_bytes": 17
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"total": 0,
|
|
||||||
"time_in_millis": 0,
|
|
||||||
"current": 0
|
|
||||||
},
|
|
||||||
"query_cache": {
|
|
||||||
"memory_size_in_bytes": 0,
|
|
||||||
"evictions": 0,
|
|
||||||
"hit_count": 0,
|
|
||||||
"miss_count": 0
|
|
||||||
},
|
|
||||||
"recovery": {
|
|
||||||
"current_as_source": 0,
|
|
||||||
"current_as_target": 0,
|
|
||||||
"throttle_time_in_millis": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"os": {
|
|
||||||
"timestamp": 1436460392944,
|
|
||||||
"load_average": [
|
|
||||||
0.01,
|
|
||||||
0.04,
|
|
||||||
0.05
|
|
||||||
],
|
|
||||||
"mem": {
|
|
||||||
"free_in_bytes": 477761536,
|
|
||||||
"used_in_bytes": 1621868544,
|
|
||||||
"free_percent": 74,
|
|
||||||
"used_percent": 25,
|
|
||||||
"actual_free_in_bytes": 1565470720,
|
|
||||||
"actual_used_in_bytes": 534159360
|
|
||||||
},
|
|
||||||
"swap": {
|
|
||||||
"used_in_bytes": 0,
|
|
||||||
"free_in_bytes": 487997440
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"process": {
|
|
||||||
"timestamp": 1436460392945,
|
|
||||||
"open_file_descriptors": 160,
|
|
||||||
"cpu": {
|
|
||||||
"percent": 2,
|
|
||||||
"sys_in_millis": 1870,
|
|
||||||
"user_in_millis": 13610,
|
|
||||||
"total_in_millis": 15480
|
|
||||||
},
|
|
||||||
"mem": {
|
|
||||||
"total_virtual_in_bytes": 4747890688
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"jvm": {
|
|
||||||
"timestamp": 1436460392945,
|
|
||||||
"uptime_in_millis": 202245,
|
|
||||||
"mem": {
|
|
||||||
"heap_used_in_bytes": 52709568,
|
|
||||||
"heap_used_percent": 5,
|
|
||||||
"heap_committed_in_bytes": 259522560,
|
|
||||||
"heap_max_in_bytes": 1038876672,
|
|
||||||
"non_heap_used_in_bytes": 39634576,
|
|
||||||
"non_heap_committed_in_bytes": 40841216,
|
|
||||||
"pools": {
|
|
||||||
"young": {
|
|
||||||
"used_in_bytes": 32685760,
|
|
||||||
"max_in_bytes": 279183360,
|
|
||||||
"peak_used_in_bytes": 71630848,
|
|
||||||
"peak_max_in_bytes": 279183360
|
|
||||||
},
|
|
||||||
"survivor": {
|
|
||||||
"used_in_bytes": 8912880,
|
|
||||||
"max_in_bytes": 34865152,
|
|
||||||
"peak_used_in_bytes": 8912888,
|
|
||||||
"peak_max_in_bytes": 34865152
|
|
||||||
},
|
|
||||||
"old": {
|
|
||||||
"used_in_bytes": 11110928,
|
|
||||||
"max_in_bytes": 724828160,
|
|
||||||
"peak_used_in_bytes": 14354608,
|
|
||||||
"peak_max_in_bytes": 724828160
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"threads": {
|
|
||||||
"count": 44,
|
|
||||||
"peak_count": 45
|
|
||||||
},
|
|
||||||
"gc": {
|
|
||||||
"collectors": {
|
|
||||||
"young": {
|
|
||||||
"collection_count": 2,
|
|
||||||
"collection_time_in_millis": 98
|
|
||||||
},
|
|
||||||
"old": {
|
|
||||||
"collection_count": 1,
|
|
||||||
"collection_time_in_millis": 24
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"buffer_pools": {
|
|
||||||
"direct": {
|
|
||||||
"count": 40,
|
|
||||||
"used_in_bytes": 6304239,
|
|
||||||
"total_capacity_in_bytes": 6304239
|
|
||||||
},
|
|
||||||
"mapped": {
|
|
||||||
"count": 0,
|
|
||||||
"used_in_bytes": 0,
|
|
||||||
"total_capacity_in_bytes": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"thread_pool": {
|
|
||||||
"percolate": {
|
|
||||||
"threads": 123,
|
|
||||||
"queue": 23,
|
|
||||||
"active": 13,
|
|
||||||
"rejected": 235,
|
|
||||||
"largest": 23,
|
|
||||||
"completed": 33
|
|
||||||
},
|
|
||||||
"fetch_shard_started": {
|
|
||||||
"threads": 3,
|
|
||||||
"queue": 1,
|
|
||||||
"active": 5,
|
|
||||||
"rejected": 6,
|
|
||||||
"largest": 4,
|
|
||||||
"completed": 54
|
|
||||||
},
|
|
||||||
"listener": {
|
|
||||||
"threads": 1,
|
|
||||||
"queue": 2,
|
|
||||||
"active": 4,
|
|
||||||
"rejected": 8,
|
|
||||||
"largest": 1,
|
|
||||||
"completed": 1
|
|
||||||
},
|
|
||||||
"index": {
|
|
||||||
"threads": 6,
|
|
||||||
"queue": 8,
|
|
||||||
"active": 4,
|
|
||||||
"rejected": 2,
|
|
||||||
"largest": 3,
|
|
||||||
"completed": 6
|
|
||||||
},
|
|
||||||
"refresh": {
|
|
||||||
"threads": 23,
|
|
||||||
"queue": 7,
|
|
||||||
"active": 3,
|
|
||||||
"rejected": 4,
|
|
||||||
"largest": 8,
|
|
||||||
"completed": 3
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"threads": 2,
|
|
||||||
"queue": 7,
|
|
||||||
"active": 2,
|
|
||||||
"rejected": 1,
|
|
||||||
"largest": 8,
|
|
||||||
"completed": 3
|
|
||||||
},
|
|
||||||
"generic": {
|
|
||||||
"threads": 1,
|
|
||||||
"queue": 4,
|
|
||||||
"active": 6,
|
|
||||||
"rejected": 3,
|
|
||||||
"largest": 2,
|
|
||||||
"completed": 27
|
|
||||||
},
|
|
||||||
"warmer": {
|
|
||||||
"threads": 2,
|
|
||||||
"queue": 7,
|
|
||||||
"active": 3,
|
|
||||||
"rejected": 2,
|
|
||||||
"largest": 3,
|
|
||||||
"completed": 1
|
|
||||||
},
|
|
||||||
"search": {
|
|
||||||
"threads": 5,
|
|
||||||
"queue": 7,
|
|
||||||
"active": 2,
|
|
||||||
"rejected": 7,
|
|
||||||
"largest": 2,
|
|
||||||
"completed": 4
|
|
||||||
},
|
|
||||||
"flush": {
|
|
||||||
"threads": 3,
|
|
||||||
"queue": 8,
|
|
||||||
"active": 0,
|
|
||||||
"rejected": 1,
|
|
||||||
"largest": 5,
|
|
||||||
"completed": 3
|
|
||||||
},
|
|
||||||
"optimize": {
|
|
||||||
"threads": 3,
|
|
||||||
"queue": 4,
|
|
||||||
"active": 1,
|
|
||||||
"rejected": 2,
|
|
||||||
"largest": 7,
|
|
||||||
"completed": 3
|
|
||||||
},
|
|
||||||
"fetch_shard_store": {
|
|
||||||
"threads": 1,
|
|
||||||
"queue": 7,
|
|
||||||
"active": 4,
|
|
||||||
"rejected": 2,
|
|
||||||
"largest": 4,
|
|
||||||
"completed": 1
|
|
||||||
},
|
|
||||||
"management": {
|
|
||||||
"threads": 2,
|
|
||||||
"queue": 3,
|
|
||||||
"active": 1,
|
|
||||||
"rejected": 6,
|
|
||||||
"largest": 2,
|
|
||||||
"completed": 22
|
|
||||||
},
|
|
||||||
"get": {
|
|
||||||
"threads": 1,
|
|
||||||
"queue": 8,
|
|
||||||
"active": 4,
|
|
||||||
"rejected": 3,
|
|
||||||
"largest": 2,
|
|
||||||
"completed": 1
|
|
||||||
},
|
|
||||||
"merge": {
|
|
||||||
"threads": 6,
|
|
||||||
"queue": 4,
|
|
||||||
"active": 5,
|
|
||||||
"rejected": 2,
|
|
||||||
"largest": 5,
|
|
||||||
"completed": 1
|
|
||||||
},
|
|
||||||
"bulk": {
|
|
||||||
"threads": 4,
|
|
||||||
"queue": 5,
|
|
||||||
"active": 7,
|
|
||||||
"rejected": 3,
|
|
||||||
"largest": 1,
|
|
||||||
"completed": 4
|
|
||||||
},
|
|
||||||
"snapshot": {
|
|
||||||
"threads": 8,
|
|
||||||
"queue": 5,
|
|
||||||
"active": 6,
|
|
||||||
"rejected": 2,
|
|
||||||
"largest": 1,
|
|
||||||
"completed": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fs": {
|
|
||||||
"timestamp": 1436460392946,
|
|
||||||
"total": {
|
|
||||||
"total_in_bytes": 19507089408,
|
|
||||||
"free_in_bytes": 16909316096,
|
|
||||||
"available_in_bytes": 15894814720
|
|
||||||
},
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"path": "/usr/share/elasticsearch/data/elasticsearch/nodes/0",
|
|
||||||
"mount": "/usr/share/elasticsearch/data",
|
|
||||||
"type": "ext4",
|
|
||||||
"total_in_bytes": 19507089408,
|
|
||||||
"free_in_bytes": 16909316096,
|
|
||||||
"available_in_bytes": 15894814720
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"transport": {
|
|
||||||
"server_open": 13,
|
|
||||||
"rx_count": 6,
|
|
||||||
"rx_size_in_bytes": 1380,
|
|
||||||
"tx_count": 6,
|
|
||||||
"tx_size_in_bytes": 1380
|
|
||||||
},
|
|
||||||
"http": {
|
|
||||||
"current_open": 3,
|
|
||||||
"total_opened": 3
|
|
||||||
},
|
|
||||||
"breakers": {
|
|
||||||
"fielddata": {
|
|
||||||
"limit_size_in_bytes": 623326003,
|
|
||||||
"limit_size": "594.4mb",
|
|
||||||
"estimated_size_in_bytes": 0,
|
|
||||||
"estimated_size": "0b",
|
|
||||||
"overhead": 1.03,
|
|
||||||
"tripped": 0
|
|
||||||
},
|
|
||||||
"request": {
|
|
||||||
"limit_size_in_bytes": 415550668,
|
|
||||||
"limit_size": "396.2mb",
|
|
||||||
"estimated_size_in_bytes": 0,
|
|
||||||
"estimated_size": "0b",
|
|
||||||
"overhead": 1.0,
|
|
||||||
"tripped": 0
|
|
||||||
},
|
|
||||||
"parent": {
|
|
||||||
"limit_size_in_bytes": 727213670,
|
|
||||||
"limit_size": "693.5mb",
|
|
||||||
"estimated_size_in_bytes": 0,
|
|
||||||
"estimated_size": "0b",
|
|
||||||
"overhead": 1.0,
|
|
||||||
"tripped": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
var indicesExpected = map[string]interface{}{
|
|
||||||
"id_cache_memory_size_in_bytes": float64(0),
|
|
||||||
"completion_size_in_bytes": float64(0),
|
|
||||||
"suggest_total": float64(0),
|
|
||||||
"suggest_time_in_millis": float64(0),
|
|
||||||
"suggest_current": float64(0),
|
|
||||||
"query_cache_memory_size_in_bytes": float64(0),
|
|
||||||
"query_cache_evictions": float64(0),
|
|
||||||
"query_cache_hit_count": float64(0),
|
|
||||||
"query_cache_miss_count": float64(0),
|
|
||||||
"store_size_in_bytes": float64(37715234),
|
|
||||||
"store_throttle_time_in_millis": float64(215),
|
|
||||||
"merges_current_docs": float64(0),
|
|
||||||
"merges_current_size_in_bytes": float64(0),
|
|
||||||
"merges_total": float64(133),
|
|
||||||
"merges_total_time_in_millis": float64(21060),
|
|
||||||
"merges_total_docs": float64(203672),
|
|
||||||
"merges_total_size_in_bytes": float64(142900226),
|
|
||||||
"merges_current": float64(0),
|
|
||||||
"filter_cache_memory_size_in_bytes": float64(7384),
|
|
||||||
"filter_cache_evictions": float64(0),
|
|
||||||
"indexing_index_total": float64(84790),
|
|
||||||
"indexing_index_time_in_millis": float64(29680),
|
|
||||||
"indexing_index_current": float64(0),
|
|
||||||
"indexing_noop_update_total": float64(0),
|
|
||||||
"indexing_throttle_time_in_millis": float64(0),
|
|
||||||
"indexing_delete_total": float64(13879),
|
|
||||||
"indexing_delete_time_in_millis": float64(1139),
|
|
||||||
"indexing_delete_current": float64(0),
|
|
||||||
"get_exists_time_in_millis": float64(0),
|
|
||||||
"get_missing_total": float64(1),
|
|
||||||
"get_missing_time_in_millis": float64(2),
|
|
||||||
"get_current": float64(0),
|
|
||||||
"get_total": float64(1),
|
|
||||||
"get_time_in_millis": float64(2),
|
|
||||||
"get_exists_total": float64(0),
|
|
||||||
"refresh_total": float64(1076),
|
|
||||||
"refresh_total_time_in_millis": float64(20078),
|
|
||||||
"percolate_current": float64(0),
|
|
||||||
"percolate_memory_size_in_bytes": float64(-1),
|
|
||||||
"percolate_queries": float64(0),
|
|
||||||
"percolate_total": float64(0),
|
|
||||||
"percolate_time_in_millis": float64(0),
|
|
||||||
"translog_operations": float64(17702),
|
|
||||||
"translog_size_in_bytes": float64(17),
|
|
||||||
"recovery_current_as_source": float64(0),
|
|
||||||
"recovery_current_as_target": float64(0),
|
|
||||||
"recovery_throttle_time_in_millis": float64(0),
|
|
||||||
"docs_count": float64(29652),
|
|
||||||
"docs_deleted": float64(5229),
|
|
||||||
"flush_total_time_in_millis": float64(2401),
|
|
||||||
"flush_total": float64(115),
|
|
||||||
"fielddata_memory_size_in_bytes": float64(12996),
|
|
||||||
"fielddata_evictions": float64(0),
|
|
||||||
"search_fetch_current": float64(0),
|
|
||||||
"search_open_contexts": float64(0),
|
|
||||||
"search_query_total": float64(1452),
|
|
||||||
"search_query_time_in_millis": float64(5695),
|
|
||||||
"search_query_current": float64(0),
|
|
||||||
"search_fetch_total": float64(414),
|
|
||||||
"search_fetch_time_in_millis": float64(146),
|
|
||||||
"warmer_current": float64(0),
|
|
||||||
"warmer_total": float64(2319),
|
|
||||||
"warmer_total_time_in_millis": float64(448),
|
|
||||||
"segments_count": float64(134),
|
|
||||||
"segments_memory_in_bytes": float64(1285212),
|
|
||||||
"segments_index_writer_memory_in_bytes": float64(0),
|
|
||||||
"segments_index_writer_max_memory_in_bytes": float64(172368955),
|
|
||||||
"segments_version_map_memory_in_bytes": float64(611844),
|
|
||||||
"segments_fixed_bit_set_memory_in_bytes": float64(0),
|
|
||||||
}
|
|
||||||
|
|
||||||
var osExpected = map[string]interface{}{
|
|
||||||
"swap_used_in_bytes": float64(0),
|
|
||||||
"swap_free_in_bytes": float64(487997440),
|
|
||||||
"timestamp": float64(1436460392944),
|
|
||||||
"mem_free_percent": float64(74),
|
|
||||||
"mem_used_percent": float64(25),
|
|
||||||
"mem_actual_free_in_bytes": float64(1565470720),
|
|
||||||
"mem_actual_used_in_bytes": float64(534159360),
|
|
||||||
"mem_free_in_bytes": float64(477761536),
|
|
||||||
"mem_used_in_bytes": float64(1621868544),
|
|
||||||
}
|
|
||||||
|
|
||||||
var processExpected = map[string]interface{}{
|
|
||||||
"mem_total_virtual_in_bytes": float64(4747890688),
|
|
||||||
"timestamp": float64(1436460392945),
|
|
||||||
"open_file_descriptors": float64(160),
|
|
||||||
"cpu_total_in_millis": float64(15480),
|
|
||||||
"cpu_percent": float64(2),
|
|
||||||
"cpu_sys_in_millis": float64(1870),
|
|
||||||
"cpu_user_in_millis": float64(13610),
|
|
||||||
}
|
|
||||||
|
|
||||||
var jvmExpected = map[string]interface{}{
|
|
||||||
"timestamp": float64(1436460392945),
|
|
||||||
"uptime_in_millis": float64(202245),
|
|
||||||
"mem_non_heap_used_in_bytes": float64(39634576),
|
|
||||||
"mem_non_heap_committed_in_bytes": float64(40841216),
|
|
||||||
"mem_pools_young_max_in_bytes": float64(279183360),
|
|
||||||
"mem_pools_young_peak_used_in_bytes": float64(71630848),
|
|
||||||
"mem_pools_young_peak_max_in_bytes": float64(279183360),
|
|
||||||
"mem_pools_young_used_in_bytes": float64(32685760),
|
|
||||||
"mem_pools_survivor_peak_used_in_bytes": float64(8912888),
|
|
||||||
"mem_pools_survivor_peak_max_in_bytes": float64(34865152),
|
|
||||||
"mem_pools_survivor_used_in_bytes": float64(8912880),
|
|
||||||
"mem_pools_survivor_max_in_bytes": float64(34865152),
|
|
||||||
"mem_pools_old_peak_max_in_bytes": float64(724828160),
|
|
||||||
"mem_pools_old_used_in_bytes": float64(11110928),
|
|
||||||
"mem_pools_old_max_in_bytes": float64(724828160),
|
|
||||||
"mem_pools_old_peak_used_in_bytes": float64(14354608),
|
|
||||||
"mem_heap_used_in_bytes": float64(52709568),
|
|
||||||
"mem_heap_used_percent": float64(5),
|
|
||||||
"mem_heap_committed_in_bytes": float64(259522560),
|
|
||||||
"mem_heap_max_in_bytes": float64(1038876672),
|
|
||||||
"threads_peak_count": float64(45),
|
|
||||||
"threads_count": float64(44),
|
|
||||||
"gc_collectors_young_collection_count": float64(2),
|
|
||||||
"gc_collectors_young_collection_time_in_millis": float64(98),
|
|
||||||
"gc_collectors_old_collection_count": float64(1),
|
|
||||||
"gc_collectors_old_collection_time_in_millis": float64(24),
|
|
||||||
"buffer_pools_direct_count": float64(40),
|
|
||||||
"buffer_pools_direct_used_in_bytes": float64(6304239),
|
|
||||||
"buffer_pools_direct_total_capacity_in_bytes": float64(6304239),
|
|
||||||
"buffer_pools_mapped_count": float64(0),
|
|
||||||
"buffer_pools_mapped_used_in_bytes": float64(0),
|
|
||||||
"buffer_pools_mapped_total_capacity_in_bytes": float64(0),
|
|
||||||
}
|
|
||||||
|
|
||||||
var threadPoolExpected = map[string]interface{}{
|
|
||||||
"merge_threads": float64(6),
|
|
||||||
"merge_queue": float64(4),
|
|
||||||
"merge_active": float64(5),
|
|
||||||
"merge_rejected": float64(2),
|
|
||||||
"merge_largest": float64(5),
|
|
||||||
"merge_completed": float64(1),
|
|
||||||
"bulk_threads": float64(4),
|
|
||||||
"bulk_queue": float64(5),
|
|
||||||
"bulk_active": float64(7),
|
|
||||||
"bulk_rejected": float64(3),
|
|
||||||
"bulk_largest": float64(1),
|
|
||||||
"bulk_completed": float64(4),
|
|
||||||
"warmer_threads": float64(2),
|
|
||||||
"warmer_queue": float64(7),
|
|
||||||
"warmer_active": float64(3),
|
|
||||||
"warmer_rejected": float64(2),
|
|
||||||
"warmer_largest": float64(3),
|
|
||||||
"warmer_completed": float64(1),
|
|
||||||
"get_largest": float64(2),
|
|
||||||
"get_completed": float64(1),
|
|
||||||
"get_threads": float64(1),
|
|
||||||
"get_queue": float64(8),
|
|
||||||
"get_active": float64(4),
|
|
||||||
"get_rejected": float64(3),
|
|
||||||
"index_threads": float64(6),
|
|
||||||
"index_queue": float64(8),
|
|
||||||
"index_active": float64(4),
|
|
||||||
"index_rejected": float64(2),
|
|
||||||
"index_largest": float64(3),
|
|
||||||
"index_completed": float64(6),
|
|
||||||
"suggest_threads": float64(2),
|
|
||||||
"suggest_queue": float64(7),
|
|
||||||
"suggest_active": float64(2),
|
|
||||||
"suggest_rejected": float64(1),
|
|
||||||
"suggest_largest": float64(8),
|
|
||||||
"suggest_completed": float64(3),
|
|
||||||
"fetch_shard_store_queue": float64(7),
|
|
||||||
"fetch_shard_store_active": float64(4),
|
|
||||||
"fetch_shard_store_rejected": float64(2),
|
|
||||||
"fetch_shard_store_largest": float64(4),
|
|
||||||
"fetch_shard_store_completed": float64(1),
|
|
||||||
"fetch_shard_store_threads": float64(1),
|
|
||||||
"management_threads": float64(2),
|
|
||||||
"management_queue": float64(3),
|
|
||||||
"management_active": float64(1),
|
|
||||||
"management_rejected": float64(6),
|
|
||||||
"management_largest": float64(2),
|
|
||||||
"management_completed": float64(22),
|
|
||||||
"percolate_queue": float64(23),
|
|
||||||
"percolate_active": float64(13),
|
|
||||||
"percolate_rejected": float64(235),
|
|
||||||
"percolate_largest": float64(23),
|
|
||||||
"percolate_completed": float64(33),
|
|
||||||
"percolate_threads": float64(123),
|
|
||||||
"listener_active": float64(4),
|
|
||||||
"listener_rejected": float64(8),
|
|
||||||
"listener_largest": float64(1),
|
|
||||||
"listener_completed": float64(1),
|
|
||||||
"listener_threads": float64(1),
|
|
||||||
"listener_queue": float64(2),
|
|
||||||
"search_rejected": float64(7),
|
|
||||||
"search_largest": float64(2),
|
|
||||||
"search_completed": float64(4),
|
|
||||||
"search_threads": float64(5),
|
|
||||||
"search_queue": float64(7),
|
|
||||||
"search_active": float64(2),
|
|
||||||
"fetch_shard_started_threads": float64(3),
|
|
||||||
"fetch_shard_started_queue": float64(1),
|
|
||||||
"fetch_shard_started_active": float64(5),
|
|
||||||
"fetch_shard_started_rejected": float64(6),
|
|
||||||
"fetch_shard_started_largest": float64(4),
|
|
||||||
"fetch_shard_started_completed": float64(54),
|
|
||||||
"refresh_rejected": float64(4),
|
|
||||||
"refresh_largest": float64(8),
|
|
||||||
"refresh_completed": float64(3),
|
|
||||||
"refresh_threads": float64(23),
|
|
||||||
"refresh_queue": float64(7),
|
|
||||||
"refresh_active": float64(3),
|
|
||||||
"optimize_threads": float64(3),
|
|
||||||
"optimize_queue": float64(4),
|
|
||||||
"optimize_active": float64(1),
|
|
||||||
"optimize_rejected": float64(2),
|
|
||||||
"optimize_largest": float64(7),
|
|
||||||
"optimize_completed": float64(3),
|
|
||||||
"snapshot_largest": float64(1),
|
|
||||||
"snapshot_completed": float64(0),
|
|
||||||
"snapshot_threads": float64(8),
|
|
||||||
"snapshot_queue": float64(5),
|
|
||||||
"snapshot_active": float64(6),
|
|
||||||
"snapshot_rejected": float64(2),
|
|
||||||
"generic_threads": float64(1),
|
|
||||||
"generic_queue": float64(4),
|
|
||||||
"generic_active": float64(6),
|
|
||||||
"generic_rejected": float64(3),
|
|
||||||
"generic_largest": float64(2),
|
|
||||||
"generic_completed": float64(27),
|
|
||||||
"flush_threads": float64(3),
|
|
||||||
"flush_queue": float64(8),
|
|
||||||
"flush_active": float64(0),
|
|
||||||
"flush_rejected": float64(1),
|
|
||||||
"flush_largest": float64(5),
|
|
||||||
"flush_completed": float64(3),
|
|
||||||
}
|
|
||||||
|
|
||||||
var fsExpected = map[string]interface{}{
|
|
||||||
"timestamp": float64(1436460392946),
|
|
||||||
"total_free_in_bytes": float64(16909316096),
|
|
||||||
"total_available_in_bytes": float64(15894814720),
|
|
||||||
"total_total_in_bytes": float64(19507089408),
|
|
||||||
}
|
|
||||||
|
|
||||||
var transportExpected = map[string]interface{}{
|
|
||||||
"server_open": float64(13),
|
|
||||||
"rx_count": float64(6),
|
|
||||||
"rx_size_in_bytes": float64(1380),
|
|
||||||
"tx_count": float64(6),
|
|
||||||
"tx_size_in_bytes": float64(1380),
|
|
||||||
}
|
|
||||||
|
|
||||||
var httpExpected = map[string]interface{}{
|
|
||||||
"current_open": float64(3),
|
|
||||||
"total_opened": float64(3),
|
|
||||||
}
|
|
||||||
|
|
||||||
var breakersExpected = map[string]interface{}{
|
|
||||||
"fielddata_estimated_size_in_bytes": float64(0),
|
|
||||||
"fielddata_overhead": float64(1.03),
|
|
||||||
"fielddata_tripped": float64(0),
|
|
||||||
"fielddata_limit_size_in_bytes": float64(623326003),
|
|
||||||
"request_estimated_size_in_bytes": float64(0),
|
|
||||||
"request_overhead": float64(1.0),
|
|
||||||
"request_tripped": float64(0),
|
|
||||||
"request_limit_size_in_bytes": float64(415550668),
|
|
||||||
"parent_overhead": float64(1.0),
|
|
||||||
"parent_tripped": float64(0),
|
|
||||||
"parent_limit_size_in_bytes": float64(727213670),
|
|
||||||
"parent_estimated_size_in_bytes": float64(0),
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
package exec
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Midnight 9/22/2015
|
|
||||||
const baseTimeSeconds = 1442905200
|
|
||||||
|
|
||||||
const validJson = `
|
|
||||||
{
|
|
||||||
"status": "green",
|
|
||||||
"num_processes": 82,
|
|
||||||
"cpu": {
|
|
||||||
"status": "red",
|
|
||||||
"nil_status": null,
|
|
||||||
"used": 8234,
|
|
||||||
"free": 32
|
|
||||||
},
|
|
||||||
"percent": 0.81,
|
|
||||||
"users": [0, 1, 2, 3]
|
|
||||||
}`
|
|
||||||
|
|
||||||
const malformedJson = `
|
|
||||||
{
|
|
||||||
"status": "green",
|
|
||||||
`
|
|
||||||
|
|
||||||
type runnerMock struct {
|
|
||||||
out []byte
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func newRunnerMock(out []byte, err error) Runner {
|
|
||||||
return &runnerMock{
|
|
||||||
out: out,
|
|
||||||
err: err,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r runnerMock) Run(e *Exec) ([]byte, error) {
|
|
||||||
if r.err != nil {
|
|
||||||
return nil, r.err
|
|
||||||
}
|
|
||||||
return r.out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExec(t *testing.T) {
|
|
||||||
e := &Exec{
|
|
||||||
runner: newRunnerMock([]byte(validJson), nil),
|
|
||||||
Command: "testcommand arg1",
|
|
||||||
}
|
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
err := e.Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, acc.NFields(), 4, "non-numeric measurements should be ignored")
|
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
|
||||||
"num_processes": float64(82),
|
|
||||||
"cpu_used": float64(8234),
|
|
||||||
"cpu_free": float64(32),
|
|
||||||
"percent": float64(0.81),
|
|
||||||
}
|
|
||||||
acc.AssertContainsFields(t, "exec", fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExecMalformed(t *testing.T) {
|
|
||||||
e := &Exec{
|
|
||||||
runner: newRunnerMock([]byte(malformedJson), nil),
|
|
||||||
Command: "badcommand arg1",
|
|
||||||
}
|
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
err := e.Gather(&acc)
|
|
||||||
require.Error(t, err)
|
|
||||||
assert.Equal(t, acc.NFields(), 0, "No new points should have been added")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCommandError(t *testing.T) {
|
|
||||||
e := &Exec{
|
|
||||||
runner: newRunnerMock(nil, fmt.Errorf("exit status code 1")),
|
|
||||||
Command: "badcommand",
|
|
||||||
}
|
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
err := e.Gather(&acc)
|
|
||||||
require.Error(t, err)
|
|
||||||
assert.Equal(t, acc.NFields(), 0, "No new points should have been added")
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
package puppetagent
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGather(t *testing.T) {
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
|
|
||||||
pa := PuppetAgent{
|
|
||||||
Location: "last_run_summary.yaml",
|
|
||||||
}
|
|
||||||
pa.Gather(&acc)
|
|
||||||
|
|
||||||
tags := map[string]string{"location": "last_run_summary.yaml"}
|
|
||||||
fields := map[string]interface{}{
|
|
||||||
"events_failure": int64(0),
|
|
||||||
"events_total": int64(0),
|
|
||||||
"events_success": int64(0),
|
|
||||||
"resources_failed": int64(0),
|
|
||||||
"resources_scheduled": int64(0),
|
|
||||||
"resources_changed": int64(0),
|
|
||||||
"resources_skipped": int64(0),
|
|
||||||
"resources_total": int64(109),
|
|
||||||
"resources_failedtorestart": int64(0),
|
|
||||||
"resources_restarted": int64(0),
|
|
||||||
"resources_outofsync": int64(0),
|
|
||||||
"changes_total": int64(0),
|
|
||||||
"time_lastrun": int64(1444936531),
|
|
||||||
"version_config": int64(1444936521),
|
|
||||||
"time_user": float64(0.004331),
|
|
||||||
"time_schedule": float64(0.001123),
|
|
||||||
"time_filebucket": float64(0.000353),
|
|
||||||
"time_file": float64(0.441472),
|
|
||||||
"time_exec": float64(0.508123),
|
|
||||||
"time_anchor": float64(0.000555),
|
|
||||||
"time_sshauthorizedkey": float64(0.000764),
|
|
||||||
"time_service": float64(1.807795),
|
|
||||||
"time_package": float64(1.325788),
|
|
||||||
"time_total": float64(8.85354707064819),
|
|
||||||
"time_configretrieval": float64(4.75567007064819),
|
|
||||||
"time_cron": float64(0.000584),
|
|
||||||
"version_puppet": "3.7.5",
|
|
||||||
}
|
|
||||||
|
|
||||||
acc.AssertContainsTaggedFields(t, "puppetagent", fields, tags)
|
|
||||||
}
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
|
||||||
"github.com/shirou/gopsutil/cpu"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCPUStats(t *testing.T) {
|
|
||||||
var mps MockPS
|
|
||||||
defer mps.AssertExpectations(t)
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
|
|
||||||
cts := cpu.CPUTimesStat{
|
|
||||||
CPU: "cpu0",
|
|
||||||
User: 3.1,
|
|
||||||
System: 8.2,
|
|
||||||
Idle: 80.1,
|
|
||||||
Nice: 1.3,
|
|
||||||
Iowait: 0.2,
|
|
||||||
Irq: 0.1,
|
|
||||||
Softirq: 0.11,
|
|
||||||
Steal: 0.0511,
|
|
||||||
Guest: 8.1,
|
|
||||||
GuestNice: 0.324,
|
|
||||||
}
|
|
||||||
|
|
||||||
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.2812, // increased by 0.0001
|
|
||||||
Guest: 12.9, // increased by 4.8
|
|
||||||
GuestNice: 2.524, // increased by 2.2
|
|
||||||
}
|
|
||||||
|
|
||||||
mps.On("CPUTimes").Return([]cpu.CPUTimesStat{cts}, nil)
|
|
||||||
|
|
||||||
cs := NewCPUStats(&mps)
|
|
||||||
|
|
||||||
cputags := map[string]string{
|
|
||||||
"cpu": "cpu0",
|
|
||||||
}
|
|
||||||
|
|
||||||
err := cs.Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Computed values are checked with delta > 0 becasue of floating point arithmatic
|
|
||||||
// imprecision
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_user", 3.1, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_system", 8.2, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_idle", 80.1, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_nice", 1.3, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_iowait", 0.2, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_irq", 0.1, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_softirq", 0.11, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_steal", 0.0511, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_guest", 8.1, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_guest_nice", 0.324, 0, 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)
|
|
||||||
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_user", 11.4, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_system", 10.9, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_idle", 158.8699, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_nice", 2.5, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_iowait", 0.7, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_irq", 1.2, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_softirq", 0.31, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_steal", 0.2812, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_guest", 12.9, 0, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "time_guest_nice", 2.524, 0, cputags)
|
|
||||||
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "usage_user", 8.3, 0.0005, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "usage_system", 2.7, 0.0005, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "usage_idle", 78.7699, 0.0005, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "usage_nice", 1.2, 0.0005, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "usage_iowait", 0.5, 0.0005, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "usage_irq", 1.1, 0.0005, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "usage_softirq", 0.2, 0.0005, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "usage_steal", 0.2301, 0.0005, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "usage_guest", 4.8, 0.0005, cputags)
|
|
||||||
assertContainsTaggedFloat(t, &acc, "cpu", "usage_guest_nice", 2.2, 0.0005, cputags)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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,
|
|
||||||
field string,
|
|
||||||
expectedValue float64,
|
|
||||||
delta float64,
|
|
||||||
tags map[string]string,
|
|
||||||
) {
|
|
||||||
var actualValue float64
|
|
||||||
for _, pt := range acc.Points {
|
|
||||||
if pt.Measurement == measurement {
|
|
||||||
for fieldname, value := range pt.Fields {
|
|
||||||
if fieldname == field {
|
|
||||||
if value, ok := value.(float64); ok {
|
|
||||||
actualValue = value
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
msg := fmt.Sprintf(
|
|
||||||
"Could not find measurement \"%s\" with requested tags within %f of %f, Actual: %f",
|
|
||||||
measurement, delta, expectedValue, actualValue)
|
|
||||||
assert.Fail(t, msg)
|
|
||||||
}
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
|
||||||
"github.com/shirou/gopsutil/disk"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestDiskStats(t *testing.T) {
|
|
||||||
var mps MockPS
|
|
||||||
defer mps.AssertExpectations(t)
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
var err error
|
|
||||||
|
|
||||||
du := []*disk.DiskUsageStat{
|
|
||||||
{
|
|
||||||
Path: "/",
|
|
||||||
Fstype: "ext4",
|
|
||||||
Total: 128,
|
|
||||||
Free: 23,
|
|
||||||
InodesTotal: 1234,
|
|
||||||
InodesFree: 234,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Path: "/home",
|
|
||||||
Fstype: "ext4",
|
|
||||||
Total: 256,
|
|
||||||
Free: 46,
|
|
||||||
InodesTotal: 2468,
|
|
||||||
InodesFree: 468,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
mps.On("DiskUsage").Return(du, nil)
|
|
||||||
|
|
||||||
err = (&DiskStats{ps: &mps}).Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
numDiskPoints := acc.NFields()
|
|
||||||
expectedAllDiskPoints := 12
|
|
||||||
assert.Equal(t, expectedAllDiskPoints, numDiskPoints)
|
|
||||||
|
|
||||||
tags1 := map[string]string{
|
|
||||||
"path": "/",
|
|
||||||
"fstype": "ext4",
|
|
||||||
}
|
|
||||||
tags2 := map[string]string{
|
|
||||||
"path": "/home",
|
|
||||||
"fstype": "ext4",
|
|
||||||
}
|
|
||||||
|
|
||||||
fields1 := map[string]interface{}{
|
|
||||||
"total": uint64(128), //tags1)
|
|
||||||
"used": uint64(105), //tags1)
|
|
||||||
"free": uint64(23), //tags1)
|
|
||||||
"inodes_total": uint64(1234), //tags1)
|
|
||||||
"inodes_free": uint64(234), //tags1)
|
|
||||||
"inodes_used": uint64(1000), //tags1)
|
|
||||||
}
|
|
||||||
fields2 := map[string]interface{}{
|
|
||||||
"total": uint64(256), //tags2)
|
|
||||||
"used": uint64(210), //tags2)
|
|
||||||
"free": uint64(46), //tags2)
|
|
||||||
"inodes_total": uint64(2468), //tags2)
|
|
||||||
"inodes_free": uint64(468), //tags2)
|
|
||||||
"inodes_used": uint64(2000), //tags2)
|
|
||||||
}
|
|
||||||
acc.AssertContainsTaggedFields(t, "disk", fields1, tags1)
|
|
||||||
acc.AssertContainsTaggedFields(t, "disk", fields2, tags2)
|
|
||||||
|
|
||||||
// We expect 6 more DiskPoints to show up with an explicit match on "/"
|
|
||||||
// and /home not matching the /dev in Mountpoints
|
|
||||||
err = (&DiskStats{ps: &mps, Mountpoints: []string{"/", "/dev"}}).Gather(&acc)
|
|
||||||
assert.Equal(t, expectedAllDiskPoints+6, acc.NFields())
|
|
||||||
|
|
||||||
// We should see all the diskpoints as Mountpoints includes both
|
|
||||||
// / and /home
|
|
||||||
err = (&DiskStats{ps: &mps, Mountpoints: []string{"/", "/home"}}).Gather(&acc)
|
|
||||||
assert.Equal(t, 2*expectedAllDiskPoints+6, acc.NFields())
|
|
||||||
}
|
|
||||||
|
|
||||||
// func TestDiskIOStats(t *testing.T) {
|
|
||||||
// var mps MockPS
|
|
||||||
// defer mps.AssertExpectations(t)
|
|
||||||
// var acc testutil.Accumulator
|
|
||||||
// var err error
|
|
||||||
|
|
||||||
// diskio1 := disk.DiskIOCountersStat{
|
|
||||||
// ReadCount: 888,
|
|
||||||
// WriteCount: 5341,
|
|
||||||
// ReadBytes: 100000,
|
|
||||||
// WriteBytes: 200000,
|
|
||||||
// ReadTime: 7123,
|
|
||||||
// WriteTime: 9087,
|
|
||||||
// Name: "sda1",
|
|
||||||
// IoTime: 123552,
|
|
||||||
// SerialNumber: "ab-123-ad",
|
|
||||||
// }
|
|
||||||
// diskio2 := disk.DiskIOCountersStat{
|
|
||||||
// ReadCount: 444,
|
|
||||||
// WriteCount: 2341,
|
|
||||||
// ReadBytes: 200000,
|
|
||||||
// WriteBytes: 400000,
|
|
||||||
// ReadTime: 3123,
|
|
||||||
// WriteTime: 6087,
|
|
||||||
// Name: "sdb1",
|
|
||||||
// IoTime: 246552,
|
|
||||||
// SerialNumber: "bb-123-ad",
|
|
||||||
// }
|
|
||||||
|
|
||||||
// mps.On("DiskIO").Return(
|
|
||||||
// map[string]disk.DiskIOCountersStat{"sda1": diskio1, "sdb1": diskio2},
|
|
||||||
// nil)
|
|
||||||
|
|
||||||
// err = (&DiskIOStats{ps: &mps}).Gather(&acc)
|
|
||||||
// require.NoError(t, err)
|
|
||||||
|
|
||||||
// numDiskIOPoints := acc.NFields()
|
|
||||||
// expectedAllDiskIOPoints := 14
|
|
||||||
// assert.Equal(t, expectedAllDiskIOPoints, numDiskIOPoints)
|
|
||||||
|
|
||||||
// dtags1 := map[string]string{
|
|
||||||
// "name": "sda1",
|
|
||||||
// "serial": "ab-123-ad",
|
|
||||||
// }
|
|
||||||
// dtags2 := map[string]string{
|
|
||||||
// "name": "sdb1",
|
|
||||||
// "serial": "bb-123-ad",
|
|
||||||
// }
|
|
||||||
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("reads", uint64(888), dtags1))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("writes", uint64(5341), dtags1))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("read_bytes", uint64(100000), dtags1))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("write_bytes", uint64(200000), dtags1))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("read_time", uint64(7123), dtags1))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("write_time", uint64(9087), dtags1))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("io_time", uint64(123552), dtags1))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("reads", uint64(444), dtags2))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("writes", uint64(2341), dtags2))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("read_bytes", uint64(200000), dtags2))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("write_bytes", uint64(400000), dtags2))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("read_time", uint64(3123), dtags2))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("write_time", uint64(6087), dtags2))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("io_time", uint64(246552), dtags2))
|
|
||||||
|
|
||||||
// // We expect 7 more DiskIOPoints to show up with an explicit match on "sdb1"
|
|
||||||
// // and serial should be missing from the tags with SkipSerialNumber set
|
|
||||||
// err = (&DiskIOStats{ps: &mps, Devices: []string{"sdb1"}, SkipSerialNumber: true}).Gather(&acc)
|
|
||||||
// assert.Equal(t, expectedAllDiskIOPoints+7, acc.NFields())
|
|
||||||
|
|
||||||
// dtags3 := map[string]string{
|
|
||||||
// "name": "sdb1",
|
|
||||||
// }
|
|
||||||
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("reads", uint64(444), dtags3))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("writes", uint64(2341), dtags3))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("read_bytes", uint64(200000), dtags3))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("write_bytes", uint64(400000), dtags3))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("read_time", uint64(3123), dtags3))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("write_time", uint64(6087), dtags3))
|
|
||||||
// assert.True(t, acc.CheckTaggedValue("io_time", uint64(246552), dtags3))
|
|
||||||
// }
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
// +build linux
|
|
||||||
|
|
||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
|
||||||
"github.com/shirou/gopsutil/cpu"
|
|
||||||
"github.com/shirou/gopsutil/docker"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestDockerStats_GenerateStats(t *testing.T) {
|
|
||||||
var mps MockPS
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
|
|
||||||
ds := &DockerContainerStat{
|
|
||||||
Name: "blah",
|
|
||||||
CPU: &cpu.CPUTimesStat{
|
|
||||||
CPU: "all",
|
|
||||||
User: 3.1,
|
|
||||||
System: 8.2,
|
|
||||||
Idle: 80.1,
|
|
||||||
Nice: 1.3,
|
|
||||||
Iowait: 0.2,
|
|
||||||
Irq: 0.1,
|
|
||||||
Softirq: 0.11,
|
|
||||||
Steal: 0.0001,
|
|
||||||
Guest: 8.1,
|
|
||||||
GuestNice: 0.324,
|
|
||||||
},
|
|
||||||
Mem: &docker.CgroupMemStat{
|
|
||||||
ContainerID: "blah",
|
|
||||||
Cache: 1,
|
|
||||||
RSS: 2,
|
|
||||||
RSSHuge: 3,
|
|
||||||
MappedFile: 4,
|
|
||||||
Pgpgin: 5,
|
|
||||||
Pgpgout: 6,
|
|
||||||
Pgfault: 7,
|
|
||||||
Pgmajfault: 8,
|
|
||||||
InactiveAnon: 9,
|
|
||||||
ActiveAnon: 10,
|
|
||||||
InactiveFile: 11,
|
|
||||||
ActiveFile: 12,
|
|
||||||
Unevictable: 13,
|
|
||||||
HierarchicalMemoryLimit: 14,
|
|
||||||
TotalCache: 15,
|
|
||||||
TotalRSS: 16,
|
|
||||||
TotalRSSHuge: 17,
|
|
||||||
TotalMappedFile: 18,
|
|
||||||
TotalPgpgIn: 19,
|
|
||||||
TotalPgpgOut: 20,
|
|
||||||
TotalPgFault: 21,
|
|
||||||
TotalPgMajFault: 22,
|
|
||||||
TotalInactiveAnon: 23,
|
|
||||||
TotalActiveAnon: 24,
|
|
||||||
TotalInactiveFile: 25,
|
|
||||||
TotalActiveFile: 26,
|
|
||||||
TotalUnevictable: 27,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
mps.On("DockerStat").Return([]*DockerContainerStat{ds}, nil)
|
|
||||||
|
|
||||||
err := (&DockerStats{&mps}).Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
dockertags := map[string]string{
|
|
||||||
"name": "blah",
|
|
||||||
"id": "",
|
|
||||||
"command": "",
|
|
||||||
}
|
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
|
||||||
"user": 3.1,
|
|
||||||
"system": 8.2,
|
|
||||||
"idle": 80.1,
|
|
||||||
"nice": 1.3,
|
|
||||||
"iowait": 0.2,
|
|
||||||
"irq": 0.1,
|
|
||||||
"softirq": 0.11,
|
|
||||||
"steal": 0.0001,
|
|
||||||
"guest": 8.1,
|
|
||||||
"guest_nice": 0.324,
|
|
||||||
|
|
||||||
"cache": uint64(1),
|
|
||||||
"rss": uint64(2),
|
|
||||||
"rss_huge": uint64(3),
|
|
||||||
"mapped_file": uint64(4),
|
|
||||||
"swap_in": uint64(5),
|
|
||||||
"swap_out": uint64(6),
|
|
||||||
"page_fault": uint64(7),
|
|
||||||
"page_major_fault": uint64(8),
|
|
||||||
"inactive_anon": uint64(9),
|
|
||||||
"active_anon": uint64(10),
|
|
||||||
"inactive_file": uint64(11),
|
|
||||||
"active_file": uint64(12),
|
|
||||||
"unevictable": uint64(13),
|
|
||||||
"memory_limit": uint64(14),
|
|
||||||
"total_cache": uint64(15),
|
|
||||||
"total_rss": uint64(16),
|
|
||||||
"total_rss_huge": uint64(17),
|
|
||||||
"total_mapped_file": uint64(18),
|
|
||||||
"total_swap_in": uint64(19),
|
|
||||||
"total_swap_out": uint64(20),
|
|
||||||
"total_page_fault": uint64(21),
|
|
||||||
"total_page_major_fault": uint64(22),
|
|
||||||
"total_inactive_anon": uint64(23),
|
|
||||||
"total_active_anon": uint64(24),
|
|
||||||
"total_inactive_file": uint64(25),
|
|
||||||
"total_active_file": uint64(26),
|
|
||||||
"total_unevictable": uint64(27),
|
|
||||||
}
|
|
||||||
|
|
||||||
acc.AssertContainsTaggedFields(t, "docker", fields, dockertags)
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
package system
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
|
||||||
"github.com/shirou/gopsutil/mem"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMemStats(t *testing.T) {
|
|
||||||
var mps MockPS
|
|
||||||
var err error
|
|
||||||
defer mps.AssertExpectations(t)
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
|
|
||||||
vms := &mem.VirtualMemoryStat{
|
|
||||||
Total: 12400,
|
|
||||||
Available: 7600,
|
|
||||||
Used: 5000,
|
|
||||||
Free: 1235,
|
|
||||||
// Active: 8134,
|
|
||||||
// Inactive: 1124,
|
|
||||||
// Buffers: 771,
|
|
||||||
// Cached: 4312,
|
|
||||||
// Wired: 134,
|
|
||||||
// Shared: 2142,
|
|
||||||
}
|
|
||||||
|
|
||||||
mps.On("VMStat").Return(vms, nil)
|
|
||||||
|
|
||||||
sms := &mem.SwapMemoryStat{
|
|
||||||
Total: 8123,
|
|
||||||
Used: 1232,
|
|
||||||
Free: 6412,
|
|
||||||
UsedPercent: 12.2,
|
|
||||||
Sin: 7,
|
|
||||||
Sout: 830,
|
|
||||||
}
|
|
||||||
|
|
||||||
mps.On("SwapStat").Return(sms, nil)
|
|
||||||
|
|
||||||
err = (&MemStats{&mps}).Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
memfields := map[string]interface{}{
|
|
||||||
"total": uint64(12400),
|
|
||||||
"available": uint64(7600),
|
|
||||||
"used": uint64(5000),
|
|
||||||
"available_percent": float64(7600) / float64(12400) * 100,
|
|
||||||
"used_percent": float64(5000) / float64(12400) * 100,
|
|
||||||
"free": uint64(1235),
|
|
||||||
"cached": uint64(0),
|
|
||||||
"buffered": uint64(0),
|
|
||||||
}
|
|
||||||
acc.AssertContainsTaggedFields(t, "mem", memfields, make(map[string]string))
|
|
||||||
|
|
||||||
acc.Points = nil
|
|
||||||
|
|
||||||
err = (&SwapStats{&mps}).Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
swapfields := map[string]interface{}{
|
|
||||||
"total": uint64(8123),
|
|
||||||
"used": uint64(1232),
|
|
||||||
"used_percent": float64(12.2),
|
|
||||||
"free": uint64(6412),
|
|
||||||
"in": uint64(7),
|
|
||||||
"out": uint64(830),
|
|
||||||
}
|
|
||||||
acc.AssertContainsTaggedFields(t, "swap", swapfields, make(map[string]string))
|
|
||||||
}
|
|
||||||
@@ -1,171 +0,0 @@
|
|||||||
package twemproxy
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
const sampleAddr = "127.0.0.1:22222"
|
|
||||||
|
|
||||||
const sampleStats = `{
|
|
||||||
"total_connections": 276448,
|
|
||||||
"uptime": 160657,
|
|
||||||
"version": "0.4.1",
|
|
||||||
"service": "nutcracker",
|
|
||||||
"curr_connections": 1322,
|
|
||||||
"source": "server1.website.com",
|
|
||||||
"demo": {
|
|
||||||
"client_connections": 1305,
|
|
||||||
"forward_error": 11684,
|
|
||||||
"client_err": 147942,
|
|
||||||
"server_ejects": 0,
|
|
||||||
"fragments": 0,
|
|
||||||
"client_eof": 126813,
|
|
||||||
"10.16.29.1:6379": {
|
|
||||||
"requests": 43604566,
|
|
||||||
"server_eof": 0,
|
|
||||||
"out_queue": 0,
|
|
||||||
"server_err": 0,
|
|
||||||
"out_queue_bytes": 0,
|
|
||||||
"in_queue": 0,
|
|
||||||
"server_timedout": 24,
|
|
||||||
"request_bytes": 2775840400,
|
|
||||||
"server_connections": 1,
|
|
||||||
"response_bytes": 7663182096,
|
|
||||||
"in_queue_bytes": 0,
|
|
||||||
"server_ejected_at": 0,
|
|
||||||
"responses": 43603900
|
|
||||||
},
|
|
||||||
"10.16.29.2:6379": {
|
|
||||||
"requests": 37870211,
|
|
||||||
"server_eof": 0,
|
|
||||||
"out_queue": 0,
|
|
||||||
"server_err": 0,
|
|
||||||
"out_queue_bytes": 0,
|
|
||||||
"in_queue": 0,
|
|
||||||
"server_timedout": 25,
|
|
||||||
"request_bytes": 2412114759,
|
|
||||||
"server_connections": 1,
|
|
||||||
"response_bytes": 5228980582,
|
|
||||||
"in_queue_bytes": 0,
|
|
||||||
"server_ejected_at": 0,
|
|
||||||
"responses": 37869551
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"timestamp": 1447312436
|
|
||||||
}`
|
|
||||||
|
|
||||||
func mockTwemproxyServer() (net.Listener, error) {
|
|
||||||
listener, err := net.Listen("tcp", sampleAddr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
go func(l net.Listener) {
|
|
||||||
for {
|
|
||||||
conn, _ := l.Accept()
|
|
||||||
conn.Write([]byte(sampleStats))
|
|
||||||
conn.Close()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}(listener)
|
|
||||||
|
|
||||||
return listener, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGather(t *testing.T) {
|
|
||||||
mockServer, err := mockTwemproxyServer()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer mockServer.Close()
|
|
||||||
|
|
||||||
twemproxy := &Twemproxy{
|
|
||||||
Addr: sampleAddr,
|
|
||||||
Pools: []string{"demo"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
acc.SetDebug(true)
|
|
||||||
err = twemproxy.Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
var sourceData map[string]interface{}
|
|
||||||
if err := json.Unmarshal([]byte(sampleStats), &sourceData); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
|
||||||
"total_connections": float64(276448),
|
|
||||||
"curr_connections": float64(1322),
|
|
||||||
"timestamp": float64(1.447312436e+09),
|
|
||||||
}
|
|
||||||
tags := map[string]string{
|
|
||||||
"twemproxy": sampleAddr,
|
|
||||||
"source": sourceData["source"].(string),
|
|
||||||
}
|
|
||||||
acc.AssertContainsTaggedFields(t, "twemproxy", fields, tags)
|
|
||||||
|
|
||||||
poolName := "demo"
|
|
||||||
poolFields := map[string]interface{}{
|
|
||||||
"client_connections": float64(1305),
|
|
||||||
"client_eof": float64(126813),
|
|
||||||
"client_err": float64(147942),
|
|
||||||
"forward_error": float64(11684),
|
|
||||||
"fragments": float64(0),
|
|
||||||
"server_ejects": float64(0),
|
|
||||||
}
|
|
||||||
tags["pool"] = poolName
|
|
||||||
acc.AssertContainsTaggedFields(t, "twemproxy_pool", poolFields, tags)
|
|
||||||
|
|
||||||
poolServerTags1 := map[string]string{
|
|
||||||
"pool": "demo",
|
|
||||||
"server": "10.16.29.2:6379",
|
|
||||||
"source": "server1.website.com",
|
|
||||||
"twemproxy": "127.0.0.1:22222",
|
|
||||||
}
|
|
||||||
poolServerFields1 := map[string]interface{}{
|
|
||||||
"in_queue": float64(0),
|
|
||||||
"in_queue_bytes": float64(0),
|
|
||||||
"out_queue": float64(0),
|
|
||||||
"out_queue_bytes": float64(0),
|
|
||||||
"request_bytes": float64(2.412114759e+09),
|
|
||||||
"requests": float64(3.7870211e+07),
|
|
||||||
"response_bytes": float64(5.228980582e+09),
|
|
||||||
"responses": float64(3.7869551e+07),
|
|
||||||
"server_connections": float64(1),
|
|
||||||
"server_ejected_at": float64(0),
|
|
||||||
"server_eof": float64(0),
|
|
||||||
"server_err": float64(0),
|
|
||||||
"server_timedout": float64(25),
|
|
||||||
}
|
|
||||||
acc.AssertContainsTaggedFields(t, "twemproxy_pool_server",
|
|
||||||
poolServerFields1, poolServerTags1)
|
|
||||||
|
|
||||||
poolServerTags2 := map[string]string{
|
|
||||||
"pool": "demo",
|
|
||||||
"server": "10.16.29.1:6379",
|
|
||||||
"source": "server1.website.com",
|
|
||||||
"twemproxy": "127.0.0.1:22222",
|
|
||||||
}
|
|
||||||
poolServerFields2 := map[string]interface{}{
|
|
||||||
"in_queue": float64(0),
|
|
||||||
"in_queue_bytes": float64(0),
|
|
||||||
"out_queue": float64(0),
|
|
||||||
"out_queue_bytes": float64(0),
|
|
||||||
"request_bytes": float64(2.7758404e+09),
|
|
||||||
"requests": float64(4.3604566e+07),
|
|
||||||
"response_bytes": float64(7.663182096e+09),
|
|
||||||
"responses": float64(4.36039e+07),
|
|
||||||
"server_connections": float64(1),
|
|
||||||
"server_ejected_at": float64(0),
|
|
||||||
"server_eof": float64(0),
|
|
||||||
"server_err": float64(0),
|
|
||||||
"server_timedout": float64(24),
|
|
||||||
}
|
|
||||||
acc.AssertContainsTaggedFields(t, "twemproxy_pool_server",
|
|
||||||
poolServerFields2, poolServerTags2)
|
|
||||||
}
|
|
||||||
@@ -1,366 +0,0 @@
|
|||||||
package zfs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/testutil"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
const arcstatsContents = `5 1 0x01 86 4128 23617128247 12081618582809582
|
|
||||||
name type data
|
|
||||||
hits 4 5968846374
|
|
||||||
misses 4 1659178751
|
|
||||||
demand_data_hits 4 4860247322
|
|
||||||
demand_data_misses 4 501499535
|
|
||||||
demand_metadata_hits 4 708608325
|
|
||||||
demand_metadata_misses 4 156591375
|
|
||||||
prefetch_data_hits 4 367047144
|
|
||||||
prefetch_data_misses 4 974529898
|
|
||||||
prefetch_metadata_hits 4 32943583
|
|
||||||
prefetch_metadata_misses 4 26557943
|
|
||||||
mru_hits 4 301176811
|
|
||||||
mru_ghost_hits 4 47066067
|
|
||||||
mfu_hits 4 5520612438
|
|
||||||
mfu_ghost_hits 4 45784009
|
|
||||||
deleted 4 1718937704
|
|
||||||
recycle_miss 4 481222994
|
|
||||||
mutex_miss 4 20575623
|
|
||||||
evict_skip 4 14655903906543
|
|
||||||
evict_l2_cached 4 145310202998272
|
|
||||||
evict_l2_eligible 4 16345402777088
|
|
||||||
evict_l2_ineligible 4 7437226893312
|
|
||||||
hash_elements 4 36617980
|
|
||||||
hash_elements_max 4 36618318
|
|
||||||
hash_collisions 4 554145157
|
|
||||||
hash_chains 4 4187651
|
|
||||||
hash_chain_max 4 26
|
|
||||||
p 4 13963222064
|
|
||||||
c 4 16381258376
|
|
||||||
c_min 4 4194304
|
|
||||||
c_max 4 16884125696
|
|
||||||
size 4 16319887096
|
|
||||||
hdr_size 4 42567864
|
|
||||||
data_size 4 60066304
|
|
||||||
meta_size 4 1701534208
|
|
||||||
other_size 4 1661543168
|
|
||||||
anon_size 4 94720
|
|
||||||
anon_evict_data 4 0
|
|
||||||
anon_evict_metadata 4 0
|
|
||||||
mru_size 4 973099008
|
|
||||||
mru_evict_data 4 9175040
|
|
||||||
mru_evict_metadata 4 32768
|
|
||||||
mru_ghost_size 4 32768
|
|
||||||
mru_ghost_evict_data 4 0
|
|
||||||
mru_ghost_evict_metadata 4 32768
|
|
||||||
mfu_size 4 788406784
|
|
||||||
mfu_evict_data 4 50881024
|
|
||||||
mfu_evict_metadata 4 81920
|
|
||||||
mfu_ghost_size 4 0
|
|
||||||
mfu_ghost_evict_data 4 0
|
|
||||||
mfu_ghost_evict_metadata 4 0
|
|
||||||
l2_hits 4 573868618
|
|
||||||
l2_misses 4 1085309718
|
|
||||||
l2_feeds 4 12182087
|
|
||||||
l2_rw_clash 4 9610
|
|
||||||
l2_read_bytes 4 32695938336768
|
|
||||||
l2_write_bytes 4 2826774778880
|
|
||||||
l2_writes_sent 4 4267687
|
|
||||||
l2_writes_done 4 4267687
|
|
||||||
l2_writes_error 4 0
|
|
||||||
l2_writes_hdr_miss 4 164
|
|
||||||
l2_evict_lock_retry 4 5
|
|
||||||
l2_evict_reading 4 0
|
|
||||||
l2_free_on_write 4 1606914
|
|
||||||
l2_cdata_free_on_write 4 1775
|
|
||||||
l2_abort_lowmem 4 83462
|
|
||||||
l2_cksum_bad 4 393860640
|
|
||||||
l2_io_error 4 53881460
|
|
||||||
l2_size 4 2471466648576
|
|
||||||
l2_asize 4 2461690072064
|
|
||||||
l2_hdr_size 4 12854175552
|
|
||||||
l2_compress_successes 4 12184849
|
|
||||||
l2_compress_zeros 4 0
|
|
||||||
l2_compress_failures 4 0
|
|
||||||
memory_throttle_count 4 0
|
|
||||||
duplicate_buffers 4 0
|
|
||||||
duplicate_buffers_size 4 0
|
|
||||||
duplicate_reads 4 0
|
|
||||||
memory_direct_count 4 5159942
|
|
||||||
memory_indirect_count 4 3034640
|
|
||||||
arc_no_grow 4 0
|
|
||||||
arc_tempreserve 4 0
|
|
||||||
arc_loaned_bytes 4 0
|
|
||||||
arc_prune 4 114554259559
|
|
||||||
arc_meta_used 4 16259820792
|
|
||||||
arc_meta_limit 4 12663094272
|
|
||||||
arc_meta_max 4 18327165696
|
|
||||||
`
|
|
||||||
|
|
||||||
const zfetchstatsContents = `3 1 0x01 11 528 23607270446 12081656848148208
|
|
||||||
name type data
|
|
||||||
hits 4 7812959060
|
|
||||||
misses 4 4154484207
|
|
||||||
colinear_hits 4 1366368
|
|
||||||
colinear_misses 4 4153117839
|
|
||||||
stride_hits 4 7309776732
|
|
||||||
stride_misses 4 222766182
|
|
||||||
reclaim_successes 4 107788388
|
|
||||||
reclaim_failures 4 4045329451
|
|
||||||
streams_resets 4 20989756
|
|
||||||
streams_noresets 4 503182328
|
|
||||||
bogus_streams 4 0
|
|
||||||
`
|
|
||||||
const vdev_cache_statsContents = `7 1 0x01 3 144 23617323692 12081684236238879
|
|
||||||
name type data
|
|
||||||
delegations 4 0
|
|
||||||
hits 4 0
|
|
||||||
misses 4 0
|
|
||||||
`
|
|
||||||
const pool_ioContents = `11 3 0x00 1 80 2225326830828 32953476980628
|
|
||||||
nread nwritten reads writes wtime wlentime wupdate rtime rlentime rupdate wcnt rcnt
|
|
||||||
1884160 6450688 22 978 272187126 2850519036 2263669418655 424226814 2850519036 2263669871823 0 0
|
|
||||||
`
|
|
||||||
|
|
||||||
var testKstatPath = os.TempDir() + "/telegraf/proc/spl/kstat/zfs"
|
|
||||||
|
|
||||||
func TestZfsPoolMetrics(t *testing.T) {
|
|
||||||
err := os.MkdirAll(testKstatPath, 0755)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = os.MkdirAll(testKstatPath+"/HOME", 0755)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(testKstatPath+"/HOME/io", []byte(pool_ioContents), 0644)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(testKstatPath+"/arcstats", []byte(arcstatsContents), 0644)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
poolMetrics := getPoolMetrics()
|
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
|
|
||||||
z := &Zfs{KstatPath: testKstatPath, KstatMetrics: []string{"arcstats"}}
|
|
||||||
err = z.Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.False(t, acc.HasMeasurement("zfs_pool"))
|
|
||||||
acc.Points = nil
|
|
||||||
|
|
||||||
z = &Zfs{KstatPath: testKstatPath, KstatMetrics: []string{"arcstats"}, PoolMetrics: true}
|
|
||||||
err = z.Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
//one pool, all metrics
|
|
||||||
tags := map[string]string{
|
|
||||||
"pool": "HOME",
|
|
||||||
}
|
|
||||||
|
|
||||||
acc.AssertContainsTaggedFields(t, "zfs_pool", poolMetrics, tags)
|
|
||||||
|
|
||||||
err = os.RemoveAll(os.TempDir() + "/telegraf")
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestZfsGeneratesMetrics(t *testing.T) {
|
|
||||||
err := os.MkdirAll(testKstatPath, 0755)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = os.MkdirAll(testKstatPath+"/HOME", 0755)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(testKstatPath+"/HOME/io", []byte(""), 0644)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(testKstatPath+"/arcstats", []byte(arcstatsContents), 0644)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(testKstatPath+"/zfetchstats", []byte(zfetchstatsContents), 0644)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(testKstatPath+"/vdev_cache_stats", []byte(vdev_cache_statsContents), 0644)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
intMetrics := getKstatMetricsAll()
|
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
|
||||||
|
|
||||||
//one pool, all metrics
|
|
||||||
tags := map[string]string{
|
|
||||||
"pools": "HOME",
|
|
||||||
}
|
|
||||||
|
|
||||||
z := &Zfs{KstatPath: testKstatPath}
|
|
||||||
err = z.Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
acc.AssertContainsTaggedFields(t, "zfs", intMetrics, tags)
|
|
||||||
acc.Points = nil
|
|
||||||
|
|
||||||
//two pools, all metrics
|
|
||||||
err = os.MkdirAll(testKstatPath+"/STORAGE", 0755)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(testKstatPath+"/STORAGE/io", []byte(""), 0644)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
tags = map[string]string{
|
|
||||||
"pools": "HOME::STORAGE",
|
|
||||||
}
|
|
||||||
|
|
||||||
z = &Zfs{KstatPath: testKstatPath}
|
|
||||||
acc = testutil.Accumulator{}
|
|
||||||
err = z.Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
acc.AssertContainsTaggedFields(t, "zfs", intMetrics, tags)
|
|
||||||
acc.Points = nil
|
|
||||||
|
|
||||||
intMetrics = getKstatMetricsArcOnly()
|
|
||||||
|
|
||||||
//two pools, one metric
|
|
||||||
z = &Zfs{KstatPath: testKstatPath, KstatMetrics: []string{"arcstats"}}
|
|
||||||
acc = testutil.Accumulator{}
|
|
||||||
err = z.Gather(&acc)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
acc.AssertContainsTaggedFields(t, "zfs", intMetrics, tags)
|
|
||||||
|
|
||||||
err = os.RemoveAll(os.TempDir() + "/telegraf")
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getKstatMetricsArcOnly() map[string]interface{} {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"arcstats_hits": int64(5968846374),
|
|
||||||
"arcstats_misses": int64(1659178751),
|
|
||||||
"arcstats_demand_data_hits": int64(4860247322),
|
|
||||||
"arcstats_demand_data_misses": int64(501499535),
|
|
||||||
"arcstats_demand_metadata_hits": int64(708608325),
|
|
||||||
"arcstats_demand_metadata_misses": int64(156591375),
|
|
||||||
"arcstats_prefetch_data_hits": int64(367047144),
|
|
||||||
"arcstats_prefetch_data_misses": int64(974529898),
|
|
||||||
"arcstats_prefetch_metadata_hits": int64(32943583),
|
|
||||||
"arcstats_prefetch_metadata_misses": int64(26557943),
|
|
||||||
"arcstats_mru_hits": int64(301176811),
|
|
||||||
"arcstats_mru_ghost_hits": int64(47066067),
|
|
||||||
"arcstats_mfu_hits": int64(5520612438),
|
|
||||||
"arcstats_mfu_ghost_hits": int64(45784009),
|
|
||||||
"arcstats_deleted": int64(1718937704),
|
|
||||||
"arcstats_recycle_miss": int64(481222994),
|
|
||||||
"arcstats_mutex_miss": int64(20575623),
|
|
||||||
"arcstats_evict_skip": int64(14655903906543),
|
|
||||||
"arcstats_evict_l2_cached": int64(145310202998272),
|
|
||||||
"arcstats_evict_l2_eligible": int64(16345402777088),
|
|
||||||
"arcstats_evict_l2_ineligible": int64(7437226893312),
|
|
||||||
"arcstats_hash_elements": int64(36617980),
|
|
||||||
"arcstats_hash_elements_max": int64(36618318),
|
|
||||||
"arcstats_hash_collisions": int64(554145157),
|
|
||||||
"arcstats_hash_chains": int64(4187651),
|
|
||||||
"arcstats_hash_chain_max": int64(26),
|
|
||||||
"arcstats_p": int64(13963222064),
|
|
||||||
"arcstats_c": int64(16381258376),
|
|
||||||
"arcstats_c_min": int64(4194304),
|
|
||||||
"arcstats_c_max": int64(16884125696),
|
|
||||||
"arcstats_size": int64(16319887096),
|
|
||||||
"arcstats_hdr_size": int64(42567864),
|
|
||||||
"arcstats_data_size": int64(60066304),
|
|
||||||
"arcstats_meta_size": int64(1701534208),
|
|
||||||
"arcstats_other_size": int64(1661543168),
|
|
||||||
"arcstats_anon_size": int64(94720),
|
|
||||||
"arcstats_anon_evict_data": int64(0),
|
|
||||||
"arcstats_anon_evict_metadata": int64(0),
|
|
||||||
"arcstats_mru_size": int64(973099008),
|
|
||||||
"arcstats_mru_evict_data": int64(9175040),
|
|
||||||
"arcstats_mru_evict_metadata": int64(32768),
|
|
||||||
"arcstats_mru_ghost_size": int64(32768),
|
|
||||||
"arcstats_mru_ghost_evict_data": int64(0),
|
|
||||||
"arcstats_mru_ghost_evict_metadata": int64(32768),
|
|
||||||
"arcstats_mfu_size": int64(788406784),
|
|
||||||
"arcstats_mfu_evict_data": int64(50881024),
|
|
||||||
"arcstats_mfu_evict_metadata": int64(81920),
|
|
||||||
"arcstats_mfu_ghost_size": int64(0),
|
|
||||||
"arcstats_mfu_ghost_evict_data": int64(0),
|
|
||||||
"arcstats_mfu_ghost_evict_metadata": int64(0),
|
|
||||||
"arcstats_l2_hits": int64(573868618),
|
|
||||||
"arcstats_l2_misses": int64(1085309718),
|
|
||||||
"arcstats_l2_feeds": int64(12182087),
|
|
||||||
"arcstats_l2_rw_clash": int64(9610),
|
|
||||||
"arcstats_l2_read_bytes": int64(32695938336768),
|
|
||||||
"arcstats_l2_write_bytes": int64(2826774778880),
|
|
||||||
"arcstats_l2_writes_sent": int64(4267687),
|
|
||||||
"arcstats_l2_writes_done": int64(4267687),
|
|
||||||
"arcstats_l2_writes_error": int64(0),
|
|
||||||
"arcstats_l2_writes_hdr_miss": int64(164),
|
|
||||||
"arcstats_l2_evict_lock_retry": int64(5),
|
|
||||||
"arcstats_l2_evict_reading": int64(0),
|
|
||||||
"arcstats_l2_free_on_write": int64(1606914),
|
|
||||||
"arcstats_l2_cdata_free_on_write": int64(1775),
|
|
||||||
"arcstats_l2_abort_lowmem": int64(83462),
|
|
||||||
"arcstats_l2_cksum_bad": int64(393860640),
|
|
||||||
"arcstats_l2_io_error": int64(53881460),
|
|
||||||
"arcstats_l2_size": int64(2471466648576),
|
|
||||||
"arcstats_l2_asize": int64(2461690072064),
|
|
||||||
"arcstats_l2_hdr_size": int64(12854175552),
|
|
||||||
"arcstats_l2_compress_successes": int64(12184849),
|
|
||||||
"arcstats_l2_compress_zeros": int64(0),
|
|
||||||
"arcstats_l2_compress_failures": int64(0),
|
|
||||||
"arcstats_memory_throttle_count": int64(0),
|
|
||||||
"arcstats_duplicate_buffers": int64(0),
|
|
||||||
"arcstats_duplicate_buffers_size": int64(0),
|
|
||||||
"arcstats_duplicate_reads": int64(0),
|
|
||||||
"arcstats_memory_direct_count": int64(5159942),
|
|
||||||
"arcstats_memory_indirect_count": int64(3034640),
|
|
||||||
"arcstats_arc_no_grow": int64(0),
|
|
||||||
"arcstats_arc_tempreserve": int64(0),
|
|
||||||
"arcstats_arc_loaned_bytes": int64(0),
|
|
||||||
"arcstats_arc_prune": int64(114554259559),
|
|
||||||
"arcstats_arc_meta_used": int64(16259820792),
|
|
||||||
"arcstats_arc_meta_limit": int64(12663094272),
|
|
||||||
"arcstats_arc_meta_max": int64(18327165696),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getKstatMetricsAll() map[string]interface{} {
|
|
||||||
otherMetrics := map[string]interface{}{
|
|
||||||
"zfetchstats_hits": int64(7812959060),
|
|
||||||
"zfetchstats_misses": int64(4154484207),
|
|
||||||
"zfetchstats_colinear_hits": int64(1366368),
|
|
||||||
"zfetchstats_colinear_misses": int64(4153117839),
|
|
||||||
"zfetchstats_stride_hits": int64(7309776732),
|
|
||||||
"zfetchstats_stride_misses": int64(222766182),
|
|
||||||
"zfetchstats_reclaim_successes": int64(107788388),
|
|
||||||
"zfetchstats_reclaim_failures": int64(4045329451),
|
|
||||||
"zfetchstats_streams_resets": int64(20989756),
|
|
||||||
"zfetchstats_streams_noresets": int64(503182328),
|
|
||||||
"zfetchstats_bogus_streams": int64(0),
|
|
||||||
"vdev_cache_stats_delegations": int64(0),
|
|
||||||
"vdev_cache_stats_hits": int64(0),
|
|
||||||
"vdev_cache_stats_misses": int64(0),
|
|
||||||
}
|
|
||||||
arcMetrics := getKstatMetricsArcOnly()
|
|
||||||
for k, v := range otherMetrics {
|
|
||||||
arcMetrics[k] = v
|
|
||||||
}
|
|
||||||
return arcMetrics
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPoolMetrics() map[string]interface{} {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"nread": int64(1884160),
|
|
||||||
"nwritten": int64(6450688),
|
|
||||||
"reads": int64(22),
|
|
||||||
"writes": int64(978),
|
|
||||||
"wtime": int64(272187126),
|
|
||||||
"wlentime": int64(2850519036),
|
|
||||||
"wupdate": int64(2263669418655),
|
|
||||||
"rtime": int64(424226814),
|
|
||||||
"rlentime": int64(2850519036),
|
|
||||||
"rupdate": int64(2263669871823),
|
|
||||||
"wcnt": int64(0),
|
|
||||||
"rcnt": int64(0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
@@ -49,7 +49,7 @@ func (j *Jolokia) SampleConfig() string {
|
|||||||
context = "/jolokia/read"
|
context = "/jolokia/read"
|
||||||
|
|
||||||
# List of servers exposing jolokia read service
|
# List of servers exposing jolokia read service
|
||||||
[[inputs.jolokia.servers]]
|
[[plugins.jolokia.servers]]
|
||||||
name = "stable"
|
name = "stable"
|
||||||
host = "192.168.103.2"
|
host = "192.168.103.2"
|
||||||
port = "8180"
|
port = "8180"
|
||||||
@@ -59,7 +59,7 @@ func (j *Jolokia) SampleConfig() string {
|
|||||||
# List of metrics collected on above servers
|
# List of metrics collected on above servers
|
||||||
# Each metric consists in a name, a jmx path and either a pass or drop slice attributes
|
# Each metric consists in a name, a jmx path and either a pass or drop slice attributes
|
||||||
# This collect all heap memory usage metrics
|
# This collect all heap memory usage metrics
|
||||||
[[inputs.jolokia.metrics]]
|
[[plugins.jolokia.metrics]]
|
||||||
name = "heap_memory_usage"
|
name = "heap_memory_usage"
|
||||||
jmx = "/java.lang:type=Memory/HeapMemoryUsage"
|
jmx = "/java.lang:type=Memory/HeapMemoryUsage"
|
||||||
`
|
`
|
||||||
@@ -75,6 +75,7 @@ func (j *Jolokia) getAttr(requestUrl *url.URL) (map[string]interface{}, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer req.Body.Close()
|
||||||
|
|
||||||
resp, err := j.jClient.MakeRequest(req)
|
resp, err := j.jClient.MakeRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -108,7 +109,7 @@ func (j *Jolokia) getAttr(requestUrl *url.URL) (map[string]interface{}, error) {
|
|||||||
return jsonOut, nil
|
return jsonOut, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *Jolokia) Gather(acc inputs.Accumulator) error {
|
func (j *Jolokia) Gather(acc plugins.Accumulator) error {
|
||||||
context := j.Context //"/jolokia/read"
|
context := j.Context //"/jolokia/read"
|
||||||
servers := j.Servers
|
servers := j.Servers
|
||||||
metrics := j.Metrics
|
metrics := j.Metrics
|
||||||
@@ -157,7 +158,7 @@ func (j *Jolokia) Gather(acc inputs.Accumulator) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("jolokia", func() inputs.Input {
|
plugins.Add("jolokia", func() plugins.Plugin {
|
||||||
return &Jolokia{jClient: &JolokiaClientImpl{client: &http.Client{}}}
|
return &Jolokia{jClient: &JolokiaClientImpl{client: &http.Client{}}}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ const empty = ""
|
|||||||
|
|
||||||
var Servers = []Server{Server{Name: "as1", Host: "127.0.0.1", Port: "8080"}}
|
var Servers = []Server{Server{Name: "as1", Host: "127.0.0.1", Port: "8080"}}
|
||||||
var HeapMetric = Metric{Name: "heap_memory_usage", Jmx: "/java.lang:type=Memory/HeapMemoryUsage"}
|
var HeapMetric = Metric{Name: "heap_memory_usage", Jmx: "/java.lang:type=Memory/HeapMemoryUsage"}
|
||||||
var UsedHeapMetric = Metric{Name: "heap_memory_usage", Jmx: "/java.lang:type=Memory/HeapMemoryUsage"}
|
var UsedHeapMetric = Metric{Name: "heap_memory_usage", Jmx: "/java.lang:type=Memory/HeapMemoryUsage", Pass: []string{"used"}}
|
||||||
|
|
||||||
type jolokiaClientStub struct {
|
type jolokiaClientStub struct {
|
||||||
responseBody string
|
responseBody string
|
||||||
@@ -79,6 +79,7 @@ func genJolokiaClientStub(response string, statusCode int, servers []Server, met
|
|||||||
|
|
||||||
// Test that the proper values are ignored or collected
|
// Test that the proper values are ignored or collected
|
||||||
func TestHttpJsonMultiValue(t *testing.T) {
|
func TestHttpJsonMultiValue(t *testing.T) {
|
||||||
|
|
||||||
jolokia := genJolokiaClientStub(validMultiValueJSON, 200, Servers, []Metric{HeapMetric})
|
jolokia := genJolokiaClientStub(validMultiValueJSON, 200, Servers, []Metric{HeapMetric})
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
@@ -87,28 +88,58 @@ func TestHttpJsonMultiValue(t *testing.T) {
|
|||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 1, len(acc.Points))
|
assert.Equal(t, 1, len(acc.Points))
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
assert.True(t, acc.CheckFieldsValue("heap_memory_usage", map[string]interface{}{"init": 67108864.0,
|
||||||
"heap_memory_usage_init": 67108864.0,
|
"committed": 456130560.0,
|
||||||
"heap_memory_usage_committed": 456130560.0,
|
"max": 477626368.0,
|
||||||
"heap_memory_usage_max": 477626368.0,
|
"used": 203288528.0}))
|
||||||
"heap_memory_usage_used": 203288528.0,
|
}
|
||||||
}
|
|
||||||
tags := map[string]string{
|
// Test that the proper values are ignored or collected
|
||||||
"host": "127.0.0.1",
|
func TestHttpJsonMultiValueWithPass(t *testing.T) {
|
||||||
"port": "8080",
|
|
||||||
"server": "as1",
|
jolokia := genJolokiaClientStub(validMultiValueJSON, 200, Servers, []Metric{UsedHeapMetric})
|
||||||
}
|
|
||||||
acc.AssertContainsTaggedFields(t, "jolokia", fields, tags)
|
var acc testutil.Accumulator
|
||||||
|
err := jolokia.Gather(&acc)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, 1, len(acc.Points))
|
||||||
|
|
||||||
|
assert.True(t, acc.CheckFieldsValue("heap_memory_usage", map[string]interface{}{"used": 203288528.0}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the proper values are ignored or collected
|
||||||
|
func TestHttpJsonMultiValueTags(t *testing.T) {
|
||||||
|
|
||||||
|
jolokia := genJolokiaClientStub(validMultiValueJSON, 200, Servers, []Metric{UsedHeapMetric})
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
err := jolokia.Gather(&acc)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, 1, len(acc.Points))
|
||||||
|
assert.NoError(t, acc.ValidateTaggedFieldsValue("heap_memory_usage", map[string]interface{}{"used": 203288528.0}, map[string]string{"host": "127.0.0.1", "port": "8080", "server": "as1"}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the proper values are ignored or collected
|
||||||
|
func TestHttpJsonSingleValueTags(t *testing.T) {
|
||||||
|
|
||||||
|
jolokia := genJolokiaClientStub(validSingleValueJSON, 200, Servers, []Metric{UsedHeapMetric})
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
err := jolokia.Gather(&acc)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, 1, len(acc.Points))
|
||||||
|
assert.NoError(t, acc.ValidateTaggedFieldsValue("heap_memory_usage", map[string]interface{}{"value": 209274376.0}, map[string]string{"host": "127.0.0.1", "port": "8080", "server": "as1"}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that the proper values are ignored or collected
|
// Test that the proper values are ignored or collected
|
||||||
func TestHttpJsonOn404(t *testing.T) {
|
func TestHttpJsonOn404(t *testing.T) {
|
||||||
|
|
||||||
jolokia := genJolokiaClientStub(validMultiValueJSON, 404, Servers,
|
jolokia := genJolokiaClientStub(validMultiValueJSON, 404, Servers, []Metric{UsedHeapMetric})
|
||||||
[]Metric{UsedHeapMetric})
|
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
acc.SetDebug(true)
|
|
||||||
err := jolokia.Gather(&acc)
|
err := jolokia.Gather(&acc)
|
||||||
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/influxdb/influxdb/models"
|
"github.com/influxdb/influxdb/models"
|
||||||
"github.com/influxdb/telegraf/plugins/inputs"
|
"github.com/influxdb/telegraf/plugins"
|
||||||
|
|
||||||
"github.com/Shopify/sarama"
|
"github.com/Shopify/sarama"
|
||||||
"github.com/wvanbergen/kafka/consumergroup"
|
"github.com/wvanbergen/kafka/consumergroup"
|
||||||
@@ -148,7 +148,7 @@ func (k *Kafka) Stop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Kafka) Gather(acc inputs.Accumulator) error {
|
func (k *Kafka) Gather(acc plugins.Accumulator) error {
|
||||||
k.Lock()
|
k.Lock()
|
||||||
defer k.Unlock()
|
defer k.Unlock()
|
||||||
npoints := len(k.pointChan)
|
npoints := len(k.pointChan)
|
||||||
@@ -160,7 +160,7 @@ func (k *Kafka) Gather(acc inputs.Accumulator) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("kafka_consumer", func() inputs.Input {
|
plugins.Add("kafka_consumer", func() plugins.Plugin {
|
||||||
return &Kafka{}
|
return &Kafka{}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -85,8 +85,7 @@ func TestRunParserAndGather(t *testing.T) {
|
|||||||
k.Gather(&acc)
|
k.Gather(&acc)
|
||||||
|
|
||||||
assert.Equal(t, len(acc.Points), 1)
|
assert.Equal(t, len(acc.Points), 1)
|
||||||
acc.AssertContainsFields(t, "cpu_load_short",
|
assert.True(t, acc.CheckValue("cpu_load_short", 23422.0))
|
||||||
map[string]interface{}{"value": float64(23422)})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func saramaMsg(val string) *sarama.ConsumerMessage {
|
func saramaMsg(val string) *sarama.ConsumerMessage {
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user