Compare commits

..

7 Commits

Author SHA1 Message Date
Gunnar Aasen
4b8d0ad35d Additional code cleanup 2018-05-24 09:45:45 -07:00
Gunnar Aasen
78e5f52966 Revert Godeps changes 2018-05-24 09:45:45 -07:00
Gunnar Aasen
79b6edadd2 Refactor to use AggregatingOutput 2018-05-24 09:44:16 -07:00
Gunnar Aasen
9490a22aeb Output: Azure Monitor: Cleanup and add README 2018-05-24 09:44:16 -07:00
Gunnar Aasen
17093efad5 Output: Azure Monitor: Initial aggregated metric implementation 2018-05-24 09:44:16 -07:00
Mark Simms
d077f5dbc7 Starting on azure monitor metrics integration with MSI auth 2018-05-24 09:42:31 -07:00
Daniel Nelson
6cea487bfc Add idea for an output that aggregates before adding to metric buffer 2018-05-24 09:42:31 -07:00
164 changed files with 2489 additions and 9286 deletions

View File

@@ -2,12 +2,15 @@
defaults: defaults:
defaults: &defaults defaults: &defaults
working_directory: '/go/src/github.com/influxdata/telegraf' working_directory: '/go/src/github.com/influxdata/telegraf'
go-1_8: &go-1_8
docker:
- image: 'circleci/golang:1.8.7'
go-1_9: &go-1_9 go-1_9: &go-1_9
docker: docker:
- image: 'circleci/golang:1.9.7' - image: 'circleci/golang:1.9.5'
go-1_10: &go-1_10 go-1_10: &go-1_10
docker: docker:
- image: 'circleci/golang:1.10.3' - image: 'circleci/golang:1.10.1'
version: 2 version: 2
jobs: jobs:
@@ -15,18 +18,17 @@ jobs:
<<: [ *defaults, *go-1_10 ] <<: [ *defaults, *go-1_10 ]
steps: steps:
- checkout - checkout
- restore_cache:
key: vendor-{{ checksum "Gopkg.lock" }}
- run: 'make deps' - run: 'make deps'
- save_cache:
name: 'vendored deps'
key: vendor-{{ checksum "Gopkg.lock" }}
paths:
- './vendor'
- persist_to_workspace: - persist_to_workspace:
root: '/go/src' root: '/go/src'
paths: paths:
- '*' - '*'
test-go-1.8:
<<: [ *defaults, *go-1_8 ]
steps:
- attach_workspace:
at: '/go/src'
- run: 'make test-ci'
test-go-1.9: test-go-1.9:
<<: [ *defaults, *go-1_9 ] <<: [ *defaults, *go-1_9 ]
steps: steps:
@@ -64,6 +66,9 @@ workflows:
build_and_release: build_and_release:
jobs: jobs:
- 'deps' - 'deps'
- 'test-go-1.8':
requires:
- 'deps'
- 'test-go-1.9': - 'test-go-1.9':
requires: requires:
- 'deps' - 'deps'
@@ -72,11 +77,15 @@ workflows:
- 'deps' - 'deps'
- 'release': - 'release':
requires: requires:
- 'test-go-1.8'
- 'test-go-1.9' - 'test-go-1.9'
- 'test-go-1.10' - 'test-go-1.10'
nightly: nightly:
jobs: jobs:
- 'deps' - 'deps'
- 'test-go-1.8':
requires:
- 'deps'
- 'test-go-1.9': - 'test-go-1.9':
requires: requires:
- 'deps' - 'deps'
@@ -85,6 +94,7 @@ workflows:
- 'deps' - 'deps'
- 'nightly': - 'nightly':
requires: requires:
- 'test-go-1.8'
- 'test-go-1.9' - 'test-go-1.9'
- 'test-go-1.10' - 'test-go-1.10'
triggers: triggers:

1
.gitignore vendored
View File

@@ -2,4 +2,3 @@
/telegraf /telegraf
/telegraf.exe /telegraf.exe
/telegraf.gz /telegraf.gz
/vendor

View File

@@ -1,53 +1,4 @@
## v1.8 [unreleased] ## v1.7 [unreleased]
### Release Notes
### New Inputs
- [tengine](./plugins/inputs/tengine/README.md) - Contributed by @ertaoxu
### New Processors
- [enum](./plugins/processors/enum/README.md) - Contributed by @KarstenSchnitter
### New Aggregators
- [valuecounter](./plugins/aggregators/valuecounter/README.md) - Contributed by @piotr1212
### Features
- [#4236](https://github.com/influxdata/telegraf/pull/4236): Add SSL/TLS support to redis input.
- [#4160](https://github.com/influxdata/telegraf/pull/4160): Add tengine input plugin.
- [#4262](https://github.com/influxdata/telegraf/pull/4262): Add power draw field to nvidia_smi plugin.
- [#4271](https://github.com/influxdata/telegraf/pull/4271): Add support for solr 7 to the solr input.
- [#4281](https://github.com/influxdata/telegraf/pull/4281): Add owner tag on partitions in burrow input.
- [#4259](https://github.com/influxdata/telegraf/pull/4259): Add container status tag to docker input.
- [#3523](https://github.com/influxdata/telegraf/pull/3523): Add valuecounter aggregator plugin.
- [#4307](https://github.com/influxdata/telegraf/pull/4307): Add new measurement with results of pgrep lookup to procstat input.
- [#4311](https://github.com/influxdata/telegraf/pull/4311): Add support for comma in logparser timestamp format.
- [#4292](https://github.com/influxdata/telegraf/pull/4292): Add path tag to tail input plugin.
- [#4322](https://github.com/influxdata/telegraf/pull/4322): Add log message when tail is added or removed from a file.
- [#4267](https://github.com/influxdata/telegraf/pull/4267): Add option to use of counter time in win perf counters.
- [#4343](https://github.com/influxdata/telegraf/pull/4343): Add energy and power field and device id tag to fibaro input.
- [#4347](https://github.com/influxdata/telegraf/pull/4347): Add http path configuration for OpenTSDB output.
- [#4352](https://github.com/influxdata/telegraf/pull/4352): Gather IPMI metrics concurrently.
- [#4362](https://github.com/influxdata/telegraf/pull/4362): Add mongo document and connection metrics.
- [#3772](https://github.com/influxdata/telegraf/pull/3772): Add Enum Processor.
## v1.7.1 [2018-07-03]
### Bugfixes
- [#4277](https://github.com/influxdata/telegraf/pull/4277): Treat sigterm as a clean shutdown signal.
- [#4284](https://github.com/influxdata/telegraf/pull/4284): Fix selection of tags under nested objects in the JSON parser.
- [#4135](https://github.com/influxdata/telegraf/issues/4135): Fix postfix input handling multi-level queues.
- [#4334](https://github.com/influxdata/telegraf/pull/4334): Fix syslog timestamp parsing with single digit day of month.
- [#2910](https://github.com/influxdata/telegraf/issues/2910): Handle mysql input variations in the user_statistics collecting.
- [#4293](https://github.com/influxdata/telegraf/issues/4293): Fix minmax and basicstats aggregators to use uint64.
- [#4290](https://github.com/influxdata/telegraf/issues/4290): Document swap input plugin.
- [#4316](https://github.com/influxdata/telegraf/issues/4316): Fix incorrect precision being applied to metric in http_listener.
## v1.7 [2018-06-12]
### Release Notes ### Release Notes
@@ -68,7 +19,6 @@
- [jti_openconfig_telemetry](./plugins/inputs/jti_openconfig_telemetry/README.md) - Contributed by @ajhai - [jti_openconfig_telemetry](./plugins/inputs/jti_openconfig_telemetry/README.md) - Contributed by @ajhai
- [mcrouter](./plugins/inputs/mcrouter/README.md) - Contributed by @cthayer - [mcrouter](./plugins/inputs/mcrouter/README.md) - Contributed by @cthayer
- [nvidia_smi](./plugins/inputs/nvidia_smi/README.md) - Contributed by @jackzampolin - [nvidia_smi](./plugins/inputs/nvidia_smi/README.md) - Contributed by @jackzampolin
- [syslog](./plugins/inputs/syslog/README.md) - Contributed by @influxdata
### New Processors ### New Processors
@@ -106,12 +56,6 @@
- [#3489](https://github.com/influxdata/telegraf/pull/3489): Add burrow input plugin. - [#3489](https://github.com/influxdata/telegraf/pull/3489): Add burrow input plugin.
- [#3969](https://github.com/influxdata/telegraf/pull/3969): Add option to unbound module to use threads as tags. - [#3969](https://github.com/influxdata/telegraf/pull/3969): Add option to unbound module to use threads as tags.
- [#4183](https://github.com/influxdata/telegraf/pull/4183): Add support for TLS and username/password auth to aerospike input. - [#4183](https://github.com/influxdata/telegraf/pull/4183): Add support for TLS and username/password auth to aerospike input.
- [#4190](https://github.com/influxdata/telegraf/pull/4190): Add special syslog timestamp parser to grok parser that uses current year.
- [#4181](https://github.com/influxdata/telegraf/pull/4181): Add syslog input plugin.
- [#4212](https://github.com/influxdata/telegraf/pull/4212): Print the enabled aggregator and processor plugins on startup.
- [#3994](https://github.com/influxdata/telegraf/pull/3994): Add static routing_key option to amqp output.
- [#3995](https://github.com/influxdata/telegraf/pull/3995): Add passive mode exchange declaration option to amqp consumer input.
- [#4216](https://github.com/influxdata/telegraf/pull/4216): Add counter fields to pf input.
### Bugfixes ### Bugfixes
@@ -119,20 +63,6 @@
- [#4036](https://github.com/influxdata/telegraf/pull/4036): Add all win_perf_counters fields for a series in a single metric. - [#4036](https://github.com/influxdata/telegraf/pull/4036): Add all win_perf_counters fields for a series in a single metric.
- [#4118](https://github.com/influxdata/telegraf/pull/4118): Report results of dns_query instead of 0ms on timeout. - [#4118](https://github.com/influxdata/telegraf/pull/4118): Report results of dns_query instead of 0ms on timeout.
- [#4155](https://github.com/influxdata/telegraf/pull/4155): Add consul service tags to metric. - [#4155](https://github.com/influxdata/telegraf/pull/4155): Add consul service tags to metric.
- [#2879](https://github.com/influxdata/telegraf/issues/2879): Fix wildcards and multi instance processes in win_perf_counters.
- [#2468](https://github.com/influxdata/telegraf/issues/2468): Fix crash on 32-bit Windows in win_perf_counters.
- [#4198](https://github.com/influxdata/telegraf/issues/4198): Fix win_perf_counters not collecting at every interval.
- [#4227](https://github.com/influxdata/telegraf/issues/4227): Use same flags for all BSD family ping variants.
- [#4266](https://github.com/influxdata/telegraf/issues/4266): Remove tags with empty values from Wavefront output.
## v1.6.4 [2018-06-05]
### Bugfixes
- [#4203](https://github.com/influxdata/telegraf/issues/4203): Fix snmp overriding of auto-configured table fields.
- [#4218](https://github.com/influxdata/telegraf/issues/4218): Fix uint support in cloudwatch output.
- [#4188](https://github.com/influxdata/telegraf/pull/4188): Fix documentation of instance_name option in varnish input.
- [#4195](https://github.com/influxdata/telegraf/pull/4195): Revert to previous aerospike library version due to memory leak.
## v1.6.3 [2018-05-21] ## v1.6.3 [2018-05-21]

View File

@@ -30,9 +30,9 @@ which can be found [on our website](http://influxdb.com/community/cla.html)
Assuming you can already build the project, run these in the telegraf directory: Assuming you can already build the project, run these in the telegraf directory:
1. `go get -u github.com/golang/dep/cmd/dep` 1. `go get github.com/sparrc/gdm`
2. `dep ensure` 1. `gdm restore`
3. `dep ensure -add github.com/[dependency]/[new-package]` 1. `GOOS=linux gdm save`
## Input Plugins ## Input Plugins
@@ -100,13 +100,6 @@ func init() {
} }
``` ```
### Input Plugin Development
* Run `make static` followed by `make plugin-[pluginName]` to spin up a docker dev environment
using docker-compose.
* ***[Optional]*** When developing a plugin, add a `dev` directory with a `docker-compose.yml` and `telegraf.conf`
as well as any other supporting files, where sensible.
## Adding Typed Metrics ## Adding Typed Metrics
In addition the the `AddFields` function, the accumulator also supports an In addition the the `AddFields` function, the accumulator also supports an

101
Godeps Normal file
View File

@@ -0,0 +1,101 @@
code.cloudfoundry.org/clock e9dc86bbf0e5bbe6bf7ff5a6f71e048959b61f71
collectd.org 2ce144541b8903101fb8f1483cc0497a68798122
github.com/aerospike/aerospike-client-go 9701404f4c60a6ea256595d24bf318f721a7e8b8
github.com/Azure/go-autorest 9ad9326b278af8fa5cc67c30c0ce9a58cc0862b2
github.com/amir/raidman c74861fe6a7bb8ede0a010ce4485bdbb4fc4c985
github.com/apache/thrift 4aaa92ece8503a6da9bc6701604f69acf2b99d07
github.com/aws/aws-sdk-go c861d27d0304a79f727e9a8a4e2ac1e74602fdc0
github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
github.com/bsm/sarama-cluster abf039439f66c1ce78017f560b490612552f6472
github.com/cenkalti/backoff b02f2bbce11d7ea6b97f282ef1771b0fe2f65ef3
github.com/couchbase/go-couchbase bfe555a140d53dc1adf390f1a1d4b0fd4ceadb28
github.com/couchbase/gomemcached 4a25d2f4e1dea9ea7dd76dfd943407abf9b07d29
github.com/couchbase/goutils 5823a0cbaaa9008406021dc5daf80125ea30bba6
github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76
github.com/dgrijalva/jwt-go dbeaa9332f19a944acb5736b4456cfcc02140e29
github.com/docker/docker f5ec1e2936dcbe7b5001c2b817188b095c700c27
github.com/docker/go-connections 990a1a1a70b0da4c4cb70e117971a4f0babfbf1a
github.com/eapache/go-resiliency b86b1ec0dd4209a588dc1285cdd471e73525c0b3
github.com/eapache/go-xerial-snappy bb955e01b9346ac19dc29eb16586c90ded99a98c
github.com/eapache/queue 44cc805cf13205b55f69e14bcb69867d1ae92f98
github.com/eclipse/paho.mqtt.golang aff15770515e3c57fc6109da73d42b0d46f7f483
github.com/go-logfmt/logfmt 390ab7935ee28ec6b286364bba9b4dd6410cb3d5
github.com/go-sql-driver/mysql 2e00b5cd70399450106cec6431c2e2ce3cae5034
github.com/gobwas/glob bea32b9cd2d6f55753d94a28e959b13f0244797a
github.com/go-ini/ini 9144852efba7c4daf409943ee90767da62d55438
github.com/gogo/protobuf 7b6c6391c4ff245962047fc1e2c6e08b1cdfa0e8
github.com/golang/protobuf 8ee79997227bf9b34611aee7946ae64735e6fd93
github.com/golang/snappy 7db9049039a047d955fe8c19b83c8ff5abd765c7
github.com/go-ole/go-ole be49f7c07711fcb603cff39e1de7c67926dc0ba7
github.com/google/go-cmp f94e52cad91c65a63acc1e75d4be223ea22e99bc
github.com/gorilla/mux 53c1911da2b537f792e7cafcb446b05ffe33b996
github.com/go-redis/redis 73b70592cdaa9e6abdfcfbf97b4a90d80728c836
github.com/go-sql-driver/mysql 2e00b5cd70399450106cec6431c2e2ce3cae5034
github.com/hailocab/go-hostpool e80d13ce29ede4452c43dea11e79b9bc8a15b478
github.com/hashicorp/consul 5174058f0d2bda63fa5198ab96c33d9a909c58ed
github.com/influxdata/tail c43482518d410361b6c383d7aebce33d0471d7bc
github.com/influxdata/toml 5d1d907f22ead1cd47adde17ceec5bda9cacaf8f
github.com/influxdata/wlog 7c63b0a71ef8300adc255344d275e10e5c3a71ec
github.com/fsnotify/fsnotify c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9
github.com/jackc/pgx 63f58fd32edb5684b9e9f4cfaac847c6b42b3917
github.com/jmespath/go-jmespath bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d
github.com/kardianos/osext c2c54e542fb797ad986b31721e1baedf214ca413
github.com/kardianos/service 6d3a0ee7d3425d9d835debc51a0ca1ffa28f4893
github.com/kballard/go-shellquote d8ec1a69a250a17bb0e419c386eac1f3711dc142
github.com/matttproud/golang_protobuf_extensions c12348ce28de40eed0136aa2b644d0ee0650e56c
github.com/Microsoft/ApplicationInsights-Go 3612f58550c1de70f1a110c78c830e55f29aa65d
github.com/Microsoft/go-winio ce2922f643c8fd76b46cadc7f404a06282678b34
github.com/miekg/dns 99f84ae56e75126dd77e5de4fae2ea034a468ca1
github.com/mitchellh/mapstructure d0303fe809921458f417bcf828397a65db30a7e4
github.com/multiplay/go-ts3 07477f49b8dfa3ada231afc7b7b17617d42afe8e
github.com/naoina/go-stringutil 6b638e95a32d0c1131db0e7fe83775cbea4a0d0b
github.com/nats-io/gnatsd 393bbb7c031433e68707c8810fda0bfcfbe6ab9b
github.com/nats-io/go-nats ea9585611a4ab58a205b9b125ebd74c389a6b898
github.com/nats-io/nats ea9585611a4ab58a205b9b125ebd74c389a6b898
github.com/nats-io/nuid 289cccf02c178dc782430d534e3c1f5b72af807f
github.com/nsqio/go-nsq eee57a3ac4174c55924125bb15eeeda8cffb6e6f
github.com/opencontainers/runc 89ab7f2ccc1e45ddf6485eaa802c35dcf321dfc8
github.com/opentracing-contrib/go-observer a52f2342449246d5bcc273e65cbdcfa5f7d6c63c
github.com/opentracing/opentracing-go 06f47b42c792fef2796e9681353e1d908c417827
github.com/openzipkin/zipkin-go-opentracing 1cafbdfde94fbf2b373534764e0863aa3bd0bf7b
github.com/pierrec/lz4 5c9560bfa9ace2bf86080bf40d46b34ae44604df
github.com/pierrec/xxHash 5a004441f897722c627870a981d02b29924215fa
github.com/pkg/errors 645ef00459ed84a119197bfb8d8205042c6df63d
github.com/pmezard/go-difflib/difflib 792786c7400a136282c1664665ae0a8db921c6c2
github.com/prometheus/client_golang c317fb74746eac4fc65fe3909195f4cf67c5562a
github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
github.com/prometheus/common dd2f054febf4a6c00f2343686efb775948a8bff4
github.com/prometheus/procfs 1878d9fbb537119d24b21ca07effd591627cd160
github.com/rcrowley/go-metrics 1f30fe9094a513ce4c700b9a54458bbb0c96996c
github.com/samuel/go-zookeeper 1d7be4effb13d2d908342d349d71a284a7542693
github.com/satori/go.uuid 5bf94b69c6b68ee1b541973bb8e1144db23a194b
github.com/shirou/gopsutil c95755e4bcd7a62bb8bd33f3a597a7c7f35e2cf3
github.com/shirou/w32 3c9377fc6748f222729a8270fe2775d149a249ad
github.com/Shopify/sarama 3b1b38866a79f06deddf0487d5c27ba0697ccd65
github.com/Sirupsen/logrus 61e43dc76f7ee59a82bdf3d71033dc12bea4c77d
github.com/soniah/gosnmp f15472a4cd6f6ea7929e4c7d9f163c49f059924f
github.com/StackExchange/wmi f3e2bae1e0cb5aef83e319133eabfee30013a4a5
github.com/streadway/amqp 63795daa9a446c920826655f26ba31c81c860fd6
github.com/stretchr/objx facf9a85c22f48d2f52f2380e4efce1768749a89
github.com/stretchr/testify 12b6f73e6084dad08a7c6e575284b177ecafbc71
github.com/tidwall/gjson 0623bd8fbdbf97cc62b98d15108832851a658e59
github.com/tidwall/match 173748da739a410c5b0b813b956f89ff94730b4c
github.com/vjeantet/grok d73e972b60935c7fec0b4ffbc904ed39ecaf7efe
github.com/wvanbergen/kafka bc265fedb9ff5b5c5d3c0fdcef4a819b3523d3ee
github.com/wvanbergen/kazoo-go 968957352185472eacb69215fa3dbfcfdbac1096
github.com/yuin/gopher-lua 66c871e454fcf10251c61bf8eff02d0978cae75a
github.com/zensqlmonitor/go-mssqldb ffe5510c6fa5e15e6d983210ab501c815b56b363
golang.org/x/crypto dc137beb6cce2043eb6b5f223ab8bf51c32459f4
golang.org/x/net a337091b0525af65de94df2eb7e98bd9962dcbe2
golang.org/x/sys 739734461d1c916b6c72a63d7efda2b27edb369f
golang.org/x/text 506f9d5c962f284575e88337e7d9296d27e729d3
google.golang.org/genproto 11c7f9e547da6db876260ce49ea7536985904c9b
google.golang.org/grpc de2209a968d48e8970546c8a710189f7461370f7
gopkg.in/asn1-ber.v1 4e86f4367175e39f69d9358a5f17b4dda270378d
gopkg.in/fatih/pool.v2 6e328e67893eb46323ad06f0e92cb9536babbabc
gopkg.in/gorethink/gorethink.v3 7ab832f7b65573104a555d84a27992ae9ea1f659
gopkg.in/ldap.v2 8168ee085ee43257585e50c6441aadf54ecb2c9f
gopkg.in/mgo.v2 3f83fa5005286a7fe593b055f0d7771a7dce4655
gopkg.in/olivere/elastic.v5 3113f9b9ad37509fe5f8a0e5e91c96fdc4435e26
gopkg.in/tomb.v1 dd632973f1e7218eb1089048e0798ec9ae7dceb8
gopkg.in/yaml.v2 4c78c975fe7c825c6d1466c42be594d1d6f3aba6

973
Gopkg.lock generated
View File

@@ -1,973 +0,0 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
branch = "master"
name = "code.cloudfoundry.org/clock"
packages = ["."]
revision = "02e53af36e6c978af692887ed449b74026d76fec"
[[projects]]
name = "collectd.org"
packages = [
"api",
"cdtime",
"network"
]
revision = "2ce144541b8903101fb8f1483cc0497a68798122"
version = "v0.3.0"
[[projects]]
name = "github.com/Microsoft/ApplicationInsights-Go"
packages = [
"appinsights",
"appinsights/contracts"
]
revision = "d2df5d440eda5372f24fcac03839a64d6cb5f7e5"
version = "v0.4.2"
[[projects]]
name = "github.com/Microsoft/go-winio"
packages = ["."]
revision = "7da180ee92d8bd8bb8c37fc560e673e6557c392f"
version = "v0.4.7"
[[projects]]
name = "github.com/Shopify/sarama"
packages = ["."]
revision = "35324cf48e33d8260e1c7c18854465a904ade249"
version = "v1.17.0"
[[projects]]
name = "github.com/StackExchange/wmi"
packages = ["."]
revision = "5d049714c4a64225c3c79a7cf7d02f7fb5b96338"
version = "1.0.0"
[[projects]]
name = "github.com/aerospike/aerospike-client-go"
packages = [
".",
"internal/lua",
"internal/lua/resources",
"logger",
"pkg/bcrypt",
"pkg/ripemd160",
"types",
"types/atomic",
"types/particle_type",
"types/rand",
"utils/buffer"
]
revision = "c10b5393e43bd60125aca6289c7b24879edb1787"
version = "v1.33.0"
[[projects]]
branch = "master"
name = "github.com/alecthomas/template"
packages = [
".",
"parse"
]
revision = "a0175ee3bccc567396460bf5acd36800cb10c49c"
[[projects]]
branch = "master"
name = "github.com/alecthomas/units"
packages = ["."]
revision = "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a"
[[projects]]
branch = "master"
name = "github.com/amir/raidman"
packages = [
".",
"proto"
]
revision = "1ccc43bfb9c93cb401a4025e49c64ba71e5e668b"
[[projects]]
branch = "master"
name = "github.com/apache/thrift"
packages = ["lib/go/thrift"]
revision = "f5f430df56871bc937950274b2c86681d3db6e59"
[[projects]]
name = "github.com/aws/aws-sdk-go"
packages = [
"aws",
"aws/awserr",
"aws/awsutil",
"aws/client",
"aws/client/metadata",
"aws/corehandlers",
"aws/credentials",
"aws/credentials/ec2rolecreds",
"aws/credentials/endpointcreds",
"aws/credentials/stscreds",
"aws/csm",
"aws/defaults",
"aws/ec2metadata",
"aws/endpoints",
"aws/request",
"aws/session",
"aws/signer/v4",
"internal/sdkio",
"internal/sdkrand",
"internal/shareddefaults",
"private/protocol",
"private/protocol/json/jsonutil",
"private/protocol/jsonrpc",
"private/protocol/query",
"private/protocol/query/queryutil",
"private/protocol/rest",
"private/protocol/xml/xmlutil",
"service/cloudwatch",
"service/kinesis",
"service/sts"
]
revision = "bfc1a07cf158c30c41a3eefba8aae043d0bb5bff"
version = "v1.14.8"
[[projects]]
branch = "master"
name = "github.com/beorn7/perks"
packages = ["quantile"]
revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
[[projects]]
name = "github.com/bsm/sarama-cluster"
packages = ["."]
revision = "cf455bc755fe41ac9bb2861e7a961833d9c2ecc3"
version = "v2.1.13"
[[projects]]
name = "github.com/cenkalti/backoff"
packages = ["."]
revision = "2ea60e5f094469f9e65adb9cd103795b73ae743e"
version = "v2.0.0"
[[projects]]
branch = "master"
name = "github.com/couchbase/go-couchbase"
packages = ["."]
revision = "16db1f1fe037412f12738fa4d8448c549c4edd77"
[[projects]]
branch = "master"
name = "github.com/couchbase/gomemcached"
packages = [
".",
"client"
]
revision = "0da75df145308b9a4e6704d762ca9d9b77752efc"
[[projects]]
branch = "master"
name = "github.com/couchbase/goutils"
packages = [
"logging",
"scramsha"
]
revision = "e865a1461c8ac0032bd37e2d4dab3289faea3873"
[[projects]]
name = "github.com/davecgh/go-spew"
packages = ["spew"]
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0"
[[projects]]
name = "github.com/dgrijalva/jwt-go"
packages = ["."]
revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e"
version = "v3.2.0"
[[projects]]
name = "github.com/docker/distribution"
packages = [
"digest",
"reference"
]
revision = "48294d928ced5dd9b378f7fd7c6f5da3ff3f2c89"
version = "v2.6.2"
[[projects]]
name = "github.com/docker/docker"
packages = [
"api/types",
"api/types/blkiodev",
"api/types/container",
"api/types/events",
"api/types/filters",
"api/types/mount",
"api/types/network",
"api/types/reference",
"api/types/registry",
"api/types/strslice",
"api/types/swarm",
"api/types/time",
"api/types/versions",
"api/types/volume",
"client",
"pkg/tlsconfig"
]
revision = "eef6495eddab52828327aade186443681ed71a4e"
version = "v17.03.2-ce-rc1"
[[projects]]
name = "github.com/docker/go-connections"
packages = [
"nat",
"sockets",
"tlsconfig"
]
revision = "3ede32e2033de7505e6500d6c868c2b9ed9f169d"
version = "v0.3.0"
[[projects]]
name = "github.com/docker/go-units"
packages = ["."]
revision = "47565b4f722fb6ceae66b95f853feed578a4a51c"
version = "v0.3.3"
[[projects]]
name = "github.com/eapache/go-resiliency"
packages = ["breaker"]
revision = "ea41b0fad31007accc7f806884dcdf3da98b79ce"
version = "v1.1.0"
[[projects]]
branch = "master"
name = "github.com/eapache/go-xerial-snappy"
packages = ["."]
revision = "bb955e01b9346ac19dc29eb16586c90ded99a98c"
[[projects]]
name = "github.com/eapache/queue"
packages = ["."]
revision = "44cc805cf13205b55f69e14bcb69867d1ae92f98"
version = "v1.1.0"
[[projects]]
name = "github.com/eclipse/paho.mqtt.golang"
packages = [
".",
"packets"
]
revision = "36d01c2b4cbeb3d2a12063e4880ce30800af9560"
version = "v1.1.1"
[[projects]]
name = "github.com/go-ini/ini"
packages = ["."]
revision = "06f5f3d67269ccec1fe5fe4134ba6e982984f7f5"
version = "v1.37.0"
[[projects]]
name = "github.com/go-logfmt/logfmt"
packages = ["."]
revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5"
version = "v0.3.0"
[[projects]]
name = "github.com/go-ole/go-ole"
packages = [
".",
"oleutil"
]
revision = "a41e3c4b706f6ae8dfbff342b06e40fa4d2d0506"
version = "v1.2.1"
[[projects]]
name = "github.com/go-redis/redis"
packages = [
".",
"internal",
"internal/consistenthash",
"internal/hashtag",
"internal/pool",
"internal/proto",
"internal/singleflight",
"internal/util"
]
revision = "83fb42932f6145ce52df09860384a4653d2d332a"
version = "v6.12.0"
[[projects]]
name = "github.com/go-sql-driver/mysql"
packages = ["."]
revision = "d523deb1b23d913de5bdada721a6071e71283618"
version = "v1.4.0"
[[projects]]
name = "github.com/gobwas/glob"
packages = [
".",
"compiler",
"match",
"syntax",
"syntax/ast",
"syntax/lexer",
"util/runes",
"util/strings"
]
revision = "5ccd90ef52e1e632236f7326478d4faa74f99438"
version = "v0.2.3"
[[projects]]
name = "github.com/gogo/protobuf"
packages = ["proto"]
revision = "1adfc126b41513cc696b209667c8656ea7aac67c"
version = "v1.0.0"
[[projects]]
name = "github.com/golang/protobuf"
packages = [
"proto",
"ptypes",
"ptypes/any",
"ptypes/duration",
"ptypes/timestamp"
]
revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265"
version = "v1.1.0"
[[projects]]
branch = "master"
name = "github.com/golang/snappy"
packages = ["."]
revision = "2e65f85255dbc3072edf28d6b5b8efc472979f5a"
[[projects]]
name = "github.com/google/go-cmp"
packages = [
"cmp",
"cmp/internal/diff",
"cmp/internal/function",
"cmp/internal/value"
]
revision = "3af367b6b30c263d47e8895973edcca9a49cf029"
version = "v0.2.0"
[[projects]]
name = "github.com/gorilla/context"
packages = ["."]
revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42"
version = "v1.1.1"
[[projects]]
name = "github.com/gorilla/mux"
packages = ["."]
revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf"
version = "v1.6.2"
[[projects]]
branch = "master"
name = "github.com/hailocab/go-hostpool"
packages = ["."]
revision = "e80d13ce29ede4452c43dea11e79b9bc8a15b478"
[[projects]]
name = "github.com/hashicorp/consul"
packages = ["api"]
revision = "5174058f0d2bda63fa5198ab96c33d9a909c58ed"
version = "v1.1.0"
[[projects]]
branch = "master"
name = "github.com/hashicorp/go-cleanhttp"
packages = ["."]
revision = "d5fe4b57a186c716b0e00b8c301cbd9b4182694d"
[[projects]]
branch = "master"
name = "github.com/hashicorp/go-rootcerts"
packages = ["."]
revision = "6bb64b370b90e7ef1fa532be9e591a81c3493e00"
[[projects]]
name = "github.com/hashicorp/serf"
packages = ["coordinate"]
revision = "d6574a5bb1226678d7010325fb6c985db20ee458"
version = "v0.8.1"
[[projects]]
name = "github.com/influxdata/go-syslog"
packages = [
"rfc5424",
"rfc5425"
]
revision = "eecd51df3ad85464a2bab9b7d3a45bc1e299059e"
version = "v1.0.1"
[[projects]]
branch = "master"
name = "github.com/influxdata/tail"
packages = [
".",
"ratelimiter",
"util",
"watch",
"winfile"
]
revision = "c43482518d410361b6c383d7aebce33d0471d7bc"
[[projects]]
branch = "master"
name = "github.com/influxdata/toml"
packages = [
".",
"ast"
]
revision = "2a2e3012f7cfbef64091cc79776311e65dfa211b"
[[projects]]
branch = "master"
name = "github.com/influxdata/wlog"
packages = ["."]
revision = "7c63b0a71ef8300adc255344d275e10e5c3a71ec"
[[projects]]
name = "github.com/jackc/pgx"
packages = [
".",
"chunkreader",
"internal/sanitize",
"pgio",
"pgproto3",
"pgtype",
"stdlib"
]
revision = "da3231b0b66e2e74cdb779f1d46c5e958ba8be27"
version = "v3.1.0"
[[projects]]
name = "github.com/jmespath/go-jmespath"
packages = ["."]
revision = "0b12d6b5"
[[projects]]
branch = "master"
name = "github.com/kardianos/osext"
packages = ["."]
revision = "ae77be60afb1dcacde03767a8c37337fad28ac14"
[[projects]]
branch = "master"
name = "github.com/kardianos/service"
packages = ["."]
revision = "615a14ed75099c9eaac6949e22ac2341bf9d3197"
[[projects]]
branch = "master"
name = "github.com/kballard/go-shellquote"
packages = ["."]
revision = "95032a82bc518f77982ea72343cc1ade730072f0"
[[projects]]
branch = "master"
name = "github.com/kr/logfmt"
packages = ["."]
revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0"
[[projects]]
branch = "master"
name = "github.com/mailru/easyjson"
packages = [
".",
"buffer",
"jlexer",
"jwriter"
]
revision = "3fdea8d05856a0c8df22ed4bc71b3219245e4485"
[[projects]]
name = "github.com/matttproud/golang_protobuf_extensions"
packages = ["pbutil"]
revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c"
version = "v1.0.1"
[[projects]]
name = "github.com/miekg/dns"
packages = ["."]
revision = "5a2b9fab83ff0f8bfc99684bd5f43a37abe560f1"
version = "v1.0.8"
[[projects]]
branch = "master"
name = "github.com/mitchellh/go-homedir"
packages = ["."]
revision = "3864e76763d94a6df2f9960b16a20a33da9f9a66"
[[projects]]
branch = "master"
name = "github.com/mitchellh/mapstructure"
packages = ["."]
revision = "bb74f1db0675b241733089d5a1faa5dd8b0ef57b"
[[projects]]
name = "github.com/multiplay/go-ts3"
packages = ["."]
revision = "d0d44555495c8776880a17e439399e715a4ef319"
version = "v1.0.0"
[[projects]]
name = "github.com/naoina/go-stringutil"
packages = ["."]
revision = "6b638e95a32d0c1131db0e7fe83775cbea4a0d0b"
version = "v0.1.0"
[[projects]]
name = "github.com/nats-io/gnatsd"
packages = [
"conf",
"logger",
"server",
"server/pse",
"util"
]
revision = "add6d7930ae6d4bff8823b28999ea87bf1bfd23d"
version = "v1.1.0"
[[projects]]
name = "github.com/nats-io/go-nats"
packages = [
".",
"encoders/builtin",
"util"
]
revision = "062418ea1c2181f52dc0f954f6204370519a868b"
version = "v1.5.0"
[[projects]]
name = "github.com/nats-io/nuid"
packages = ["."]
revision = "289cccf02c178dc782430d534e3c1f5b72af807f"
version = "v1.0.0"
[[projects]]
name = "github.com/nsqio/go-nsq"
packages = ["."]
revision = "eee57a3ac4174c55924125bb15eeeda8cffb6e6f"
version = "v1.0.7"
[[projects]]
branch = "master"
name = "github.com/opentracing-contrib/go-observer"
packages = ["."]
revision = "a52f2342449246d5bcc273e65cbdcfa5f7d6c63c"
[[projects]]
name = "github.com/opentracing/opentracing-go"
packages = [
".",
"ext",
"log"
]
revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38"
version = "v1.0.2"
[[projects]]
name = "github.com/openzipkin/zipkin-go-opentracing"
packages = [
".",
"flag",
"thrift/gen-go/scribe",
"thrift/gen-go/zipkincore",
"types",
"wire"
]
revision = "26cf9707480e6b90e5eff22cf0bbf05319154232"
version = "v0.3.4"
[[projects]]
name = "github.com/pierrec/lz4"
packages = [
".",
"internal/xxh32"
]
revision = "6b9367c9ff401dbc54fabce3fb8d972e799b702d"
version = "v2.0.2"
[[projects]]
name = "github.com/pkg/errors"
packages = ["."]
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
version = "v0.8.0"
[[projects]]
name = "github.com/pmezard/go-difflib"
packages = ["difflib"]
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
version = "v1.0.0"
[[projects]]
name = "github.com/prometheus/client_golang"
packages = [
"prometheus",
"prometheus/promhttp"
]
revision = "c5b7fccd204277076155f10851dad72b76a49317"
version = "v0.8.0"
[[projects]]
branch = "master"
name = "github.com/prometheus/client_model"
packages = ["go"]
revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c"
[[projects]]
branch = "master"
name = "github.com/prometheus/common"
packages = [
"expfmt",
"internal/bitbucket.org/ww/goautoneg",
"log",
"model"
]
revision = "7600349dcfe1abd18d72d3a1770870d9800a7801"
[[projects]]
branch = "master"
name = "github.com/prometheus/procfs"
packages = [
".",
"internal/util",
"nfs",
"xfs"
]
revision = "7d6f385de8bea29190f15ba9931442a0eaef9af7"
[[projects]]
branch = "master"
name = "github.com/rcrowley/go-metrics"
packages = ["."]
revision = "e2704e165165ec55d062f5919b4b29494e9fa790"
[[projects]]
branch = "master"
name = "github.com/samuel/go-zookeeper"
packages = ["zk"]
revision = "c4fab1ac1bec58281ad0667dc3f0907a9476ac47"
[[projects]]
name = "github.com/satori/go.uuid"
packages = ["."]
revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3"
version = "v1.2.0"
[[projects]]
name = "github.com/shirou/gopsutil"
packages = [
"cpu",
"disk",
"host",
"internal/common",
"load",
"mem",
"net",
"process"
]
revision = "eeb1d38d69593f121e060d24d17f7b1f0936b203"
version = "v2.18.05"
[[projects]]
branch = "master"
name = "github.com/shirou/w32"
packages = ["."]
revision = "bb4de0191aa41b5507caa14b0650cdbddcd9280b"
[[projects]]
name = "github.com/sirupsen/logrus"
packages = ["."]
revision = "c155da19408a8799da419ed3eeb0cb5db0ad5dbc"
version = "v1.0.5"
[[projects]]
branch = "master"
name = "github.com/soniah/gosnmp"
packages = ["."]
revision = "bcf840db66be7d64bf96c3c0e075c92e3d98f793"
[[projects]]
branch = "master"
name = "github.com/streadway/amqp"
packages = ["."]
revision = "e5adc2ada8b8efff032bf61173a233d143e9318e"
[[projects]]
name = "github.com/stretchr/objx"
packages = ["."]
revision = "477a77ecc69700c7cdeb1fa9e129548e1c1c393c"
version = "v0.1.1"
[[projects]]
name = "github.com/stretchr/testify"
packages = [
"assert",
"mock",
"require"
]
revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
version = "v1.2.2"
[[projects]]
name = "github.com/tidwall/gjson"
packages = ["."]
revision = "afaeb9562041a8018c74e006551143666aed08bf"
version = "v1.1.1"
[[projects]]
branch = "master"
name = "github.com/tidwall/match"
packages = ["."]
revision = "1731857f09b1f38450e2c12409748407822dc6be"
[[projects]]
name = "github.com/vjeantet/grok"
packages = ["."]
revision = "ce01e59abcf6fbc9833b7deb5e4b8ee1769bcc53"
version = "v1.0.0"
[[projects]]
branch = "master"
name = "github.com/wvanbergen/kafka"
packages = ["consumergroup"]
revision = "e2edea948ddfee841ea9a263b32ccca15f7d6c2f"
[[projects]]
branch = "master"
name = "github.com/wvanbergen/kazoo-go"
packages = ["."]
revision = "f72d8611297a7cf105da904c04198ad701a60101"
[[projects]]
branch = "master"
name = "github.com/yuin/gopher-lua"
packages = [
".",
"ast",
"parse",
"pm"
]
revision = "ca850f594eaafa5468da2bd53b865e4ee55be18b"
[[projects]]
branch = "master"
name = "github.com/zensqlmonitor/go-mssqldb"
packages = ["."]
revision = "e8fbf836e44e86764eba398361d1825651709547"
[[projects]]
branch = "master"
name = "golang.org/x/crypto"
packages = [
"bcrypt",
"blowfish",
"ed25519",
"ed25519/internal/edwards25519",
"md4",
"pbkdf2",
"ssh/terminal"
]
revision = "027cca12c2d63e3d62b670d901e8a2c95854feec"
[[projects]]
branch = "master"
name = "golang.org/x/net"
packages = [
"bpf",
"context",
"context/ctxhttp",
"html",
"html/atom",
"html/charset",
"http/httpguts",
"http2",
"http2/hpack",
"idna",
"internal/iana",
"internal/socket",
"internal/socks",
"internal/timeseries",
"ipv4",
"ipv6",
"proxy",
"trace",
"websocket"
]
revision = "db08ff08e8622530d9ed3a0e8ac279f6d4c02196"
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = [
"unix",
"windows",
"windows/registry",
"windows/svc",
"windows/svc/debug",
"windows/svc/eventlog",
"windows/svc/mgr"
]
revision = "6c888cc515d3ed83fc103cf1d84468aad274b0a7"
[[projects]]
name = "golang.org/x/text"
packages = [
"collate",
"collate/build",
"encoding",
"encoding/charmap",
"encoding/htmlindex",
"encoding/internal",
"encoding/internal/identifier",
"encoding/japanese",
"encoding/korean",
"encoding/simplifiedchinese",
"encoding/traditionalchinese",
"encoding/unicode",
"internal/colltab",
"internal/gen",
"internal/tag",
"internal/triegen",
"internal/ucd",
"internal/utf8internal",
"language",
"runes",
"secure/bidirule",
"transform",
"unicode/bidi",
"unicode/cldr",
"unicode/norm",
"unicode/rangetable"
]
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
version = "v0.3.0"
[[projects]]
name = "google.golang.org/appengine"
packages = ["cloudsql"]
revision = "b1f26356af11148e710935ed1ac8a7f5702c7612"
version = "v1.1.0"
[[projects]]
branch = "master"
name = "google.golang.org/genproto"
packages = ["googleapis/rpc/status"]
revision = "32ee49c4dd805befd833990acba36cb75042378c"
[[projects]]
name = "google.golang.org/grpc"
packages = [
".",
"balancer",
"balancer/base",
"balancer/roundrobin",
"channelz",
"codes",
"connectivity",
"credentials",
"encoding",
"encoding/proto",
"grpclb/grpc_lb_v1/messages",
"grpclog",
"internal",
"keepalive",
"metadata",
"naming",
"peer",
"resolver",
"resolver/dns",
"resolver/passthrough",
"stats",
"status",
"tap",
"transport"
]
revision = "7a6a684ca69eb4cae85ad0a484f2e531598c047b"
version = "v1.12.2"
[[projects]]
name = "gopkg.in/alecthomas/kingpin.v2"
packages = ["."]
revision = "947dcec5ba9c011838740e680966fd7087a71d0d"
version = "v2.2.6"
[[projects]]
name = "gopkg.in/asn1-ber.v1"
packages = ["."]
revision = "379148ca0225df7a432012b8df0355c2a2063ac0"
version = "v1.2"
[[projects]]
name = "gopkg.in/fatih/pool.v2"
packages = ["."]
revision = "010e0b745d12eaf8426c95f9c3924d81dd0b668f"
version = "v2.0.0"
[[projects]]
name = "gopkg.in/fsnotify.v1"
packages = ["."]
revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9"
source = "https://github.com/fsnotify/fsnotify/archive/v1.4.7.tar.gz"
version = "v1.4.7"
[[projects]]
name = "gopkg.in/gorethink/gorethink.v3"
packages = [
".",
"encoding",
"ql2",
"types"
]
revision = "7f5bdfd858bb064d80559b2a32b86669c5de5d3b"
version = "v3.0.5"
[[projects]]
name = "gopkg.in/ldap.v2"
packages = ["."]
revision = "bb7a9ca6e4fbc2129e3db588a34bc970ffe811a9"
version = "v2.5.1"
[[projects]]
branch = "v2"
name = "gopkg.in/mgo.v2"
packages = [
".",
"bson",
"internal/json",
"internal/sasl",
"internal/scram"
]
revision = "3f83fa5005286a7fe593b055f0d7771a7dce4655"
[[projects]]
name = "gopkg.in/olivere/elastic.v5"
packages = [
".",
"config",
"uritemplates"
]
revision = "b708306d715bea9b983685e94ab4602cdc9f988b"
version = "v5.0.69"
[[projects]]
branch = "v1"
name = "gopkg.in/tomb.v1"
packages = ["."]
revision = "dd632973f1e7218eb1089048e0798ec9ae7dceb8"
[[projects]]
name = "gopkg.in/yaml.v2"
packages = ["."]
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
version = "v2.2.1"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "024194b983d91b9500fe97e0aa0ddb5fe725030cb51ddfb034e386cae1098370"
solver-name = "gps-cdcl"
solver-version = 1

View File

@@ -1,243 +0,0 @@
[[constraint]]
name = "collectd.org"
version = "0.3.0"
[[constraint]]
name = "github.com/aerospike/aerospike-client-go"
version = "^1.33.0"
[[constraint]]
name = "github.com/amir/raidman"
branch = "master"
[[constraint]]
name = "github.com/apache/thrift"
branch = "master"
[[constraint]]
name = "github.com/aws/aws-sdk-go"
version = "1.14.8"
# version = "1.8.39"
[[constraint]]
name = "github.com/bsm/sarama-cluster"
version = "2.1.13"
# version = "2.1.10"
[[constraint]]
name = "github.com/couchbase/go-couchbase"
branch = "master"
[[constraint]]
name = "github.com/dgrijalva/jwt-go"
version = "3.2.0"
# version = "3.1.0"
[[constraint]]
name = "github.com/docker/docker"
version = "~17.03.2-ce"
[[constraint]]
name = "github.com/docker/go-connections"
version = "0.3.0"
# version = "0.2.1"
[[constraint]]
name = "github.com/eclipse/paho.mqtt.golang"
version = "~1.1.1"
# version = "1.1.0"
[[constraint]]
name = "github.com/go-sql-driver/mysql"
version = "1.4.0"
# version = "1.3.0"
[[constraint]]
name = "github.com/gobwas/glob"
version = "0.2.3"
# version = "0.2.2"
[[constraint]]
name = "github.com/golang/protobuf"
version = "1.1.0"
# version = "1.0.0"
[[constraint]]
name = "github.com/google/go-cmp"
version = "0.2.0"
# version = "0.1.0"
[[constraint]]
name = "github.com/gorilla/mux"
version = "1.6.2"
# version = "1.6.1"
[[constraint]]
name = "github.com/go-redis/redis"
version = "6.12.0"
[[constraint]]
name = "github.com/hashicorp/consul"
version = "1.1.0"
[[constraint]]
name = "github.com/influxdata/go-syslog"
version = "1.0.1"
[[constraint]]
name = "github.com/influxdata/tail"
branch = "master"
[[constraint]]
name = "github.com/influxdata/toml"
branch = "master"
[[constraint]]
name = "github.com/influxdata/wlog"
branch = "master"
[[constraint]]
name = "github.com/jackc/pgx"
version = "3.1.0"
[[constraint]]
name = "github.com/kardianos/service"
branch = "master"
[[constraint]]
name = "github.com/kballard/go-shellquote"
branch = "master"
[[constraint]]
name = "github.com/matttproud/golang_protobuf_extensions"
version = "1.0.1"
[[constraint]]
name = "github.com/Microsoft/ApplicationInsights-Go"
branch = "master"
[[constraint]]
name = "github.com/miekg/dns"
version = "1.0.8"
# version = "1.0.0"
[[constraint]]
name = "github.com/multiplay/go-ts3"
version = "1.0.0"
[[constraint]]
name = "github.com/nats-io/gnatsd"
version = "1.1.0"
# version = "1.0.4"
[[constraint]]
name = "github.com/nats-io/go-nats"
version = "1.5.0"
# version = "1.3.0"
[[constraint]]
name = "github.com/nsqio/go-nsq"
version = "1.0.7"
[[constraint]]
name = "github.com/openzipkin/zipkin-go-opentracing"
version = "0.3.4"
# version = "0.3.0"
[[constraint]]
name = "github.com/prometheus/client_golang"
version = "0.8.0"
[[constraint]]
name = "github.com/prometheus/client_model"
branch = "master"
[[constraint]]
name = "github.com/prometheus/common"
branch = "master"
[[constraint]]
name = "github.com/satori/go.uuid"
version = "1.2.0"
[[constraint]]
name = "github.com/shirou/gopsutil"
version = "2.18.05"
# version = "2.18.04"
[[constraint]]
name = "github.com/Shopify/sarama"
version = "1.17.0"
# version = "1.15.0"
[[constraint]]
name = "github.com/soniah/gosnmp"
branch = "master"
[[constraint]]
name = "github.com/StackExchange/wmi"
version = "1.0.0"
[[constraint]]
name = "github.com/streadway/amqp"
branch = "master"
[[constraint]]
name = "github.com/stretchr/testify"
version = "1.2.2"
# version = "1.2.1"
[[constraint]]
name = "github.com/tidwall/gjson"
version = "1.1.1"
# version = "1.0.0"
[[constraint]]
name = "github.com/vjeantet/grok"
version = "1.0.0"
[[constraint]]
name = "github.com/wvanbergen/kafka"
branch = "master"
[[constraint]]
name = "github.com/zensqlmonitor/go-mssqldb"
branch = "master"
[[constraint]]
name = "golang.org/x/net"
branch = "master"
[[constraint]]
name = "golang.org/x/sys"
branch = "master"
[[constraint]]
name = "google.golang.org/grpc"
version = "1.12.2"
# version = "1.8.0"
[[constraint]]
name = "gopkg.in/gorethink/gorethink.v3"
version = "3.0.5"
[[constraint]]
name = "gopkg.in/ldap.v2"
version = "2.5.1"
[[constraint]]
name = "gopkg.in/mgo.v2"
branch = "v2"
[[constraint]]
name = "gopkg.in/olivere/elastic.v5"
version = "^5.0.69"
# version = "^6.1.23"
[[constraint]]
name = "gopkg.in/yaml.v2"
version = "^2.2.1"
[[override]]
source = "https://github.com/fsnotify/fsnotify/archive/v1.4.7.tar.gz"
name = "gopkg.in/fsnotify.v1"

View File

@@ -23,8 +23,8 @@ all:
deps: deps:
go get -u github.com/golang/lint/golint go get -u github.com/golang/lint/golint
go get -u github.com/golang/dep/cmd/dep go get github.com/sparrc/gdm
dep ensure gdm restore --parallel=false
telegraf: telegraf:
go build -ldflags "$(LDFLAGS)" ./cmd/telegraf go build -ldflags "$(LDFLAGS)" ./cmd/telegraf
@@ -34,7 +34,7 @@ go-install:
install: telegraf install: telegraf
mkdir -p $(DESTDIR)$(PREFIX)/bin/ mkdir -p $(DESTDIR)$(PREFIX)/bin/
cp telegraf $(DESTDIR)$(PREFIX)/bin/ cp $(TELEGRAF) $(DESTDIR)$(PREFIX)/bin/
test: test:
go test -short ./... go test -short ./...
@@ -54,11 +54,11 @@ fmtcheck:
@echo '[INFO] done.' @echo '[INFO] done.'
test-windows: test-windows:
go test -short ./plugins/inputs/ping/... go test ./plugins/inputs/ping/...
go test -short ./plugins/inputs/win_perf_counters/... go test ./plugins/inputs/win_perf_counters/...
go test -short ./plugins/inputs/win_services/... go test ./plugins/inputs/win_services/...
go test -short ./plugins/inputs/procstat/... go test ./plugins/inputs/procstat/...
go test -short ./plugins/inputs/ntpq/... go test ./plugins/inputs/ntpq/...
# vet runs the Go source code static analysis tool `vet` to find # vet runs the Go source code static analysis tool `vet` to find
# any common errors. # any common errors.
@@ -92,15 +92,4 @@ docker-image:
plugins/parsers/influx/machine.go: plugins/parsers/influx/machine.go.rl plugins/parsers/influx/machine.go: plugins/parsers/influx/machine.go.rl
ragel -Z -G2 $^ -o $@ ragel -Z -G2 $^ -o $@
static: .PHONY: deps telegraf install test test-windows lint vet test-all package clean docker-image fmtcheck uint64
@echo "Building static linux binary..."
@CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64 \
go build -ldflags "$(LDFLAGS)" ./cmd/telegraf
plugin-%:
@echo "Starting dev environment for $${$(@)} input plugin..."
@docker-compose -f plugins/inputs/$${$(@)}/dev/docker-compose.yml up
.PHONY: deps telegraf install test test-windows lint vet test-all package clean docker-image fmtcheck uint64 static

View File

@@ -40,9 +40,9 @@ Ansible role: https://github.com/rossmcdonald/telegraf
### From Source: ### From Source:
Telegraf requires golang version 1.9 or newer, the Makefile requires GNU make. Telegraf requires golang version 1.8+, the Makefile requires GNU make.
Dependencies are managed with [dep](https://github.com/golang/dep), Dependencies are managed with [gdm](https://github.com/sparrc/gdm),
which is installed by the Makefile if you don't have it already. which is installed by the Makefile if you don't have it already.
1. [Install Go](https://golang.org/doc/install) 1. [Install Go](https://golang.org/doc/install)
@@ -211,9 +211,7 @@ configuration options.
* [snmp_legacy](./plugins/inputs/snmp_legacy) * [snmp_legacy](./plugins/inputs/snmp_legacy)
* [solr](./plugins/inputs/solr) * [solr](./plugins/inputs/solr)
* [sql server](./plugins/inputs/sqlserver) (microsoft) * [sql server](./plugins/inputs/sqlserver) (microsoft)
* [syslog](./plugins/inputs/syslog)
* [teamspeak](./plugins/inputs/teamspeak) * [teamspeak](./plugins/inputs/teamspeak)
* [tengine](./plugins/inputs/tengine)
* [tomcat](./plugins/inputs/tomcat) * [tomcat](./plugins/inputs/tomcat)
* [twemproxy](./plugins/inputs/twemproxy) * [twemproxy](./plugins/inputs/twemproxy)
* [unbound](./plugins/inputs/unbound) * [unbound](./plugins/inputs/unbound)
@@ -282,7 +280,6 @@ formats may be used with input plugins supporting the `data_format` option:
* [basicstats](./plugins/aggregators/basicstats) * [basicstats](./plugins/aggregators/basicstats)
* [minmax](./plugins/aggregators/minmax) * [minmax](./plugins/aggregators/minmax)
* [histogram](./plugins/aggregators/histogram) * [histogram](./plugins/aggregators/histogram)
* [valuecounter](./plugins/aggregators/valuecounter)
## Output Plugins ## Output Plugins

View File

@@ -362,6 +362,24 @@ func (a *Agent) Run(shutdown chan struct{}) error {
metricC := make(chan telegraf.Metric, 100) metricC := make(chan telegraf.Metric, 100)
aggC := make(chan telegraf.Metric, 100) aggC := make(chan telegraf.Metric, 100)
// Start all ServicePlugins
for _, input := range a.Config.Inputs {
input.SetDefaultTags(a.Config.Tags)
switch p := input.Input.(type) {
case telegraf.ServiceInput:
acc := NewAccumulator(input, metricC)
// Service input plugins should set their own precision of their
// metrics.
acc.SetPrecision(time.Nanosecond, 0)
if err := p.Start(acc); err != nil {
log.Printf("E! Service for input %s failed to start, exiting\n%s\n",
input.Name(), err.Error())
return err
}
defer p.Stop()
}
}
// Round collection to nearest interval by sleeping // Round collection to nearest interval by sleeping
if a.Config.Agent.RoundInterval { if a.Config.Agent.RoundInterval {
i := int64(a.Config.Agent.Interval.Duration) i := int64(a.Config.Agent.Interval.Duration)
@@ -401,25 +419,6 @@ func (a *Agent) Run(shutdown chan struct{}) error {
}(input, interval) }(input, interval)
} }
// Start all ServicePlugins inputs after all other
// plugins are loaded so that no metrics get dropped
for _, input := range a.Config.Inputs {
input.SetDefaultTags(a.Config.Tags)
switch p := input.Input.(type) {
case telegraf.ServiceInput:
acc := NewAccumulator(input, metricC)
// Service input plugins should set their own precision of their
// metrics.
acc.SetPrecision(time.Nanosecond, 0)
if err := p.Start(acc); err != nil {
log.Printf("E! Service for input %s failed to start, exiting\n%s\n",
input.Name(), err.Error())
return err
}
defer p.Stop()
}
}
wg.Wait() wg.Wait()
a.Close() a.Close()
return nil return nil

View File

@@ -21,7 +21,6 @@ install:
- 7z x "C:\Cache\gnuwin32-dep.zip" -oC:\GnuWin32 -y - 7z x "C:\Cache\gnuwin32-dep.zip" -oC:\GnuWin32 -y
- go version - go version
- go env - go env
- git config --system core.longpaths true
build_script: build_script:
- cmd: C:\GnuWin32\bin\make deps - cmd: C:\GnuWin32\bin\make deps

View File

@@ -58,7 +58,7 @@ var fService = flag.String("service", "",
var fRunAsConsole = flag.Bool("console", false, "run as console application (windows only)") var fRunAsConsole = flag.Bool("console", false, "run as console application (windows only)")
var ( var (
nextVersion = "1.8.0" nextVersion = "1.7.0"
version string version string
commit string commit string
branch string branch string
@@ -147,11 +147,11 @@ func reloadLoop(
shutdown := make(chan struct{}) shutdown := make(chan struct{})
signals := make(chan os.Signal) signals := make(chan os.Signal)
signal.Notify(signals, os.Interrupt, syscall.SIGHUP, syscall.SIGTERM) signal.Notify(signals, os.Interrupt, syscall.SIGHUP)
go func() { go func() {
select { select {
case sig := <-signals: case sig := <-signals:
if sig == os.Interrupt || sig == syscall.SIGTERM { if sig == os.Interrupt {
close(shutdown) close(shutdown)
} }
if sig == syscall.SIGHUP { if sig == syscall.SIGHUP {
@@ -166,10 +166,8 @@ func reloadLoop(
}() }()
log.Printf("I! Starting Telegraf %s\n", displayVersion()) log.Printf("I! Starting Telegraf %s\n", displayVersion())
log.Printf("I! Loaded inputs: %s", strings.Join(c.InputNames(), " "))
log.Printf("I! Loaded aggregators: %s", strings.Join(c.AggregatorNames(), " "))
log.Printf("I! Loaded processors: %s", strings.Join(c.ProcessorNames(), " "))
log.Printf("I! Loaded outputs: %s", strings.Join(c.OutputNames(), " ")) log.Printf("I! Loaded outputs: %s", strings.Join(c.OutputNames(), " "))
log.Printf("I! Loaded inputs: %s", strings.Join(c.InputNames(), " "))
log.Printf("I! Tags enabled: %s", c.ListTags()) log.Printf("I! Tags enabled: %s", c.ListTags())
if *fPidfile != "" { if *fPidfile != "" {

View File

@@ -44,7 +44,6 @@ following works:
- github.com/hashicorp/raft [MPL](https://github.com/hashicorp/raft/blob/master/LICENSE) - github.com/hashicorp/raft [MPL](https://github.com/hashicorp/raft/blob/master/LICENSE)
- github.com/influxdata/tail [MIT](https://github.com/influxdata/tail/blob/master/LICENSE.txt) - github.com/influxdata/tail [MIT](https://github.com/influxdata/tail/blob/master/LICENSE.txt)
- github.com/influxdata/toml [MIT](https://github.com/influxdata/toml/blob/master/LICENSE) - github.com/influxdata/toml [MIT](https://github.com/influxdata/toml/blob/master/LICENSE)
- github.com/influxdata/go-syslog [MIT](https://github.com/influxdata/go-syslog/blob/develop/LICENSE)
- github.com/influxdata/wlog [MIT](https://github.com/influxdata/wlog/blob/master/LICENSE) - github.com/influxdata/wlog [MIT](https://github.com/influxdata/wlog/blob/master/LICENSE)
- github.com/jackc/pgx [MIT](https://github.com/jackc/pgx/blob/master/LICENSE) - github.com/jackc/pgx [MIT](https://github.com/jackc/pgx/blob/master/LICENSE)
- github.com/jmespath/go-jmespath [APACHE](https://github.com/jmespath/go-jmespath/blob/master/LICENSE) - github.com/jmespath/go-jmespath [APACHE](https://github.com/jmespath/go-jmespath/blob/master/LICENSE)

View File

@@ -158,74 +158,30 @@
# # timeout = "5s" # # timeout = "5s"
# # Publishes metrics to an AMQP broker # # Configuration for the AMQP server to send metrics to
# [[outputs.amqp]] # [[outputs.amqp]]
# ## Broker to publish to. # ## AMQP url
# ## deprecated in 1.7; use the brokers option # url = "amqp://localhost:5672/influxdb"
# # url = "amqp://localhost:5672/influxdb" # ## AMQP exchange
#
# ## Brokers to publish to. If multiple brokers are specified a random broker
# ## will be selected anytime a connection is established. This can be
# ## helpful for load balancing when not using a dedicated load balancer.
# brokers = ["amqp://localhost:5672/influxdb"]
#
# ## Maximum messages to send over a connection. Once this is reached, the
# ## connection is closed and a new connection is made. This can be helpful for
# ## load balancing when not using a dedicated load balancer.
# # max_messages = 0
#
# ## Exchange to declare and publish to.
# exchange = "telegraf" # exchange = "telegraf"
#
# ## Exchange type; common types are "direct", "fanout", "topic", "header", "x-consistent-hash".
# # exchange_type = "topic"
#
# ## If true, exchange will be passively declared.
# # exchange_declare_passive = false
#
# ## If true, exchange will be created as a durable exchange.
# # exchange_durable = true
#
# ## Additional exchange arguments.
# # exchange_arguments = { }
# # exchange_arguments = {"hash_propery" = "timestamp"}
#
# ## Authentication credentials for the PLAIN auth_method.
# # username = ""
# # password = ""
#
# ## Auth method. PLAIN and EXTERNAL are supported # ## Auth method. PLAIN and EXTERNAL are supported
# ## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as # ## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
# ## described here: https://www.rabbitmq.com/plugins.html # ## described here: https://www.rabbitmq.com/plugins.html
# # auth_method = "PLAIN" # # auth_method = "PLAIN"
# ## Telegraf tag to use as a routing key
# ## ie, if this tag exists, its value will be used as the routing key
# routing_tag = "host"
# ## Delivery Mode controls if a published message is persistent
# ## Valid options are "transient" and "persistent". default: "transient"
# delivery_mode = "transient"
# #
# ## Metric tag to use as a routing key. # ## InfluxDB retention policy
# ## ie, if this tag exists, its value will be used as the routing key # # retention_policy = "default"
# # routing_tag = "host" # ## InfluxDB database
#
# ## Static routing key. Used when no routing_tag is set or as a fallback
# ## when the tag specified in routing tag is not found.
# # routing_key = ""
# # routing_key = "telegraf"
#
# ## Delivery Mode controls if a published message is persistent.
# ## One of "transient" or "persistent".
# # delivery_mode = "transient"
#
# ## InfluxDB database added as a message header.
# ## deprecated in 1.7; use the headers option
# # database = "telegraf" # # database = "telegraf"
# #
# ## InfluxDB retention policy added as a message header # ## Write timeout, formatted as a string. If not provided, will default
# ## deprecated in 1.7; use the headers option # ## to 5s. 0s means no timeout (not recommended).
# # retention_policy = "default"
#
# ## Static headers added to each published message.
# # headers = { }
# # headers = {"database" = "telegraf", "retention_policy" = "default"}
#
# ## Connection timeout. If not provided, will default to 5s. 0s means no
# ## timeout (not recommended).
# # timeout = "5s" # # timeout = "5s"
# #
# ## Optional TLS Config # ## Optional TLS Config
@@ -235,16 +191,11 @@
# ## Use TLS but skip chain & host verification # ## Use TLS but skip chain & host verification
# # insecure_skip_verify = false # # insecure_skip_verify = false
# #
# ## If true use batch serialization format instead of line based delimiting.
# ## Only applies to data formats which are not line based such as JSON.
# ## Recommended to set to true.
# # use_batch_format = false
#
# ## Data format to output. # ## Data format to output.
# ## Each data format has its own unique set of configuration options, read # ## Each data format has its own unique set of configuration options, read
# ## more about them here: # ## more about them here:
# ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md # ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md
# # data_format = "influx" # data_format = "influx"
# # Send metrics to Azure Application Insights # # Send metrics to Azure Application Insights
@@ -393,10 +344,6 @@
# ## Graphite output template # ## Graphite output template
# ## see https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md # ## see https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md
# template = "host.tags.measurement.field" # template = "host.tags.measurement.field"
#
# ## Enable Graphite tags support
# # graphite_tag_support = false
#
# ## timeout in seconds for the write connection to graphite # ## timeout in seconds for the write connection to graphite
# timeout = 2 # timeout = 2
# #
@@ -429,6 +376,11 @@
# # username = "username" # # username = "username"
# # password = "pa$$word" # # password = "pa$$word"
# #
# ## Additional HTTP headers
# # [outputs.http.headers]
# # # Should be set to "application/json" for json data_format
# # Content-Type = "text/plain; charset=utf-8"
#
# ## Optional TLS Config # ## Optional TLS Config
# # tls_ca = "/etc/telegraf/ca.pem" # # tls_ca = "/etc/telegraf/ca.pem"
# # tls_cert = "/etc/telegraf/cert.pem" # # tls_cert = "/etc/telegraf/cert.pem"
@@ -441,11 +393,6 @@
# ## more about them here: # ## more about them here:
# ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md # ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md
# # data_format = "influx" # # data_format = "influx"
#
# ## Additional HTTP headers
# # [outputs.http.headers]
# # # Should be set manually to "application/json" for json data_format
# # Content-Type = "text/plain; charset=utf-8"
# # Configuration for sending metrics to an Instrumental project # # Configuration for sending metrics to an Instrumental project
@@ -723,10 +670,6 @@
# ## Not used with telnet API. # ## Not used with telnet API.
# httpBatchSize = 50 # httpBatchSize = 50
# #
# ## URI Path for Http requests to OpenTSDB.
# ## Used in cases where OpenTSDB is located behind a reverse proxy.
# httpPath = "/api/put"
#
# ## Debug true - Prints OpenTSDB communication # ## Debug true - Prints OpenTSDB communication
# debug = false # debug = false
# #
@@ -882,34 +825,6 @@
# PROCESSOR PLUGINS # # PROCESSOR PLUGINS #
############################################################################### ###############################################################################
# # Convert values to another metric value type
# [[processors.converter]]
# ## Tags to convert
# ##
# ## The table key determines the target type, and the array of key-values
# ## select the keys to convert. The array may contain globs.
# ## <target-type> = [<tag-key>...]
# [processors.converter.tags]
# string = []
# integer = []
# unsigned = []
# boolean = []
# float = []
#
# ## Fields to convert
# ##
# ## The table key determines the target type, and the array of key-values
# ## select the keys to convert. The array may contain globs.
# ## <target-type> = [<field-key>...]
# [processors.converter.fields]
# tag = []
# string = []
# integer = []
# unsigned = []
# boolean = []
# float = []
# # Apply metric modifications using override semantics. # # Apply metric modifications using override semantics.
# [[processors.override]] # [[processors.override]]
# ## All modifications on inputs and aggregators can be overridden: # ## All modifications on inputs and aggregators can be overridden:
@@ -926,36 +841,6 @@
# [[processors.printer]] # [[processors.printer]]
# # Transforms tag and field values with regex pattern
# [[processors.regex]]
# ## Tag and field conversions defined in a separate sub-tables
# # [[processors.regex.tags]]
# # ## Tag to change
# # key = "resp_code"
# # ## Regular expression to match on a tag value
# # pattern = "^(\\d)\\d\\d$"
# # ## Pattern for constructing a new value (${1} represents first subgroup)
# # replacement = "${1}xx"
#
# # [[processors.regex.fields]]
# # key = "request"
# # ## All the power of the Go regular expressions available here
# # ## For example, named subgroups
# # pattern = "^/api(?P<method>/[\\w/]+)\\S*"
# # replacement = "${method}"
# # ## If result_key is present, a new field will be created
# # ## instead of changing existing field
# # result_key = "method"
#
# ## Multiple conversions may be applied for one field sequentially
# ## Let's extract one more value
# # [[processors.regex.fields]]
# # key = "request"
# # pattern = ".*category=(\\w+).*"
# # replacement = "${1}"
# # result_key = "search_category"
# # Print all metrics that pass through this filter. # # Print all metrics that pass through this filter.
# [[processors.topk]] # [[processors.topk]]
# ## How many seconds between aggregations # ## How many seconds between aggregations
@@ -1081,7 +966,7 @@
# mount_points = ["/"] # mount_points = ["/"]
## Ignore mount points by filesystem type. ## Ignore mount points by filesystem type.
ignore_fs = ["tmpfs", "devtmpfs", "devfs", "overlay", "aufs", "squashfs"] ignore_fs = ["tmpfs", "devtmpfs", "devfs"]
# Read metrics about disk IO by device # Read metrics about disk IO by device
@@ -1142,17 +1027,6 @@
# ## This plugin will query all namespaces the aerospike # ## This plugin will query all namespaces the aerospike
# ## server has configured and get stats for them. # ## server has configured and get stats for them.
# servers = ["localhost:3000"] # servers = ["localhost:3000"]
#
# # username = "telegraf"
# # password = "pa$$word"
#
# ## Optional TLS Config
# # enable_tls = false
# # tls_ca = "/etc/telegraf/ca.pem"
# # tls_cert = "/etc/telegraf/cert.pem"
# # tls_key = "/etc/telegraf/key.pem"
# ## If false, skip chain & host verification
# # insecure_skip_verify = true
# # Read Apache status information (mod_status) # # Read Apache status information (mod_status)
@@ -1177,32 +1051,6 @@
# # insecure_skip_verify = false # # insecure_skip_verify = false
# # Gather metrics from Apache Aurora schedulers
# [[inputs.aurora]]
# ## Schedulers are the base addresses of your Aurora Schedulers
# schedulers = ["http://127.0.0.1:8081"]
#
# ## Set of role types to collect metrics from.
# ##
# ## The scheduler roles are checked each interval by contacting the
# ## scheduler nodes; zookeeper is not contacted.
# # roles = ["leader", "follower"]
#
# ## Timeout is the max time for total network operations.
# # timeout = "5s"
#
# ## Username and password are sent using HTTP Basic Auth.
# # username = "username"
# # password = "pa$$word"
#
# ## Optional TLS Config
# # tls_ca = "/etc/telegraf/ca.pem"
# # tls_cert = "/etc/telegraf/cert.pem"
# # tls_key = "/etc/telegraf/key.pem"
# ## Use TLS but skip chain & host verification
# # insecure_skip_verify = false
# # Read metrics of bcache from stats_total and dirty_data # # Read metrics of bcache from stats_total and dirty_data
# [[inputs.bcache]] # [[inputs.bcache]]
# ## Bcache sets path # ## Bcache sets path
@@ -1227,49 +1075,6 @@
# # bond_interfaces = ["bond0"] # # bond_interfaces = ["bond0"]
# # Collect Kafka topics and consumers status from Burrow HTTP API.
# [[inputs.burrow]]
# ## Burrow API endpoints in format "schema://host:port".
# ## Default is "http://localhost:8000".
# servers = ["http://localhost:8000"]
#
# ## Override Burrow API prefix.
# ## Useful when Burrow is behind reverse-proxy.
# # api_prefix = "/v3/kafka"
#
# ## Maximum time to receive response.
# # response_timeout = "5s"
#
# ## Limit per-server concurrent connections.
# ## Useful in case of large number of topics or consumer groups.
# # concurrent_connections = 20
#
# ## Filter clusters, default is no filtering.
# ## Values can be specified as glob patterns.
# # clusters_include = []
# # clusters_exclude = []
#
# ## Filter consumer groups, default is no filtering.
# ## Values can be specified as glob patterns.
# # groups_include = []
# # groups_exclude = []
#
# ## Filter topics, default is no filtering.
# ## Values can be specified as glob patterns.
# # topics_include = []
# # topics_exclude = []
#
# ## Credentials for basic HTTP authentication.
# # username = ""
# # password = ""
#
# ## Optional SSL config
# # ssl_ca = "/etc/telegraf/ca.pem"
# # ssl_cert = "/etc/telegraf/cert.pem"
# # ssl_key = "/etc/telegraf/key.pem"
# # insecure_skip_verify = false
# # Collects performance metrics from the MON and OSD nodes in a Ceph storage cluster. # # Collects performance metrics from the MON and OSD nodes in a Ceph storage cluster.
# [[inputs.ceph]] # [[inputs.ceph]]
# ## This is the recommended interval to poll. Too frequent and you will lose # ## This is the recommended interval to poll. Too frequent and you will lose
@@ -2791,9 +2596,6 @@
# ## Remove numbers from field names. # ## Remove numbers from field names.
# ## If true, a field name like 'temp1_input' will be changed to 'temp_input'. # ## If true, a field name like 'temp1_input' will be changed to 'temp_input'.
# # remove_numbers = true # # remove_numbers = true
#
# ## Timeout is the maximum amount of time that the sensors command can run.
# # timeout = "5s"
# # Read metrics from storage devices supporting S.M.A.R.T. # # Read metrics from storage devices supporting S.M.A.R.T.
@@ -3145,27 +2947,23 @@
# pools = ["redis_pool", "mc_pool"] # pools = ["redis_pool", "mc_pool"]
# # A plugin to collect stats from the Unbound DNS resolver # # A plugin to collect stats from Unbound - a validating, recursive, and caching DNS resolver
# [[inputs.unbound]] # [[inputs.unbound]]
# ## Address of server to connect to, read from unbound conf default, optionally ':port'
# ## Will lookup IP if given a hostname
# server = "127.0.0.1:8953"
#
# ## If running as a restricted user you can prepend sudo for additional access: # ## If running as a restricted user you can prepend sudo for additional access:
# # use_sudo = false # #use_sudo = false
# #
# ## The default location of the unbound-control binary can be overridden with: # ## The default location of the unbound-control binary can be overridden with:
# # binary = "/usr/sbin/unbound-control" # binary = "/usr/sbin/unbound-control"
# #
# ## The default timeout of 1s can be overriden with: # ## The default timeout of 1s can be overriden with:
# # timeout = "1s" # timeout = "1s"
# #
# ## When set to true, thread metrics are tagged with the thread id. # ## Use the builtin fielddrop/fieldpass telegraf filters in order to keep/remove specific fields
# ## # fieldpass = ["total_*", "num_*","time_up", "mem_*"]
# ## The default is false for backwards compatibility, and will be change to #
# ## true in a future version. It is recommended to set to true on new # ## IP of server to connect to, read from unbound conf default, optionally ':port'
# ## deployments. # ## Will lookup IP if given a hostname
# thread_as_tag = false # server = "127.0.0.1:8953"
# # A plugin to collect stats from Varnish HTTP Cache # # A plugin to collect stats from Varnish HTTP Cache
@@ -3184,7 +2982,7 @@
# #
# ## Optional name for the varnish instance (or working directory) to query # ## Optional name for the varnish instance (or working directory) to query
# ## Usually appened after -n in varnish cli # ## Usually appened after -n in varnish cli
# # instance_name = instanceName # #name = instanceName
# # Read metrics of ZFS from arcstats, zfetchstats, vdev_cache_stats, and pools # # Read metrics of ZFS from arcstats, zfetchstats, vdev_cache_stats, and pools
@@ -3231,43 +3029,17 @@
# # AMQP consumer plugin # # AMQP consumer plugin
# [[inputs.amqp_consumer]] # [[inputs.amqp_consumer]]
# ## Broker to consume from. # ## AMQP url
# ## deprecated in 1.7; use the brokers option # url = "amqp://localhost:5672/influxdb"
# # url = "amqp://localhost:5672/influxdb" # ## AMQP exchange
#
# ## Brokers to consume from. If multiple brokers are specified a random broker
# ## will be selected anytime a connection is established. This can be
# ## helpful for load balancing when not using a dedicated load balancer.
# brokers = ["amqp://localhost:5672/influxdb"]
#
# ## Authentication credentials for the PLAIN auth_method.
# # username = ""
# # password = ""
#
# ## Exchange to declare and consume from.
# exchange = "telegraf" # exchange = "telegraf"
#
# ## Exchange type; common types are "direct", "fanout", "topic", "header", "x-consistent-hash".
# # exchange_type = "topic"
#
# ## If true, exchange will be passively declared.
# # exchange_passive = false
#
# ## Exchange durability can be either "transient" or "durable".
# # exchange_durability = "durable"
#
# ## Additional exchange arguments.
# # exchange_arguments = { }
# # exchange_arguments = {"hash_propery" = "timestamp"}
#
# ## AMQP queue name # ## AMQP queue name
# queue = "telegraf" # queue = "telegraf"
#
# ## Binding Key # ## Binding Key
# binding_key = "#" # binding_key = "#"
# #
# ## Maximum number of messages server should give to the worker. # ## Maximum number of messages server should give to the worker.
# # prefetch_count = 50 # prefetch_count = 50
# #
# ## Auth method. PLAIN and EXTERNAL are supported # ## Auth method. PLAIN and EXTERNAL are supported
# ## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as # ## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
@@ -3788,46 +3560,6 @@
# percentile_limit = 1000 # percentile_limit = 1000
# # Accepts syslog messages per RFC5425
# [[inputs.syslog]]
# ## Specify an ip or hostname with port - eg., tcp://localhost:6514, tcp://10.0.0.1:6514
# ## Protocol, address and port to host the syslog receiver.
# ## If no host is specified, then localhost is used.
# ## If no port is specified, 6514 is used (RFC5425#section-4.1).
# server = "tcp://:6514"
#
# ## TLS Config
# # tls_allowed_cacerts = ["/etc/telegraf/ca.pem"]
# # tls_cert = "/etc/telegraf/cert.pem"
# # tls_key = "/etc/telegraf/key.pem"
#
# ## Period between keep alive probes.
# ## 0 disables keep alive probes.
# ## Defaults to the OS configuration.
# ## Only applies to stream sockets (e.g. TCP).
# # keep_alive_period = "5m"
#
# ## Maximum number of concurrent connections (default = 0).
# ## 0 means unlimited.
# ## Only applies to stream sockets (e.g. TCP).
# # max_connections = 1024
#
# ## Read timeout (default = 500ms).
# ## 0 means unlimited.
# # read_timeout = 500ms
#
# ## Whether to parse in best effort mode or not (default = false).
# ## By default best effort parsing is off.
# # best_effort = false
#
# ## Character to prepend to SD-PARAMs (default = "_").
# ## A syslog message can contain multiple parameters and multiple identifiers within structured data section.
# ## Eg., [id1 name1="val1" name2="val2"][id2 name1="val1" nameA="valA"]
# ## For each combination a field is created.
# ## Its name is created concatenating identifier, sdparam_separator, and parameter name.
# # sdparam_separator = "_"
# # Stream a log file, like the tail -f command # # Stream a log file, like the tail -f command
# [[inputs.tail]] # [[inputs.tail]]
# ## files to tail. # ## files to tail.

View File

@@ -242,7 +242,7 @@
# #
# ## Ignore some mountpoints by filesystem type. For example (dev)tmpfs (usually # ## Ignore some mountpoints by filesystem type. For example (dev)tmpfs (usually
# ## present on /run, /var/run, /dev/shm or /dev). # ## present on /run, /var/run, /dev/shm or /dev).
# # ignore_fs = ["tmpfs", "devtmpfs", "devfs", "overlay", "aufs", "squashfs"] # # ignore_fs = ["tmpfs", "devtmpfs"]
# # Read metrics about disk IO by device # # Read metrics about disk IO by device

View File

@@ -156,24 +156,6 @@ func (c *Config) InputNames() []string {
return name return name
} }
// Outputs returns a list of strings of the configured aggregators.
func (c *Config) AggregatorNames() []string {
var name []string
for _, aggregator := range c.Aggregators {
name = append(name, aggregator.Name())
}
return name
}
// Outputs returns a list of strings of the configured processors.
func (c *Config) ProcessorNames() []string {
var name []string
for _, processor := range c.Processors {
name = append(name, processor.Name)
}
return name
}
// Outputs returns a list of strings of the configured outputs. // Outputs returns a list of strings of the configured outputs.
func (c *Config) OutputNames() []string { func (c *Config) OutputNames() []string {
var name []string var name []string

View File

@@ -11,7 +11,6 @@ import (
"os/exec" "os/exec"
"strconv" "strconv"
"strings" "strings"
"syscall"
"time" "time"
"unicode" "unicode"
) )
@@ -194,15 +193,3 @@ func RandomSleep(max time.Duration, shutdown chan struct{}) {
return return
} }
} }
// Exit status takes the error from exec.Command
// and returns the exit status and true
// if error is not exit status, will return 0 and false
func ExitStatus(err error) (int, bool) {
if exiterr, ok := err.(*exec.ExitError); ok {
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
return status.ExitStatus(), true
}
}
return 0, false
}

View File

@@ -1,7 +1,6 @@
package models package models
import ( import (
"log"
"time" "time"
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
@@ -154,7 +153,6 @@ func (r *RunningAggregator) Run(
m.Time().After(r.periodEnd.Add(truncation).Add(r.Config.Delay)) { m.Time().After(r.periodEnd.Add(truncation).Add(r.Config.Delay)) {
// the metric is outside the current aggregation period, so // the metric is outside the current aggregation period, so
// skip it. // skip it.
log.Printf("D! aggregator: metric \"%s\" is not in the current timewindow, skipping", m.Name())
continue continue
} }
r.add(m) r.add(m)

View File

@@ -113,6 +113,11 @@ func (ro *RunningOutput) AddMetric(m telegraf.Metric) {
m, _ = metric.New(name, tags, fields, t) m, _ = metric.New(name, tags, fields, t)
} }
if output, ok := ro.Output.(telegraf.AggregatingOutput); ok {
output.Add(m)
return
}
ro.metrics.Add(m) ro.metrics.Add(m)
if ro.metrics.Len() == ro.MetricBatchSize { if ro.metrics.Len() == ro.MetricBatchSize {
batch := ro.metrics.Batch(ro.MetricBatchSize) batch := ro.metrics.Batch(ro.MetricBatchSize)
@@ -125,6 +130,12 @@ func (ro *RunningOutput) AddMetric(m telegraf.Metric) {
// Write writes all cached points to this output. // Write writes all cached points to this output.
func (ro *RunningOutput) Write() error { func (ro *RunningOutput) Write() error {
if output, ok := ro.Output.(telegraf.AggregatingOutput); ok {
metrics := output.Push()
ro.metrics.Add(metrics...)
output.Reset()
}
nFails, nMetrics := ro.failMetrics.Len(), ro.metrics.Len() nFails, nMetrics := ro.failMetrics.Len(), ro.metrics.Len()
ro.BufferSize.Set(int64(nFails + nMetrics)) ro.BufferSize.Set(int64(nFails + nMetrics))
log.Printf("D! Output [%s] buffer fullness: %d / %d metrics. ", log.Printf("D! Output [%s] buffer fullness: %d / %d metrics. ",

View File

@@ -17,7 +17,7 @@ type ClientConfig struct {
// Deprecated in 1.7; use TLS variables above // Deprecated in 1.7; use TLS variables above
SSLCA string `toml:"ssl_ca"` SSLCA string `toml:"ssl_ca"`
SSLCert string `toml:"ssl_cert"` SSLCert string `toml:"ssl_cert"`
SSLKey string `toml:"ssl_key"` SSLKey string `toml:"ssl_ca"`
} }
// ServerConfig represents the standard server TLS config. // ServerConfig represents the standard server TLS config.

View File

@@ -13,6 +13,12 @@ type Output interface {
Write(metrics []Metric) error Write(metrics []Metric) error
} }
type AggregatingOutput interface {
Add(in Metric)
Push() []Metric
Reset()
}
type ServiceOutput interface { type ServiceOutput interface {
// Connect to the Output // Connect to the Output
Connect() error Connect() error

View File

@@ -4,5 +4,4 @@ import (
_ "github.com/influxdata/telegraf/plugins/aggregators/basicstats" _ "github.com/influxdata/telegraf/plugins/aggregators/basicstats"
_ "github.com/influxdata/telegraf/plugins/aggregators/histogram" _ "github.com/influxdata/telegraf/plugins/aggregators/histogram"
_ "github.com/influxdata/telegraf/plugins/aggregators/minmax" _ "github.com/influxdata/telegraf/plugins/aggregators/minmax"
_ "github.com/influxdata/telegraf/plugins/aggregators/valuecounter"
) )

View File

@@ -246,8 +246,6 @@ func convert(in interface{}) (float64, bool) {
return v, true return v, true
case int64: case int64:
return float64(v), true return float64(v), true
case uint64:
return float64(v), true
default: default:
return 0, false return 0, false
} }

View File

@@ -28,7 +28,6 @@ var m2, _ = metric.New("m1",
"c": float64(4), "c": float64(4),
"d": float64(6), "d": float64(6),
"e": float64(200), "e": float64(200),
"f": uint64(200),
"ignoreme": "string", "ignoreme": "string",
"andme": true, "andme": true,
}, },
@@ -82,10 +81,6 @@ func TestBasicStatsWithPeriod(t *testing.T) {
"e_max": float64(200), "e_max": float64(200),
"e_min": float64(200), "e_min": float64(200),
"e_mean": float64(200), "e_mean": float64(200),
"f_count": float64(1), //f
"f_max": float64(200),
"f_min": float64(200),
"f_mean": float64(200),
} }
expectedTags := map[string]string{ expectedTags := map[string]string{
"foo": "bar", "foo": "bar",
@@ -149,10 +144,6 @@ func TestBasicStatsDifferentPeriods(t *testing.T) {
"e_max": float64(200), "e_max": float64(200),
"e_min": float64(200), "e_min": float64(200),
"e_mean": float64(200), "e_mean": float64(200),
"f_count": float64(1), //f
"f_max": float64(200),
"f_min": float64(200),
"f_mean": float64(200),
} }
expectedTags = map[string]string{ expectedTags = map[string]string{
"foo": "bar", "foo": "bar",
@@ -178,7 +169,6 @@ func TestBasicStatsWithOnlyCount(t *testing.T) {
"c_count": float64(2), "c_count": float64(2),
"d_count": float64(2), "d_count": float64(2),
"e_count": float64(1), "e_count": float64(1),
"f_count": float64(1),
} }
expectedTags := map[string]string{ expectedTags := map[string]string{
"foo": "bar", "foo": "bar",
@@ -204,7 +194,6 @@ func TestBasicStatsWithOnlyMin(t *testing.T) {
"c_min": float64(2), "c_min": float64(2),
"d_min": float64(2), "d_min": float64(2),
"e_min": float64(200), "e_min": float64(200),
"f_min": float64(200),
} }
expectedTags := map[string]string{ expectedTags := map[string]string{
"foo": "bar", "foo": "bar",
@@ -230,7 +219,6 @@ func TestBasicStatsWithOnlyMax(t *testing.T) {
"c_max": float64(4), "c_max": float64(4),
"d_max": float64(6), "d_max": float64(6),
"e_max": float64(200), "e_max": float64(200),
"f_max": float64(200),
} }
expectedTags := map[string]string{ expectedTags := map[string]string{
"foo": "bar", "foo": "bar",
@@ -256,7 +244,6 @@ func TestBasicStatsWithOnlyMean(t *testing.T) {
"c_mean": float64(3), "c_mean": float64(3),
"d_mean": float64(4), "d_mean": float64(4),
"e_mean": float64(200), "e_mean": float64(200),
"f_mean": float64(200),
} }
expectedTags := map[string]string{ expectedTags := map[string]string{
"foo": "bar", "foo": "bar",
@@ -282,7 +269,6 @@ func TestBasicStatsWithOnlySum(t *testing.T) {
"c_sum": float64(6), "c_sum": float64(6),
"d_sum": float64(8), "d_sum": float64(8),
"e_sum": float64(200), "e_sum": float64(200),
"f_sum": float64(200),
} }
expectedTags := map[string]string{ expectedTags := map[string]string{
"foo": "bar", "foo": "bar",
@@ -413,8 +399,6 @@ func TestBasicStatsWithMinAndMax(t *testing.T) {
"d_min": float64(2), "d_min": float64(2),
"e_max": float64(200), //e "e_max": float64(200), //e
"e_min": float64(200), "e_min": float64(200),
"f_max": float64(200), //f
"f_min": float64(200),
} }
expectedTags := map[string]string{ expectedTags := map[string]string{
"foo": "bar", "foo": "bar",
@@ -466,11 +450,6 @@ func TestBasicStatsWithAllStats(t *testing.T) {
"e_min": float64(200), "e_min": float64(200),
"e_mean": float64(200), "e_mean": float64(200),
"e_sum": float64(200), "e_sum": float64(200),
"f_count": float64(1), //f
"f_max": float64(200),
"f_min": float64(200),
"f_mean": float64(200),
"f_sum": float64(200),
} }
expectedTags := map[string]string{ expectedTags := map[string]string{
"foo": "bar", "foo": "bar",

View File

@@ -107,8 +107,6 @@ func convert(in interface{}) (float64, bool) {
return v, true return v, true
case int64: case int64:
return float64(v), true return float64(v), true
case uint64:
return float64(v), true
default: default:
return 0, false return 0, false
} }

View File

@@ -38,7 +38,6 @@ var m2, _ = metric.New("m1",
"i": float64(1), "i": float64(1),
"j": float64(1), "j": float64(1),
"k": float64(200), "k": float64(200),
"l": uint64(200),
"ignoreme": "string", "ignoreme": "string",
"andme": true, "andme": true,
}, },
@@ -86,8 +85,6 @@ func TestMinMaxWithPeriod(t *testing.T) {
"j_min": float64(1), "j_min": float64(1),
"k_max": float64(200), "k_max": float64(200),
"k_min": float64(200), "k_min": float64(200),
"l_max": float64(200),
"l_min": float64(200),
} }
expectedTags := map[string]string{ expectedTags := map[string]string{
"foo": "bar", "foo": "bar",
@@ -157,8 +154,6 @@ func TestMinMaxDifferentPeriods(t *testing.T) {
"j_min": float64(1), "j_min": float64(1),
"k_max": float64(200), "k_max": float64(200),
"k_min": float64(200), "k_min": float64(200),
"l_max": float64(200),
"l_min": float64(200),
} }
expectedTags = map[string]string{ expectedTags = map[string]string{
"foo": "bar", "foo": "bar",

View File

@@ -1,73 +0,0 @@
# ValueCounter Aggregator Plugin
The valuecounter plugin counts the occurrence of values in fields and emits the
counter once every 'period' seconds.
A use case for the valuecounter plugin is when you are processing a HTTP access
log (with the logparser input) and want to count the HTTP status codes.
The fields which will be counted must be configured with the `fields`
configuration directive. When no `fields` is provided the plugin will not count
any fields. The results are emitted in fields in the format:
`originalfieldname_fieldvalue = count`.
Valuecounter only works on fields of the type int, bool or string. Float fields
are being dropped to prevent the creating of too many fields.
### Configuration:
```toml
[[aggregators.valuecounter]]
## General Aggregator Arguments:
## The period on which to flush & clear the aggregator.
period = "30s"
## If true, the original metric will be dropped by the
## aggregator and will not get sent to the output plugins.
drop_original = false
## The fields for which the values will be counted
fields = ["status"]
```
### Measurements & Fields:
- measurement1
- field_value1
- field_value2
### Tags:
No tags are applied by this aggregator.
### Example Output:
Example for parsing a HTTP access log.
telegraf.conf:
```
[[inputs.logparser]]
files = ["/tmp/tst.log"]
[inputs.logparser.grok]
patterns = ['%{DATA:url:tag} %{NUMBER:response:string}']
measurement = "access"
[[aggregators.valuecounter]]
namepass = ["access"]
fields = ["response"]
```
/tmp/tst.log
```
/some/path 200
/some/path 401
/some/path 200
```
```
$ telegraf --config telegraf.conf --quiet
access,url=/some/path,path=/tmp/tst.log,host=localhost.localdomain response="200" 1511948755991487011
access,url=/some/path,path=/tmp/tst.log,host=localhost.localdomain response="401" 1511948755991522282
access,url=/some/path,path=/tmp/tst.log,host=localhost.localdomain response="200" 1511948755991531697
access,path=/tmp/tst.log,host=localhost.localdomain,url=/some/path response_200=2i,response_401=1i 1511948761000000000
```

View File

@@ -1,108 +0,0 @@
package valuecounter
import (
"fmt"
"log"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/aggregators"
)
type aggregate struct {
name string
tags map[string]string
fieldCount map[string]int
}
// ValueCounter an aggregation plugin
type ValueCounter struct {
cache map[uint64]aggregate
Fields []string
}
// NewValueCounter create a new aggregation plugin which counts the occurances
// of fields and emits the count.
func NewValueCounter() telegraf.Aggregator {
vc := &ValueCounter{}
vc.Reset()
return vc
}
var sampleConfig = `
## General Aggregator Arguments:
## The period on which to flush & clear the aggregator.
period = "30s"
## If true, the original metric will be dropped by the
## aggregator and will not get sent to the output plugins.
drop_original = false
## The fields for which the values will be counted
fields = []
`
// SampleConfig generates a sample config for the ValueCounter plugin
func (vc *ValueCounter) SampleConfig() string {
return sampleConfig
}
// Description returns the description of the ValueCounter plugin
func (vc *ValueCounter) Description() string {
return "Count the occurance of values in fields."
}
// Add is run on every metric which passes the plugin
func (vc *ValueCounter) Add(in telegraf.Metric) {
id := in.HashID()
// Check if the cache already has an entry for this metric, if not create it
if _, ok := vc.cache[id]; !ok {
a := aggregate{
name: in.Name(),
tags: in.Tags(),
fieldCount: make(map[string]int),
}
vc.cache[id] = a
}
// Check if this metric has fields which we need to count, if so increment
// the count.
for fk, fv := range in.Fields() {
for _, cf := range vc.Fields {
if fk == cf {
// Do not process float types to prevent memory from blowing up
switch fv.(type) {
default:
log.Printf("I! Valuecounter: Unsupported field type. " +
"Must be an int, string or bool. Ignoring.")
continue
case uint64, int64, string, bool:
}
fn := fmt.Sprintf("%v_%v", fk, fv)
vc.cache[id].fieldCount[fn]++
}
}
}
}
// Push emits the counters
func (vc *ValueCounter) Push(acc telegraf.Accumulator) {
for _, agg := range vc.cache {
fields := map[string]interface{}{}
for field, count := range agg.fieldCount {
fields[field] = count
}
acc.AddFields(agg.name, fields, agg.tags)
}
}
// Reset the cache, executed after each push
func (vc *ValueCounter) Reset() {
vc.cache = make(map[uint64]aggregate)
}
func init() {
aggregators.Add("valuecounter", func() telegraf.Aggregator {
return NewValueCounter()
})
}

View File

@@ -1,126 +0,0 @@
package valuecounter
import (
"testing"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/metric"
"github.com/influxdata/telegraf/testutil"
)
// Create a valuecounter with config
func NewTestValueCounter(fields []string) telegraf.Aggregator {
vc := &ValueCounter{
Fields: fields,
}
vc.Reset()
return vc
}
var m1, _ = metric.New("m1",
map[string]string{"foo": "bar"},
map[string]interface{}{
"status": 200,
"somefield": 20.1,
"foobar": "bar",
},
time.Now(),
)
var m2, _ = metric.New("m1",
map[string]string{"foo": "bar"},
map[string]interface{}{
"status": "OK",
"ignoreme": "string",
"andme": true,
"boolfield": false,
},
time.Now(),
)
func BenchmarkApply(b *testing.B) {
vc := NewTestValueCounter([]string{"status"})
for n := 0; n < b.N; n++ {
vc.Add(m1)
vc.Add(m2)
}
}
// Test basic functionality
func TestBasic(t *testing.T) {
vc := NewTestValueCounter([]string{"status"})
acc := testutil.Accumulator{}
vc.Add(m1)
vc.Add(m2)
vc.Add(m1)
vc.Push(&acc)
expectedFields := map[string]interface{}{
"status_200": 2,
"status_OK": 1,
}
expectedTags := map[string]string{
"foo": "bar",
}
acc.AssertContainsTaggedFields(t, "m1", expectedFields, expectedTags)
}
// Test with multiple fields to count
func TestMultipleFields(t *testing.T) {
vc := NewTestValueCounter([]string{"status", "somefield", "boolfield"})
acc := testutil.Accumulator{}
vc.Add(m1)
vc.Add(m2)
vc.Add(m2)
vc.Add(m1)
vc.Push(&acc)
expectedFields := map[string]interface{}{
"status_200": 2,
"status_OK": 2,
"boolfield_false": 2,
}
expectedTags := map[string]string{
"foo": "bar",
}
acc.AssertContainsTaggedFields(t, "m1", expectedFields, expectedTags)
}
// Test with a reset between two runs
func TestWithReset(t *testing.T) {
vc := NewTestValueCounter([]string{"status"})
acc := testutil.Accumulator{}
vc.Add(m1)
vc.Add(m1)
vc.Add(m2)
vc.Push(&acc)
expectedFields := map[string]interface{}{
"status_200": 2,
"status_OK": 1,
}
expectedTags := map[string]string{
"foo": "bar",
}
acc.AssertContainsTaggedFields(t, "m1", expectedFields, expectedTags)
acc.ClearMetrics()
vc.Reset()
vc.Add(m2)
vc.Add(m2)
vc.Add(m1)
vc.Push(&acc)
expectedFields = map[string]interface{}{
"status_200": 1,
"status_OK": 2,
}
acc.AssertContainsTaggedFields(t, "m1", expectedFields, expectedTags)
}

View File

@@ -97,13 +97,11 @@ import (
_ "github.com/influxdata/telegraf/plugins/inputs/solr" _ "github.com/influxdata/telegraf/plugins/inputs/solr"
_ "github.com/influxdata/telegraf/plugins/inputs/sqlserver" _ "github.com/influxdata/telegraf/plugins/inputs/sqlserver"
_ "github.com/influxdata/telegraf/plugins/inputs/statsd" _ "github.com/influxdata/telegraf/plugins/inputs/statsd"
_ "github.com/influxdata/telegraf/plugins/inputs/syslog"
_ "github.com/influxdata/telegraf/plugins/inputs/sysstat" _ "github.com/influxdata/telegraf/plugins/inputs/sysstat"
_ "github.com/influxdata/telegraf/plugins/inputs/system" _ "github.com/influxdata/telegraf/plugins/inputs/system"
_ "github.com/influxdata/telegraf/plugins/inputs/tail" _ "github.com/influxdata/telegraf/plugins/inputs/tail"
_ "github.com/influxdata/telegraf/plugins/inputs/tcp_listener" _ "github.com/influxdata/telegraf/plugins/inputs/tcp_listener"
_ "github.com/influxdata/telegraf/plugins/inputs/teamspeak" _ "github.com/influxdata/telegraf/plugins/inputs/teamspeak"
_ "github.com/influxdata/telegraf/plugins/inputs/tengine"
_ "github.com/influxdata/telegraf/plugins/inputs/tomcat" _ "github.com/influxdata/telegraf/plugins/inputs/tomcat"
_ "github.com/influxdata/telegraf/plugins/inputs/trig" _ "github.com/influxdata/telegraf/plugins/inputs/trig"
_ "github.com/influxdata/telegraf/plugins/inputs/twemproxy" _ "github.com/influxdata/telegraf/plugins/inputs/twemproxy"

View File

@@ -15,48 +15,23 @@ The following defaults are known to work with RabbitMQ:
```toml ```toml
# AMQP consumer plugin # AMQP consumer plugin
[[inputs.amqp_consumer]] [[inputs.amqp_consumer]]
## Broker to consume from. ## AMQP url
## deprecated in 1.7; use the brokers option url = "amqp://localhost:5672/influxdb"
# url = "amqp://localhost:5672/influxdb" ## AMQP exchange
## Brokers to consume from. If multiple brokers are specified a random broker
## will be selected anytime a connection is established. This can be
## helpful for load balancing when not using a dedicated load balancer.
brokers = ["amqp://localhost:5672/influxdb"]
## Authentication credentials for the PLAIN auth_method.
# username = ""
# password = ""
## Exchange to declare and consume from.
exchange = "telegraf" exchange = "telegraf"
## Exchange type; common types are "direct", "fanout", "topic", "header", "x-consistent-hash".
# exchange_type = "topic"
## If true, exchange will be passively declared.
# exchange_passive = false
## Exchange durability can be either "transient" or "durable".
# exchange_durability = "durable"
## Additional exchange arguments.
# exchange_arguments = { }
# exchange_arguments = {"hash_propery" = "timestamp"}
## AMQP queue name ## AMQP queue name
queue = "telegraf" queue = "telegraf"
## Binding Key ## Binding Key
binding_key = "#" binding_key = "#"
## Maximum number of messages server should give to the worker. ## Controls how many messages the server will try to keep on the network
# prefetch_count = 50 ## for consumers before receiving delivery acks.
#prefetch_count = 50
## Auth method. PLAIN and EXTERNAL are supported ## Auth method. PLAIN and EXTERNAL are supported.
## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as ## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
## described here: https://www.rabbitmq.com/plugins.html ## described here: https://www.rabbitmq.com/plugins.html
# auth_method = "PLAIN" # auth_method = "PLAIN"
## Optional TLS Config ## Optional TLS Config
# tls_ca = "/etc/telegraf/ca.pem" # tls_ca = "/etc/telegraf/ca.pem"
# tls_cert = "/etc/telegraf/cert.pem" # tls_cert = "/etc/telegraf/cert.pem"

View File

@@ -1,10 +1,8 @@
package amqp_consumer package amqp_consumer
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"math/rand"
"strings" "strings"
"sync" "sync"
"time" "time"
@@ -19,16 +17,9 @@ import (
// AMQPConsumer is the top level struct for this plugin // AMQPConsumer is the top level struct for this plugin
type AMQPConsumer struct { type AMQPConsumer struct {
URL string `toml:"url"` // deprecated in 1.7; use brokers URL string
Brokers []string `toml:"brokers"` // AMQP exchange
Username string `toml:"username"` Exchange string
Password string `toml:"password"`
Exchange string `toml:"exchange"`
ExchangeType string `toml:"exchange_type"`
ExchangeDurability string `toml:"exchange_durability"`
ExchangePassive bool `toml:"exchange_passive"`
ExchangeArguments map[string]string `toml:"exchange_arguments"`
// Queue Name // Queue Name
Queue string Queue string
// Binding Key // Binding Key
@@ -57,55 +48,23 @@ func (a *externalAuth) Response() string {
} }
const ( const (
DefaultAuthMethod = "PLAIN" DefaultAuthMethod = "PLAIN"
DefaultBroker = "amqp://localhost:5672/influxdb"
DefaultExchangeType = "topic"
DefaultExchangeDurability = "durable"
DefaultPrefetchCount = 50 DefaultPrefetchCount = 50
) )
func (a *AMQPConsumer) SampleConfig() string { func (a *AMQPConsumer) SampleConfig() string {
return ` return `
## Broker to consume from. ## AMQP url
## deprecated in 1.7; use the brokers option url = "amqp://localhost:5672/influxdb"
# url = "amqp://localhost:5672/influxdb" ## AMQP exchange
## Brokers to consume from. If multiple brokers are specified a random broker
## will be selected anytime a connection is established. This can be
## helpful for load balancing when not using a dedicated load balancer.
brokers = ["amqp://localhost:5672/influxdb"]
## Authentication credentials for the PLAIN auth_method.
# username = ""
# password = ""
## Exchange to declare and consume from.
exchange = "telegraf" exchange = "telegraf"
## Exchange type; common types are "direct", "fanout", "topic", "header", "x-consistent-hash".
# exchange_type = "topic"
## If true, exchange will be passively declared.
# exchange_passive = false
## Exchange durability can be either "transient" or "durable".
# exchange_durability = "durable"
## Additional exchange arguments.
# exchange_arguments = { }
# exchange_arguments = {"hash_propery" = "timestamp"}
## AMQP queue name ## AMQP queue name
queue = "telegraf" queue = "telegraf"
## Binding Key ## Binding Key
binding_key = "#" binding_key = "#"
## Maximum number of messages server should give to the worker. ## Maximum number of messages server should give to the worker.
# prefetch_count = 50 prefetch_count = 50
## Auth method. PLAIN and EXTERNAL are supported ## Auth method. PLAIN and EXTERNAL are supported
## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as ## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
@@ -147,21 +106,16 @@ func (a *AMQPConsumer) createConfig() (*amqp.Config, error) {
return nil, err return nil, err
} }
var auth []amqp.Authentication // parse auth method
var sasl []amqp.Authentication // nil by default
if strings.ToUpper(a.AuthMethod) == "EXTERNAL" { if strings.ToUpper(a.AuthMethod) == "EXTERNAL" {
auth = []amqp.Authentication{&externalAuth{}} sasl = []amqp.Authentication{&externalAuth{}}
} else if a.Username != "" || a.Password != "" {
auth = []amqp.Authentication{
&amqp.PlainAuth{
Username: a.Username,
Password: a.Password,
},
}
} }
config := amqp.Config{ config := amqp.Config{
TLSClientConfig: tls, TLSClientConfig: tls,
SASL: auth, // if nil, it will be PLAIN SASL: sasl, // if nil, it will be PLAIN
} }
return &config, nil return &config, nil
} }
@@ -209,55 +163,28 @@ func (a *AMQPConsumer) Start(acc telegraf.Accumulator) error {
} }
func (a *AMQPConsumer) connect(amqpConf *amqp.Config) (<-chan amqp.Delivery, error) { func (a *AMQPConsumer) connect(amqpConf *amqp.Config) (<-chan amqp.Delivery, error) {
brokers := a.Brokers conn, err := amqp.DialConfig(a.URL, *amqpConf)
if len(brokers) == 0 { if err != nil {
brokers = []string{a.URL} return nil, err
} }
a.conn = conn
p := rand.Perm(len(brokers)) ch, err := conn.Channel()
for _, n := range p {
broker := brokers[n]
log.Printf("D! [amqp_consumer] connecting to %q", broker)
conn, err := amqp.DialConfig(broker, *amqpConf)
if err == nil {
a.conn = conn
log.Printf("D! [amqp_consumer] connected to %q", broker)
break
}
log.Printf("D! [amqp_consumer] error connecting to %q", broker)
}
if a.conn == nil {
return nil, errors.New("could not connect to any broker")
}
ch, err := a.conn.Channel()
if err != nil { if err != nil {
return nil, fmt.Errorf("Failed to open a channel: %s", err) return nil, fmt.Errorf("Failed to open a channel: %s", err)
} }
var exchangeDurable = true err = ch.ExchangeDeclare(
switch a.ExchangeDurability { a.Exchange, // name
case "transient": "topic", // type
exchangeDurable = false true, // durable
default: false, // auto-deleted
exchangeDurable = true false, // internal
} false, // no-wait
nil, // arguments
exchangeArgs := make(amqp.Table, len(a.ExchangeArguments)) )
for k, v := range a.ExchangeArguments {
exchangeArgs[k] = v
}
err = declareExchange(
ch,
a.Exchange,
a.ExchangeType,
a.ExchangePassive,
exchangeDurable,
exchangeArgs)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("Failed to declare an exchange: %s", err)
} }
q, err := ch.QueueDeclare( q, err := ch.QueueDeclare(
@@ -309,42 +236,6 @@ func (a *AMQPConsumer) connect(amqpConf *amqp.Config) (<-chan amqp.Delivery, err
return msgs, err return msgs, err
} }
func declareExchange(
channel *amqp.Channel,
exchangeName string,
exchangeType string,
exchangePassive bool,
exchangeDurable bool,
exchangeArguments amqp.Table,
) error {
var err error
if exchangePassive {
err = channel.ExchangeDeclarePassive(
exchangeName,
exchangeType,
exchangeDurable,
false, // delete when unused
false, // internal
false, // no-wait
exchangeArguments,
)
} else {
err = channel.ExchangeDeclare(
exchangeName,
exchangeType,
exchangeDurable,
false, // delete when unused
false, // internal
false, // no-wait
exchangeArguments,
)
}
if err != nil {
return fmt.Errorf("error declaring exchange: %v", err)
}
return nil
}
// Read messages from queue and add them to the Accumulator // Read messages from queue and add them to the Accumulator
func (a *AMQPConsumer) process(msgs <-chan amqp.Delivery, acc telegraf.Accumulator) { func (a *AMQPConsumer) process(msgs <-chan amqp.Delivery, acc telegraf.Accumulator) {
defer a.wg.Done() defer a.wg.Done()
@@ -376,11 +267,8 @@ func (a *AMQPConsumer) Stop() {
func init() { func init() {
inputs.Add("amqp_consumer", func() telegraf.Input { inputs.Add("amqp_consumer", func() telegraf.Input {
return &AMQPConsumer{ return &AMQPConsumer{
URL: DefaultBroker, AuthMethod: DefaultAuthMethod,
AuthMethod: DefaultAuthMethod, PrefetchCount: DefaultPrefetchCount,
ExchangeType: DefaultExchangeType,
ExchangeDurability: DefaultExchangeDurability,
PrefetchCount: DefaultPrefetchCount,
} }
}) })
} }

View File

@@ -8,7 +8,6 @@ Supported Burrow version: `1.x`
### Configuration ### Configuration
``` ```
[[inputs.burrow]]
## Burrow API endpoints in format "schema://host:port". ## Burrow API endpoints in format "schema://host:port".
## Default is "http://localhost:8000". ## Default is "http://localhost:8000".
servers = ["http://localhost:8000"] servers = ["http://localhost:8000"]
@@ -92,7 +91,6 @@ Supported Burrow version: `1.x`
- group (string) - group (string)
- topic (string) - topic (string)
- partition (int) - partition (int)
- owner (string)
* `burrow_topic` * `burrow_topic`
- cluster (string) - cluster (string)

View File

@@ -116,7 +116,6 @@ type (
Start apiStatusResponseLagItem `json:"start"` Start apiStatusResponseLagItem `json:"start"`
End apiStatusResponseLagItem `json:"end"` End apiStatusResponseLagItem `json:"end"`
CurrentLag int64 `json:"current_lag"` CurrentLag int64 `json:"current_lag"`
Owner string `json:"owner"`
} }
// response: lag field item // response: lag field item
@@ -448,7 +447,6 @@ func (b *burrow) genGroupLagMetrics(r *apiResponse, cluster, group string, acc t
"group": group, "group": group,
"topic": partition.Topic, "topic": partition.Topic,
"partition": strconv.FormatInt(int64(partition.Partition), 10), "partition": strconv.FormatInt(int64(partition.Partition), 10),
"owner": partition.Owner,
}, },
) )
} }

View File

@@ -129,9 +129,9 @@ func TestBurrowPartition(t *testing.T) {
}, },
} }
tags := []map[string]string{ tags := []map[string]string{
{"cluster": "clustername1", "group": "group1", "topic": "topicA", "partition": "0", "owner": "kafka1"}, {"cluster": "clustername1", "group": "group1", "topic": "topicA", "partition": "0"},
{"cluster": "clustername1", "group": "group1", "topic": "topicA", "partition": "1", "owner": "kafka2"}, {"cluster": "clustername1", "group": "group1", "topic": "topicA", "partition": "1"},
{"cluster": "clustername1", "group": "group1", "topic": "topicA", "partition": "2", "owner": "kafka3"}, {"cluster": "clustername1", "group": "group1", "topic": "topicA", "partition": "2"},
} }
require.Empty(t, acc.Errors) require.Empty(t, acc.Errors)

View File

@@ -10,7 +10,7 @@
{ {
"topic": "topicA", "topic": "topicA",
"partition": 0, "partition": 0,
"owner": "kafka1", "owner": "kafka",
"status": "OK", "status": "OK",
"start": { "start": {
"offset": 431323195, "offset": 431323195,
@@ -28,7 +28,7 @@
{ {
"topic": "topicA", "topic": "topicA",
"partition": 1, "partition": 1,
"owner": "kafka2", "owner": "kafka",
"status": "OK", "status": "OK",
"start": { "start": {
"offset": 431322962, "offset": 431322962,
@@ -46,7 +46,7 @@
{ {
"topic": "topicA", "topic": "topicA",
"partition": 2, "partition": 2,
"owner": "kafka3", "owner": "kafka",
"status": "OK", "status": "OK",
"start": { "start": {
"offset": 428636563, "offset": 428636563,

View File

@@ -3,15 +3,14 @@
package conntrack package conntrack
import ( import (
"github.com/influxdata/telegraf/testutil"
"github.com/stretchr/testify/assert"
"io/ioutil" "io/ioutil"
"os" "os"
"path" "path"
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
"github.com/influxdata/telegraf/testutil"
"github.com/stretchr/testify/assert"
) )
func restoreDflts(savedFiles, savedDirs []string) { func restoreDflts(savedFiles, savedDirs []string) {
@@ -40,7 +39,6 @@ func TestDefaultsUsed(t *testing.T) {
tmpFile, err := ioutil.TempFile(tmpdir, "ip_conntrack_count") tmpFile, err := ioutil.TempFile(tmpdir, "ip_conntrack_count")
assert.NoError(t, err) assert.NoError(t, err)
defer os.Remove(tmpFile.Name())
dfltDirs = []string{tmpdir} dfltDirs = []string{tmpdir}
fname := path.Base(tmpFile.Name()) fname := path.Base(tmpFile.Name())
@@ -65,8 +63,6 @@ func TestConfigsUsed(t *testing.T) {
cntFile, err := ioutil.TempFile(tmpdir, "nf_conntrack_count") cntFile, err := ioutil.TempFile(tmpdir, "nf_conntrack_count")
maxFile, err := ioutil.TempFile(tmpdir, "nf_conntrack_max") maxFile, err := ioutil.TempFile(tmpdir, "nf_conntrack_max")
assert.NoError(t, err) assert.NoError(t, err)
defer os.Remove(cntFile.Name())
defer os.Remove(maxFile.Name())
dfltDirs = []string{tmpdir} dfltDirs = []string{tmpdir}
cntFname := path.Base(cntFile.Name()) cntFname := path.Base(cntFile.Name())

View File

@@ -124,7 +124,6 @@ docker API.
- server_version - server_version
- container_image - container_image
- container_name - container_name
- container_status
- container_version - container_version
- fields: - fields:
- total_pgmafault - total_pgmafault
@@ -168,7 +167,6 @@ docker API.
- server_version - server_version
- container_image - container_image
- container_name - container_name
- container_status
- container_version - container_version
- cpu - cpu
- fields: - fields:
@@ -188,7 +186,6 @@ docker API.
- server_version - server_version
- container_image - container_image
- container_name - container_name
- container_status
- container_version - container_version
- network - network
- fields: - fields:
@@ -208,7 +205,6 @@ docker API.
- server_version - server_version
- container_image - container_image
- container_name - container_name
- container_status
- container_version - container_version
- device - device
- fields: - fields:
@@ -230,27 +226,11 @@ docker API.
- server_version - server_version
- container_image - container_image
- container_name - container_name
- container_status
- container_version - container_version
- fields: - fields:
- health_status (string) - health_status (string)
- failing_streak (integer) - failing_streak (integer)
- docker_container_status
- tags:
- engine_host
- server_version
- container_image
- container_name
- container_status
- container_version
- fields:
- oomkilled (boolean)
- pid (integer)
- exitcode (integer)
- started_at (integer)
- finished_at (integer)
- docker_swarm - docker_swarm
- tags: - tags:
- service_id - service_id
@@ -265,12 +245,12 @@ docker API.
``` ```
docker,engine_host=debian-stretch-docker,server_version=17.09.0-ce n_containers=6i,n_containers_paused=0i,n_containers_running=1i,n_containers_stopped=5i,n_cpus=2i,n_goroutines=41i,n_images=2i,n_listener_events=0i,n_used_file_descriptors=27i 1524002041000000000 docker,engine_host=debian-stretch-docker,server_version=17.09.0-ce n_containers=6i,n_containers_paused=0i,n_containers_running=1i,n_containers_stopped=5i,n_cpus=2i,n_goroutines=41i,n_images=2i,n_listener_events=0i,n_used_file_descriptors=27i 1524002041000000000
docker,engine_host=debian-stretch-docker,server_version=17.09.0-ce,unit=bytes memory_total=2101661696i 1524002041000000000 docker,engine_host=debian-stretch-docker,server_version=17.09.0-ce,unit=bytes memory_total=2101661696i 1524002041000000000
docker_container_mem,container_image=telegraf,container_name=zen_ritchie,container_status=running,container_version=unknown,engine_host=debian-stretch-docker,server_version=17.09.0-ce active_anon=8327168i,active_file=2314240i,cache=27402240i,container_id="adc4ba9593871bf2ab95f3ffde70d1b638b897bb225d21c2c9c84226a10a8cf4",hierarchical_memory_limit=9223372036854771712i,inactive_anon=0i,inactive_file=25088000i,limit=2101661696i,mapped_file=20582400i,max_usage=36646912i,pgfault=4193i,pgmajfault=214i,pgpgin=9243i,pgpgout=520i,rss=8327168i,rss_huge=0i,total_active_anon=8327168i,total_active_file=2314240i,total_cache=27402240i,total_inactive_anon=0i,total_inactive_file=25088000i,total_mapped_file=20582400i,total_pgfault=4193i,total_pgmajfault=214i,total_pgpgin=9243i,total_pgpgout=520i,total_rss=8327168i,total_rss_huge=0i,total_unevictable=0i,total_writeback=0i,unevictable=0i,usage=36528128i,usage_percent=0.4342225020025297,writeback=0i 1524002042000000000 docker_container_mem,container_image=telegraf,container_name=zen_ritchie,container_version=unknown,engine_host=debian-stretch-docker,server_version=17.09.0-ce active_anon=8327168i,active_file=2314240i,cache=27402240i,container_id="adc4ba9593871bf2ab95f3ffde70d1b638b897bb225d21c2c9c84226a10a8cf4",hierarchical_memory_limit=9223372036854771712i,inactive_anon=0i,inactive_file=25088000i,limit=2101661696i,mapped_file=20582400i,max_usage=36646912i,pgfault=4193i,pgmajfault=214i,pgpgin=9243i,pgpgout=520i,rss=8327168i,rss_huge=0i,total_active_anon=8327168i,total_active_file=2314240i,total_cache=27402240i,total_inactive_anon=0i,total_inactive_file=25088000i,total_mapped_file=20582400i,total_pgfault=4193i,total_pgmajfault=214i,total_pgpgin=9243i,total_pgpgout=520i,total_rss=8327168i,total_rss_huge=0i,total_unevictable=0i,total_writeback=0i,unevictable=0i,usage=36528128i,usage_percent=0.4342225020025297,writeback=0i 1524002042000000000
docker_container_cpu,container_image=telegraf,container_name=zen_ritchie,container_status=running,container_version=unknown,cpu=cpu-total,engine_host=debian-stretch-docker,server_version=17.09.0-ce container_id="adc4ba9593871bf2ab95f3ffde70d1b638b897bb225d21c2c9c84226a10a8cf4",throttling_periods=0i,throttling_throttled_periods=0i,throttling_throttled_time=0i,usage_in_kernelmode=40000000i,usage_in_usermode=100000000i,usage_percent=0,usage_system=6394210000000i,usage_total=117319068i 1524002042000000000 docker_container_cpu,container_image=telegraf,container_name=zen_ritchie,container_version=unknown,cpu=cpu-total,engine_host=debian-stretch-docker,server_version=17.09.0-ce container_id="adc4ba9593871bf2ab95f3ffde70d1b638b897bb225d21c2c9c84226a10a8cf4",throttling_periods=0i,throttling_throttled_periods=0i,throttling_throttled_time=0i,usage_in_kernelmode=40000000i,usage_in_usermode=100000000i,usage_percent=0,usage_system=6394210000000i,usage_total=117319068i 1524002042000000000
docker_container_cpu,container_image=telegraf,container_name=zen_ritchie,container_status=running,container_version=unknown,cpu=cpu0,engine_host=debian-stretch-docker,server_version=17.09.0-ce container_id="adc4ba9593871bf2ab95f3ffde70d1b638b897bb225d21c2c9c84226a10a8cf4",usage_total=20825265i 1524002042000000000 docker_container_cpu,container_image=telegraf,container_name=zen_ritchie,container_version=unknown,cpu=cpu0,engine_host=debian-stretch-docker,server_version=17.09.0-ce container_id="adc4ba9593871bf2ab95f3ffde70d1b638b897bb225d21c2c9c84226a10a8cf4",usage_total=20825265i 1524002042000000000
docker_container_cpu,container_image=telegraf,container_name=zen_ritchie,container_status=running,container_version=unknown,cpu=cpu1,engine_host=debian-stretch-docker,server_version=17.09.0-ce container_id="adc4ba9593871bf2ab95f3ffde70d1b638b897bb225d21c2c9c84226a10a8cf4",usage_total=96493803i 1524002042000000000 docker_container_cpu,container_image=telegraf,container_name=zen_ritchie,container_version=unknown,cpu=cpu1,engine_host=debian-stretch-docker,server_version=17.09.0-ce container_id="adc4ba9593871bf2ab95f3ffde70d1b638b897bb225d21c2c9c84226a10a8cf4",usage_total=96493803i 1524002042000000000
docker_container_net,container_image=telegraf,container_name=zen_ritchie,container_status=running,container_version=unknown,engine_host=debian-stretch-docker,network=eth0,server_version=17.09.0-ce container_id="adc4ba9593871bf2ab95f3ffde70d1b638b897bb225d21c2c9c84226a10a8cf4",rx_bytes=1576i,rx_dropped=0i,rx_errors=0i,rx_packets=20i,tx_bytes=0i,tx_dropped=0i,tx_errors=0i,tx_packets=0i 1524002042000000000 docker_container_net,container_image=telegraf,container_name=zen_ritchie,container_version=unknown,engine_host=debian-stretch-docker,network=eth0,server_version=17.09.0-ce container_id="adc4ba9593871bf2ab95f3ffde70d1b638b897bb225d21c2c9c84226a10a8cf4",rx_bytes=1576i,rx_dropped=0i,rx_errors=0i,rx_packets=20i,tx_bytes=0i,tx_dropped=0i,tx_errors=0i,tx_packets=0i 1524002042000000000
docker_container_blkio,container_image=telegraf,container_name=zen_ritchie,container_status=running,container_version=unknown,device=254:0,engine_host=debian-stretch-docker,server_version=17.09.0-ce container_id="adc4ba9593871bf2ab95f3ffde70d1b638b897bb225d21c2c9c84226a10a8cf4",io_service_bytes_recursive_async=27398144i,io_service_bytes_recursive_read=27398144i,io_service_bytes_recursive_sync=0i,io_service_bytes_recursive_total=27398144i,io_service_bytes_recursive_write=0i,io_serviced_recursive_async=529i,io_serviced_recursive_read=529i,io_serviced_recursive_sync=0i,io_serviced_recursive_total=529i,io_serviced_recursive_write=0i 1524002042000000000 docker_container_blkio,container_image=telegraf,container_name=zen_ritchie,container_version=unknown,device=254:0,engine_host=debian-stretch-docker,server_version=17.09.0-ce container_id="adc4ba9593871bf2ab95f3ffde70d1b638b897bb225d21c2c9c84226a10a8cf4",io_service_bytes_recursive_async=27398144i,io_service_bytes_recursive_read=27398144i,io_service_bytes_recursive_sync=0i,io_service_bytes_recursive_total=27398144i,io_service_bytes_recursive_write=0i,io_serviced_recursive_async=529i,io_serviced_recursive_read=529i,io_serviced_recursive_sync=0i,io_serviced_recursive_total=529i,io_serviced_recursive_write=0i 1524002042000000000
docker_container_health,container_image=telegraf,container_name=zen_ritchie,container_status=running,container_version=unknown,engine_host=debian-stretch-docker,server_version=17.09.0-ce failing_streak=0i,health_status="healthy" 1524007529000000000 docker_container_health,container_image=telegraf,container_name=zen_ritchie,container_version=unknown,engine_host=debian-stretch-docker,server_version=17.09.0-ce failing_streak=0i,health_status="healthy" 1524007529000000000
docker_swarm,service_id=xaup2o9krw36j2dy1mjx1arjw,service_mode=replicated,service_name=test tasks_desired=3,tasks_running=3 1508968160000000000 docker_swarm,service_id=xaup2o9krw36j2dy1mjx1arjw,service_mode=replicated,service_name=test tasks_desired=3,tasks_running=3 1508968160000000000
``` ```

View File

@@ -366,22 +366,9 @@ func (d *Docker) gatherContainer(
var v *types.StatsJSON var v *types.StatsJSON
// Parse container name // Parse container name
cname := "unknown" cname := "unknown"
match := false if len(container.Names) > 0 {
if len(container.Names) == 0 { // for tests // Not sure what to do with other names, just take the first.
match = true cname = strings.TrimPrefix(container.Names[0], "/")
}
for i := range container.Names {
if !match {
match = d.containerFilter.Match(strings.TrimPrefix(container.Names[i], "/"))
if match {
cname = strings.TrimPrefix(container.Names[i], "/")
}
}
}
if !match {
return nil
} }
// the image name sometimes has a version part, or a private repo // the image name sometimes has a version part, or a private repo
@@ -404,6 +391,10 @@ func (d *Docker) gatherContainer(
"container_version": imageVersion, "container_version": imageVersion,
} }
if !d.containerFilter.Match(cname) {
return nil
}
ctx, cancel := context.WithTimeout(context.Background(), d.Timeout.Duration) ctx, cancel := context.WithTimeout(context.Background(), d.Timeout.Duration)
defer cancel() defer cancel()
r, err := d.client.ContainerStats(ctx, container.ID, false) r, err := d.client.ContainerStats(ctx, container.ID, false)
@@ -420,11 +411,6 @@ func (d *Docker) gatherContainer(
} }
daemonOSType := r.OSType daemonOSType := r.OSType
// use common (printed at `docker ps`) name for container
if cname != strings.TrimPrefix(v.Name, "/") && v.Name != "" {
tags["container_name"] = strings.TrimPrefix(v.Name, "/")
}
// Add labels to tags // Add labels to tags
for k, label := range container.Labels { for k, label := range container.Labels {
if d.labelFilter.Match(k) { if d.labelFilter.Match(k) {
@@ -449,23 +435,6 @@ func (d *Docker) gatherContainer(
} }
} }
} }
if info.State != nil {
tags["container_status"] = info.State.Status
statefields := map[string]interface{}{
"oomkilled": info.State.OOMKilled,
"pid": info.State.Pid,
"exitcode": info.State.ExitCode,
}
container_time, err := time.Parse(time.RFC3339, info.State.StartedAt)
if err == nil && !container_time.IsZero() {
statefields["started_at"] = container_time.UnixNano()
}
container_time, err = time.Parse(time.RFC3339, info.State.FinishedAt)
if err == nil && !container_time.IsZero() {
statefields["finished_at"] = container_time.UnixNano()
}
acc.AddFields("docker_container_status", statefields, tags, time.Now())
}
if info.State.Health != nil { if info.State.Health != nil {
healthfields := map[string]interface{}{ healthfields := map[string]interface{}{
@@ -475,12 +444,12 @@ func (d *Docker) gatherContainer(
acc.AddFields("docker_container_health", healthfields, tags, time.Now()) acc.AddFields("docker_container_health", healthfields, tags, time.Now())
} }
parseContainerStats(v, acc, tags, container.ID, d.PerDevice, d.Total, daemonOSType) gatherContainerStats(v, acc, tags, container.ID, d.PerDevice, d.Total, daemonOSType)
return nil return nil
} }
func parseContainerStats( func gatherContainerStats(
stat *types.StatsJSON, stat *types.StatsJSON,
acc telegraf.Accumulator, acc telegraf.Accumulator,
tags map[string]string, tags map[string]string,

View File

@@ -107,7 +107,7 @@ func TestDockerGatherContainerStats(t *testing.T) {
"container_image": "redis/image", "container_image": "redis/image",
} }
parseContainerStats(stats, &acc, tags, "123456789", true, true, "linux") gatherContainerStats(stats, &acc, tags, "123456789", true, true, "linux")
// test docker_container_net measurement // test docker_container_net measurement
netfields := map[string]interface{}{ netfields := map[string]interface{}{
@@ -653,7 +653,6 @@ func TestDockerGatherInfo(t *testing.T) {
"label1": "test_value_1", "label1": "test_value_1",
"label2": "test_value_2", "label2": "test_value_2",
"server_version": "17.09.0-ce", "server_version": "17.09.0-ce",
"container_status": "running",
}, },
) )
acc.AssertContainsTaggedFields(t, acc.AssertContainsTaggedFields(t,
@@ -677,7 +676,6 @@ func TestDockerGatherInfo(t *testing.T) {
"label1": "test_value_1", "label1": "test_value_1",
"label2": "test_value_2", "label2": "test_value_2",
"server_version": "17.09.0-ce", "server_version": "17.09.0-ce",
"container_status": "running",
}, },
) )
} }

View File

@@ -484,12 +484,6 @@ var containerInspect = types.ContainerJSON{
FailingStreak: 1, FailingStreak: 1,
Status: "Unhealthy", Status: "Unhealthy",
}, },
Status: "running",
OOMKilled: false,
Pid: 1234,
ExitCode: 0,
StartedAt: "2018-06-14T05:48:53.266176036Z",
FinishedAt: "0001-01-01T00:00:00Z",
}, },
}, },
} }

View File

@@ -24,14 +24,11 @@ Those values could be true (1) or false (0) for switches, percentage for dimmers
- fibaro - fibaro
- tags: - tags:
- deviceId (device id)
- section (section name) - section (section name)
- room (room name) - room (room name)
- name (device name) - name (device name)
- type (device type) - type (device type)
- fields: - fields:
- energy (float, when available from device)
- power (float, when available from device)
- value (float) - value (float)
- value2 (float, when available from device) - value2 (float, when available from device)
@@ -39,17 +36,16 @@ Those values could be true (1) or false (0) for switches, percentage for dimmers
### Example Output: ### Example Output:
``` ```
fibaro,deviceId=9,host=vm1,name=Fenêtre\ haute,room=Cuisine,section=Cuisine,type=com.fibaro.FGRM222 energy=2.04,power=0.7,value=99,value2=99 1529996807000000000 fibaro,host=vm1,name=Escaliers,room=Dégagement,section=Pièces\ communes,type=com.fibaro.binarySwitch value=0 1523351010000000000
fibaro,deviceId=10,host=vm1,name=Escaliers,room=Dégagement,section=Pièces\ communes,type=com.fibaro.binarySwitch value=0 1529996807000000000 fibaro,host=vm1,name=Porte\ fenêtre,room=Salon,section=Pièces\ communes,type=com.fibaro.FGRM222 value=99,value2=99 1523351010000000000
fibaro,deviceId=13,host=vm1,name=Porte\ fenêtre,room=Salon,section=Pièces\ communes,type=com.fibaro.FGRM222 energy=4.33,power=0.7,value=99,value2=99 1529996807000000000 fibaro,host=vm1,name=LED\ îlot\ central,room=Cuisine,section=Cuisine,type=com.fibaro.binarySwitch value=0 1523351010000000000
fibaro,deviceId=21,host=vm1,name=LED\ îlot\ central,room=Cuisine,section=Cuisine,type=com.fibaro.binarySwitch value=0 1529996807000000000 fibaro,host=vm1,name=Détérioration,room=Entrée,section=Pièces\ communes,type=com.fibaro.heatDetector value=0 1523351010000000000
fibaro,deviceId=90,host=vm1,name=Détérioration,room=Entrée,section=Pièces\ communes,type=com.fibaro.heatDetector value=0 1529996807000000000 fibaro,host=vm1,name=Température,room=Cave,section=Cave,type=com.fibaro.temperatureSensor value=17.87 1523351010000000000
fibaro,deviceId=163,host=vm1,name=Température,room=Cave,section=Cave,type=com.fibaro.temperatureSensor value=21.62 1529996807000000000 fibaro,host=vm1,name=Présence,room=Garde-manger,section=Cuisine,type=com.fibaro.FGMS001 value=1 1523351010000000000
fibaro,deviceId=191,host=vm1,name=Présence,room=Garde-manger,section=Cuisine,type=com.fibaro.FGMS001 value=1 1529996807000000000 fibaro,host=vm1,name=Luminosité,room=Garde-manger,section=Cuisine,type=com.fibaro.lightSensor value=92 1523351010000000000
fibaro,deviceId=193,host=vm1,name=Luminosité,room=Garde-manger,section=Cuisine,type=com.fibaro.lightSensor value=195 1529996807000000000 fibaro,host=vm1,name=Etat,room=Garage,section=Extérieur,type=com.fibaro.doorSensor value=0 1523351010000000000
fibaro,deviceId=200,host=vm1,name=Etat,room=Garage,section=Extérieur,type=com.fibaro.doorSensor value=0 1529996807000000000 fibaro,host=vm1,name=CO2\ (ppm),room=Salon,section=Pièces\ communes,type=com.fibaro.multilevelSensor value=880 1523351010000000000
fibaro,deviceId=220,host=vm1,name=CO2\ (ppm),room=Salon,section=Pièces\ communes,type=com.fibaro.multilevelSensor value=536 1529996807000000000 fibaro,host=vm1,name=Humidité\ (%),room=Salon,section=Pièces\ communes,type=com.fibaro.humiditySensor value=53 1523351010000000000
fibaro,deviceId=221,host=vm1,name=Humidité\ (%),room=Salon,section=Pièces\ communes,type=com.fibaro.humiditySensor value=61 1529996807000000000 fibaro,host=vm1,name=Pression\ (mb),room=Salon,section=Pièces\ communes,type=com.fibaro.multilevelSensor value=1006.9 1523351010000000000
fibaro,deviceId=222,host=vm1,name=Pression\ (mb),room=Salon,section=Pièces\ communes,type=com.fibaro.multilevelSensor value=1013.7 1529996807000000000 fibaro,host=vm1,name=Bruit\ (db),room=Salon,section=Pièces\ communes,type=com.fibaro.multilevelSensor value=58 1523351010000000000
fibaro,deviceId=223,host=vm1,name=Bruit\ (db),room=Salon,section=Pièces\ communes,type=com.fibaro.multilevelSensor value=44 1529996807000000000
``` ```

View File

@@ -67,8 +67,6 @@ type Devices struct {
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
Properties struct { Properties struct {
Dead interface{} `json:"dead"` Dead interface{} `json:"dead"`
Energy interface{} `json:"energy"`
Power interface{} `json:"power"`
Value interface{} `json:"value"` Value interface{} `json:"value"`
Value2 interface{} `json:"value2"` Value2 interface{} `json:"value2"`
} `json:"properties"` } `json:"properties"`
@@ -164,26 +162,13 @@ func (f *Fibaro) Gather(acc telegraf.Accumulator) error {
} }
tags := map[string]string{ tags := map[string]string{
"deviceId": strconv.FormatUint(uint64(device.ID), 10), "section": sections[rooms[device.RoomID].SectionID],
"section": sections[rooms[device.RoomID].SectionID], "room": rooms[device.RoomID].Name,
"room": rooms[device.RoomID].Name, "name": device.Name,
"name": device.Name, "type": device.Type,
"type": device.Type,
} }
fields := make(map[string]interface{}) fields := make(map[string]interface{})
if device.Properties.Energy != nil {
if fValue, err := strconv.ParseFloat(device.Properties.Energy.(string), 64); err == nil {
fields["energy"] = fValue
}
}
if device.Properties.Power != nil {
if fValue, err := strconv.ParseFloat(device.Properties.Power.(string), 64); err == nil {
fields["power"] = fValue
}
}
if device.Properties.Value != nil { if device.Properties.Value != nil {
value := device.Properties.Value value := device.Properties.Value
switch value { switch value {

View File

@@ -119,8 +119,6 @@ const devicesJSON = `
"type": "com.fibaro.FGRM222", "type": "com.fibaro.FGRM222",
"enabled": true, "enabled": true,
"properties": { "properties": {
"energy": "4.33",
"power": "0.7",
"dead": "false", "dead": "false",
"value": "50", "value": "50",
"value2": "75" "value2": "75"
@@ -180,27 +178,27 @@ func TestJSONSuccess(t *testing.T) {
assert.Equal(t, uint64(5), acc.NMetrics()) assert.Equal(t, uint64(5), acc.NMetrics())
// Ensure fields / values are correct - Device 1 // Ensure fields / values are correct - Device 1
tags := map[string]string{"deviceId": "1", "section": "Section 1", "room": "Room 1", "name": "Device 1", "type": "com.fibaro.binarySwitch"} tags := map[string]string{"section": "Section 1", "room": "Room 1", "name": "Device 1", "type": "com.fibaro.binarySwitch"}
fields := map[string]interface{}{"value": float64(0)} fields := map[string]interface{}{"value": float64(0)}
acc.AssertContainsTaggedFields(t, "fibaro", fields, tags) acc.AssertContainsTaggedFields(t, "fibaro", fields, tags)
// Ensure fields / values are correct - Device 2 // Ensure fields / values are correct - Device 2
tags = map[string]string{"deviceId": "2", "section": "Section 2", "room": "Room 2", "name": "Device 2", "type": "com.fibaro.binarySwitch"} tags = map[string]string{"section": "Section 2", "room": "Room 2", "name": "Device 2", "type": "com.fibaro.binarySwitch"}
fields = map[string]interface{}{"value": float64(1)} fields = map[string]interface{}{"value": float64(1)}
acc.AssertContainsTaggedFields(t, "fibaro", fields, tags) acc.AssertContainsTaggedFields(t, "fibaro", fields, tags)
// Ensure fields / values are correct - Device 3 // Ensure fields / values are correct - Device 3
tags = map[string]string{"deviceId": "3", "section": "Section 3", "room": "Room 3", "name": "Device 3", "type": "com.fibaro.multilevelSwitch"} tags = map[string]string{"section": "Section 3", "room": "Room 3", "name": "Device 3", "type": "com.fibaro.multilevelSwitch"}
fields = map[string]interface{}{"value": float64(67)} fields = map[string]interface{}{"value": float64(67)}
acc.AssertContainsTaggedFields(t, "fibaro", fields, tags) acc.AssertContainsTaggedFields(t, "fibaro", fields, tags)
// Ensure fields / values are correct - Device 4 // Ensure fields / values are correct - Device 4
tags = map[string]string{"deviceId": "4", "section": "Section 3", "room": "Room 4", "name": "Device 4", "type": "com.fibaro.temperatureSensor"} tags = map[string]string{"section": "Section 3", "room": "Room 4", "name": "Device 4", "type": "com.fibaro.temperatureSensor"}
fields = map[string]interface{}{"value": float64(22.8)} fields = map[string]interface{}{"value": float64(22.8)}
acc.AssertContainsTaggedFields(t, "fibaro", fields, tags) acc.AssertContainsTaggedFields(t, "fibaro", fields, tags)
// Ensure fields / values are correct - Device 5 // Ensure fields / values are correct - Device 5
tags = map[string]string{"deviceId": "5", "section": "Section 3", "room": "Room 4", "name": "Device 5", "type": "com.fibaro.FGRM222"} tags = map[string]string{"section": "Section 3", "room": "Room 4", "name": "Device 5", "type": "com.fibaro.FGRM222"}
fields = map[string]interface{}{"energy": float64(4.33), "power": float64(0.7), "value": float64(50), "value2": float64(75)} fields = map[string]interface{}{"value": float64(50), "value2": float64(75)}
acc.AssertContainsTaggedFields(t, "fibaro", fields, tags) acc.AssertContainsTaggedFields(t, "fibaro", fields, tags)
} }

View File

@@ -343,9 +343,6 @@ func (h *HTTPListener) serveWrite(res http.ResponseWriter, req *http.Request) {
} }
func (h *HTTPListener) parse(b []byte, t time.Time, precision string) error { func (h *HTTPListener) parse(b []byte, t time.Time, precision string) error {
h.mu.Lock()
defer h.mu.Unlock()
h.handler.SetTimePrecision(getPrecisionMultiplier(precision)) h.handler.SetTimePrecision(getPrecisionMultiplier(precision))
h.handler.SetTimeFunc(func() time.Time { return t }) h.handler.SetTimeFunc(func() time.Time { return t })
metrics, err := h.parser.Parse(b) metrics, err := h.parser.Parse(b)

View File

@@ -5,7 +5,6 @@ import (
"os/exec" "os/exec"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
@@ -62,18 +61,13 @@ func (m *Ipmi) Gather(acc telegraf.Accumulator) error {
} }
if len(m.Servers) > 0 { if len(m.Servers) > 0 {
wg := sync.WaitGroup{}
for _, server := range m.Servers { for _, server := range m.Servers {
wg.Add(1) err := m.parse(acc, server)
go func(a telegraf.Accumulator, s string) { if err != nil {
defer wg.Done() acc.AddError(err)
err := m.parse(a, s) continue
if err != nil { }
a.AddError(err)
}
}(acc, server)
} }
wg.Wait()
} else { } else {
err := m.parse(acc, "") err := m.parse(acc, "")
if err != nil { if err != nil {

View File

@@ -172,14 +172,8 @@ Both `jolokia2_agent` and `jolokia2_proxy` plugins support default configuration
### Example Configurations: ### Example Configurations:
- [ActiveMQ](/plugins/inputs/jolokia2/examples/activemq.conf)
- [BitBucket](/plugins/inputs/jolokia2/examples/bitbucket.conf)
- [Cassandra](/plugins/inputs/jolokia2/examples/cassandra.conf)
- [Hadoop-HDFS](/plugins/inputs/jolokia2/examples/hadoop-hdfs.conf)
- [Java JVM](/plugins/inputs/jolokia2/examples/java.conf) - [Java JVM](/plugins/inputs/jolokia2/examples/java.conf)
- [JBoss](/plugins/inputs/jolokia2/examples/jboss.conf)
- [Kafka](/plugins/inputs/jolokia2/examples/kafka.conf) - [Kafka](/plugins/inputs/jolokia2/examples/kafka.conf)
- [Tomcat](/plugins/inputs/jolokia2/examples/tomcat.conf) - [Cassandra](/plugins/inputs/jolokia2/examples/cassandra.conf)
- [Weblogic](/plugins/inputs/jolokia2/examples/weblogic.conf)
Please help improve this list and contribute new configuration files by opening an issue or pull request. Please help improve this list and contribute new configuration files by opening an issue or pull request.

View File

@@ -1,57 +0,0 @@
## Jolokia is bundled with ActiveMQ
[[inputs.jolokia2_agent]]
urls = ["http://localhost:8161/api/jolokia"]
name_prefix = "activemq."
username = "admin"
password = "admin"
### JVM Generic
[[inputs.jolokia2_agent.metric]]
name = "OperatingSystem"
mbean = "java.lang:type=OperatingSystem"
paths = ["ProcessCpuLoad","SystemLoadAverage","SystemCpuLoad"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_runtime"
mbean = "java.lang:type=Runtime"
paths = ["Uptime"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory"
mbean = "java.lang:type=Memory"
paths = ["HeapMemoryUsage", "NonHeapMemoryUsage", "ObjectPendingFinalizationCount"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_garbage_collector"
mbean = "java.lang:name=*,type=GarbageCollector"
paths = ["CollectionTime", "CollectionCount"]
tag_keys = ["name"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory_pool"
mbean = "java.lang:name=*,type=MemoryPool"
paths = ["Usage", "PeakUsage", "CollectionUsage"]
tag_keys = ["name"]
tag_prefix = "pool_"
### ACTIVEMQ
[[inputs.jolokia2_agent.metric]]
name = "queue"
mbean = "org.apache.activemq:brokerName=*,destinationName=*,destinationType=Queue,type=Broker"
paths = ["QueueSize","EnqueueCount","ConsumerCount","DispatchCount","DequeueCount","ProducerCount","InFlightCount"]
tag_keys = ["brokerName","destinationName"]
[[inputs.jolokia2_agent.metric]]
name = "topic"
mbean = "org.apache.activemq:brokerName=*,destinationName=*,destinationType=Topic,type=Broker"
paths = ["ProducerCount","DequeueCount","ConsumerCount","QueueSize","EnqueueCount"]
tag_keys = ["brokerName","destinationName"]
[[inputs.jolokia2_agent.metric]]
name = "broker"
mbean = "org.apache.activemq:brokerName=*,type=Broker"
paths = ["TotalConsumerCount","TotalMessageCount","TotalEnqueueCount","TotalDequeueCount","MemoryLimit","MemoryPercentUsage","StoreLimit","StorePercentUsage","TempPercentUsage","TempLimit"]
tag_keys = ["brokerName"]

View File

@@ -1,39 +0,0 @@
[[inputs.jolokia2_agent]]
urls = ["http://localhost:8778/jolokia"]
name_prefix = "bitbucket."
[[inputs.jolokia2_agent.metric]]
name = "jvm_operatingsystem"
mbean = "java.lang:type=OperatingSystem"
[[inputs.jolokia2_agent.metric]]
name = "jvm_runtime"
mbean = "java.lang:type=Runtime"
[[inputs.jolokia2_agent.metric]]
name = "jvm_thread"
mbean = "java.lang:type=Threading"
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory"
mbean = "java.lang:type=Memory"
[[inputs.jolokia2_agent.metric]]
name = "jvm_class_loading"
mbean = "java.lang:type=ClassLoading"
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory_pool"
mbean = "java.lang:type=MemoryPool,name=*"
[[inputs.jolokia2_agent.metric]]
name = "webhooks"
mbean = "com.atlassian.webhooks:name=*"
[[inputs.jolokia2_agent.metric]]
name = "atlassian"
mbean = "com.atlassian.bitbucket:name=*"
[[inputs.jolokia2_agent.metric]]
name = "thread_pools"
mbean = "com.atlassian.bitbucket.thread-pools:name=*"

View File

@@ -1,85 +0,0 @@
################
# NAMENODE #
################
[[inputs.jolokia2_agent]]
urls = ["http://localhost:8778/jolokia"]
name_prefix = "hadoop.hdfs.namenode."
[[inputs.jolokia2_agent.metric]]
name = "FSNamesystem"
mbean = "Hadoop:name=FSNamesystem,service=NameNode"
paths = ["CapacityTotal", "CapacityRemaining", "CapacityUsedNonDFS", "NumLiveDataNodes", "NumDeadDataNodes", "NumInMaintenanceDeadDataNodes", "NumDecomDeadDataNodes"]
[[inputs.jolokia2_agent.metric]]
name = "FSNamesystemState"
mbean = "Hadoop:name=FSNamesystemState,service=NameNode"
paths = ["VolumeFailuresTotal", "UnderReplicatedBlocks", "BlocksTotal"]
[[inputs.jolokia2_agent.metric]]
name = "OperatingSystem"
mbean = "java.lang:type=OperatingSystem"
paths = ["ProcessCpuLoad", "SystemLoadAverage", "SystemCpuLoad"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_runtime"
mbean = "java.lang:type=Runtime"
paths = ["Uptime"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory"
mbean = "java.lang:type=Memory"
paths = ["HeapMemoryUsage", "NonHeapMemoryUsage", "ObjectPendingFinalizationCount"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_garbage_collector"
mbean = "java.lang:name=*,type=GarbageCollector"
paths = ["CollectionTime", "CollectionCount"]
tag_keys = ["name"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory_pool"
mbean = "java.lang:name=*,type=MemoryPool"
paths = ["Usage", "PeakUsage", "CollectionUsage"]
tag_keys = ["name"]
tag_prefix = "pool_"
################
# DATANODE #
################
[[inputs.jolokia2_agent]]
urls = ["http://localhost:7778/jolokia"]
name_prefix = "hadoop.hdfs.datanode."
[[inputs.jolokia2_agent.metric]]
name = "FSDatasetState"
mbean = "Hadoop:name=FSDatasetState,service=DataNode"
paths = ["Capacity", "DfsUsed", "Remaining", "NumBlocksFailedToUnCache", "NumBlocksFailedToCache", "NumBlocksCached"]
[[inputs.jolokia2_agent.metric]]
name = "OperatingSystem"
mbean = "java.lang:type=OperatingSystem"
paths = ["ProcessCpuLoad", "SystemLoadAverage", "SystemCpuLoad"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_runtime"
mbean = "java.lang:type=Runtime"
paths = ["Uptime"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory"
mbean = "java.lang:type=Memory"
paths = ["HeapMemoryUsage", "NonHeapMemoryUsage", "ObjectPendingFinalizationCount"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_garbage_collector"
mbean = "java.lang:name=*,type=GarbageCollector"
paths = ["CollectionTime", "CollectionCount"]
tag_keys = ["name"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory_pool"
mbean = "java.lang:name=*,type=MemoryPool"
paths = ["Usage", "PeakUsage", "CollectionUsage"]
tag_keys = ["name"]
tag_prefix = "pool_"

View File

@@ -1,59 +0,0 @@
[[inputs.jolokia2_agent]]
urls = ["http://localhost:8080/jolokia"]
name_prefix = "jboss."
### JVM Generic
[[inputs.jolokia2_agent.metric]]
name = "OperatingSystem"
mbean = "java.lang:type=OperatingSystem"
paths = ["ProcessCpuLoad","SystemLoadAverage","SystemCpuLoad"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_runtime"
mbean = "java.lang:type=Runtime"
paths = ["Uptime"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory"
mbean = "java.lang:type=Memory"
paths = ["HeapMemoryUsage", "NonHeapMemoryUsage", "ObjectPendingFinalizationCount"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_garbage_collector"
mbean = "java.lang:name=*,type=GarbageCollector"
paths = ["CollectionTime", "CollectionCount"]
tag_keys = ["name"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory_pool"
mbean = "java.lang:name=*,type=MemoryPool"
paths = ["Usage", "PeakUsage", "CollectionUsage"]
tag_keys = ["name"]
tag_prefix = "pool_"
### JBOSS
[[inputs.jolokia2_agent.metric]]
name = "connectors.http"
mbean = "jboss.as:https-listener=*,server=*,subsystem=undertow"
paths = ["bytesReceived","bytesSent","errorCount","requestCount"]
tag_keys = ["server","https-listener"]
[[inputs.jolokia2_agent.metric]]
name = "connectors.http"
mbean = "jboss.as:http-listener=*,server=*,subsystem=undertow"
paths = ["bytesReceived","bytesSent","errorCount","requestCount"]
tag_keys = ["server","http-listener"]
[[inputs.jolokia2_agent.metric]]
name = "datasource.jdbc"
mbean = "jboss.as:data-source=*,statistics=jdbc,subsystem=datasources"
paths = ["PreparedStatementCacheAccessCount","PreparedStatementCacheHitCount","PreparedStatementCacheMissCount"]
tag_keys = ["data-source"]
[[inputs.jolokia2_agent.metric]]
name = "datasource.pool"
mbean = "jboss.as:data-source=*,statistics=pool,subsystem=datasources"
paths = ["AvailableCount","ActiveCount","MaxUsedCount"]
tag_keys = ["data-source"]

View File

@@ -1,65 +0,0 @@
[[inputs.jolokia2_agent]]
urls = ["http://localhost:8080/jolokia"]
name_prefix = "tomcat."
### JVM Generic
[[inputs.jolokia2_agent.metric]]
name = "OperatingSystem"
mbean = "java.lang:type=OperatingSystem"
paths = ["ProcessCpuLoad","SystemLoadAverage","SystemCpuLoad"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_runtime"
mbean = "java.lang:type=Runtime"
paths = ["Uptime"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory"
mbean = "java.lang:type=Memory"
paths = ["HeapMemoryUsage", "NonHeapMemoryUsage", "ObjectPendingFinalizationCount"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_garbage_collector"
mbean = "java.lang:name=*,type=GarbageCollector"
paths = ["CollectionTime", "CollectionCount"]
tag_keys = ["name"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory_pool"
mbean = "java.lang:name=*,type=MemoryPool"
paths = ["Usage", "PeakUsage", "CollectionUsage"]
tag_keys = ["name"]
tag_prefix = "pool_"
### TOMCAT
[[inputs.jolokia2_agent.metric]]
name = "GlobalRequestProcessor"
mbean = "Catalina:name=*,type=GlobalRequestProcessor"
paths = ["requestCount","bytesReceived","bytesSent","processingTime","errorCount"]
tag_keys = ["name"]
[[inputs.jolokia2_agent.metric]]
name = "JspMonitor"
mbean = "Catalina:J2EEApplication=*,J2EEServer=*,WebModule=*,name=jsp,type=JspMonitor"
paths = ["jspReloadCount","jspCount","jspUnloadCount"]
tag_keys = ["J2EEApplication","J2EEServer","WebModule"]
[[inputs.jolokia2_agent.metric]]
name = "ThreadPool"
mbean = "Catalina:name=*,type=ThreadPool"
paths = ["maxThreads","currentThreadCount","currentThreadsBusy"]
tag_keys = ["name"]
[[inputs.jolokia2_agent.metric]]
name = "Servlet"
mbean = "Catalina:J2EEApplication=*,J2EEServer=*,WebModule=*,j2eeType=Servlet,name=*"
paths = ["processingTime","errorCount","requestCount"]
tag_keys = ["name","J2EEApplication","J2EEServer","WebModule"]
[[inputs.jolokia2_agent.metric]]
name = "Cache"
mbean = "Catalina:context=*,host=*,name=Cache,type=WebResourceRoot"
paths = ["hitCount","lookupCount"]
tag_keys = ["context","host"]

View File

@@ -1,56 +0,0 @@
[[inputs.jolokia2_agent]]
urls = ["http://localhost:8080/jolokia"]
name_prefix = "weblogic."
### JVM Generic
[[inputs.jolokia2_agent.metric]]
name = "OperatingSystem"
mbean = "java.lang:type=OperatingSystem"
paths = ["ProcessCpuLoad","SystemLoadAverage","SystemCpuLoad"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_runtime"
mbean = "java.lang:type=Runtime"
paths = ["Uptime"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory"
mbean = "java.lang:type=Memory"
paths = ["HeapMemoryUsage", "NonHeapMemoryUsage", "ObjectPendingFinalizationCount"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_garbage_collector"
mbean = "java.lang:name=*,type=GarbageCollector"
paths = ["CollectionTime", "CollectionCount"]
tag_keys = ["name"]
[[inputs.jolokia2_agent.metric]]
name = "jvm_memory_pool"
mbean = "java.lang:name=*,type=MemoryPool"
paths = ["Usage", "PeakUsage", "CollectionUsage"]
tag_keys = ["name"]
tag_prefix = "pool_"
### WLS
[[inputs.jolokia2_agent.metric]]
name = "JTARuntime"
mbean = "com.bea:Name=JTARuntime,ServerRuntime=*,Type=JTARuntime"
paths = ["SecondsActiveTotalCount","TransactionRolledBackTotalCount","TransactionRolledBackSystemTotalCount","TransactionRolledBackAppTotalCount","TransactionRolledBackResourceTotalCount","TransactionHeuristicsTotalCount","TransactionAbandonedTotalCount","TransactionTotalCount","TransactionRolledBackTimeoutTotalCount","ActiveTransactionsTotalCount","TransactionCommittedTotalCount"]
tag_keys = ["ServerRuntime"]
tag_prefix = "wls_"
[[inputs.jolokia2_agent.metric]]
name = "ThreadPoolRuntime"
mbean = "com.bea:Name=ThreadPoolRuntime,ServerRuntime=*,Type=ThreadPoolRuntime"
paths = ["StuckThreadCount","CompletedRequestCount","ExecuteThreadTotalCount","ExecuteThreadIdleCount","StandbyThreadCount","Throughput","HoggingThreadCount","PendingUserRequestCount"]
tag_keys = ["ServerRuntime"]
tag_prefix = "wls_"
[[inputs.jolokia2_agent.metric]]
name = "JMSRuntime"
mbean = "com.bea:Name=*.jms,ServerRuntime=*,Type=JMSRuntime"
paths = ["ConnectionsCurrentCount","ConnectionsHighCount","ConnectionsTotalCount","JMSServersCurrentCount","JMSServersHighCount","JMSServersTotalCount"]
tag_keys = ["name","ServerRuntime"]
tag_prefix = "wls_"

View File

@@ -108,9 +108,7 @@ You must capture at least one field per line.
- ts-"CUSTOM" - ts-"CUSTOM"
CUSTOM time layouts must be within quotes and be the representation of the CUSTOM time layouts must be within quotes and be the representation of the
"reference time", which is `Mon Jan 2 15:04:05 -0700 MST 2006`. "reference time", which is `Mon Jan 2 15:04:05 -0700 MST 2006`
To match a comma decimal point you can use a period. For example `%{TIMESTAMP:timestamp:ts-"2006-01-02 15:04:05.000"}` can be used to match `"2018-01-02 15:04:05,000"`
To match a comma decimal point you can use a period in the pattern string.
See https://golang.org/pkg/time/#Parse for more details. See https://golang.org/pkg/time/#Parse for more details.
Telegraf has many of its own [built-in patterns](./grok/patterns/influx-patterns), Telegraf has many of its own [built-in patterns](./grok/patterns/influx-patterns),

View File

@@ -1,13 +0,0 @@
version: '3'
services:
telegraf:
image: glinton/scratch
volumes:
- ./telegraf.conf:/telegraf.conf
- ../../../../telegraf:/telegraf
- ./test.log:/var/log/test.log
entrypoint:
- /telegraf
- --config
- /telegraf.conf

View File

@@ -1,12 +0,0 @@
[agent]
interval="1s"
flush_interval="1s"
[[inputs.logparser]]
files = ["/var/log/test.log"]
from_beginning = true
[inputs.logparser.grok]
patterns = [ "%{COMBINED_LOG_FORMAT}", "%{CLIENT:client_ip} %{NOTSPACE:ident} %{NOTSPACE:auth} \\[%{TIMESTAMP_ISO8601:timestamp}\\] \"(?:%{WORD:verb:tag} %{NOTSPACE:request}(?: HTTP/%{NUMBER:http_version:float})?|%{DATA})\" %{NUMBER:resp_code:tag} (?:%{NUMBER:resp_bytes:int}|-) %{QS:referrer} %{QS:agent}"]
[[outputs.file]]
files = ["stdout"]

View File

@@ -1,2 +0,0 @@
127.0.0.1 ident auth [10/Oct/2000:13:55:36 -0700] "GET /anything HTTP/1.0" 200 2326 "http://localhost:8083/" "Chrome/51.0.2704.84"
127.0.0.1 ident auth [2018-02-21 13:10:34,555] "GET /peter HTTP/1.0" 200 2326 "http://localhost:8083/" "Chrome/51.0.2704.84"

View File

@@ -293,7 +293,7 @@ func (p *Parser) ParseLine(line string) (telegraf.Metric, error) {
timestamp = time.Unix(0, iv) timestamp = time.Unix(0, iv)
} }
case SYSLOG_TIMESTAMP: case SYSLOG_TIMESTAMP:
ts, err := time.ParseInLocation(time.Stamp, v, p.loc) ts, err := time.ParseInLocation("Jan 02 15:04:05", v, p.loc)
if err == nil { if err == nil {
if ts.Year() == 0 { if ts.Year() == 0 {
ts = ts.AddDate(timestamp.Year(), 0, 0) ts = ts.AddDate(timestamp.Year(), 0, 0)
@@ -335,9 +335,6 @@ func (p *Parser) ParseLine(line string) (telegraf.Metric, error) {
case DROP: case DROP:
// goodbye! // goodbye!
default: default:
// Replace commas with dot character
v = strings.Replace(v, ",", ".", -1)
ts, err := time.ParseInLocation(t, v, p.loc) ts, err := time.ParseInLocation(t, v, p.loc)
if err == nil { if err == nil {
timestamp = ts timestamp = ts

View File

@@ -971,57 +971,14 @@ func TestNewlineInPatterns(t *testing.T) {
require.NotNil(t, m) require.NotNil(t, m)
} }
func TestSyslogTimestamp(t *testing.T) { func TestSyslogTimestampParser(t *testing.T) {
tests := []struct {
name string
line string
expected time.Time
}{
{
name: "two digit day of month",
line: "Sep 25 09:01:55 value=42",
expected: time.Date(2018, time.September, 25, 9, 1, 55, 0, time.UTC),
},
{
name: "one digit day of month single space",
line: "Sep 2 09:01:55 value=42",
expected: time.Date(2018, time.September, 2, 9, 1, 55, 0, time.UTC),
},
{
name: "one digit day of month double space",
line: "Sep 2 09:01:55 value=42",
expected: time.Date(2018, time.September, 2, 9, 1, 55, 0, time.UTC),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Parser{
Patterns: []string{`%{SYSLOGTIMESTAMP:timestamp:ts-syslog} value=%{NUMBER:value:int}`},
timeFunc: func() time.Time { return time.Date(2017, time.April, 1, 0, 0, 0, 0, time.UTC) },
}
require.NoError(t, p.Compile())
m, err := p.ParseLine(tt.line)
require.NoError(t, err)
require.NotNil(t, m)
require.Equal(t, tt.expected, m.Time())
})
}
}
func TestReplaceTimestampComma(t *testing.T) {
p := &Parser{ p := &Parser{
Patterns: []string{`%{TIMESTAMP_ISO8601:timestamp:ts-"2006-01-02 15:04:05.000"} successfulMatches=%{NUMBER:value:int}`}, Patterns: []string{`%{SYSLOGTIMESTAMP:timestamp:ts-syslog} value=%{NUMBER:value:int}`},
timeFunc: func() time.Time { return time.Date(2018, time.April, 1, 0, 0, 0, 0, nil) },
} }
require.NoError(t, p.Compile()) require.NoError(t, p.Compile())
m, err := p.ParseLine("2018-02-21 13:10:34,555 successfulMatches=1") m, err := p.ParseLine("Sep 25 09:01:55 value=42")
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, m) require.NotNil(t, m)
require.Equal(t, 2018, m.Time().Year()) require.Equal(t, 2018, m.Time().Year())
require.Equal(t, 13, m.Time().Hour())
require.Equal(t, 34, m.Time().Second())
//Convert Nanosecond to milisecond for compare
require.Equal(t, 555, m.Time().Nanosecond()/1000000)
} }

View File

@@ -203,10 +203,6 @@ func (l *LogParserPlugin) tailNewfiles(fromBeginning bool) error {
Poll: poll, Poll: poll,
Logger: tail.DiscardingLogger, Logger: tail.DiscardingLogger,
}) })
//add message saying a new tailer was added for the file
log.Printf("D! tail added for file: %v", file)
if err != nil { if err != nil {
l.acc.AddError(err) l.acc.AddError(err)
continue continue
@@ -291,10 +287,6 @@ func (l *LogParserPlugin) Stop() {
for _, t := range l.tailers { for _, t := range l.tailers {
err := t.Stop() err := t.Stop()
//message for a stopped tailer
log.Printf("D! tail dropped for file: %v", t.Filename)
if err != nil { if err != nil {
log.Printf("E! Error stopping tail on file %s\n", t.Filename) log.Printf("E! Error stopping tail on file %s\n", t.Filename)
} }

View File

@@ -1,16 +0,0 @@
version: '3'
services:
mongodb:
image: mongo
telegraf:
image: glinton/scratch
volumes:
- ./telegraf.conf:/telegraf.conf
- ../../../../telegraf:/telegraf
depends_on:
- mongodb
entrypoint:
- /telegraf
- --config
- /telegraf.conf

View File

@@ -1,9 +0,0 @@
[agent]
interval="1s"
flush_interval="3s"
[[inputs.mongodb]]
servers = ["mongodb://mongodb:27017"]
[[outputs.file]]
files = ["stdout"]

View File

@@ -31,35 +31,28 @@ func NewMongodbData(statLine *StatLine, tags map[string]string) *MongodbData {
} }
var DefaultStats = map[string]string{ var DefaultStats = map[string]string{
"inserts_per_sec": "Insert", "inserts_per_sec": "Insert",
"queries_per_sec": "Query", "queries_per_sec": "Query",
"updates_per_sec": "Update", "updates_per_sec": "Update",
"deletes_per_sec": "Delete", "deletes_per_sec": "Delete",
"getmores_per_sec": "GetMore", "getmores_per_sec": "GetMore",
"commands_per_sec": "Command", "commands_per_sec": "Command",
"flushes_per_sec": "Flushes", "flushes_per_sec": "Flushes",
"vsize_megabytes": "Virtual", "vsize_megabytes": "Virtual",
"resident_megabytes": "Resident", "resident_megabytes": "Resident",
"queued_reads": "QueuedReaders", "queued_reads": "QueuedReaders",
"queued_writes": "QueuedWriters", "queued_writes": "QueuedWriters",
"active_reads": "ActiveReaders", "active_reads": "ActiveReaders",
"active_writes": "ActiveWriters", "active_writes": "ActiveWriters",
"net_in_bytes": "NetIn", "net_in_bytes": "NetIn",
"net_out_bytes": "NetOut", "net_out_bytes": "NetOut",
"open_connections": "NumConnections", "open_connections": "NumConnections",
"ttl_deletes_per_sec": "DeletedDocuments", "ttl_deletes_per_sec": "DeletedDocuments",
"ttl_passes_per_sec": "Passes", "ttl_passes_per_sec": "Passes",
"cursor_timed_out": "TimedOutC", "cursor_timed_out": "TimedOutC",
"cursor_no_timeout": "NoTimeoutC", "cursor_no_timeout": "NoTimeoutC",
"cursor_pinned": "PinnedC", "cursor_pinned": "PinnedC",
"cursor_total": "TotalC", "cursor_total": "TotalC",
"document_deleted": "DeletedD",
"document_inserted": "InsertedD",
"document_returned": "ReturnedD",
"document_updated": "UpdatedD",
"connections_current": "CurrentC",
"connections_available": "AvailableC",
"connections_total_created": "TotalCreatedC",
} }
var DefaultReplStats = map[string]string{ var DefaultReplStats = map[string]string{

View File

@@ -38,13 +38,6 @@ func TestAddNonReplStats(t *testing.T) {
NoTimeoutC: 0, NoTimeoutC: 0,
PinnedC: 0, PinnedC: 0,
TotalC: 0, TotalC: 0,
DeletedD: 0,
InsertedD: 0,
ReturnedD: 0,
UpdatedD: 0,
CurrentC: 0,
AvailableC: 0,
TotalCreatedC: 0,
}, },
tags, tags,
) )
@@ -189,50 +182,43 @@ func TestStateTag(t *testing.T) {
d.AddDefaultStats() d.AddDefaultStats()
d.flush(&acc) d.flush(&acc)
fields := map[string]interface{}{ fields := map[string]interface{}{
"active_reads": int64(0), "active_reads": int64(0),
"active_writes": int64(0), "active_writes": int64(0),
"commands_per_sec": int64(0), "commands_per_sec": int64(0),
"deletes_per_sec": int64(0), "deletes_per_sec": int64(0),
"flushes_per_sec": int64(0), "flushes_per_sec": int64(0),
"getmores_per_sec": int64(0), "getmores_per_sec": int64(0),
"inserts_per_sec": int64(0), "inserts_per_sec": int64(0),
"member_status": "PRI", "member_status": "PRI",
"state": "PRIMARY", "state": "PRIMARY",
"net_in_bytes": int64(0), "net_in_bytes": int64(0),
"net_out_bytes": int64(0), "net_out_bytes": int64(0),
"open_connections": int64(0), "open_connections": int64(0),
"queries_per_sec": int64(0), "queries_per_sec": int64(0),
"queued_reads": int64(0), "queued_reads": int64(0),
"queued_writes": int64(0), "queued_writes": int64(0),
"repl_commands_per_sec": int64(0), "repl_commands_per_sec": int64(0),
"repl_deletes_per_sec": int64(0), "repl_deletes_per_sec": int64(0),
"repl_getmores_per_sec": int64(0), "repl_getmores_per_sec": int64(0),
"repl_inserts_per_sec": int64(0), "repl_inserts_per_sec": int64(0),
"repl_queries_per_sec": int64(0), "repl_queries_per_sec": int64(0),
"repl_updates_per_sec": int64(0), "repl_updates_per_sec": int64(0),
"repl_lag": int64(0), "repl_lag": int64(0),
"repl_oplog_window_sec": int64(0), "repl_oplog_window_sec": int64(0),
"resident_megabytes": int64(0), "resident_megabytes": int64(0),
"updates_per_sec": int64(0), "updates_per_sec": int64(0),
"vsize_megabytes": int64(0), "vsize_megabytes": int64(0),
"ttl_deletes_per_sec": int64(0), "ttl_deletes_per_sec": int64(0),
"ttl_passes_per_sec": int64(0), "ttl_passes_per_sec": int64(0),
"jumbo_chunks": int64(0), "jumbo_chunks": int64(0),
"total_in_use": int64(0), "total_in_use": int64(0),
"total_available": int64(0), "total_available": int64(0),
"total_created": int64(0), "total_created": int64(0),
"total_refreshing": int64(0), "total_refreshing": int64(0),
"cursor_timed_out": int64(0), "cursor_timed_out": int64(0),
"cursor_no_timeout": int64(0), "cursor_no_timeout": int64(0),
"cursor_pinned": int64(0), "cursor_pinned": int64(0),
"cursor_total": int64(0), "cursor_total": int64(0),
"document_deleted": int64(0),
"document_inserted": int64(0),
"document_returned": int64(0),
"document_updated": int64(0),
"connections_current": int64(0),
"connections_available": int64(0),
"connections_total_created": int64(0),
} }
acc.AssertContainsTaggedFields(t, "mongodb", fields, stateTags) acc.AssertContainsTaggedFields(t, "mongodb", fields, stateTags)
} }

View File

@@ -225,7 +225,7 @@ type FlushStats struct {
type ConnectionStats struct { type ConnectionStats struct {
Current int64 `bson:"current"` Current int64 `bson:"current"`
Available int64 `bson:"available"` Available int64 `bson:"available"`
TotalCreated int64 `bson:"total_created"` TotalCreated int64 `bson:"totalCreated"`
} }
// DurTiming stores information related to journaling. // DurTiming stores information related to journaling.
@@ -289,9 +289,8 @@ type OpcountStats struct {
// MetricsStats stores information related to metrics // MetricsStats stores information related to metrics
type MetricsStats struct { type MetricsStats struct {
TTL *TTLStats `bson:"ttl"` TTL *TTLStats `bson:"ttl"`
Cursor *CursorStats `bson:"cursor"` Cursor *CursorStats `bson:"cursor"`
Document *DocumentStats `bson:"document"`
} }
// TTLStats stores information related to documents with a ttl index. // TTLStats stores information related to documents with a ttl index.
@@ -306,14 +305,6 @@ type CursorStats struct {
Open *OpenCursorStats `bson:"open"` Open *OpenCursorStats `bson:"open"`
} }
// DocumentStats stores information related to document metrics.
type DocumentStats struct {
Deleted int64 `bson:"deleted"`
Inserted int64 `bson:"inserted"`
Returned int64 `bson:"returned"`
Updated int64 `bson:"updated"`
}
// OpenCursorStats stores information related to open cursor metrics // OpenCursorStats stores information related to open cursor metrics
type OpenCursorStats struct { type OpenCursorStats struct {
NoTimeout int64 `bson:"noTimeout"` NoTimeout int64 `bson:"noTimeout"`
@@ -466,12 +457,6 @@ type StatLine struct {
TimedOutC int64 TimedOutC int64
NoTimeoutC, PinnedC, TotalC int64 NoTimeoutC, PinnedC, TotalC int64
// Document fields
DeletedD, InsertedD, ReturnedD, UpdatedD int64
// Connection fields
CurrentC, AvailableC, TotalCreatedC int64
// Collection locks (3.0 mmap only) // Collection locks (3.0 mmap only)
CollectionLocks *CollectionLockStatus CollectionLocks *CollectionLockStatus

View File

@@ -1,42 +0,0 @@
version: '3'
services:
mysql:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: telegraf
MYSQL_DATABASE: telegraf
MYSQL_USER: telegraf
MYSQL_PASSWORD: telegraf
maria:
image: mariadb
restart: always
environment:
MYSQL_ROOT_PASSWORD: telegraf
MYSQL_DATABASE: telegraf
MYSQL_USER: telegraf
MYSQL_PASSWORD: telegraf
command: mysqld --userstat=1
percona:
image: percona
restart: always
environment:
MYSQL_ROOT_PASSWORD: telegraf
MYSQL_DATABASE: telegraf
MYSQL_USER: telegraf
MYSQL_PASSWORD: telegraf
telegraf:
image: glinton/scratch
depends_on:
- mysql
- maria
- percona
volumes:
- ./telegraf.conf:/telegraf.conf
- ../../../../telegraf:/telegraf
entrypoint:
- /telegraf
- --config
- /telegraf.conf

View File

@@ -1,61 +0,0 @@
# Uncomment each input as needed to test plugin
## mysql
#[[inputs.mysql]]
# servers = ["root:telegraf@tcp(mysql:3306)/"]
# gather_table_schema = true
# gather_process_list = true
# gather_user_statistics = true
# gather_info_schema_auto_inc = true
# gather_innodb_metrics = true
# gather_slave_status = true
# gather_binary_logs = false
# gather_table_io_waits = true
# gather_table_lock_waits = true
# gather_index_io_waits = true
# gather_event_waits = true
# gather_file_events_stats = true
# gather_perf_events_statements = true
# interval_slow = "30m"
# table_schema_databases = []
#
## mariadb
#[[inputs.mysql]]
# servers = ["root:telegraf@tcp(maria:3306)/"]
# gather_table_schema = true
# gather_process_list = true
# gather_user_statistics = true
# gather_info_schema_auto_inc = true
# gather_innodb_metrics = true
# gather_slave_status = true
# gather_binary_logs = false
# gather_table_io_waits = true
# gather_table_lock_waits = true
# gather_index_io_waits = true
# gather_event_waits = true
# gather_file_events_stats = true
# gather_perf_events_statements = true
# interval_slow = "30m"
# table_schema_databases = []
# percona
[[inputs.mysql]]
servers = ["root:telegraf@tcp(percona:3306)/"]
gather_table_schema = true
gather_process_list = true
gather_user_statistics = true
gather_info_schema_auto_inc = true
gather_innodb_metrics = true
gather_slave_status = true
gather_binary_logs = false
gather_table_io_waits = true
gather_table_lock_waits = true
gather_index_io_waits = true
gather_event_waits = true
gather_file_events_stats = true
gather_perf_events_statements = true
interval_slow = "30m"
table_schema_databases = []
[[outputs.file]]
files = ["stdout"]

View File

@@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"database/sql" "database/sql"
"fmt" "fmt"
"log"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@@ -79,7 +80,7 @@ var sampleConfig = `
## gather thread state counts from INFORMATION_SCHEMA.PROCESSLIST ## gather thread state counts from INFORMATION_SCHEMA.PROCESSLIST
gather_process_list = true gather_process_list = true
# #
## gather user statistics from INFORMATION_SCHEMA.USER_STATISTICS ## gather thread state counts from INFORMATION_SCHEMA.USER_STATISTICS
gather_user_statistics = true gather_user_statistics = true
# #
## gather auto_increment columns and max values from information schema ## gather auto_increment columns and max values from information schema
@@ -281,8 +282,9 @@ const (
GROUP BY command,state GROUP BY command,state
ORDER BY null` ORDER BY null`
infoSchemaUserStatisticsQuery = ` infoSchemaUserStatisticsQuery = `
SELECT * SELECT *,count(*)
FROM information_schema.user_statistics` FROM information_schema.user_statistics
GROUP BY user`
infoSchemaAutoIncQuery = ` infoSchemaAutoIncQuery = `
SELECT table_schema, table_name, column_name, auto_increment, SELECT table_schema, table_name, column_name, auto_increment,
CAST(pow(2, case data_type CAST(pow(2, case data_type
@@ -759,6 +761,103 @@ func (m *Mysql) gatherGlobalStatuses(db *sql.DB, serv string, acc telegraf.Accum
if len(fields) > 0 { if len(fields) > 0 {
acc.AddFields("mysql", fields, tags) acc.AddFields("mysql", fields, tags)
} }
// gather connection metrics from processlist for each user
if m.GatherProcessList {
conn_rows, err := db.Query("SELECT user, sum(1) FROM INFORMATION_SCHEMA.PROCESSLIST GROUP BY user")
if err != nil {
log.Printf("E! MySQL Error gathering process list: %s", err)
} else {
for conn_rows.Next() {
var user string
var connections int64
err = conn_rows.Scan(&user, &connections)
if err != nil {
return err
}
tags := map[string]string{"server": servtag, "user": user}
fields := make(map[string]interface{})
if err != nil {
return err
}
fields["connections"] = connections
acc.AddFields("mysql_users", fields, tags)
}
}
}
// gather connection metrics from user_statistics for each user
if m.GatherUserStatistics {
conn_rows, err := db.Query("select user, total_connections, concurrent_connections, connected_time, busy_time, cpu_time, bytes_received, bytes_sent, binlog_bytes_written, rows_fetched, rows_updated, table_rows_read, select_commands, update_commands, other_commands, commit_transactions, rollback_transactions, denied_connections, lost_connections, access_denied, empty_queries, total_ssl_connections FROM INFORMATION_SCHEMA.USER_STATISTICS GROUP BY user")
if err != nil {
log.Printf("E! MySQL Error gathering user stats: %s", err)
} else {
for conn_rows.Next() {
var user string
var total_connections int64
var concurrent_connections int64
var connected_time int64
var busy_time int64
var cpu_time int64
var bytes_received int64
var bytes_sent int64
var binlog_bytes_written int64
var rows_fetched int64
var rows_updated int64
var table_rows_read int64
var select_commands int64
var update_commands int64
var other_commands int64
var commit_transactions int64
var rollback_transactions int64
var denied_connections int64
var lost_connections int64
var access_denied int64
var empty_queries int64
var total_ssl_connections int64
err = conn_rows.Scan(&user, &total_connections, &concurrent_connections,
&connected_time, &busy_time, &cpu_time, &bytes_received, &bytes_sent, &binlog_bytes_written,
&rows_fetched, &rows_updated, &table_rows_read, &select_commands, &update_commands, &other_commands,
&commit_transactions, &rollback_transactions, &denied_connections, &lost_connections, &access_denied,
&empty_queries, &total_ssl_connections,
)
if err != nil {
return err
}
tags := map[string]string{"server": servtag, "user": user}
fields := map[string]interface{}{
"total_connections": total_connections,
"concurrent_connections": concurrent_connections,
"connected_time": connected_time,
"busy_time": busy_time,
"cpu_time": cpu_time,
"bytes_received": bytes_received,
"bytes_sent": bytes_sent,
"binlog_bytes_written": binlog_bytes_written,
"rows_fetched": rows_fetched,
"rows_updated": rows_updated,
"table_rows_read": table_rows_read,
"select_commands": select_commands,
"update_commands": update_commands,
"other_commands": other_commands,
"commit_transactions": commit_transactions,
"rollback_transactions": rollback_transactions,
"denied_connections": denied_connections,
"lost_connections": lost_connections,
"access_denied": access_denied,
"empty_queries": empty_queries,
"total_ssl_connections": total_ssl_connections,
}
acc.AddFields("mysql_user_stats", fields, tags)
}
}
}
return nil return nil
} }
@@ -809,29 +908,6 @@ func (m *Mysql) GatherProcessListStatuses(db *sql.DB, serv string, acc telegraf.
} else { } else {
acc.AddFields("mysql_process_list", fields, tags) acc.AddFields("mysql_process_list", fields, tags)
} }
// get count of connections from each user
conn_rows, err := db.Query("SELECT user, sum(1) AS connections FROM INFORMATION_SCHEMA.PROCESSLIST GROUP BY user")
if err != nil {
return err
}
for conn_rows.Next() {
var user string
var connections int64
err = conn_rows.Scan(&user, &connections)
if err != nil {
return err
}
tags := map[string]string{"server": servtag, "user": user}
fields := make(map[string]interface{})
fields["connections"] = connections
acc.AddFields("mysql_users", fields, tags)
}
return nil return nil
} }
@@ -841,190 +917,77 @@ func (m *Mysql) GatherUserStatisticsStatuses(db *sql.DB, serv string, acc telegr
// run query // run query
rows, err := db.Query(infoSchemaUserStatisticsQuery) rows, err := db.Query(infoSchemaUserStatisticsQuery)
if err != nil { if err != nil {
// disable collecting if table is not found (mysql specific error)
// (suppresses repeat errors)
if strings.Contains(err.Error(), "nknown table 'user_statistics'") {
m.GatherUserStatistics = false
}
return err return err
} }
defer rows.Close() defer rows.Close()
var (
cols, err := columnsToLower(rows.Columns()) user string
if err != nil { total_connections int64
return err concurrent_connections int64
} connected_time int64
busy_time int64
read, err := getColSlice(len(cols)) cpu_time int64
if err != nil { bytes_received int64
return err bytes_sent int64
} binlog_bytes_written int64
rows_fetched int64
rows_updated int64
table_rows_read int64
select_commands int64
update_commands int64
other_commands int64
commit_transactions int64
rollback_transactions int64
denied_connections int64
lost_connections int64
access_denied int64
empty_queries int64
total_ssl_connections int64
count uint32
)
servtag := getDSNTag(serv) servtag := getDSNTag(serv)
for rows.Next() { for rows.Next() {
err = rows.Scan(read...) err = rows.Scan(&user, &total_connections, &concurrent_connections,
&connected_time, &busy_time, &cpu_time, &bytes_received, &bytes_sent, &binlog_bytes_written,
&rows_fetched, &rows_updated, &table_rows_read, &select_commands, &update_commands, &other_commands,
&commit_transactions, &rollback_transactions, &denied_connections, &lost_connections, &access_denied,
&empty_queries, &total_ssl_connections, &count,
)
if err != nil { if err != nil {
return err return err
} }
tags := map[string]string{"server": servtag, "user": *read[0].(*string)} tags := map[string]string{"server": servtag, "user": user}
fields := map[string]interface{}{} fields := map[string]interface{}{
for i := range cols { "total_connections": total_connections,
if i == 0 { "concurrent_connections": concurrent_connections,
continue // skip "user" "connected_time": connected_time,
} "busy_time": busy_time,
switch v := read[i].(type) { "cpu_time": cpu_time,
case *int64: "bytes_received": bytes_received,
fields[cols[i]] = *v "bytes_sent": bytes_sent,
case *float64: "binlog_bytes_written": binlog_bytes_written,
fields[cols[i]] = *v "rows_fetched": rows_fetched,
case *string: "rows_updated": rows_updated,
fields[cols[i]] = *v "table_rows_read": table_rows_read,
default: "select_commands": select_commands,
return fmt.Errorf("Unknown column type - %T", v) "update_commands": update_commands,
} "other_commands": other_commands,
"commit_transactions": commit_transactions,
"rollback_transactions": rollback_transactions,
"denied_connections": denied_connections,
"lost_connections": lost_connections,
"access_denied": access_denied,
"empty_queries": empty_queries,
"total_ssl_connections": total_ssl_connections,
} }
acc.AddFields("mysql_user_stats", fields, tags) acc.AddFields("mysql_user_stats", fields, tags)
} }
return nil return nil
} }
// columnsToLower converts selected column names to lowercase.
func columnsToLower(s []string, e error) ([]string, error) {
if e != nil {
return nil, e
}
d := make([]string, len(s))
for i := range s {
d[i] = strings.ToLower(s[i])
}
return d, nil
}
// getColSlice returns an in interface slice that can be used in the row.Scan().
func getColSlice(l int) ([]interface{}, error) {
// list of all possible column names
var (
user string
total_connections int64
concurrent_connections int64
connected_time int64
busy_time int64
cpu_time int64
bytes_received int64
bytes_sent int64
binlog_bytes_written int64
rows_read int64
rows_sent int64
rows_deleted int64
rows_inserted int64
rows_updated int64
select_commands int64
update_commands int64
other_commands int64
commit_transactions int64
rollback_transactions int64
denied_connections int64
lost_connections int64
access_denied int64
empty_queries int64
total_ssl_connections int64
max_statement_time_exceeded int64
// maria specific
fbusy_time float64
fcpu_time float64
// percona specific
rows_fetched int64
table_rows_read int64
)
switch l {
case 23: // maria5
return []interface{}{
&user,
&total_connections,
&concurrent_connections,
&connected_time,
&fbusy_time,
&fcpu_time,
&bytes_received,
&bytes_sent,
&binlog_bytes_written,
&rows_read,
&rows_sent,
&rows_deleted,
&rows_inserted,
&rows_updated,
&select_commands,
&update_commands,
&other_commands,
&commit_transactions,
&rollback_transactions,
&denied_connections,
&lost_connections,
&access_denied,
&empty_queries,
}, nil
case 25: // maria10
return []interface{}{
&user,
&total_connections,
&concurrent_connections,
&connected_time,
&fbusy_time,
&fcpu_time,
&bytes_received,
&bytes_sent,
&binlog_bytes_written,
&rows_read,
&rows_sent,
&rows_deleted,
&rows_inserted,
&rows_updated,
&select_commands,
&update_commands,
&other_commands,
&commit_transactions,
&rollback_transactions,
&denied_connections,
&lost_connections,
&access_denied,
&empty_queries,
&total_ssl_connections,
&max_statement_time_exceeded,
}, nil
case 22: // percona
return []interface{}{
&user,
&total_connections,
&concurrent_connections,
&connected_time,
&busy_time,
&cpu_time,
&bytes_received,
&bytes_sent,
&binlog_bytes_written,
&rows_fetched,
&rows_updated,
&table_rows_read,
&select_commands,
&update_commands,
&other_commands,
&commit_transactions,
&rollback_transactions,
&denied_connections,
&lost_connections,
&access_denied,
&empty_queries,
&total_ssl_connections,
}, nil
}
return nil, fmt.Errorf("Not Supported - %d columns", l)
}
// gatherPerfTableIOWaits can be used to get total count and time // gatherPerfTableIOWaits can be used to get total count and time
// of I/O wait event for each table and process // of I/O wait event for each table and process
func (m *Mysql) gatherPerfTableIOWaits(db *sql.DB, serv string, acc telegraf.Accumulator) error { func (m *Mysql) gatherPerfTableIOWaits(db *sql.DB, serv string, acc telegraf.Accumulator) error {

View File

@@ -49,7 +49,7 @@ func TestMysqlGetDSNTag(t *testing.T) {
}, },
{ {
"tcp(localhost)/", "tcp(localhost)/",
"localhost:3306", "localhost",
}, },
{ {
"root:passwd@tcp(192.168.1.1:3306)/?tls=false", "root:passwd@tcp(192.168.1.1:3306)/?tls=false",

View File

@@ -8,7 +8,7 @@ import (
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/inputs" "github.com/influxdata/telegraf/plugins/inputs"
"github.com/influxdata/telegraf/plugins/parsers" "github.com/influxdata/telegraf/plugins/parsers"
nats "github.com/nats-io/go-nats" "github.com/nats-io/nats"
) )
type natsError struct { type natsError struct {

View File

@@ -5,7 +5,7 @@ import (
"github.com/influxdata/telegraf/plugins/parsers" "github.com/influxdata/telegraf/plugins/parsers"
"github.com/influxdata/telegraf/testutil" "github.com/influxdata/telegraf/testutil"
nats "github.com/nats-io/go-nats" "github.com/nats-io/nats"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View File

@@ -17,17 +17,16 @@ This plugin uses a query on the [`nvidia-smi`](https://developer.nvidia.com/nvid
### Metrics ### Metrics
- measurement: `nvidia_smi` - measurement: `nvidia_smi`
- tags - tags
- `name` (type of GPU e.g. `GeForce GTX 1070 Ti`) - `name` (type of GPU e.g. `GeForce GTX 170 Ti`)
- `compute_mode` (The compute mode of the GPU e.g. `Default`) - `compute_mode` (The compute mode of the GPU e.g. `Default`)
- `index` (The port index where the GPU is connected to the motherboard e.g. `1`) - `index` (The port index where the GPU is connected to the motherboard e.g. `1`)
- `pstate` (Overclocking state for the GPU e.g. `P0`) - `pstate` (Overclocking state for the GPU e.g. `P0`)
- `uuid` (A unique identifier for the GPU e.g. `GPU-f9ba66fc-a7f5-94c5-da19-019ef2f9c665`) - `uuid` (A unique identifier for the GPU e.g. `GPU-f9ba66fc-a7f5-94c5-da19-019ef2f9c665`)
- fields - fields
- `fan_speed` (integer, percentage) - `fan_speed` (integer, percentage)
- `memory_free` (integer, MiB) - `memory_free` (integer, KB)
- `memory_used` (integer, MiB) - `memory_used` (integer, KB)
- `memory_total` (integer, MiB) - `memory_total` (integer, KB)
- `power_draw` (float, W)
- `temperature_gpu` (integer, degrees C) - `temperature_gpu` (integer, degrees C)
- `utilization_gpu` (integer, percentage) - `utilization_gpu` (integer, percentage)
- `utilization_memory` (integer, percentage) - `utilization_memory` (integer, percentage)

View File

@@ -16,21 +16,20 @@ import (
var ( var (
measurement = "nvidia_smi" measurement = "nvidia_smi"
metrics = "fan.speed,memory.total,memory.used,memory.free,pstate,temperature.gpu,name,uuid,compute_mode,utilization.gpu,utilization.memory,index,power.draw" metrics = "fan.speed,memory.total,memory.used,memory.free,pstate,temperature.gpu,name,uuid,compute_mode,utilization.gpu,utilization.memory,index"
metricNames = [][]string{ metricNames = [][]string{
[]string{"fan_speed", "integer"}, []string{"fan_speed", "field"},
[]string{"memory_total", "integer"}, []string{"memory_total", "field"},
[]string{"memory_used", "integer"}, []string{"memory_used", "field"},
[]string{"memory_free", "integer"}, []string{"memory_free", "field"},
[]string{"pstate", "tag"}, []string{"pstate", "tag"},
[]string{"temperature_gpu", "integer"}, []string{"temperature_gpu", "field"},
[]string{"name", "tag"}, []string{"name", "tag"},
[]string{"uuid", "tag"}, []string{"uuid", "tag"},
[]string{"compute_mode", "tag"}, []string{"compute_mode", "tag"},
[]string{"utilization_gpu", "integer"}, []string{"utilization_gpu", "field"},
[]string{"utilization_memory", "integer"}, []string{"utilization_memory", "field"},
[]string{"index", "tag"}, []string{"index", "tag"},
[]string{"power_draw", "float"},
} }
) )
@@ -128,7 +127,7 @@ func parseLine(line string) (map[string]string, map[string]interface{}, error) {
for i, m := range metricNames { for i, m := range metricNames {
col := strings.TrimSpace(met[i]) col := strings.TrimSpace(met[i])
// Handle the tags // First handle the tags
if m[1] == "tag" { if m[1] == "tag" {
tags[m[0]] = col tags[m[0]] = col
continue continue
@@ -138,23 +137,12 @@ func parseLine(line string) (map[string]string, map[string]interface{}, error) {
continue continue
} }
// Parse the integers // Then parse the integers out of the fields
if m[1] == "integer" { out, err := strconv.ParseInt(col, 10, 64)
out, err := strconv.ParseInt(col, 10, 64) if err != nil {
if err != nil { return tags, fields, err
return tags, fields, err
}
fields[m[0]] = out
}
// Parse the floats
if m[1] == "float" {
out, err := strconv.ParseFloat(col, 64)
if err != nil {
return tags, fields, err
}
fields[m[0]] = out
} }
fields[m[0]] = out
} }
// Return the tags and fields // Return the tags and fields

View File

@@ -7,7 +7,7 @@ import (
) )
func TestParseLineStandard(t *testing.T) { func TestParseLineStandard(t *testing.T) {
line := "85, 8114, 553, 7561, P2, 61, GeForce GTX 1070 Ti, GPU-d1911b8a-f5c8-5e66-057c-486561269de8, Default, 100, 93, 1, 0.0\n" line := "85, 8114, 553, 7561, P2, 61, GeForce GTX 1070 Ti, GPU-d1911b8a-f5c8-5e66-057c-486561269de8, Default, 100, 93, 1\n"
tags, fields, err := parseLine(line) tags, fields, err := parseLine(line)
if err != nil { if err != nil {
t.Fail() t.Fail()
@@ -37,7 +37,7 @@ func TestParseLineBad(t *testing.T) {
} }
func TestParseLineNotSupported(t *testing.T) { func TestParseLineNotSupported(t *testing.T) {
line := "[Not Supported], 7606, 0, 7606, P0, 38, Tesla P4, GPU-xxx, Default, 0, 0, 0, 0.0\n" line := "[Not Supported], 7606, 0, 7606, P0, 38, Tesla P4, GPU-xxx, Default, 0, 0, 0\n"
_, fields, err := parseLine(line) _, fields, err := parseLine(line)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, nil, fields["fan_speed"]) require.Equal(t, nil, fields["fan_speed"])

View File

@@ -14,7 +14,7 @@ To use this plugin you must enable the [monitoring](https://www.openldap.org/dev
# ldaps, starttls, or no encryption. default is an empty string, disabling all encryption. # ldaps, starttls, or no encryption. default is an empty string, disabling all encryption.
# note that port will likely need to be changed to 636 for ldaps # note that port will likely need to be changed to 636 for ldaps
# valid options: "" | "starttls" | "ldaps" # valid options: "" | "starttls" | "ldaps"
tls = "" ssl = ""
# skip peer certificate verification. Default is false. # skip peer certificate verification. Default is false.
insecure_skip_verify = false insecure_skip_verify = false

View File

@@ -15,11 +15,9 @@ import (
type Openldap struct { type Openldap struct {
Host string Host string
Port int Port int
SSL string `toml:"ssl"` // Deprecated in 1.7; use TLS Ssl string
TLS string `toml:"tls"`
InsecureSkipVerify bool InsecureSkipVerify bool
SSLCA string `toml:"ssl_ca"` // Deprecated in 1.7; use TLSCA SslCa string
TLSCA string `toml:"tls_ca"`
BindDn string BindDn string
BindPassword string BindPassword string
ReverseMetricNames bool ReverseMetricNames bool
@@ -32,7 +30,7 @@ const sampleConfig string = `
# ldaps, starttls, or no encryption. default is an empty string, disabling all encryption. # ldaps, starttls, or no encryption. default is an empty string, disabling all encryption.
# note that port will likely need to be changed to 636 for ldaps # note that port will likely need to be changed to 636 for ldaps
# valid options: "" | "starttls" | "ldaps" # valid options: "" | "starttls" | "ldaps"
tls = "" ssl = ""
# skip peer certificate verification. Default is false. # skip peer certificate verification. Default is false.
insecure_skip_verify = false insecure_skip_verify = false
@@ -72,11 +70,9 @@ func NewOpenldap() *Openldap {
return &Openldap{ return &Openldap{
Host: "localhost", Host: "localhost",
Port: 389, Port: 389,
SSL: "", Ssl: "",
TLS: "",
InsecureSkipVerify: false, InsecureSkipVerify: false,
SSLCA: "", SslCa: "",
TLSCA: "",
BindDn: "", BindDn: "",
BindPassword: "", BindPassword: "",
ReverseMetricNames: false, ReverseMetricNames: false,
@@ -85,19 +81,12 @@ func NewOpenldap() *Openldap {
// gather metrics // gather metrics
func (o *Openldap) Gather(acc telegraf.Accumulator) error { func (o *Openldap) Gather(acc telegraf.Accumulator) error {
if o.TLS == "" {
o.TLS = o.SSL
}
if o.TLSCA == "" {
o.TLSCA = o.SSLCA
}
var err error var err error
var l *ldap.Conn var l *ldap.Conn
if o.TLS != "" { if o.Ssl != "" {
// build tls config // build tls config
clientTLSConfig := tls.ClientConfig{ clientTLSConfig := tls.ClientConfig{
TLSCA: o.TLSCA, SSLCA: o.SslCa,
InsecureSkipVerify: o.InsecureSkipVerify, InsecureSkipVerify: o.InsecureSkipVerify,
} }
tlsConfig, err := clientTLSConfig.TLSConfig() tlsConfig, err := clientTLSConfig.TLSConfig()
@@ -105,13 +94,13 @@ func (o *Openldap) Gather(acc telegraf.Accumulator) error {
acc.AddError(err) acc.AddError(err)
return nil return nil
} }
if o.TLS == "ldaps" { if o.Ssl == "ldaps" {
l, err = ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", o.Host, o.Port), tlsConfig) l, err = ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", o.Host, o.Port), tlsConfig)
if err != nil { if err != nil {
acc.AddError(err) acc.AddError(err)
return nil return nil
} }
} else if o.TLS == "starttls" { } else if o.Ssl == "starttls" {
l, err = ldap.Dial("tcp", fmt.Sprintf("%s:%d", o.Host, o.Port)) l, err = ldap.Dial("tcp", fmt.Sprintf("%s:%d", o.Host, o.Port))
if err != nil { if err != nil {
acc.AddError(err) acc.AddError(err)
@@ -119,7 +108,7 @@ func (o *Openldap) Gather(acc telegraf.Accumulator) error {
} }
err = l.StartTLS(tlsConfig) err = l.StartTLS(tlsConfig)
} else { } else {
acc.AddError(fmt.Errorf("Invalid setting for ssl: %s", o.TLS)) acc.AddError(fmt.Errorf("Invalid setting for ssl: %s", o.Ssl))
return nil return nil
} }
} else { } else {

View File

@@ -1,11 +1,10 @@
package openldap package openldap
import ( import (
"gopkg.in/ldap.v2"
"strconv" "strconv"
"testing" "testing"
"gopkg.in/ldap.v2"
"github.com/influxdata/telegraf/testutil" "github.com/influxdata/telegraf/testutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -75,7 +74,7 @@ func TestOpenldapStartTLS(t *testing.T) {
o := &Openldap{ o := &Openldap{
Host: testutil.GetLocalHost(), Host: testutil.GetLocalHost(),
Port: 389, Port: 389,
SSL: "starttls", Ssl: "starttls",
InsecureSkipVerify: true, InsecureSkipVerify: true,
} }
@@ -93,7 +92,7 @@ func TestOpenldapLDAPS(t *testing.T) {
o := &Openldap{ o := &Openldap{
Host: testutil.GetLocalHost(), Host: testutil.GetLocalHost(),
Port: 636, Port: 636,
SSL: "ldaps", Ssl: "ldaps",
InsecureSkipVerify: true, InsecureSkipVerify: true,
} }
@@ -111,7 +110,7 @@ func TestOpenldapInvalidSSL(t *testing.T) {
o := &Openldap{ o := &Openldap{
Host: testutil.GetLocalHost(), Host: testutil.GetLocalHost(),
Port: 636, Port: 636,
SSL: "invalid", Ssl: "invalid",
InsecureSkipVerify: true, InsecureSkipVerify: true,
} }
@@ -130,7 +129,7 @@ func TestOpenldapBind(t *testing.T) {
o := &Openldap{ o := &Openldap{
Host: testutil.GetLocalHost(), Host: testutil.GetLocalHost(),
Port: 389, Port: 389,
SSL: "", Ssl: "",
InsecureSkipVerify: true, InsecureSkipVerify: true,
BindDn: "cn=manager,cn=config", BindDn: "cn=manager,cn=config",
BindPassword: "secret", BindPassword: "secret",
@@ -158,7 +157,7 @@ func TestOpenldapReverseMetrics(t *testing.T) {
o := &Openldap{ o := &Openldap{
Host: testutil.GetLocalHost(), Host: testutil.GetLocalHost(),
Port: 389, Port: 389,
SSL: "", Ssl: "",
InsecureSkipVerify: true, InsecureSkipVerify: true,
BindDn: "cn=manager,cn=config", BindDn: "cn=manager,cn=config",
BindPassword: "secret", BindPassword: "secret",

View File

@@ -31,21 +31,6 @@ telegraf ALL=(root) NOPASSWD: /sbin/pfctl -s info
- searches (integer, count) - searches (integer, count)
- inserts (integer, count) - inserts (integer, count)
- removals (integer, count) - removals (integer, count)
- match (integer, count)
- bad-offset (integer, count)
- fragment (integer, count)
- short (integer, count)
- normalize (integer, count)
- memory (integer, count)
- bad-timestamp (integer, count)
- congestion (integer, count)
- ip-option (integer, count)
- proto-cksum (integer, count)
- state-mismatch (integer, count)
- state-insert (integer, count)
- state-limit (integer, count)
- src-limit (integer, count)
- synproxy (integer, count)
### Example Output: ### Example Output:

View File

@@ -67,7 +67,7 @@ func errMissingData(tag string) error {
type pfctlOutputStanza struct { type pfctlOutputStanza struct {
HeaderRE *regexp.Regexp HeaderRE *regexp.Regexp
ParseFunc func([]string, map[string]interface{}) error ParseFunc func([]string, telegraf.Accumulator) error
Found bool Found bool
} }
@@ -76,16 +76,11 @@ var pfctlOutputStanzas = []*pfctlOutputStanza{
HeaderRE: regexp.MustCompile("^State Table"), HeaderRE: regexp.MustCompile("^State Table"),
ParseFunc: parseStateTable, ParseFunc: parseStateTable,
}, },
&pfctlOutputStanza{
HeaderRE: regexp.MustCompile("^Counters"),
ParseFunc: parseCounterTable,
},
} }
var anyTableHeaderRE = regexp.MustCompile("^[A-Z]") var anyTableHeaderRE = regexp.MustCompile("^[A-Z]")
func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error { func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error {
fields := make(map[string]interface{})
scanner := bufio.NewScanner(strings.NewReader(pfoutput)) scanner := bufio.NewScanner(strings.NewReader(pfoutput))
for scanner.Scan() { for scanner.Scan() {
line := scanner.Text() line := scanner.Text()
@@ -96,14 +91,10 @@ func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error
line = scanner.Text() line = scanner.Text()
for !anyTableHeaderRE.MatchString(line) { for !anyTableHeaderRE.MatchString(line) {
stanzaLines = append(stanzaLines, line) stanzaLines = append(stanzaLines, line)
more := scanner.Scan() scanner.Scan()
if more { line = scanner.Text()
line = scanner.Text()
} else {
break
}
} }
if perr := s.ParseFunc(stanzaLines, fields); perr != nil { if perr := s.ParseFunc(stanzaLines, acc); perr != nil {
return perr return perr
} }
s.Found = true s.Found = true
@@ -115,8 +106,6 @@ func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error
return errParseHeader return errParseHeader
} }
} }
acc.AddFields(measurement, fields, make(map[string]string))
return nil return nil
} }
@@ -135,40 +124,11 @@ var StateTable = []*Entry{
var stateTableRE = regexp.MustCompile(`^ (.*?)\s+(\d+)`) var stateTableRE = regexp.MustCompile(`^ (.*?)\s+(\d+)`)
func parseStateTable(lines []string, fields map[string]interface{}) error { func parseStateTable(lines []string, acc telegraf.Accumulator) error {
return storeFieldValues(lines, stateTableRE, fields, StateTable)
}
var CounterTable = []*Entry{
&Entry{"match", "match", -1},
&Entry{"bad-offset", "bad-offset", -1},
&Entry{"fragment", "fragment", -1},
&Entry{"short", "short", -1},
&Entry{"normalize", "normalize", -1},
&Entry{"memory", "memory", -1},
&Entry{"bad-timestamp", "bad-timestamp", -1},
&Entry{"congestion", "congestion", -1},
&Entry{"ip-option", "ip-option", -1},
&Entry{"proto-cksum", "proto-cksum", -1},
&Entry{"state-mismatch", "state-mismatch", -1},
&Entry{"state-insert", "state-insert", -1},
&Entry{"state-limit", "state-limit", -1},
&Entry{"src-limit", "src-limit", -1},
&Entry{"synproxy", "synproxy", -1},
}
var counterTableRE = regexp.MustCompile(`^ (.*?)\s+(\d+)`)
func parseCounterTable(lines []string, fields map[string]interface{}) error {
return storeFieldValues(lines, counterTableRE, fields, CounterTable)
}
func storeFieldValues(lines []string, regex *regexp.Regexp, fields map[string]interface{}, entryTable []*Entry) error {
for _, v := range lines { for _, v := range lines {
entries := regex.FindStringSubmatch(v) entries := stateTableRE.FindStringSubmatch(v)
if entries != nil { if entries != nil {
for _, f := range entryTable { for _, f := range StateTable {
if f.PfctlTitle == entries[1] { if f.PfctlTitle == entries[1] {
var err error var err error
if f.Value, err = strconv.ParseInt(entries[2], 10, 64); err != nil { if f.Value, err = strconv.ParseInt(entries[2], 10, 64); err != nil {
@@ -179,13 +139,15 @@ func storeFieldValues(lines []string, regex *regexp.Regexp, fields map[string]in
} }
} }
for _, v := range entryTable { fields := make(map[string]interface{})
for _, v := range StateTable {
if v.Value == -1 { if v.Value == -1 {
return errMissingData(v.PfctlTitle) return errMissingData(v.PfctlTitle)
} }
fields[v.Field] = v.Value fields[v.Field] = v.Value
} }
acc.AddFields(measurement, fields, make(map[string]string))
return nil return nil
} }

View File

@@ -152,25 +152,10 @@ Counters
measurements: []measurementResult{ measurements: []measurementResult{
measurementResult{ measurementResult{
fields: map[string]interface{}{ fields: map[string]interface{}{
"entries": int64(2), "entries": int64(2),
"searches": int64(11325), "searches": int64(11325),
"inserts": int64(5), "inserts": int64(5),
"removals": int64(3), "removals": int64(3)},
"match": int64(11226),
"bad-offset": int64(0),
"fragment": int64(0),
"short": int64(0),
"normalize": int64(0),
"memory": int64(0),
"bad-timestamp": int64(0),
"congestion": int64(0),
"ip-option": int64(0),
"proto-cksum": int64(0),
"state-mismatch": int64(0),
"state-insert": int64(0),
"state-limit": int64(0),
"src-limit": int64(0),
"synproxy": int64(0)},
tags: map[string]string{}, tags: map[string]string{},
}, },
}, },
@@ -212,25 +197,10 @@ Counters
measurements: []measurementResult{ measurements: []measurementResult{
measurementResult{ measurementResult{
fields: map[string]interface{}{ fields: map[string]interface{}{
"entries": int64(649), "entries": int64(649),
"searches": int64(18421725761), "searches": int64(18421725761),
"inserts": int64(156762508), "inserts": int64(156762508),
"removals": int64(156761859), "removals": int64(156761859)},
"match": int64(473002784),
"bad-offset": int64(0),
"fragment": int64(2729),
"short": int64(107),
"normalize": int64(1685),
"memory": int64(101),
"bad-timestamp": int64(0),
"congestion": int64(0),
"ip-option": int64(152301),
"proto-cksum": int64(108),
"state-mismatch": int64(24393),
"state-insert": int64(92),
"state-limit": int64(0),
"src-limit": int64(0),
"synproxy": int64(0)},
tags: map[string]string{}, tags: map[string]string{},
}, },
}, },

View File

@@ -175,7 +175,7 @@ func (p *Ping) args(url string) []string {
} }
if p.Timeout > 0 { if p.Timeout > 0 {
switch runtime.GOOS { switch runtime.GOOS {
case "darwin", "freebsd", "netbsd", "openbsd": case "darwin":
args = append(args, "-W", strconv.FormatFloat(p.Timeout*1000, 'f', -1, 64)) args = append(args, "-W", strconv.FormatFloat(p.Timeout*1000, 'f', -1, 64))
case "linux": case "linux":
args = append(args, "-W", strconv.FormatFloat(p.Timeout, 'f', -1, 64)) args = append(args, "-W", strconv.FormatFloat(p.Timeout, 'f', -1, 64))
@@ -186,7 +186,7 @@ func (p *Ping) args(url string) []string {
} }
if p.Deadline > 0 { if p.Deadline > 0 {
switch runtime.GOOS { switch runtime.GOOS {
case "darwin", "freebsd", "netbsd", "openbsd": case "darwin":
args = append(args, "-t", strconv.Itoa(p.Deadline)) args = append(args, "-t", strconv.Itoa(p.Deadline))
case "linux": case "linux":
args = append(args, "-w", strconv.Itoa(p.Deadline)) args = append(args, "-w", strconv.Itoa(p.Deadline))
@@ -197,10 +197,10 @@ func (p *Ping) args(url string) []string {
} }
if p.Interface != "" { if p.Interface != "" {
switch runtime.GOOS { switch runtime.GOOS {
case "darwin", "freebsd", "netbsd", "openbsd":
args = append(args, "-S", p.Interface)
case "linux": case "linux":
args = append(args, "-I", p.Interface) args = append(args, "-I", p.Interface)
case "freebsd", "darwin":
args = append(args, "-S", p.Interface)
default: default:
// Not sure the best option here, just assume GNU ping? // Not sure the best option here, just assume GNU ping?
args = append(args, "-I", p.Interface) args = append(args, "-I", p.Interface)

View File

@@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path"
"strings" "strings"
"time" "time"
@@ -28,37 +28,36 @@ func getQueueDirectory() (string, error) {
return strings.TrimSpace(string(qd)), nil return strings.TrimSpace(string(qd)), nil
} }
func qScan(path string, acc telegraf.Accumulator) (int64, int64, int64, error) { func qScan(path string) (int64, int64, int64, error) {
f, err := os.Open(path)
if err != nil {
return 0, 0, 0, err
}
finfos, err := f.Readdir(-1)
f.Close()
if err != nil {
return 0, 0, 0, err
}
var length, size int64 var length, size int64
var oldest time.Time var oldest time.Time
err := filepath.Walk(path, func(_ string, finfo os.FileInfo, err error) error { for _, finfo := range finfos {
if err != nil {
acc.AddError(fmt.Errorf("error scanning %s: %s", path, err))
return nil
}
if finfo.IsDir() {
return nil
}
length++ length++
size += finfo.Size() size += finfo.Size()
ctime := statCTime(finfo.Sys()) ctime := statCTime(finfo.Sys())
if ctime.IsZero() { if ctime.IsZero() {
return nil continue
} }
if oldest.IsZero() || ctime.Before(oldest) { if oldest.IsZero() || ctime.Before(oldest) {
oldest = ctime oldest = ctime
} }
return nil
})
if err != nil {
return 0, 0, 0, err
} }
var age int64 var age int64
if !oldest.IsZero() { if !oldest.IsZero() {
age = int64(time.Now().Sub(oldest) / time.Second) age = int64(time.Now().Sub(oldest) / time.Second)
} else if length != 0 { } else if len(finfos) != 0 {
// system doesn't support ctime // system doesn't support ctime
age = -1 age = -1
} }
@@ -78,8 +77,8 @@ func (p *Postfix) Gather(acc telegraf.Accumulator) error {
} }
} }
for _, q := range []string{"active", "hold", "incoming", "maildrop", "deferred"} { for _, q := range []string{"active", "hold", "incoming", "maildrop"} {
length, size, age, err := qScan(filepath.Join(p.QueueDirectory, q), acc) length, size, age, err := qScan(path.Join(p.QueueDirectory, q))
if err != nil { if err != nil {
acc.AddError(fmt.Errorf("error scanning queue %s: %s", q, err)) acc.AddError(fmt.Errorf("error scanning queue %s: %s", q, err))
continue continue
@@ -91,6 +90,30 @@ func (p *Postfix) Gather(acc telegraf.Accumulator) error {
acc.AddFields("postfix_queue", fields, map[string]string{"queue": q}) acc.AddFields("postfix_queue", fields, map[string]string{"queue": q})
} }
var dLength, dSize int64
dAge := int64(-1)
for _, q := range []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"} {
length, size, age, err := qScan(path.Join(p.QueueDirectory, "deferred", q))
if err != nil {
if os.IsNotExist(err) {
// the directories are created on first use
continue
}
acc.AddError(fmt.Errorf("error scanning queue deferred/%s: %s", q, err))
return nil
}
dLength += length
dSize += size
if age > dAge {
dAge = age
}
}
fields := map[string]interface{}{"length": dLength, "size": dSize}
if dAge != -1 {
fields["age"] = dAge
}
acc.AddFields("postfix_queue", fields, map[string]string{"queue": "deferred"})
return nil return nil
} }

View File

@@ -3,7 +3,7 @@ package postfix
import ( import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path"
"testing" "testing"
"github.com/influxdata/telegraf/testutil" "github.com/influxdata/telegraf/testutil"
@@ -16,16 +16,19 @@ func TestGather(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
defer os.RemoveAll(td) defer os.RemoveAll(td)
for _, q := range []string{"active", "hold", "incoming", "maildrop", "deferred/0/0", "deferred/F/F"} { for _, q := range []string{"active", "hold", "incoming", "maildrop", "deferred"} {
require.NoError(t, os.MkdirAll(filepath.FromSlash(td+"/"+q), 0755)) require.NoError(t, os.Mkdir(path.Join(td, q), 0755))
}
for _, q := range []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "F"} { // "E" deliberately left off
require.NoError(t, os.Mkdir(path.Join(td, "deferred", q), 0755))
} }
require.NoError(t, ioutil.WriteFile(filepath.FromSlash(td+"/active/01"), []byte("abc"), 0644)) require.NoError(t, ioutil.WriteFile(path.Join(td, "active", "01"), []byte("abc"), 0644))
require.NoError(t, ioutil.WriteFile(filepath.FromSlash(td+"/active/02"), []byte("defg"), 0644)) require.NoError(t, ioutil.WriteFile(path.Join(td, "active", "02"), []byte("defg"), 0644))
require.NoError(t, ioutil.WriteFile(filepath.FromSlash(td+"/hold/01"), []byte("abc"), 0644)) require.NoError(t, ioutil.WriteFile(path.Join(td, "hold", "01"), []byte("abc"), 0644))
require.NoError(t, ioutil.WriteFile(filepath.FromSlash(td+"/incoming/01"), []byte("abcd"), 0644)) require.NoError(t, ioutil.WriteFile(path.Join(td, "incoming", "01"), []byte("abcd"), 0644))
require.NoError(t, ioutil.WriteFile(filepath.FromSlash(td+"/deferred/0/0/01"), []byte("abc"), 0644)) require.NoError(t, ioutil.WriteFile(path.Join(td, "deferred", "0", "01"), []byte("abc"), 0644))
require.NoError(t, ioutil.WriteFile(filepath.FromSlash(td+"/deferred/F/F/F1"), []byte("abc"), 0644)) require.NoError(t, ioutil.WriteFile(path.Join(td, "deferred", "F", "F1"), []byte("abc"), 0644))
p := Postfix{ p := Postfix{
QueueDirectory: td, QueueDirectory: td,

View File

@@ -1,8 +1,6 @@
# Procstat Input Plugin # Procstat Input Plugin
The procstat plugin can be used to monitor the system resource usage of one or more processes. The procstat plugin can be used to monitor the system resource usage of one or more processes.
The procstat_lookup metric displays the query information,
specifically the number of PIDs returned on a search
Processes can be selected for monitoring using one of several methods: Processes can be selected for monitoring using one of several methods:
- pidfile - pidfile
@@ -129,18 +127,7 @@ implemented as a WMI query. The pattern allows fuzzy matching using only
- voluntary_context_switches (int) - voluntary_context_switches (int)
- write_bytes (int, *telegraf* may need to be ran as **root**) - write_bytes (int, *telegraf* may need to be ran as **root**)
- write_count (int, *telegraf* may need to be ran as **root**) - write_count (int, *telegraf* may need to be ran as **root**)
- procstat_lookup
- tags:
- exe (string)
- pid_finder (string)
- pid_file (string)
- pattern (string)
- prefix (string)
- user (string)
- systemd_unit (string)
- cgroup (string)
- fields:
- pid_count (int)
*NOTE: Resource limit > 2147483647 will be reported as 2147483647.* *NOTE: Resource limit > 2147483647 will be reported as 2147483647.*
### Example Output: ### Example Output:

View File

@@ -6,8 +6,6 @@ import (
"os/exec" "os/exec"
"strconv" "strconv"
"strings" "strings"
"github.com/influxdata/telegraf/internal"
) )
// Implemention of PIDGatherer that execs pgrep to find processes // Implemention of PIDGatherer that execs pgrep to find processes
@@ -64,12 +62,6 @@ func find(path string, args []string) ([]PID, error) {
func run(path string, args []string) (string, error) { func run(path string, args []string) (string, error) {
out, err := exec.Command(path, args...).Output() out, err := exec.Command(path, args...).Output()
//if exit code 1, ie no processes found, do not return error
if i, _ := internal.ExitStatus(err); i == 1 {
return "", nil
}
if err != nil { if err != nil {
return "", fmt.Errorf("Error running %s: %s", path, err) return "", fmt.Errorf("Error running %s: %s", path, err)
} }

View File

@@ -97,7 +97,7 @@ func (p *Procstat) Gather(acc telegraf.Accumulator) error {
p.createProcess = defaultProcess p.createProcess = defaultProcess
} }
procs, err := p.updateProcesses(acc, p.procs) procs, err := p.updateProcesses(p.procs)
if err != nil { if err != nil {
acc.AddError(fmt.Errorf("E! Error: procstat getting process, exe: [%s] pidfile: [%s] pattern: [%s] user: [%s] %s", acc.AddError(fmt.Errorf("E! Error: procstat getting process, exe: [%s] pidfile: [%s] pattern: [%s] user: [%s] %s",
p.Exe, p.PidFile, p.Pattern, p.User, err.Error())) p.Exe, p.PidFile, p.Pattern, p.User, err.Error()))
@@ -230,8 +230,8 @@ func (p *Procstat) addMetrics(proc Process, acc telegraf.Accumulator) {
} }
// Update monitored Processes // Update monitored Processes
func (p *Procstat) updateProcesses(acc telegraf.Accumulator, prevInfo map[PID]Process) (map[PID]Process, error) { func (p *Procstat) updateProcesses(prevInfo map[PID]Process) (map[PID]Process, error) {
pids, tags, err := p.findPids(acc) pids, tags, err := p.findPids()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -281,9 +281,9 @@ func (p *Procstat) getPIDFinder() (PIDFinder, error) {
} }
// Get matching PIDs and their initial tags // Get matching PIDs and their initial tags
func (p *Procstat) findPids(acc telegraf.Accumulator) ([]PID, map[string]string, error) { func (p *Procstat) findPids() ([]PID, map[string]string, error) {
var pids []PID var pids []PID
tags := make(map[string]string) var tags map[string]string
var err error var err error
f, err := p.getPIDFinder() f, err := p.getPIDFinder()
@@ -313,18 +313,7 @@ func (p *Procstat) findPids(acc telegraf.Accumulator) ([]PID, map[string]string,
err = fmt.Errorf("Either exe, pid_file, user, pattern, systemd_unit, or cgroup must be specified") err = fmt.Errorf("Either exe, pid_file, user, pattern, systemd_unit, or cgroup must be specified")
} }
rTags := make(map[string]string) return pids, tags, err
for k, v := range tags {
rTags[k] = v
}
//adds a metric with info on the pgrep query
fields := make(map[string]interface{})
tags["pid_finder"] = p.PidFinder
fields["pid_count"] = len(pids)
acc.AddFields("procstat_lookup", fields, tags)
return pids, rTags, err
} }
// execCommand is so tests can mock out exec.Command usage. // execCommand is so tests can mock out exec.Command usage.

View File

@@ -343,8 +343,7 @@ func TestGather_systemdUnitPIDs(t *testing.T) {
createPIDFinder: pidFinder([]PID{}, nil), createPIDFinder: pidFinder([]PID{}, nil),
SystemdUnit: "TestGather_systemdUnitPIDs", SystemdUnit: "TestGather_systemdUnitPIDs",
} }
var acc testutil.Accumulator pids, tags, err := p.findPids()
pids, tags, err := p.findPids(&acc)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, []PID{11408}, pids) assert.Equal(t, []PID{11408}, pids)
assert.Equal(t, "TestGather_systemdUnitPIDs", tags["systemd_unit"]) assert.Equal(t, "TestGather_systemdUnitPIDs", tags["systemd_unit"])
@@ -365,20 +364,8 @@ func TestGather_cgroupPIDs(t *testing.T) {
createPIDFinder: pidFinder([]PID{}, nil), createPIDFinder: pidFinder([]PID{}, nil),
CGroup: td, CGroup: td,
} }
var acc testutil.Accumulator pids, tags, err := p.findPids()
pids, tags, err := p.findPids(&acc)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, []PID{1234, 5678}, pids) assert.Equal(t, []PID{1234, 5678}, pids)
assert.Equal(t, td, tags["cgroup"]) assert.Equal(t, td, tags["cgroup"])
} }
func TestProcstatLookupMetric(t *testing.T) {
p := Procstat{
createPIDFinder: pidFinder([]PID{543}, nil),
Exe: "-Gsys",
}
var acc testutil.Accumulator
err := acc.GatherError(p.Gather)
require.NoError(t, err)
require.Equal(t, len(p.procs)+1, len(acc.Metrics))
}

View File

@@ -14,13 +14,6 @@
## If no servers are specified, then localhost is used as the host. ## If no servers are specified, then localhost is used as the host.
## If no port is specified, 6379 is used ## If no port is specified, 6379 is used
servers = ["tcp://localhost:6379"] servers = ["tcp://localhost:6379"]
## Optional TLS Config
# tls_ca = "/etc/telegraf/ca.pem"
# tls_cert = "/etc/telegraf/cert.pem"
# tls_key = "/etc/telegraf/key.pem"
## Use TLS but skip chain & host verification
# insecure_skip_verify = true
``` ```
### Measurements & Fields: ### Measurements & Fields:

View File

@@ -13,13 +13,11 @@ import (
"github.com/go-redis/redis" "github.com/go-redis/redis"
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal/tls"
"github.com/influxdata/telegraf/plugins/inputs" "github.com/influxdata/telegraf/plugins/inputs"
) )
type Redis struct { type Redis struct {
Servers []string Servers []string
tls.ClientConfig
clients []Client clients []Client
initialized bool initialized bool
@@ -58,13 +56,6 @@ var sampleConfig = `
## If no servers are specified, then localhost is used as the host. ## If no servers are specified, then localhost is used as the host.
## If no port is specified, 6379 is used ## If no port is specified, 6379 is used
servers = ["tcp://localhost:6379"] servers = ["tcp://localhost:6379"]
## Optional TLS Config
# tls_ca = "/etc/telegraf/ca.pem"
# tls_cert = "/etc/telegraf/cert.pem"
# tls_key = "/etc/telegraf/key.pem"
## Use TLS but skip chain & host verification
# insecure_skip_verify = true
` `
func (r *Redis) SampleConfig() string { func (r *Redis) SampleConfig() string {
@@ -118,18 +109,12 @@ func (r *Redis) init(acc telegraf.Accumulator) error {
address = u.Host address = u.Host
} }
tlsConfig, err := r.ClientConfig.TLSConfig()
if err != nil {
return err
}
client := redis.NewClient( client := redis.NewClient(
&redis.Options{ &redis.Options{
Addr: address, Addr: address,
Password: password, Password: password,
Network: u.Scheme, Network: u.Scheme,
PoolSize: 1, PoolSize: 1,
TLSConfig: tlsConfig,
}, },
) )

View File

@@ -218,20 +218,10 @@ func (t *Table) initBuild() error {
if err != nil { if err != nil {
return err return err
} }
if t.Name == "" { if t.Name == "" {
t.Name = oidText t.Name = oidText
} }
t.Fields = append(t.Fields, fields...)
knownOIDs := map[string]bool{}
for _, f := range t.Fields {
knownOIDs[f.Oid] = true
}
for _, f := range fields {
if !knownOIDs[f.Oid] {
t.Fields = append(t.Fields, f)
}
}
return nil return nil
} }

View File

@@ -21,7 +21,7 @@ var mockedCommands = [][]string{
{"snmptranslate", "-Td", "-Ob", "-m", "all", "1.0.0.1.1"}, {"snmptranslate", "-Td", "-Ob", "-m", "all", "1.0.0.1.1"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.0.1.1"}, {"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.0.1.1"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.0.1.1.0"}, {"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.0.1.1.0"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.0.1.5"}, {"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.0.1.4"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.2.3"}, {"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.2.3"},
{"snmptranslate", "-Td", "-Ob", ".iso.2.3"}, {"snmptranslate", "-Td", "-Ob", ".iso.2.3"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".999"}, {"snmptranslate", "-Td", "-Ob", "-m", "all", ".999"},
@@ -30,7 +30,6 @@ var mockedCommands = [][]string{
{"snmptranslate", "-Td", "-Ob", "TEST::testTable"}, {"snmptranslate", "-Td", "-Ob", "TEST::testTable"},
{"snmptranslate", "-Td", "-Ob", "TEST::connections"}, {"snmptranslate", "-Td", "-Ob", "TEST::connections"},
{"snmptranslate", "-Td", "-Ob", "TEST::latency"}, {"snmptranslate", "-Td", "-Ob", "TEST::latency"},
{"snmptranslate", "-Td", "-Ob", "TEST::description"},
{"snmptranslate", "-Td", "-Ob", "TEST::hostname"}, {"snmptranslate", "-Td", "-Ob", "TEST::hostname"},
{"snmptranslate", "-Td", "-Ob", "IF-MIB::ifPhysAddress.1"}, {"snmptranslate", "-Td", "-Ob", "IF-MIB::ifPhysAddress.1"},
{"snmptranslate", "-Td", "-Ob", "BRIDGE-MIB::dot1dTpFdbAddress.1"}, {"snmptranslate", "-Td", "-Ob", "BRIDGE-MIB::dot1dTpFdbAddress.1"},

View File

@@ -67,7 +67,7 @@ var mockedCommandResults = map[string]mockedCommandResult{
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x001.0.0.1.1": mockedCommandResult{stdout: "TEST::hostname\nhostname OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) 1 1 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x001.0.0.1.1": mockedCommandResult{stdout: "TEST::hostname\nhostname OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) 1 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.0.1.1": mockedCommandResult{stdout: "TEST::server\nserver OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 1 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.0.1.1": mockedCommandResult{stdout: "TEST::server\nserver OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.0.1.1.0": mockedCommandResult{stdout: "TEST::server.0\nserver OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) server(1) 0 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.0.1.1.0": mockedCommandResult{stdout: "TEST::server.0\nserver OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) server(1) 0 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.0.1.5": mockedCommandResult{stdout: "TEST::testTableEntry.5\ntestTableEntry OBJECT-TYPE\n -- FROM\tTEST\n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n INDEX\t\t{ server }\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 5 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.0.1.4": mockedCommandResult{stdout: "TEST::testTableEntry.4\ntestTableEntry OBJECT-TYPE\n -- FROM\tTEST\n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n INDEX\t\t{ server }\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 4 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.2.3": mockedCommandResult{stdout: "iso.2.3\niso OBJECT-TYPE\n -- FROM\t#-1\n::= { iso(1) 2 3 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.2.3": mockedCommandResult{stdout: "iso.2.3\niso OBJECT-TYPE\n -- FROM\t#-1\n::= { iso(1) 2 3 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00.iso.2.3": mockedCommandResult{stdout: "iso.2.3\niso OBJECT-TYPE\n -- FROM\t#-1\n::= { iso(1) 2 3 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00.iso.2.3": mockedCommandResult{stdout: "iso.2.3\niso OBJECT-TYPE\n -- FROM\t#-1\n::= { iso(1) 2 3 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.999": mockedCommandResult{stdout: ".999\n [TRUNCATED]\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.999": mockedCommandResult{stdout: ".999\n [TRUNCATED]\n", stderr: "", exitError: false},
@@ -76,11 +76,10 @@ var mockedCommandResults = map[string]mockedCommandResult{
"snmptranslate\x00-Td\x00-Ob\x00TEST::testTable": mockedCommandResult{stdout: "TEST::testTable\ntestTable OBJECT-TYPE\n -- FROM\tTEST\n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) 0 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00TEST::testTable": mockedCommandResult{stdout: "TEST::testTable\ntestTable OBJECT-TYPE\n -- FROM\tTEST\n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) 0 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TEST::connections": mockedCommandResult{stdout: "TEST::connections\nconnections OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tINTEGER\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 2 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00TEST::connections": mockedCommandResult{stdout: "TEST::connections\nconnections OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tINTEGER\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 2 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TEST::latency": mockedCommandResult{stdout: "TEST::latency\nlatency OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 3 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00TEST::latency": mockedCommandResult{stdout: "TEST::latency\nlatency OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 3 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TEST::description": mockedCommandResult{stdout: "TEST::description\ndescription OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 4 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TEST::hostname": mockedCommandResult{stdout: "TEST::hostname\nhostname OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) 1 1 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00TEST::hostname": mockedCommandResult{stdout: "TEST::hostname\nhostname OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) 1 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00IF-MIB::ifPhysAddress.1": mockedCommandResult{stdout: "IF-MIB::ifPhysAddress.1\nifPhysAddress OBJECT-TYPE\n -- FROM\tIF-MIB\n -- TEXTUAL CONVENTION PhysAddress\n SYNTAX\tOCTET STRING\n DISPLAY-HINT\t\"1x:\"\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n DESCRIPTION\t\"The interface's address at its protocol sub-layer. For\n example, for an 802.x interface, this object normally\n contains a MAC address. The interface's media-specific MIB\n must define the bit and byte ordering and the format of the\n value of this object. For interfaces which do not have such\n an address (e.g., a serial line), this object should contain\n an octet string of zero length.\"\n::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) interfaces(2) ifTable(2) ifEntry(1) ifPhysAddress(6) 1 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00IF-MIB::ifPhysAddress.1": mockedCommandResult{stdout: "IF-MIB::ifPhysAddress.1\nifPhysAddress OBJECT-TYPE\n -- FROM\tIF-MIB\n -- TEXTUAL CONVENTION PhysAddress\n SYNTAX\tOCTET STRING\n DISPLAY-HINT\t\"1x:\"\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n DESCRIPTION\t\"The interface's address at its protocol sub-layer. For\n example, for an 802.x interface, this object normally\n contains a MAC address. The interface's media-specific MIB\n must define the bit and byte ordering and the format of the\n value of this object. For interfaces which do not have such\n an address (e.g., a serial line), this object should contain\n an octet string of zero length.\"\n::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) interfaces(2) ifTable(2) ifEntry(1) ifPhysAddress(6) 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00BRIDGE-MIB::dot1dTpFdbAddress.1": mockedCommandResult{stdout: "BRIDGE-MIB::dot1dTpFdbAddress.1\ndot1dTpFdbAddress OBJECT-TYPE\n -- FROM\tBRIDGE-MIB\n -- TEXTUAL CONVENTION MacAddress\n SYNTAX\tOCTET STRING (6) \n DISPLAY-HINT\t\"1x:\"\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n DESCRIPTION\t\"A unicast MAC address for which the bridge has\n forwarding and/or filtering information.\"\n::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) dot1dBridge(17) dot1dTp(4) dot1dTpFdbTable(3) dot1dTpFdbEntry(1) dot1dTpFdbAddress(1) 1 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00BRIDGE-MIB::dot1dTpFdbAddress.1": mockedCommandResult{stdout: "BRIDGE-MIB::dot1dTpFdbAddress.1\ndot1dTpFdbAddress OBJECT-TYPE\n -- FROM\tBRIDGE-MIB\n -- TEXTUAL CONVENTION MacAddress\n SYNTAX\tOCTET STRING (6) \n DISPLAY-HINT\t\"1x:\"\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n DESCRIPTION\t\"A unicast MAC address for which the bridge has\n forwarding and/or filtering information.\"\n::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) dot1dBridge(17) dot1dTp(4) dot1dTpFdbTable(3) dot1dTpFdbEntry(1) dot1dTpFdbAddress(1) 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TCP-MIB::tcpConnectionLocalAddress.1": mockedCommandResult{stdout: "TCP-MIB::tcpConnectionLocalAddress.1\ntcpConnectionLocalAddress OBJECT-TYPE\n -- FROM\tTCP-MIB\n -- TEXTUAL CONVENTION InetAddress\n SYNTAX\tOCTET STRING (0..255) \n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n DESCRIPTION\t\"The local IP address for this TCP connection. The type\n of this address is determined by the value of\n tcpConnectionLocalAddressType.\n\n As this object is used in the index for the\n tcpConnectionTable, implementors should be\n careful not to create entries that would result in OIDs\n with more than 128 subidentifiers; otherwise the information\n cannot be accessed by using SNMPv1, SNMPv2c, or SNMPv3.\"\n::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) tcp(6) tcpConnectionTable(19) tcpConnectionEntry(1) tcpConnectionLocalAddress(2) 1 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00-Ob\x00TCP-MIB::tcpConnectionLocalAddress.1": mockedCommandResult{stdout: "TCP-MIB::tcpConnectionLocalAddress.1\ntcpConnectionLocalAddress OBJECT-TYPE\n -- FROM\tTCP-MIB\n -- TEXTUAL CONVENTION InetAddress\n SYNTAX\tOCTET STRING (0..255) \n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n DESCRIPTION\t\"The local IP address for this TCP connection. The type\n of this address is determined by the value of\n tcpConnectionLocalAddressType.\n\n As this object is used in the index for the\n tcpConnectionTable, implementors should be\n careful not to create entries that would result in OIDs\n with more than 128 subidentifiers; otherwise the information\n cannot be accessed by using SNMPv1, SNMPv2c, or SNMPv3.\"\n::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) tcp(6) tcpConnectionTable(19) tcpConnectionEntry(1) tcpConnectionLocalAddress(2) 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00TEST::testTable.1": mockedCommandResult{stdout: "TEST::testTableEntry\ntestTableEntry OBJECT-TYPE\n -- FROM\tTEST\n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n INDEX\t\t{ server }\n::= { iso(1) 0 testOID(0) testTable(0) 1 }\n", stderr: "", exitError: false}, "snmptranslate\x00-Td\x00TEST::testTable.1": mockedCommandResult{stdout: "TEST::testTableEntry\ntestTableEntry OBJECT-TYPE\n -- FROM\tTEST\n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n INDEX\t\t{ server }\n::= { iso(1) 0 testOID(0) testTable(0) 1 }\n", stderr: "", exitError: false},
"snmptable\x00-Ch\x00-Cl\x00-c\x00public\x00127.0.0.1\x00TEST::testTable": mockedCommandResult{stdout: "server connections latency description \nTEST::testTable: No entries\n", stderr: "", exitError: false}, "snmptable\x00-Ch\x00-Cl\x00-c\x00public\x00127.0.0.1\x00TEST::testTable": mockedCommandResult{stdout: "server connections latency \nTEST::testTable: No entries\n", stderr: "", exitError: false},
} }

View File

@@ -72,7 +72,7 @@ var tsc = &testSNMPConnection{
".1.0.0.0.1.3.1": "0.456", ".1.0.0.0.1.3.1": "0.456",
".1.0.0.0.1.3.2": "0.000", ".1.0.0.0.1.3.2": "0.000",
".1.0.0.0.1.3.3": "9.999", ".1.0.0.0.1.3.3": "9.999",
".1.0.0.0.1.5.0": 123456, ".1.0.0.0.1.4.0": 123456,
".1.0.0.1.1": "baz", ".1.0.0.1.1": "baz",
".1.0.0.1.2": 234, ".1.0.0.1.2": 234,
".1.0.0.1.3": []byte("byte slice"), ".1.0.0.1.3": []byte("byte slice"),
@@ -159,23 +159,19 @@ func TestFieldInit(t *testing.T) {
func TestTableInit(t *testing.T) { func TestTableInit(t *testing.T) {
tbl := Table{ tbl := Table{
Oid: ".1.0.0.0", Oid: ".1.0.0.0",
Fields: []Field{ Fields: []Field{{Oid: ".999", Name: "foo"}},
{Oid: ".999", Name: "foo"},
{Oid: "TEST::description", Name: "description", IsTag: true},
},
} }
err := tbl.init() err := tbl.init()
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "testTable", tbl.Name) assert.Equal(t, "testTable", tbl.Name)
assert.Len(t, tbl.Fields, 5) assert.Len(t, tbl.Fields, 4)
assert.Contains(t, tbl.Fields, Field{Oid: ".999", Name: "foo", initialized: true}) assert.Contains(t, tbl.Fields, Field{Oid: ".999", Name: "foo", initialized: true})
assert.Contains(t, tbl.Fields, Field{Oid: ".1.0.0.0.1.1", Name: "server", IsTag: true, initialized: true}) assert.Contains(t, tbl.Fields, Field{Oid: ".1.0.0.0.1.1", Name: "server", IsTag: true, initialized: true})
assert.Contains(t, tbl.Fields, Field{Oid: ".1.0.0.0.1.2", Name: "connections", initialized: true}) assert.Contains(t, tbl.Fields, Field{Oid: ".1.0.0.0.1.2", Name: "connections", initialized: true})
assert.Contains(t, tbl.Fields, Field{Oid: ".1.0.0.0.1.3", Name: "latency", initialized: true}) assert.Contains(t, tbl.Fields, Field{Oid: ".1.0.0.0.1.3", Name: "latency", initialized: true})
assert.Contains(t, tbl.Fields, Field{Oid: ".1.0.0.0.1.4", Name: "description", IsTag: true, initialized: true})
} }
func TestSnmpInit(t *testing.T) { func TestSnmpInit(t *testing.T) {
@@ -191,11 +187,10 @@ func TestSnmpInit(t *testing.T) {
err := s.init() err := s.init()
require.NoError(t, err) require.NoError(t, err)
assert.Len(t, s.Tables[0].Fields, 4) assert.Len(t, s.Tables[0].Fields, 3)
assert.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.0.0.0.1.1", Name: "server", IsTag: true, initialized: true}) assert.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.0.0.0.1.1", Name: "server", IsTag: true, initialized: true})
assert.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.0.0.0.1.2", Name: "connections", initialized: true}) assert.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.0.0.0.1.2", Name: "connections", initialized: true})
assert.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.0.0.0.1.3", Name: "latency", initialized: true}) assert.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.0.0.0.1.3", Name: "latency", initialized: true})
assert.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.0.0.0.1.4", Name: "description", initialized: true})
assert.Equal(t, Field{ assert.Equal(t, Field{
Oid: ".1.0.0.1.1", Oid: ".1.0.0.1.1",
@@ -584,7 +579,7 @@ func TestGather(t *testing.T) {
Fields: []Field{ Fields: []Field{
{ {
Name: "myOtherField", Name: "myOtherField",
Oid: ".1.0.0.0.1.5", Oid: ".1.0.0.0.1.4",
}, },
}, },
}, },

View File

@@ -22,7 +22,6 @@ TestTableEntry ::=
server OCTET STRING, server OCTET STRING,
connections INTEGER, connections INTEGER,
latency OCTET STRING, latency OCTET STRING,
description OCTET STRING,
} }
server OBJECT-TYPE server OBJECT-TYPE
@@ -43,12 +42,6 @@ latency OBJECT-TYPE
STATUS current STATUS current
::= { testTableEntry 3 } ::= { testTableEntry 3 }
description OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
::= { testTableEntry 4 }
hostname OBJECT-TYPE hostname OBJECT-TYPE
SYNTAX OCTET STRING SYNTAX OCTET STRING
MAX-ACCESS read-only MAX-ACCESS read-only

View File

@@ -3,11 +3,9 @@ package socket_listener
import ( import (
"bytes" "bytes"
"crypto/tls" "crypto/tls"
"io/ioutil"
"log" "log"
"net" "net"
"os" "os"
"path/filepath"
"testing" "testing"
"time" "time"
@@ -52,17 +50,14 @@ func TestSocketListener_tcp_tls(t *testing.T) {
} }
func TestSocketListener_unix_tls(t *testing.T) { func TestSocketListener_unix_tls(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "telegraf") defer testEmptyLog(t)()
require.NoError(t, err)
defer os.RemoveAll(tmpdir)
sock := filepath.Join(tmpdir, "socket_listener.TestSocketListener_unix_tls.sock")
sl := newSocketListener() sl := newSocketListener()
sl.ServiceAddress = "unix://" + sock sl.ServiceAddress = "unix:///tmp/telegraf_test.sock"
sl.ServerConfig = *pki.TLSServerConfig() sl.ServerConfig = *pki.TLSServerConfig()
acc := &testutil.Accumulator{} acc := &testutil.Accumulator{}
err = sl.Start(acc) err := sl.Start(acc)
require.NoError(t, err) require.NoError(t, err)
defer sl.Stop() defer sl.Stop()
@@ -70,7 +65,7 @@ func TestSocketListener_unix_tls(t *testing.T) {
tlsCfg.InsecureSkipVerify = true tlsCfg.InsecureSkipVerify = true
require.NoError(t, err) require.NoError(t, err)
secureClient, err := tls.Dial("unix", sock, tlsCfg) secureClient, err := tls.Dial("unix", "/tmp/telegraf_test.sock", tlsCfg)
require.NoError(t, err) require.NoError(t, err)
testSocketListener(t, sl, secureClient) testSocketListener(t, sl, secureClient)
@@ -113,48 +108,38 @@ func TestSocketListener_udp(t *testing.T) {
} }
func TestSocketListener_unix(t *testing.T) { func TestSocketListener_unix(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "telegraf")
require.NoError(t, err)
defer os.RemoveAll(tmpdir)
sock := filepath.Join(tmpdir, "socket_listener.TestSocketListener_unix.sock")
defer testEmptyLog(t)() defer testEmptyLog(t)()
os.Create(sock) os.Create("/tmp/telegraf_test.sock")
sl := newSocketListener() sl := newSocketListener()
sl.ServiceAddress = "unix://" + sock sl.ServiceAddress = "unix:///tmp/telegraf_test.sock"
sl.ReadBufferSize = 1024 sl.ReadBufferSize = 1024
acc := &testutil.Accumulator{} acc := &testutil.Accumulator{}
err = sl.Start(acc) err := sl.Start(acc)
require.NoError(t, err) require.NoError(t, err)
defer sl.Stop() defer sl.Stop()
client, err := net.Dial("unix", sock) client, err := net.Dial("unix", "/tmp/telegraf_test.sock")
require.NoError(t, err) require.NoError(t, err)
testSocketListener(t, sl, client) testSocketListener(t, sl, client)
} }
func TestSocketListener_unixgram(t *testing.T) { func TestSocketListener_unixgram(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "telegraf")
require.NoError(t, err)
defer os.RemoveAll(tmpdir)
sock := filepath.Join(tmpdir, "socket_listener.TestSocketListener_unixgram.sock")
defer testEmptyLog(t)() defer testEmptyLog(t)()
os.Create(sock) os.Create("/tmp/telegraf_test.sock")
sl := newSocketListener() sl := newSocketListener()
sl.ServiceAddress = "unixgram://" + sock sl.ServiceAddress = "unixgram:///tmp/telegraf_test.sock"
sl.ReadBufferSize = 1024 sl.ReadBufferSize = 1024
acc := &testutil.Accumulator{} acc := &testutil.Accumulator{}
err = sl.Start(acc) err := sl.Start(acc)
require.NoError(t, err) require.NoError(t, err)
defer sl.Stop() defer sl.Stop()
client, err := net.Dial("unixgram", sock) client, err := net.Dial("unixgram", "/tmp/telegraf_test.sock")
require.NoError(t, err) require.NoError(t, err)
testSocketListener(t, sl, client) testSocketListener(t, sl, client)

View File

@@ -5,7 +5,7 @@ The [solr](http://lucene.apache.org/solr/) plugin collects stats via the
More about [performance statistics](https://cwiki.apache.org/confluence/display/solr/Performance+Statistics+Reference) More about [performance statistics](https://cwiki.apache.org/confluence/display/solr/Performance+Statistics+Reference)
Tested from 3.5 to 7.* Tested from 3.5 to 6.*
### Configuration: ### Configuration:

View File

@@ -113,7 +113,20 @@ type Hitratio interface{}
// Cache is an exported type that // Cache is an exported type that
// contains cache metrics // contains cache metrics
type Cache struct { type Cache struct {
Stats map[string]interface{} `json:"stats"` Stats struct {
CumulativeEvictions int64 `json:"cumulative_evictions"`
CumulativeHitratio Hitratio `json:"cumulative_hitratio"`
CumulativeHits int64 `json:"cumulative_hits"`
CumulativeInserts int64 `json:"cumulative_inserts"`
CumulativeLookups int64 `json:"cumulative_lookups"`
Evictions int64 `json:"evictions"`
Hitratio Hitratio `json:"hitratio"`
Hits int64 `json:"hits"`
Inserts int64 `json:"inserts"`
Lookups int64 `json:"lookups"`
Size int64 `json:"size"`
WarmupTime int64 `json:"warmupTime"`
} `json:"stats"`
} }
// NewSolr return a new instance of Solr // NewSolr return a new instance of Solr
@@ -411,30 +424,21 @@ func addCacheMetricsToAcc(acc telegraf.Accumulator, core string, mBeansData *MBe
return err return err
} }
for name, metrics := range cacheMetrics { for name, metrics := range cacheMetrics {
coreFields := make(map[string]interface{}) cumulativeHits := getFloat(metrics.Stats.CumulativeHitratio)
for key, value := range metrics.Stats { hitratio := getFloat(metrics.Stats.Hitratio)
splitKey := strings.Split(key, ".") coreFields := map[string]interface{}{
newKey := splitKey[len(splitKey)-1] "cumulative_evictions": metrics.Stats.CumulativeEvictions,
switch newKey { "cumulative_hitratio": cumulativeHits,
case "cumulative_evictions", "cumulative_hits": metrics.Stats.CumulativeHits,
"cumulative_hits", "cumulative_inserts": metrics.Stats.CumulativeInserts,
"cumulative_inserts", "cumulative_lookups": metrics.Stats.CumulativeLookups,
"cumulative_lookups", "evictions": metrics.Stats.Evictions,
"eviction", "hitratio": hitratio,
"hits", "hits": metrics.Stats.Hits,
"inserts", "inserts": metrics.Stats.Inserts,
"lookups", "lookups": metrics.Stats.Lookups,
"size", "size": metrics.Stats.Size,
"evictions": "warmup_time": metrics.Stats.WarmupTime,
coreFields[newKey] = getInt(value)
case "hitratio",
"cumulative_hitratio":
coreFields[newKey] = getFloat(value)
case "warmupTime":
coreFields["warmup_time"] = getInt(value)
default:
continue
}
} }
acc.AddFields( acc.AddFields(
"solr_cache", "solr_cache",

View File

@@ -43,17 +43,6 @@ func TestGatherStats(t *testing.T) {
map[string]string{"core": "main", "handler": "filterCache"}) map[string]string{"core": "main", "handler": "filterCache"})
} }
func TestSolr7MbeansStats(t *testing.T) {
ts := createMockSolr7Server()
solr := NewSolr()
solr.Servers = []string{ts.URL}
var acc testutil.Accumulator
require.NoError(t, solr.Gather(&acc))
acc.AssertContainsTaggedFields(t, "solr_cache",
solr7CacheExpected,
map[string]string{"core": "main", "handler": "documentCache"})
}
func TestSolr3GatherStats(t *testing.T) { func TestSolr3GatherStats(t *testing.T) {
ts := createMockSolr3Server() ts := createMockSolr3Server()
solr := NewSolr() solr := NewSolr()
@@ -161,18 +150,3 @@ func createMockSolr3Server() *httptest.Server {
} }
})) }))
} }
func createMockSolr7Server() *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.Contains(r.URL.Path, "/solr/admin/cores") {
w.WriteHeader(http.StatusOK)
fmt.Fprintln(w, statusResponse)
} else if strings.Contains(r.URL.Path, "solr/main/admin") {
w.WriteHeader(http.StatusOK)
fmt.Fprintln(w, mBeansSolr7Response)
} else {
w.WriteHeader(http.StatusNotFound)
fmt.Fprintln(w, "nope")
}
}))
}

View File

@@ -1,60 +0,0 @@
package solr
const mBeansSolr7Response = `
{
"responseHeader":{
"status":0,
"QTime":2
},
"solr-mbeans":[
"CORE",
{
},
"QUERYHANDLER",
{
},
"UPDATEHANDLER",
{
},
"CACHE",
{
"documentCache":{
"class":"org.apache.solr.search.LRUCache",
"description":"LRU Cache(maxSize=16384, initialSize=4096)",
"stats":{
"CACHE.searcher.documentCache.evictions": 141485,
"CACHE.searcher.documentCache.cumulative_lookups": 265132,
"CACHE.searcher.documentCache.hitratio": 0.44,
"CACHE.searcher.documentCache.size": 8192,
"CACHE.searcher.documentCache.cumulative_hitratio": 0.42,
"CACHE.searcher.documentCache.lookups": 1234,
"CACHE.searcher.documentCache.warmupTime": 1,
"CACHE.searcher.documentCache.inserts": 987,
"CACHE.searcher.documentCache.hits": 1111,
"CACHE.searcher.documentCache.cumulative_hits": 115364,
"CACHE.searcher.documentCache.cumulative_inserts": 149768,
"CACHE.searcher.documentCache.cumulative_evictions": 141486
}
}
}
]
}
`
var solr7CacheExpected = map[string]interface{}{
"evictions": int64(141485),
"cumulative_evictions": int64(141486),
"cumulative_hitratio": float64(0.42),
"cumulative_hits": int64(115364),
"cumulative_inserts": int64(149768),
"cumulative_lookups": int64(265132),
"hitratio": float64(0.44),
"hits": int64(1111),
"inserts": int64(987),
"lookups": int64(1234),
"size": int64(8192),
"warmup_time": int64(1),
}

View File

@@ -1,98 +0,0 @@
# Syslog Input Plugin
The syslog plugin listens for syslog messages transmitted over
[UDP](https://tools.ietf.org/html/rfc5426) or
[TCP](https://tools.ietf.org/html/rfc5425).
Syslog messages should be formatted according to
[RFC 5424](https://tools.ietf.org/html/rfc5424).
### Configuration
```toml
[[inputs.syslog]]
## Specify an ip or hostname with port - eg., tcp://localhost:6514, tcp://10.0.0.1:6514
## Protocol, address and port to host the syslog receiver.
## If no host is specified, then localhost is used.
## If no port is specified, 6514 is used (RFC5425#section-4.1).
server = "tcp://:6514"
## TLS Config
# tls_allowed_cacerts = ["/etc/telegraf/ca.pem"]
# tls_cert = "/etc/telegraf/cert.pem"
# tls_key = "/etc/telegraf/key.pem"
## Period between keep alive probes.
## 0 disables keep alive probes.
## Defaults to the OS configuration.
## Only applies to stream sockets (e.g. TCP).
# keep_alive_period = "5m"
## Maximum number of concurrent connections (default = 0).
## 0 means unlimited.
## Only applies to stream sockets (e.g. TCP).
# max_connections = 1024
## Read timeout (default = 500ms).
## 0 means unlimited.
# read_timeout = 500ms
## Whether to parse in best effort mode or not (default = false).
## By default best effort parsing is off.
# best_effort = false
## Character to prepend to SD-PARAMs (default = "_").
## A syslog message can contain multiple parameters and multiple identifiers within structured data section.
## Eg., [id1 name1="val1" name2="val2"][id2 name1="val1" nameA="valA"]
## For each combination a field is created.
## Its name is created concatenating identifier, sdparam_separator, and parameter name.
# sdparam_separator = "_"
```
#### Best Effort
The [`best_effort`](https://github.com/influxdata/go-syslog#best-effort-mode)
option instructs the parser to extract partial but valid info from syslog
messages. If unset only full messages will be collected.
### Metrics
- syslog
- tags
- severity (string)
- facility (string)
- hostname (string)
- appname (string)
- fields
- version (integer)
- severity_code (integer)
- facility_code (integer)
- timestamp (integer)
- procid (string)
- msgid (string)
- sdid (bool)
- *Structured Data* (string)
### Rsyslog Integration
Rsyslog can be configured to forward logging messages to Telegraf by configuring
[remote logging](https://www.rsyslog.com/doc/v8-stable/configuration/actions.html#remote-machine).
Most system are setup with a configuration split between `/etc/rsyslog.conf`
and the files in the `/etc/rsyslog.d/` directory, it is recommended to add the
new configuration into the config directory to simplify updates to the main
config file.
Add the following lines to `/etc/rsyslog.d/50-telegraf.conf` making
adjustments to the target address as needed:
```
$ActionQueueType LinkedList # use asynchronous processing
$ActionQueueFileName srvrfwd # set file name, also enables disk mode
$ActionResumeRetryCount -1 # infinite retries on insert failure
$ActionQueueSaveOnShutdown on # save in-memory data if rsyslog shuts down
# forward over tcp with octet framing according to RFC 5425
*.* @@(o)127.0.0.1:6514;RSYSLOG_SyslogProtocol23Format
```
To complete TLS setup please refer to [rsyslog docs](https://www.rsyslog.com/doc/v8-stable/tutorials/tls.html).

Some files were not shown because too many files have changed in this diff Show More