Compare commits
113 Commits
ga-azure-m
...
bugfix/433
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f4bd9ad82 | ||
|
|
4ea618ea26 | ||
|
|
a7545e6cac | ||
|
|
58e815fdd1 | ||
|
|
06682c6350 | ||
|
|
839ca60b0e | ||
|
|
9fe90d71f4 | ||
|
|
2ee374cf50 | ||
|
|
220e6c5361 | ||
|
|
c7cfc2ec39 | ||
|
|
9bc63c2f7a | ||
|
|
56ea2eb57b | ||
|
|
210dfcee83 | ||
|
|
b7a02c73b3 | ||
|
|
73e2e6afc5 | ||
|
|
b2586a7eaf | ||
|
|
abfbf4f4f2 | ||
|
|
85eacf268b | ||
|
|
1a781a5851 | ||
|
|
ed2bc1151b | ||
|
|
b2e972cd81 | ||
|
|
54056f3808 | ||
|
|
5aa199e2b3 | ||
|
|
9bd5e10133 | ||
|
|
beaef8e3da | ||
|
|
a10262c5d6 | ||
|
|
8bf18d6ac7 | ||
|
|
23523ffd10 | ||
|
|
523d761f34 | ||
|
|
3f28add025 | ||
|
|
ee6e4b0afd | ||
|
|
16454e25ba | ||
|
|
2a1feb6db9 | ||
|
|
61e197d254 | ||
|
|
1bd41ef3ce | ||
|
|
d7c756e9ff | ||
|
|
39206677f8 | ||
|
|
b66eb2fec7 | ||
|
|
3ad10283ef | ||
|
|
84e9a5c97e | ||
|
|
c98b58dacc | ||
|
|
98d86df797 | ||
|
|
4e9e57e210 | ||
|
|
7781507c01 | ||
|
|
8482c40a91 | ||
|
|
0dda9b8319 | ||
|
|
4e69d10ff7 | ||
|
|
f689463e8e | ||
|
|
f217d12de5 | ||
|
|
886795063e | ||
|
|
30dc95fa78 | ||
|
|
40fac0a9b4 | ||
|
|
36df4c5ae5 | ||
|
|
70ffed3a4d | ||
|
|
bf59bcf721 | ||
|
|
a789f97feb | ||
|
|
d2e00a3205 | ||
|
|
daddd8bbac | ||
|
|
d16530677d | ||
|
|
1ea18ffd0a | ||
|
|
dd2223ae1c | ||
|
|
90eebd88af | ||
|
|
d2e729dfaf | ||
|
|
f64d612294 | ||
|
|
76ec90e66d | ||
|
|
1690f36b09 | ||
|
|
87f711a19a | ||
|
|
58895d6b03 | ||
|
|
cd9ad77038 | ||
|
|
8563238059 | ||
|
|
11335f5fee | ||
|
|
acba20af1a | ||
|
|
229b6bd944 | ||
|
|
7fe6e2f5ae | ||
|
|
a4214abfc4 | ||
|
|
5f0cbd1255 | ||
|
|
3ef4dff4ec | ||
|
|
dfe7b5eec2 | ||
|
|
92a8f795f5 | ||
|
|
b1d77ade55 | ||
|
|
7103077b3f | ||
|
|
7332ce0e95 | ||
|
|
2be32f0a80 | ||
|
|
701e157ef0 | ||
|
|
eb94bb29fd | ||
|
|
449bd5c3b9 | ||
|
|
96abff0660 | ||
|
|
9eab3572ff | ||
|
|
be8b87000c | ||
|
|
ff93c3c326 | ||
|
|
df1fe7a2b4 | ||
|
|
a04cfee349 | ||
|
|
da6ad34fc8 | ||
|
|
179bcfdcbb | ||
|
|
e3f1d28908 | ||
|
|
fcea745e99 | ||
|
|
90bcb5bc3c | ||
|
|
312116c101 | ||
|
|
2cc2913d81 | ||
|
|
b556eb8b2f | ||
|
|
8b28f40cc0 | ||
|
|
cabee8f8e0 | ||
|
|
e0071f365a | ||
|
|
5ae2b02f5d | ||
|
|
59f0a5354f | ||
|
|
c8b68430f0 | ||
|
|
1ac64596bf | ||
|
|
b78984554c | ||
|
|
2def31bc3d | ||
|
|
010e4f5b0b | ||
|
|
ce3b367dac | ||
|
|
f3f753310f | ||
|
|
50d721ae05 |
@@ -2,15 +2,12 @@
|
||||
defaults:
|
||||
defaults: &defaults
|
||||
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
|
||||
docker:
|
||||
- image: 'circleci/golang:1.9.5'
|
||||
- image: 'circleci/golang:1.9.7'
|
||||
go-1_10: &go-1_10
|
||||
docker:
|
||||
- image: 'circleci/golang:1.10.1'
|
||||
- image: 'circleci/golang:1.10.3'
|
||||
|
||||
version: 2
|
||||
jobs:
|
||||
@@ -18,17 +15,18 @@ jobs:
|
||||
<<: [ *defaults, *go-1_10 ]
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
key: vendor-{{ checksum "Gopkg.lock" }}
|
||||
- run: 'make deps'
|
||||
- save_cache:
|
||||
name: 'vendored deps'
|
||||
key: vendor-{{ checksum "Gopkg.lock" }}
|
||||
paths:
|
||||
- './vendor'
|
||||
- persist_to_workspace:
|
||||
root: '/go/src'
|
||||
paths:
|
||||
- '*'
|
||||
test-go-1.8:
|
||||
<<: [ *defaults, *go-1_8 ]
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: '/go/src'
|
||||
- run: 'make test-ci'
|
||||
test-go-1.9:
|
||||
<<: [ *defaults, *go-1_9 ]
|
||||
steps:
|
||||
@@ -66,9 +64,6 @@ workflows:
|
||||
build_and_release:
|
||||
jobs:
|
||||
- 'deps'
|
||||
- 'test-go-1.8':
|
||||
requires:
|
||||
- 'deps'
|
||||
- 'test-go-1.9':
|
||||
requires:
|
||||
- 'deps'
|
||||
@@ -77,15 +72,11 @@ workflows:
|
||||
- 'deps'
|
||||
- 'release':
|
||||
requires:
|
||||
- 'test-go-1.8'
|
||||
- 'test-go-1.9'
|
||||
- 'test-go-1.10'
|
||||
nightly:
|
||||
jobs:
|
||||
- 'deps'
|
||||
- 'test-go-1.8':
|
||||
requires:
|
||||
- 'deps'
|
||||
- 'test-go-1.9':
|
||||
requires:
|
||||
- 'deps'
|
||||
@@ -94,7 +85,6 @@ workflows:
|
||||
- 'deps'
|
||||
- 'nightly':
|
||||
requires:
|
||||
- 'test-go-1.8'
|
||||
- 'test-go-1.9'
|
||||
- 'test-go-1.10'
|
||||
triggers:
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@
|
||||
/telegraf
|
||||
/telegraf.exe
|
||||
/telegraf.gz
|
||||
/vendor
|
||||
|
||||
64
CHANGELOG.md
64
CHANGELOG.md
@@ -1,4 +1,45 @@
|
||||
## v1.7 [unreleased]
|
||||
## v1.8 [unreleased]
|
||||
|
||||
### Release Notes
|
||||
|
||||
### New Inputs
|
||||
|
||||
- [tengine](./plugins/inputs/tengine/README.md) - Contributed by @ertaoxu
|
||||
|
||||
### 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.
|
||||
|
||||
## v1.7.1 [unreleased]
|
||||
|
||||
### 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.
|
||||
|
||||
## v1.7 [2018-06-12]
|
||||
|
||||
### Release Notes
|
||||
|
||||
@@ -19,6 +60,7 @@
|
||||
- [jti_openconfig_telemetry](./plugins/inputs/jti_openconfig_telemetry/README.md) - Contributed by @ajhai
|
||||
- [mcrouter](./plugins/inputs/mcrouter/README.md) - Contributed by @cthayer
|
||||
- [nvidia_smi](./plugins/inputs/nvidia_smi/README.md) - Contributed by @jackzampolin
|
||||
- [syslog](./plugins/inputs/syslog/README.md) - Contributed by @influxdata
|
||||
|
||||
### New Processors
|
||||
|
||||
@@ -56,6 +98,12 @@
|
||||
- [#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.
|
||||
- [#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
|
||||
|
||||
@@ -63,6 +111,20 @@
|
||||
- [#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.
|
||||
- [#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]
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
1. `go get github.com/sparrc/gdm`
|
||||
1. `gdm restore`
|
||||
1. `GOOS=linux gdm save`
|
||||
1. `go get -u github.com/golang/dep/cmd/dep`
|
||||
2. `dep ensure`
|
||||
3. `dep ensure -add github.com/[dependency]/[new-package]`
|
||||
|
||||
## Input Plugins
|
||||
|
||||
@@ -100,6 +100,13 @@ 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
|
||||
|
||||
In addition the the `AddFields` function, the accumulator also supports an
|
||||
|
||||
101
Godeps
101
Godeps
@@ -1,101 +0,0 @@
|
||||
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
Normal file
973
Gopkg.lock
generated
Normal file
@@ -0,0 +1,973 @@
|
||||
# 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
|
||||
243
Gopkg.toml
Normal file
243
Gopkg.toml
Normal file
@@ -0,0 +1,243 @@
|
||||
[[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"
|
||||
29
Makefile
29
Makefile
@@ -23,8 +23,8 @@ all:
|
||||
|
||||
deps:
|
||||
go get -u github.com/golang/lint/golint
|
||||
go get github.com/sparrc/gdm
|
||||
gdm restore --parallel=false
|
||||
go get -u github.com/golang/dep/cmd/dep
|
||||
dep ensure
|
||||
|
||||
telegraf:
|
||||
go build -ldflags "$(LDFLAGS)" ./cmd/telegraf
|
||||
@@ -34,7 +34,7 @@ go-install:
|
||||
|
||||
install: telegraf
|
||||
mkdir -p $(DESTDIR)$(PREFIX)/bin/
|
||||
cp $(TELEGRAF) $(DESTDIR)$(PREFIX)/bin/
|
||||
cp telegraf $(DESTDIR)$(PREFIX)/bin/
|
||||
|
||||
test:
|
||||
go test -short ./...
|
||||
@@ -54,11 +54,11 @@ fmtcheck:
|
||||
@echo '[INFO] done.'
|
||||
|
||||
test-windows:
|
||||
go test ./plugins/inputs/ping/...
|
||||
go test ./plugins/inputs/win_perf_counters/...
|
||||
go test ./plugins/inputs/win_services/...
|
||||
go test ./plugins/inputs/procstat/...
|
||||
go test ./plugins/inputs/ntpq/...
|
||||
go test -short ./plugins/inputs/ping/...
|
||||
go test -short ./plugins/inputs/win_perf_counters/...
|
||||
go test -short ./plugins/inputs/win_services/...
|
||||
go test -short ./plugins/inputs/procstat/...
|
||||
go test -short ./plugins/inputs/ntpq/...
|
||||
|
||||
# vet runs the Go source code static analysis tool `vet` to find
|
||||
# any common errors.
|
||||
@@ -92,4 +92,15 @@ docker-image:
|
||||
plugins/parsers/influx/machine.go: plugins/parsers/influx/machine.go.rl
|
||||
ragel -Z -G2 $^ -o $@
|
||||
|
||||
.PHONY: deps telegraf install test test-windows lint vet test-all package clean docker-image fmtcheck uint64
|
||||
static:
|
||||
@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
|
||||
|
||||
@@ -40,9 +40,9 @@ Ansible role: https://github.com/rossmcdonald/telegraf
|
||||
|
||||
### From Source:
|
||||
|
||||
Telegraf requires golang version 1.8+, the Makefile requires GNU make.
|
||||
Telegraf requires golang version 1.9 or newer, the Makefile requires GNU make.
|
||||
|
||||
Dependencies are managed with [gdm](https://github.com/sparrc/gdm),
|
||||
Dependencies are managed with [dep](https://github.com/golang/dep),
|
||||
which is installed by the Makefile if you don't have it already.
|
||||
|
||||
1. [Install Go](https://golang.org/doc/install)
|
||||
@@ -211,7 +211,9 @@ configuration options.
|
||||
* [snmp_legacy](./plugins/inputs/snmp_legacy)
|
||||
* [solr](./plugins/inputs/solr)
|
||||
* [sql server](./plugins/inputs/sqlserver) (microsoft)
|
||||
* [syslog](./plugins/inputs/syslog)
|
||||
* [teamspeak](./plugins/inputs/teamspeak)
|
||||
* [tengine](./plugins/inputs/tengine)
|
||||
* [tomcat](./plugins/inputs/tomcat)
|
||||
* [twemproxy](./plugins/inputs/twemproxy)
|
||||
* [unbound](./plugins/inputs/unbound)
|
||||
@@ -280,6 +282,7 @@ formats may be used with input plugins supporting the `data_format` option:
|
||||
* [basicstats](./plugins/aggregators/basicstats)
|
||||
* [minmax](./plugins/aggregators/minmax)
|
||||
* [histogram](./plugins/aggregators/histogram)
|
||||
* [valuecounter](./plugins/aggregators/valuecounter)
|
||||
|
||||
## Output Plugins
|
||||
|
||||
|
||||
@@ -362,24 +362,6 @@ func (a *Agent) Run(shutdown chan struct{}) error {
|
||||
metricC := 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
|
||||
if a.Config.Agent.RoundInterval {
|
||||
i := int64(a.Config.Agent.Interval.Duration)
|
||||
@@ -419,6 +401,25 @@ func (a *Agent) Run(shutdown chan struct{}) error {
|
||||
}(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()
|
||||
a.Close()
|
||||
return nil
|
||||
|
||||
@@ -21,6 +21,7 @@ install:
|
||||
- 7z x "C:\Cache\gnuwin32-dep.zip" -oC:\GnuWin32 -y
|
||||
- go version
|
||||
- go env
|
||||
- git config --system core.longpaths true
|
||||
|
||||
build_script:
|
||||
- cmd: C:\GnuWin32\bin\make deps
|
||||
|
||||
@@ -58,7 +58,7 @@ var fService = flag.String("service", "",
|
||||
var fRunAsConsole = flag.Bool("console", false, "run as console application (windows only)")
|
||||
|
||||
var (
|
||||
nextVersion = "1.7.0"
|
||||
nextVersion = "1.8.0"
|
||||
version string
|
||||
commit string
|
||||
branch string
|
||||
@@ -147,11 +147,11 @@ func reloadLoop(
|
||||
|
||||
shutdown := make(chan struct{})
|
||||
signals := make(chan os.Signal)
|
||||
signal.Notify(signals, os.Interrupt, syscall.SIGHUP)
|
||||
signal.Notify(signals, os.Interrupt, syscall.SIGHUP, syscall.SIGTERM)
|
||||
go func() {
|
||||
select {
|
||||
case sig := <-signals:
|
||||
if sig == os.Interrupt {
|
||||
if sig == os.Interrupt || sig == syscall.SIGTERM {
|
||||
close(shutdown)
|
||||
}
|
||||
if sig == syscall.SIGHUP {
|
||||
@@ -166,8 +166,10 @@ func reloadLoop(
|
||||
}()
|
||||
|
||||
log.Printf("I! Starting Telegraf %s\n", displayVersion())
|
||||
log.Printf("I! Loaded outputs: %s", strings.Join(c.OutputNames(), " "))
|
||||
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! Tags enabled: %s", c.ListTags())
|
||||
|
||||
if *fPidfile != "" {
|
||||
|
||||
@@ -44,6 +44,7 @@ following works:
|
||||
- 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/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/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)
|
||||
|
||||
@@ -158,30 +158,74 @@
|
||||
# # timeout = "5s"
|
||||
|
||||
|
||||
# # Configuration for the AMQP server to send metrics to
|
||||
# # Publishes metrics to an AMQP broker
|
||||
# [[outputs.amqp]]
|
||||
# ## AMQP url
|
||||
# url = "amqp://localhost:5672/influxdb"
|
||||
# ## AMQP exchange
|
||||
# ## Broker to publish to.
|
||||
# ## deprecated in 1.7; use the brokers option
|
||||
# # url = "amqp://localhost:5672/influxdb"
|
||||
#
|
||||
# ## 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 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
|
||||
# ## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
|
||||
# ## described here: https://www.rabbitmq.com/plugins.html
|
||||
# # 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"
|
||||
#
|
||||
# ## InfluxDB retention policy
|
||||
# # retention_policy = "default"
|
||||
# ## InfluxDB database
|
||||
# ## Metric tag to use as a routing key.
|
||||
# ## ie, if this tag exists, its value will be used as the routing key
|
||||
# # routing_tag = "host"
|
||||
#
|
||||
# ## 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"
|
||||
#
|
||||
# ## Write timeout, formatted as a string. If not provided, will default
|
||||
# ## to 5s. 0s means no timeout (not recommended).
|
||||
# ## InfluxDB retention policy added as a message header
|
||||
# ## deprecated in 1.7; use the headers option
|
||||
# # 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"
|
||||
#
|
||||
# ## Optional TLS Config
|
||||
@@ -191,11 +235,16 @@
|
||||
# ## Use TLS but skip chain & host verification
|
||||
# # 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.
|
||||
# ## Each data format has its own unique set of configuration options, read
|
||||
# ## more about them here:
|
||||
# ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md
|
||||
# data_format = "influx"
|
||||
# # data_format = "influx"
|
||||
|
||||
|
||||
# # Send metrics to Azure Application Insights
|
||||
@@ -344,6 +393,10 @@
|
||||
# ## Graphite output template
|
||||
# ## see https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md
|
||||
# template = "host.tags.measurement.field"
|
||||
#
|
||||
# ## Enable Graphite tags support
|
||||
# # graphite_tag_support = false
|
||||
#
|
||||
# ## timeout in seconds for the write connection to graphite
|
||||
# timeout = 2
|
||||
#
|
||||
@@ -376,11 +429,6 @@
|
||||
# # username = "username"
|
||||
# # 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
|
||||
# # tls_ca = "/etc/telegraf/ca.pem"
|
||||
# # tls_cert = "/etc/telegraf/cert.pem"
|
||||
@@ -393,6 +441,11 @@
|
||||
# ## more about them here:
|
||||
# ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md
|
||||
# # 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
|
||||
@@ -670,6 +723,10 @@
|
||||
# ## Not used with telnet API.
|
||||
# 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 = false
|
||||
#
|
||||
@@ -825,6 +882,34 @@
|
||||
# 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.
|
||||
# [[processors.override]]
|
||||
# ## All modifications on inputs and aggregators can be overridden:
|
||||
@@ -841,6 +926,36 @@
|
||||
# [[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.
|
||||
# [[processors.topk]]
|
||||
# ## How many seconds between aggregations
|
||||
@@ -966,7 +1081,7 @@
|
||||
# mount_points = ["/"]
|
||||
|
||||
## Ignore mount points by filesystem type.
|
||||
ignore_fs = ["tmpfs", "devtmpfs", "devfs"]
|
||||
ignore_fs = ["tmpfs", "devtmpfs", "devfs", "overlay", "aufs", "squashfs"]
|
||||
|
||||
|
||||
# Read metrics about disk IO by device
|
||||
@@ -1027,6 +1142,17 @@
|
||||
# ## This plugin will query all namespaces the aerospike
|
||||
# ## server has configured and get stats for them.
|
||||
# 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)
|
||||
@@ -1051,6 +1177,32 @@
|
||||
# # 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
|
||||
# [[inputs.bcache]]
|
||||
# ## Bcache sets path
|
||||
@@ -1075,6 +1227,49 @@
|
||||
# # 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.
|
||||
# [[inputs.ceph]]
|
||||
# ## This is the recommended interval to poll. Too frequent and you will lose
|
||||
@@ -2596,6 +2791,9 @@
|
||||
# ## Remove numbers from field names.
|
||||
# ## If true, a field name like 'temp1_input' will be changed to 'temp_input'.
|
||||
# # 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.
|
||||
@@ -2947,23 +3145,27 @@
|
||||
# pools = ["redis_pool", "mc_pool"]
|
||||
|
||||
|
||||
# # A plugin to collect stats from Unbound - a validating, recursive, and caching DNS resolver
|
||||
# # A plugin to collect stats from the Unbound DNS resolver
|
||||
# [[inputs.unbound]]
|
||||
# ## If running as a restricted user you can prepend sudo for additional access:
|
||||
# #use_sudo = false
|
||||
#
|
||||
# ## The default location of the unbound-control binary can be overridden with:
|
||||
# binary = "/usr/sbin/unbound-control"
|
||||
#
|
||||
# ## The default timeout of 1s can be overriden with:
|
||||
# timeout = "1s"
|
||||
#
|
||||
# ## Use the builtin fielddrop/fieldpass telegraf filters in order to keep/remove specific fields
|
||||
# fieldpass = ["total_*", "num_*","time_up", "mem_*"]
|
||||
#
|
||||
# ## IP of server to connect to, read from unbound conf default, optionally ':port'
|
||||
# ## 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:
|
||||
# # use_sudo = false
|
||||
#
|
||||
# ## The default location of the unbound-control binary can be overridden with:
|
||||
# # binary = "/usr/sbin/unbound-control"
|
||||
#
|
||||
# ## The default timeout of 1s can be overriden with:
|
||||
# # timeout = "1s"
|
||||
#
|
||||
# ## When set to true, thread metrics are tagged with the thread id.
|
||||
# ##
|
||||
# ## 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
|
||||
# ## deployments.
|
||||
# thread_as_tag = false
|
||||
|
||||
|
||||
# # A plugin to collect stats from Varnish HTTP Cache
|
||||
@@ -2982,7 +3184,7 @@
|
||||
#
|
||||
# ## Optional name for the varnish instance (or working directory) to query
|
||||
# ## Usually appened after -n in varnish cli
|
||||
# #name = instanceName
|
||||
# # instance_name = instanceName
|
||||
|
||||
|
||||
# # Read metrics of ZFS from arcstats, zfetchstats, vdev_cache_stats, and pools
|
||||
@@ -3029,17 +3231,43 @@
|
||||
|
||||
# # AMQP consumer plugin
|
||||
# [[inputs.amqp_consumer]]
|
||||
# ## AMQP url
|
||||
# url = "amqp://localhost:5672/influxdb"
|
||||
# ## AMQP exchange
|
||||
# ## Broker to consume from.
|
||||
# ## deprecated in 1.7; use the brokers option
|
||||
# # url = "amqp://localhost:5672/influxdb"
|
||||
#
|
||||
# ## 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 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
|
||||
# queue = "telegraf"
|
||||
#
|
||||
# ## Binding Key
|
||||
# binding_key = "#"
|
||||
#
|
||||
# ## Maximum number of messages server should give to the worker.
|
||||
# prefetch_count = 50
|
||||
# # prefetch_count = 50
|
||||
#
|
||||
# ## Auth method. PLAIN and EXTERNAL are supported
|
||||
# ## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
|
||||
@@ -3560,6 +3788,46 @@
|
||||
# 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
|
||||
# [[inputs.tail]]
|
||||
# ## files to tail.
|
||||
|
||||
@@ -242,7 +242,7 @@
|
||||
#
|
||||
# ## Ignore some mountpoints by filesystem type. For example (dev)tmpfs (usually
|
||||
# ## present on /run, /var/run, /dev/shm or /dev).
|
||||
# # ignore_fs = ["tmpfs", "devtmpfs"]
|
||||
# # ignore_fs = ["tmpfs", "devtmpfs", "devfs", "overlay", "aufs", "squashfs"]
|
||||
|
||||
|
||||
# # Read metrics about disk IO by device
|
||||
|
||||
@@ -156,6 +156,24 @@ func (c *Config) InputNames() []string {
|
||||
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.
|
||||
func (c *Config) OutputNames() []string {
|
||||
var name []string
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
"unicode"
|
||||
)
|
||||
@@ -193,3 +194,15 @@ func RandomSleep(max time.Duration, shutdown chan struct{}) {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
@@ -153,6 +154,7 @@ func (r *RunningAggregator) Run(
|
||||
m.Time().After(r.periodEnd.Add(truncation).Add(r.Config.Delay)) {
|
||||
// the metric is outside the current aggregation period, so
|
||||
// skip it.
|
||||
log.Printf("D! aggregator: metric \"%s\" is not in the current timewindow, skipping", m.Name())
|
||||
continue
|
||||
}
|
||||
r.add(m)
|
||||
|
||||
@@ -113,11 +113,6 @@ func (ro *RunningOutput) AddMetric(m telegraf.Metric) {
|
||||
m, _ = metric.New(name, tags, fields, t)
|
||||
}
|
||||
|
||||
if output, ok := ro.Output.(telegraf.AggregatingOutput); ok {
|
||||
output.Add(m)
|
||||
return
|
||||
}
|
||||
|
||||
ro.metrics.Add(m)
|
||||
if ro.metrics.Len() == ro.MetricBatchSize {
|
||||
batch := ro.metrics.Batch(ro.MetricBatchSize)
|
||||
@@ -130,12 +125,6 @@ func (ro *RunningOutput) AddMetric(m telegraf.Metric) {
|
||||
|
||||
// Write writes all cached points to this output.
|
||||
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()
|
||||
ro.BufferSize.Set(int64(nFails + nMetrics))
|
||||
log.Printf("D! Output [%s] buffer fullness: %d / %d metrics. ",
|
||||
|
||||
@@ -17,7 +17,7 @@ type ClientConfig struct {
|
||||
// Deprecated in 1.7; use TLS variables above
|
||||
SSLCA string `toml:"ssl_ca"`
|
||||
SSLCert string `toml:"ssl_cert"`
|
||||
SSLKey string `toml:"ssl_ca"`
|
||||
SSLKey string `toml:"ssl_key"`
|
||||
}
|
||||
|
||||
// ServerConfig represents the standard server TLS config.
|
||||
|
||||
@@ -13,12 +13,6 @@ type Output interface {
|
||||
Write(metrics []Metric) error
|
||||
}
|
||||
|
||||
type AggregatingOutput interface {
|
||||
Add(in Metric)
|
||||
Push() []Metric
|
||||
Reset()
|
||||
}
|
||||
|
||||
type ServiceOutput interface {
|
||||
// Connect to the Output
|
||||
Connect() error
|
||||
|
||||
@@ -4,4 +4,5 @@ import (
|
||||
_ "github.com/influxdata/telegraf/plugins/aggregators/basicstats"
|
||||
_ "github.com/influxdata/telegraf/plugins/aggregators/histogram"
|
||||
_ "github.com/influxdata/telegraf/plugins/aggregators/minmax"
|
||||
_ "github.com/influxdata/telegraf/plugins/aggregators/valuecounter"
|
||||
)
|
||||
|
||||
@@ -246,6 +246,8 @@ func convert(in interface{}) (float64, bool) {
|
||||
return v, true
|
||||
case int64:
|
||||
return float64(v), true
|
||||
case uint64:
|
||||
return float64(v), true
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ var m2, _ = metric.New("m1",
|
||||
"c": float64(4),
|
||||
"d": float64(6),
|
||||
"e": float64(200),
|
||||
"f": uint64(200),
|
||||
"ignoreme": "string",
|
||||
"andme": true,
|
||||
},
|
||||
@@ -81,6 +82,10 @@ func TestBasicStatsWithPeriod(t *testing.T) {
|
||||
"e_max": float64(200),
|
||||
"e_min": 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{
|
||||
"foo": "bar",
|
||||
@@ -144,6 +149,10 @@ func TestBasicStatsDifferentPeriods(t *testing.T) {
|
||||
"e_max": float64(200),
|
||||
"e_min": 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{
|
||||
"foo": "bar",
|
||||
@@ -169,6 +178,7 @@ func TestBasicStatsWithOnlyCount(t *testing.T) {
|
||||
"c_count": float64(2),
|
||||
"d_count": float64(2),
|
||||
"e_count": float64(1),
|
||||
"f_count": float64(1),
|
||||
}
|
||||
expectedTags := map[string]string{
|
||||
"foo": "bar",
|
||||
@@ -194,6 +204,7 @@ func TestBasicStatsWithOnlyMin(t *testing.T) {
|
||||
"c_min": float64(2),
|
||||
"d_min": float64(2),
|
||||
"e_min": float64(200),
|
||||
"f_min": float64(200),
|
||||
}
|
||||
expectedTags := map[string]string{
|
||||
"foo": "bar",
|
||||
@@ -219,6 +230,7 @@ func TestBasicStatsWithOnlyMax(t *testing.T) {
|
||||
"c_max": float64(4),
|
||||
"d_max": float64(6),
|
||||
"e_max": float64(200),
|
||||
"f_max": float64(200),
|
||||
}
|
||||
expectedTags := map[string]string{
|
||||
"foo": "bar",
|
||||
@@ -244,6 +256,7 @@ func TestBasicStatsWithOnlyMean(t *testing.T) {
|
||||
"c_mean": float64(3),
|
||||
"d_mean": float64(4),
|
||||
"e_mean": float64(200),
|
||||
"f_mean": float64(200),
|
||||
}
|
||||
expectedTags := map[string]string{
|
||||
"foo": "bar",
|
||||
@@ -269,6 +282,7 @@ func TestBasicStatsWithOnlySum(t *testing.T) {
|
||||
"c_sum": float64(6),
|
||||
"d_sum": float64(8),
|
||||
"e_sum": float64(200),
|
||||
"f_sum": float64(200),
|
||||
}
|
||||
expectedTags := map[string]string{
|
||||
"foo": "bar",
|
||||
@@ -399,6 +413,8 @@ func TestBasicStatsWithMinAndMax(t *testing.T) {
|
||||
"d_min": float64(2),
|
||||
"e_max": float64(200), //e
|
||||
"e_min": float64(200),
|
||||
"f_max": float64(200), //f
|
||||
"f_min": float64(200),
|
||||
}
|
||||
expectedTags := map[string]string{
|
||||
"foo": "bar",
|
||||
@@ -450,6 +466,11 @@ func TestBasicStatsWithAllStats(t *testing.T) {
|
||||
"e_min": float64(200),
|
||||
"e_mean": 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{
|
||||
"foo": "bar",
|
||||
|
||||
@@ -107,6 +107,8 @@ func convert(in interface{}) (float64, bool) {
|
||||
return v, true
|
||||
case int64:
|
||||
return float64(v), true
|
||||
case uint64:
|
||||
return float64(v), true
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ var m2, _ = metric.New("m1",
|
||||
"i": float64(1),
|
||||
"j": float64(1),
|
||||
"k": float64(200),
|
||||
"l": uint64(200),
|
||||
"ignoreme": "string",
|
||||
"andme": true,
|
||||
},
|
||||
@@ -85,6 +86,8 @@ func TestMinMaxWithPeriod(t *testing.T) {
|
||||
"j_min": float64(1),
|
||||
"k_max": float64(200),
|
||||
"k_min": float64(200),
|
||||
"l_max": float64(200),
|
||||
"l_min": float64(200),
|
||||
}
|
||||
expectedTags := map[string]string{
|
||||
"foo": "bar",
|
||||
@@ -154,6 +157,8 @@ func TestMinMaxDifferentPeriods(t *testing.T) {
|
||||
"j_min": float64(1),
|
||||
"k_max": float64(200),
|
||||
"k_min": float64(200),
|
||||
"l_max": float64(200),
|
||||
"l_min": float64(200),
|
||||
}
|
||||
expectedTags = map[string]string{
|
||||
"foo": "bar",
|
||||
|
||||
73
plugins/aggregators/valuecounter/README.md
Normal file
73
plugins/aggregators/valuecounter/README.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 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
|
||||
```
|
||||
108
plugins/aggregators/valuecounter/valuecounter.go
Normal file
108
plugins/aggregators/valuecounter/valuecounter.go
Normal file
@@ -0,0 +1,108 @@
|
||||
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()
|
||||
})
|
||||
}
|
||||
126
plugins/aggregators/valuecounter/valuecounter_test.go
Normal file
126
plugins/aggregators/valuecounter/valuecounter_test.go
Normal file
@@ -0,0 +1,126 @@
|
||||
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)
|
||||
}
|
||||
@@ -97,11 +97,13 @@ import (
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/solr"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/sqlserver"
|
||||
_ "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/system"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/tail"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/tcp_listener"
|
||||
_ "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/trig"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/twemproxy"
|
||||
|
||||
@@ -15,23 +15,48 @@ The following defaults are known to work with RabbitMQ:
|
||||
```toml
|
||||
# AMQP consumer plugin
|
||||
[[inputs.amqp_consumer]]
|
||||
## AMQP url
|
||||
url = "amqp://localhost:5672/influxdb"
|
||||
## AMQP exchange
|
||||
## Broker to consume from.
|
||||
## deprecated in 1.7; use the brokers option
|
||||
# url = "amqp://localhost:5672/influxdb"
|
||||
|
||||
## 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 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
|
||||
queue = "telegraf"
|
||||
## Binding Key
|
||||
binding_key = "#"
|
||||
|
||||
## Controls how many messages the server will try to keep on the network
|
||||
## for consumers before receiving delivery acks.
|
||||
#prefetch_count = 50
|
||||
## Maximum number of messages server should give to the worker.
|
||||
# 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
|
||||
## described here: https://www.rabbitmq.com/plugins.html
|
||||
# auth_method = "PLAIN"
|
||||
|
||||
## Optional TLS Config
|
||||
# tls_ca = "/etc/telegraf/ca.pem"
|
||||
# tls_cert = "/etc/telegraf/cert.pem"
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package amqp_consumer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -17,9 +19,16 @@ import (
|
||||
|
||||
// AMQPConsumer is the top level struct for this plugin
|
||||
type AMQPConsumer struct {
|
||||
URL string
|
||||
// AMQP exchange
|
||||
Exchange string
|
||||
URL string `toml:"url"` // deprecated in 1.7; use brokers
|
||||
Brokers []string `toml:"brokers"`
|
||||
Username string `toml:"username"`
|
||||
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 string
|
||||
// Binding Key
|
||||
@@ -48,23 +57,55 @@ func (a *externalAuth) Response() string {
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultAuthMethod = "PLAIN"
|
||||
DefaultAuthMethod = "PLAIN"
|
||||
|
||||
DefaultBroker = "amqp://localhost:5672/influxdb"
|
||||
|
||||
DefaultExchangeType = "topic"
|
||||
DefaultExchangeDurability = "durable"
|
||||
|
||||
DefaultPrefetchCount = 50
|
||||
)
|
||||
|
||||
func (a *AMQPConsumer) SampleConfig() string {
|
||||
return `
|
||||
## AMQP url
|
||||
url = "amqp://localhost:5672/influxdb"
|
||||
## AMQP exchange
|
||||
## Broker to consume from.
|
||||
## deprecated in 1.7; use the brokers option
|
||||
# url = "amqp://localhost:5672/influxdb"
|
||||
|
||||
## 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 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
|
||||
queue = "telegraf"
|
||||
|
||||
## Binding Key
|
||||
binding_key = "#"
|
||||
|
||||
## Maximum number of messages server should give to the worker.
|
||||
prefetch_count = 50
|
||||
# prefetch_count = 50
|
||||
|
||||
## Auth method. PLAIN and EXTERNAL are supported
|
||||
## Using EXTERNAL requires enabling the rabbitmq_auth_mechanism_ssl plugin as
|
||||
@@ -106,16 +147,21 @@ func (a *AMQPConsumer) createConfig() (*amqp.Config, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// parse auth method
|
||||
var sasl []amqp.Authentication // nil by default
|
||||
|
||||
var auth []amqp.Authentication
|
||||
if strings.ToUpper(a.AuthMethod) == "EXTERNAL" {
|
||||
sasl = []amqp.Authentication{&externalAuth{}}
|
||||
auth = []amqp.Authentication{&externalAuth{}}
|
||||
} else if a.Username != "" || a.Password != "" {
|
||||
auth = []amqp.Authentication{
|
||||
&amqp.PlainAuth{
|
||||
Username: a.Username,
|
||||
Password: a.Password,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
config := amqp.Config{
|
||||
TLSClientConfig: tls,
|
||||
SASL: sasl, // if nil, it will be PLAIN
|
||||
SASL: auth, // if nil, it will be PLAIN
|
||||
}
|
||||
return &config, nil
|
||||
}
|
||||
@@ -163,28 +209,55 @@ func (a *AMQPConsumer) Start(acc telegraf.Accumulator) error {
|
||||
}
|
||||
|
||||
func (a *AMQPConsumer) connect(amqpConf *amqp.Config) (<-chan amqp.Delivery, error) {
|
||||
conn, err := amqp.DialConfig(a.URL, *amqpConf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
brokers := a.Brokers
|
||||
if len(brokers) == 0 {
|
||||
brokers = []string{a.URL}
|
||||
}
|
||||
a.conn = conn
|
||||
|
||||
ch, err := conn.Channel()
|
||||
p := rand.Perm(len(brokers))
|
||||
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 {
|
||||
return nil, fmt.Errorf("Failed to open a channel: %s", err)
|
||||
}
|
||||
|
||||
err = ch.ExchangeDeclare(
|
||||
a.Exchange, // name
|
||||
"topic", // type
|
||||
true, // durable
|
||||
false, // auto-deleted
|
||||
false, // internal
|
||||
false, // no-wait
|
||||
nil, // arguments
|
||||
)
|
||||
var exchangeDurable = true
|
||||
switch a.ExchangeDurability {
|
||||
case "transient":
|
||||
exchangeDurable = false
|
||||
default:
|
||||
exchangeDurable = true
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, fmt.Errorf("Failed to declare an exchange: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
q, err := ch.QueueDeclare(
|
||||
@@ -236,6 +309,42 @@ func (a *AMQPConsumer) connect(amqpConf *amqp.Config) (<-chan amqp.Delivery, 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
|
||||
func (a *AMQPConsumer) process(msgs <-chan amqp.Delivery, acc telegraf.Accumulator) {
|
||||
defer a.wg.Done()
|
||||
@@ -267,8 +376,11 @@ func (a *AMQPConsumer) Stop() {
|
||||
func init() {
|
||||
inputs.Add("amqp_consumer", func() telegraf.Input {
|
||||
return &AMQPConsumer{
|
||||
AuthMethod: DefaultAuthMethod,
|
||||
PrefetchCount: DefaultPrefetchCount,
|
||||
URL: DefaultBroker,
|
||||
AuthMethod: DefaultAuthMethod,
|
||||
ExchangeType: DefaultExchangeType,
|
||||
ExchangeDurability: DefaultExchangeDurability,
|
||||
PrefetchCount: DefaultPrefetchCount,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ Supported Burrow version: `1.x`
|
||||
### Configuration
|
||||
|
||||
```
|
||||
[[inputs.burrow]]
|
||||
## Burrow API endpoints in format "schema://host:port".
|
||||
## Default is "http://localhost:8000".
|
||||
servers = ["http://localhost:8000"]
|
||||
@@ -91,6 +92,7 @@ Supported Burrow version: `1.x`
|
||||
- group (string)
|
||||
- topic (string)
|
||||
- partition (int)
|
||||
- owner (string)
|
||||
|
||||
* `burrow_topic`
|
||||
- cluster (string)
|
||||
|
||||
@@ -116,6 +116,7 @@ type (
|
||||
Start apiStatusResponseLagItem `json:"start"`
|
||||
End apiStatusResponseLagItem `json:"end"`
|
||||
CurrentLag int64 `json:"current_lag"`
|
||||
Owner string `json:"owner"`
|
||||
}
|
||||
|
||||
// response: lag field item
|
||||
@@ -447,6 +448,7 @@ func (b *burrow) genGroupLagMetrics(r *apiResponse, cluster, group string, acc t
|
||||
"group": group,
|
||||
"topic": partition.Topic,
|
||||
"partition": strconv.FormatInt(int64(partition.Partition), 10),
|
||||
"owner": partition.Owner,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -129,9 +129,9 @@ func TestBurrowPartition(t *testing.T) {
|
||||
},
|
||||
}
|
||||
tags := []map[string]string{
|
||||
{"cluster": "clustername1", "group": "group1", "topic": "topicA", "partition": "0"},
|
||||
{"cluster": "clustername1", "group": "group1", "topic": "topicA", "partition": "1"},
|
||||
{"cluster": "clustername1", "group": "group1", "topic": "topicA", "partition": "2"},
|
||||
{"cluster": "clustername1", "group": "group1", "topic": "topicA", "partition": "0", "owner": "kafka1"},
|
||||
{"cluster": "clustername1", "group": "group1", "topic": "topicA", "partition": "1", "owner": "kafka2"},
|
||||
{"cluster": "clustername1", "group": "group1", "topic": "topicA", "partition": "2", "owner": "kafka3"},
|
||||
}
|
||||
|
||||
require.Empty(t, acc.Errors)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{
|
||||
"topic": "topicA",
|
||||
"partition": 0,
|
||||
"owner": "kafka",
|
||||
"owner": "kafka1",
|
||||
"status": "OK",
|
||||
"start": {
|
||||
"offset": 431323195,
|
||||
@@ -28,7 +28,7 @@
|
||||
{
|
||||
"topic": "topicA",
|
||||
"partition": 1,
|
||||
"owner": "kafka",
|
||||
"owner": "kafka2",
|
||||
"status": "OK",
|
||||
"start": {
|
||||
"offset": 431322962,
|
||||
@@ -46,7 +46,7 @@
|
||||
{
|
||||
"topic": "topicA",
|
||||
"partition": 2,
|
||||
"owner": "kafka",
|
||||
"owner": "kafka3",
|
||||
"status": "OK",
|
||||
"start": {
|
||||
"offset": 428636563,
|
||||
|
||||
@@ -3,14 +3,15 @@
|
||||
package conntrack
|
||||
|
||||
import (
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func restoreDflts(savedFiles, savedDirs []string) {
|
||||
@@ -39,6 +40,7 @@ func TestDefaultsUsed(t *testing.T) {
|
||||
|
||||
tmpFile, err := ioutil.TempFile(tmpdir, "ip_conntrack_count")
|
||||
assert.NoError(t, err)
|
||||
defer os.Remove(tmpFile.Name())
|
||||
|
||||
dfltDirs = []string{tmpdir}
|
||||
fname := path.Base(tmpFile.Name())
|
||||
@@ -63,6 +65,8 @@ func TestConfigsUsed(t *testing.T) {
|
||||
cntFile, err := ioutil.TempFile(tmpdir, "nf_conntrack_count")
|
||||
maxFile, err := ioutil.TempFile(tmpdir, "nf_conntrack_max")
|
||||
assert.NoError(t, err)
|
||||
defer os.Remove(cntFile.Name())
|
||||
defer os.Remove(maxFile.Name())
|
||||
|
||||
dfltDirs = []string{tmpdir}
|
||||
cntFname := path.Base(cntFile.Name())
|
||||
|
||||
@@ -124,6 +124,7 @@ docker API.
|
||||
- server_version
|
||||
- container_image
|
||||
- container_name
|
||||
- container_status
|
||||
- container_version
|
||||
- fields:
|
||||
- total_pgmafault
|
||||
@@ -167,6 +168,7 @@ docker API.
|
||||
- server_version
|
||||
- container_image
|
||||
- container_name
|
||||
- container_status
|
||||
- container_version
|
||||
- cpu
|
||||
- fields:
|
||||
@@ -186,6 +188,7 @@ docker API.
|
||||
- server_version
|
||||
- container_image
|
||||
- container_name
|
||||
- container_status
|
||||
- container_version
|
||||
- network
|
||||
- fields:
|
||||
@@ -205,6 +208,7 @@ docker API.
|
||||
- server_version
|
||||
- container_image
|
||||
- container_name
|
||||
- container_status
|
||||
- container_version
|
||||
- device
|
||||
- fields:
|
||||
@@ -226,11 +230,27 @@ docker API.
|
||||
- server_version
|
||||
- container_image
|
||||
- container_name
|
||||
- container_status
|
||||
- container_version
|
||||
- fields:
|
||||
- health_status (string)
|
||||
- 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
|
||||
- tags:
|
||||
- service_id
|
||||
@@ -245,12 +265,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,unit=bytes memory_total=2101661696i 1524002041000000000
|
||||
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_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=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=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_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_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_version=unknown,engine_host=debian-stretch-docker,server_version=17.09.0-ce failing_streak=0i,health_status="healthy" 1524007529000000000
|
||||
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_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_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_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_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_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_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_swarm,service_id=xaup2o9krw36j2dy1mjx1arjw,service_mode=replicated,service_name=test tasks_desired=3,tasks_running=3 1508968160000000000
|
||||
```
|
||||
|
||||
@@ -435,6 +435,23 @@ 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 {
|
||||
healthfields := map[string]interface{}{
|
||||
|
||||
@@ -653,6 +653,7 @@ func TestDockerGatherInfo(t *testing.T) {
|
||||
"label1": "test_value_1",
|
||||
"label2": "test_value_2",
|
||||
"server_version": "17.09.0-ce",
|
||||
"container_status": "running",
|
||||
},
|
||||
)
|
||||
acc.AssertContainsTaggedFields(t,
|
||||
@@ -676,6 +677,7 @@ func TestDockerGatherInfo(t *testing.T) {
|
||||
"label1": "test_value_1",
|
||||
"label2": "test_value_2",
|
||||
"server_version": "17.09.0-ce",
|
||||
"container_status": "running",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -484,6 +484,12 @@ var containerInspect = types.ContainerJSON{
|
||||
FailingStreak: 1,
|
||||
Status: "Unhealthy",
|
||||
},
|
||||
Status: "running",
|
||||
OOMKilled: false,
|
||||
Pid: 1234,
|
||||
ExitCode: 0,
|
||||
StartedAt: "2018-06-14T05:48:53.266176036Z",
|
||||
FinishedAt: "0001-01-01T00:00:00Z",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -24,11 +24,14 @@ Those values could be true (1) or false (0) for switches, percentage for dimmers
|
||||
|
||||
- fibaro
|
||||
- tags:
|
||||
- deviceId (device id)
|
||||
- section (section name)
|
||||
- room (room name)
|
||||
- name (device name)
|
||||
- type (device type)
|
||||
- fields:
|
||||
- energy (float, when available from device)
|
||||
- power (float, when available from device)
|
||||
- value (float)
|
||||
- value2 (float, when available from device)
|
||||
|
||||
@@ -36,16 +39,17 @@ Those values could be true (1) or false (0) for switches, percentage for dimmers
|
||||
### Example Output:
|
||||
|
||||
```
|
||||
fibaro,host=vm1,name=Escaliers,room=Dégagement,section=Pièces\ communes,type=com.fibaro.binarySwitch value=0 1523351010000000000
|
||||
fibaro,host=vm1,name=Porte\ fenêtre,room=Salon,section=Pièces\ communes,type=com.fibaro.FGRM222 value=99,value2=99 1523351010000000000
|
||||
fibaro,host=vm1,name=LED\ îlot\ central,room=Cuisine,section=Cuisine,type=com.fibaro.binarySwitch value=0 1523351010000000000
|
||||
fibaro,host=vm1,name=Détérioration,room=Entrée,section=Pièces\ communes,type=com.fibaro.heatDetector value=0 1523351010000000000
|
||||
fibaro,host=vm1,name=Température,room=Cave,section=Cave,type=com.fibaro.temperatureSensor value=17.87 1523351010000000000
|
||||
fibaro,host=vm1,name=Présence,room=Garde-manger,section=Cuisine,type=com.fibaro.FGMS001 value=1 1523351010000000000
|
||||
fibaro,host=vm1,name=Luminosité,room=Garde-manger,section=Cuisine,type=com.fibaro.lightSensor value=92 1523351010000000000
|
||||
fibaro,host=vm1,name=Etat,room=Garage,section=Extérieur,type=com.fibaro.doorSensor value=0 1523351010000000000
|
||||
fibaro,host=vm1,name=CO2\ (ppm),room=Salon,section=Pièces\ communes,type=com.fibaro.multilevelSensor value=880 1523351010000000000
|
||||
fibaro,host=vm1,name=Humidité\ (%),room=Salon,section=Pièces\ communes,type=com.fibaro.humiditySensor value=53 1523351010000000000
|
||||
fibaro,host=vm1,name=Pression\ (mb),room=Salon,section=Pièces\ communes,type=com.fibaro.multilevelSensor value=1006.9 1523351010000000000
|
||||
fibaro,host=vm1,name=Bruit\ (db),room=Salon,section=Pièces\ communes,type=com.fibaro.multilevelSensor value=58 1523351010000000000
|
||||
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,deviceId=10,host=vm1,name=Escaliers,room=Dégagement,section=Pièces\ communes,type=com.fibaro.binarySwitch value=0 1529996807000000000
|
||||
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,deviceId=21,host=vm1,name=LED\ îlot\ central,room=Cuisine,section=Cuisine,type=com.fibaro.binarySwitch value=0 1529996807000000000
|
||||
fibaro,deviceId=90,host=vm1,name=Détérioration,room=Entrée,section=Pièces\ communes,type=com.fibaro.heatDetector value=0 1529996807000000000
|
||||
fibaro,deviceId=163,host=vm1,name=Température,room=Cave,section=Cave,type=com.fibaro.temperatureSensor value=21.62 1529996807000000000
|
||||
fibaro,deviceId=191,host=vm1,name=Présence,room=Garde-manger,section=Cuisine,type=com.fibaro.FGMS001 value=1 1529996807000000000
|
||||
fibaro,deviceId=193,host=vm1,name=Luminosité,room=Garde-manger,section=Cuisine,type=com.fibaro.lightSensor value=195 1529996807000000000
|
||||
fibaro,deviceId=200,host=vm1,name=Etat,room=Garage,section=Extérieur,type=com.fibaro.doorSensor value=0 1529996807000000000
|
||||
fibaro,deviceId=220,host=vm1,name=CO2\ (ppm),room=Salon,section=Pièces\ communes,type=com.fibaro.multilevelSensor value=536 1529996807000000000
|
||||
fibaro,deviceId=221,host=vm1,name=Humidité\ (%),room=Salon,section=Pièces\ communes,type=com.fibaro.humiditySensor value=61 1529996807000000000
|
||||
fibaro,deviceId=222,host=vm1,name=Pression\ (mb),room=Salon,section=Pièces\ communes,type=com.fibaro.multilevelSensor value=1013.7 1529996807000000000
|
||||
fibaro,deviceId=223,host=vm1,name=Bruit\ (db),room=Salon,section=Pièces\ communes,type=com.fibaro.multilevelSensor value=44 1529996807000000000
|
||||
```
|
||||
|
||||
@@ -67,6 +67,8 @@ type Devices struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Properties struct {
|
||||
Dead interface{} `json:"dead"`
|
||||
Energy interface{} `json:"energy"`
|
||||
Power interface{} `json:"power"`
|
||||
Value interface{} `json:"value"`
|
||||
Value2 interface{} `json:"value2"`
|
||||
} `json:"properties"`
|
||||
@@ -162,13 +164,26 @@ func (f *Fibaro) Gather(acc telegraf.Accumulator) error {
|
||||
}
|
||||
|
||||
tags := map[string]string{
|
||||
"section": sections[rooms[device.RoomID].SectionID],
|
||||
"room": rooms[device.RoomID].Name,
|
||||
"name": device.Name,
|
||||
"type": device.Type,
|
||||
"deviceId": strconv.FormatUint(uint64(device.ID), 10),
|
||||
"section": sections[rooms[device.RoomID].SectionID],
|
||||
"room": rooms[device.RoomID].Name,
|
||||
"name": device.Name,
|
||||
"type": device.Type,
|
||||
}
|
||||
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 {
|
||||
value := device.Properties.Value
|
||||
switch value {
|
||||
|
||||
@@ -119,6 +119,8 @@ const devicesJSON = `
|
||||
"type": "com.fibaro.FGRM222",
|
||||
"enabled": true,
|
||||
"properties": {
|
||||
"energy": "4.33",
|
||||
"power": "0.7",
|
||||
"dead": "false",
|
||||
"value": "50",
|
||||
"value2": "75"
|
||||
@@ -178,27 +180,27 @@ func TestJSONSuccess(t *testing.T) {
|
||||
assert.Equal(t, uint64(5), acc.NMetrics())
|
||||
|
||||
// Ensure fields / values are correct - Device 1
|
||||
tags := map[string]string{"section": "Section 1", "room": "Room 1", "name": "Device 1", "type": "com.fibaro.binarySwitch"}
|
||||
tags := map[string]string{"deviceId": "1", "section": "Section 1", "room": "Room 1", "name": "Device 1", "type": "com.fibaro.binarySwitch"}
|
||||
fields := map[string]interface{}{"value": float64(0)}
|
||||
acc.AssertContainsTaggedFields(t, "fibaro", fields, tags)
|
||||
|
||||
// Ensure fields / values are correct - Device 2
|
||||
tags = map[string]string{"section": "Section 2", "room": "Room 2", "name": "Device 2", "type": "com.fibaro.binarySwitch"}
|
||||
tags = map[string]string{"deviceId": "2", "section": "Section 2", "room": "Room 2", "name": "Device 2", "type": "com.fibaro.binarySwitch"}
|
||||
fields = map[string]interface{}{"value": float64(1)}
|
||||
acc.AssertContainsTaggedFields(t, "fibaro", fields, tags)
|
||||
|
||||
// Ensure fields / values are correct - Device 3
|
||||
tags = map[string]string{"section": "Section 3", "room": "Room 3", "name": "Device 3", "type": "com.fibaro.multilevelSwitch"}
|
||||
tags = map[string]string{"deviceId": "3", "section": "Section 3", "room": "Room 3", "name": "Device 3", "type": "com.fibaro.multilevelSwitch"}
|
||||
fields = map[string]interface{}{"value": float64(67)}
|
||||
acc.AssertContainsTaggedFields(t, "fibaro", fields, tags)
|
||||
|
||||
// Ensure fields / values are correct - Device 4
|
||||
tags = map[string]string{"section": "Section 3", "room": "Room 4", "name": "Device 4", "type": "com.fibaro.temperatureSensor"}
|
||||
tags = map[string]string{"deviceId": "4", "section": "Section 3", "room": "Room 4", "name": "Device 4", "type": "com.fibaro.temperatureSensor"}
|
||||
fields = map[string]interface{}{"value": float64(22.8)}
|
||||
acc.AssertContainsTaggedFields(t, "fibaro", fields, tags)
|
||||
|
||||
// Ensure fields / values are correct - Device 5
|
||||
tags = map[string]string{"section": "Section 3", "room": "Room 4", "name": "Device 5", "type": "com.fibaro.FGRM222"}
|
||||
fields = map[string]interface{}{"value": float64(50), "value2": float64(75)}
|
||||
tags = map[string]string{"deviceId": "5", "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)}
|
||||
acc.AssertContainsTaggedFields(t, "fibaro", fields, tags)
|
||||
}
|
||||
|
||||
@@ -172,8 +172,14 @@ Both `jolokia2_agent` and `jolokia2_proxy` plugins support default configuration
|
||||
|
||||
### Example Configurations:
|
||||
|
||||
- [Java JVM](/plugins/inputs/jolokia2/examples/java.conf)
|
||||
- [Kafka](/plugins/inputs/jolokia2/examples/kafka.conf)
|
||||
- [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)
|
||||
- [JBoss](/plugins/inputs/jolokia2/examples/jboss.conf)
|
||||
- [Kafka](/plugins/inputs/jolokia2/examples/kafka.conf)
|
||||
- [Tomcat](/plugins/inputs/jolokia2/examples/tomcat.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.
|
||||
|
||||
57
plugins/inputs/jolokia2/examples/activemq.conf
Normal file
57
plugins/inputs/jolokia2/examples/activemq.conf
Normal file
@@ -0,0 +1,57 @@
|
||||
## 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"]
|
||||
39
plugins/inputs/jolokia2/examples/bitbucket.conf
Normal file
39
plugins/inputs/jolokia2/examples/bitbucket.conf
Normal file
@@ -0,0 +1,39 @@
|
||||
[[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=*"
|
||||
85
plugins/inputs/jolokia2/examples/hadoop-hdfs.conf
Normal file
85
plugins/inputs/jolokia2/examples/hadoop-hdfs.conf
Normal file
@@ -0,0 +1,85 @@
|
||||
################
|
||||
# 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_"
|
||||
59
plugins/inputs/jolokia2/examples/jboss.conf
Normal file
59
plugins/inputs/jolokia2/examples/jboss.conf
Normal file
@@ -0,0 +1,59 @@
|
||||
[[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"]
|
||||
65
plugins/inputs/jolokia2/examples/tomcat.conf
Normal file
65
plugins/inputs/jolokia2/examples/tomcat.conf
Normal file
@@ -0,0 +1,65 @@
|
||||
[[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"]
|
||||
56
plugins/inputs/jolokia2/examples/weblogic.conf
Normal file
56
plugins/inputs/jolokia2/examples/weblogic.conf
Normal file
@@ -0,0 +1,56 @@
|
||||
[[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_"
|
||||
@@ -108,7 +108,9 @@ You must capture at least one field per line.
|
||||
- ts-"CUSTOM"
|
||||
|
||||
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.
|
||||
|
||||
Telegraf has many of its own [built-in patterns](./grok/patterns/influx-patterns),
|
||||
|
||||
13
plugins/inputs/logparser/dev/docker-compose.yml
Normal file
13
plugins/inputs/logparser/dev/docker-compose.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
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
|
||||
12
plugins/inputs/logparser/dev/telegraf.conf
Normal file
12
plugins/inputs/logparser/dev/telegraf.conf
Normal file
@@ -0,0 +1,12 @@
|
||||
[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"]
|
||||
2
plugins/inputs/logparser/dev/test.log
Normal file
2
plugins/inputs/logparser/dev/test.log
Normal file
@@ -0,0 +1,2 @@
|
||||
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"
|
||||
@@ -293,7 +293,7 @@ func (p *Parser) ParseLine(line string) (telegraf.Metric, error) {
|
||||
timestamp = time.Unix(0, iv)
|
||||
}
|
||||
case SYSLOG_TIMESTAMP:
|
||||
ts, err := time.ParseInLocation("Jan 02 15:04:05", v, p.loc)
|
||||
ts, err := time.ParseInLocation(time.Stamp, v, p.loc)
|
||||
if err == nil {
|
||||
if ts.Year() == 0 {
|
||||
ts = ts.AddDate(timestamp.Year(), 0, 0)
|
||||
@@ -335,6 +335,9 @@ func (p *Parser) ParseLine(line string) (telegraf.Metric, error) {
|
||||
case DROP:
|
||||
// goodbye!
|
||||
default:
|
||||
// Replace commas with dot character
|
||||
v = strings.Replace(v, ",", ".", -1)
|
||||
|
||||
ts, err := time.ParseInLocation(t, v, p.loc)
|
||||
if err == nil {
|
||||
timestamp = ts
|
||||
|
||||
@@ -971,14 +971,57 @@ func TestNewlineInPatterns(t *testing.T) {
|
||||
require.NotNil(t, m)
|
||||
}
|
||||
|
||||
func TestSyslogTimestampParser(t *testing.T) {
|
||||
p := &Parser{
|
||||
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) },
|
||||
func TestSyslogTimestamp(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{
|
||||
Patterns: []string{`%{TIMESTAMP_ISO8601:timestamp:ts-"2006-01-02 15:04:05.000"} successfulMatches=%{NUMBER:value:int}`},
|
||||
}
|
||||
|
||||
require.NoError(t, p.Compile())
|
||||
m, err := p.ParseLine("Sep 25 09:01:55 value=42")
|
||||
m, err := p.ParseLine("2018-02-21 13:10:34,555 successfulMatches=1")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, m)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -203,6 +203,10 @@ func (l *LogParserPlugin) tailNewfiles(fromBeginning bool) error {
|
||||
Poll: poll,
|
||||
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 {
|
||||
l.acc.AddError(err)
|
||||
continue
|
||||
@@ -287,6 +291,10 @@ func (l *LogParserPlugin) Stop() {
|
||||
|
||||
for _, t := range l.tailers {
|
||||
err := t.Stop()
|
||||
|
||||
//message for a stopped tailer
|
||||
log.Printf("D! tail dropped for file: %v", t.Filename)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("E! Error stopping tail on file %s\n", t.Filename)
|
||||
}
|
||||
|
||||
16
plugins/inputs/mongodb/dev/docker-compose.yml
Normal file
16
plugins/inputs/mongodb/dev/docker-compose.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
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
|
||||
9
plugins/inputs/mongodb/dev/telegraf.conf
Normal file
9
plugins/inputs/mongodb/dev/telegraf.conf
Normal file
@@ -0,0 +1,9 @@
|
||||
[agent]
|
||||
interval="1s"
|
||||
flush_interval="3s"
|
||||
|
||||
[[inputs.mongodb]]
|
||||
servers = ["mongodb://mongodb:27017"]
|
||||
|
||||
[[outputs.file]]
|
||||
files = ["stdout"]
|
||||
42
plugins/inputs/mysql/dev/docker-compose.yml
Normal file
42
plugins/inputs/mysql/dev/docker-compose.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
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
|
||||
61
plugins/inputs/mysql/dev/telegraf.conf
Normal file
61
plugins/inputs/mysql/dev/telegraf.conf
Normal file
@@ -0,0 +1,61 @@
|
||||
# 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"]
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -80,7 +79,7 @@ var sampleConfig = `
|
||||
## gather thread state counts from INFORMATION_SCHEMA.PROCESSLIST
|
||||
gather_process_list = true
|
||||
#
|
||||
## gather thread state counts from INFORMATION_SCHEMA.USER_STATISTICS
|
||||
## gather user statistics from INFORMATION_SCHEMA.USER_STATISTICS
|
||||
gather_user_statistics = true
|
||||
#
|
||||
## gather auto_increment columns and max values from information schema
|
||||
@@ -282,9 +281,8 @@ const (
|
||||
GROUP BY command,state
|
||||
ORDER BY null`
|
||||
infoSchemaUserStatisticsQuery = `
|
||||
SELECT *,count(*)
|
||||
FROM information_schema.user_statistics
|
||||
GROUP BY user`
|
||||
SELECT *
|
||||
FROM information_schema.user_statistics`
|
||||
infoSchemaAutoIncQuery = `
|
||||
SELECT table_schema, table_name, column_name, auto_increment,
|
||||
CAST(pow(2, case data_type
|
||||
@@ -761,103 +759,6 @@ func (m *Mysql) gatherGlobalStatuses(db *sql.DB, serv string, acc telegraf.Accum
|
||||
if len(fields) > 0 {
|
||||
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
|
||||
}
|
||||
@@ -908,6 +809,29 @@ func (m *Mysql) GatherProcessListStatuses(db *sql.DB, serv string, acc telegraf.
|
||||
} else {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -917,77 +841,190 @@ func (m *Mysql) GatherUserStatisticsStatuses(db *sql.DB, serv string, acc telegr
|
||||
// run query
|
||||
rows, err := db.Query(infoSchemaUserStatisticsQuery)
|
||||
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
|
||||
}
|
||||
defer rows.Close()
|
||||
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_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
|
||||
)
|
||||
|
||||
cols, err := columnsToLower(rows.Columns())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
read, err := getColSlice(len(cols))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
servtag := getDSNTag(serv)
|
||||
for rows.Next() {
|
||||
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,
|
||||
)
|
||||
err = rows.Scan(read...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tags := map[string]string{"server": servtag, "user": user}
|
||||
fields := map[string]interface{}{
|
||||
tags := map[string]string{"server": servtag, "user": *read[0].(*string)}
|
||||
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,
|
||||
for i := range cols {
|
||||
if i == 0 {
|
||||
continue // skip "user"
|
||||
}
|
||||
switch v := read[i].(type) {
|
||||
case *int64:
|
||||
fields[cols[i]] = *v
|
||||
case *float64:
|
||||
fields[cols[i]] = *v
|
||||
case *string:
|
||||
fields[cols[i]] = *v
|
||||
default:
|
||||
return fmt.Errorf("Unknown column type - %T", v)
|
||||
}
|
||||
}
|
||||
acc.AddFields("mysql_user_stats", fields, tags)
|
||||
}
|
||||
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
|
||||
// of I/O wait event for each table and process
|
||||
func (m *Mysql) gatherPerfTableIOWaits(db *sql.DB, serv string, acc telegraf.Accumulator) error {
|
||||
|
||||
@@ -49,7 +49,7 @@ func TestMysqlGetDSNTag(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"tcp(localhost)/",
|
||||
"localhost",
|
||||
"localhost:3306",
|
||||
},
|
||||
{
|
||||
"root:passwd@tcp(192.168.1.1:3306)/?tls=false",
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
"github.com/influxdata/telegraf/plugins/parsers"
|
||||
"github.com/nats-io/nats"
|
||||
nats "github.com/nats-io/go-nats"
|
||||
)
|
||||
|
||||
type natsError struct {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/influxdata/telegraf/plugins/parsers"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
"github.com/nats-io/nats"
|
||||
nats "github.com/nats-io/go-nats"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
||||
@@ -17,16 +17,17 @@ This plugin uses a query on the [`nvidia-smi`](https://developer.nvidia.com/nvid
|
||||
### Metrics
|
||||
- measurement: `nvidia_smi`
|
||||
- tags
|
||||
- `name` (type of GPU e.g. `GeForce GTX 170 Ti`)
|
||||
- `name` (type of GPU e.g. `GeForce GTX 1070 Ti`)
|
||||
- `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`)
|
||||
- `pstate` (Overclocking state for the GPU e.g. `P0`)
|
||||
- `uuid` (A unique identifier for the GPU e.g. `GPU-f9ba66fc-a7f5-94c5-da19-019ef2f9c665`)
|
||||
- fields
|
||||
- `fan_speed` (integer, percentage)
|
||||
- `memory_free` (integer, KB)
|
||||
- `memory_used` (integer, KB)
|
||||
- `memory_total` (integer, KB)
|
||||
- `memory_free` (integer, MiB)
|
||||
- `memory_used` (integer, MiB)
|
||||
- `memory_total` (integer, MiB)
|
||||
- `power_draw` (float, W)
|
||||
- `temperature_gpu` (integer, degrees C)
|
||||
- `utilization_gpu` (integer, percentage)
|
||||
- `utilization_memory` (integer, percentage)
|
||||
|
||||
@@ -16,20 +16,21 @@ import (
|
||||
|
||||
var (
|
||||
measurement = "nvidia_smi"
|
||||
metrics = "fan.speed,memory.total,memory.used,memory.free,pstate,temperature.gpu,name,uuid,compute_mode,utilization.gpu,utilization.memory,index"
|
||||
metrics = "fan.speed,memory.total,memory.used,memory.free,pstate,temperature.gpu,name,uuid,compute_mode,utilization.gpu,utilization.memory,index,power.draw"
|
||||
metricNames = [][]string{
|
||||
[]string{"fan_speed", "field"},
|
||||
[]string{"memory_total", "field"},
|
||||
[]string{"memory_used", "field"},
|
||||
[]string{"memory_free", "field"},
|
||||
[]string{"fan_speed", "integer"},
|
||||
[]string{"memory_total", "integer"},
|
||||
[]string{"memory_used", "integer"},
|
||||
[]string{"memory_free", "integer"},
|
||||
[]string{"pstate", "tag"},
|
||||
[]string{"temperature_gpu", "field"},
|
||||
[]string{"temperature_gpu", "integer"},
|
||||
[]string{"name", "tag"},
|
||||
[]string{"uuid", "tag"},
|
||||
[]string{"compute_mode", "tag"},
|
||||
[]string{"utilization_gpu", "field"},
|
||||
[]string{"utilization_memory", "field"},
|
||||
[]string{"utilization_gpu", "integer"},
|
||||
[]string{"utilization_memory", "integer"},
|
||||
[]string{"index", "tag"},
|
||||
[]string{"power_draw", "float"},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -127,7 +128,7 @@ func parseLine(line string) (map[string]string, map[string]interface{}, error) {
|
||||
for i, m := range metricNames {
|
||||
col := strings.TrimSpace(met[i])
|
||||
|
||||
// First handle the tags
|
||||
// Handle the tags
|
||||
if m[1] == "tag" {
|
||||
tags[m[0]] = col
|
||||
continue
|
||||
@@ -137,12 +138,23 @@ func parseLine(line string) (map[string]string, map[string]interface{}, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Then parse the integers out of the fields
|
||||
out, err := strconv.ParseInt(col, 10, 64)
|
||||
if err != nil {
|
||||
return tags, fields, err
|
||||
// Parse the integers
|
||||
if m[1] == "integer" {
|
||||
out, err := strconv.ParseInt(col, 10, 64)
|
||||
if err != nil {
|
||||
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
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
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\n"
|
||||
line := "85, 8114, 553, 7561, P2, 61, GeForce GTX 1070 Ti, GPU-d1911b8a-f5c8-5e66-057c-486561269de8, Default, 100, 93, 1, 0.0\n"
|
||||
tags, fields, err := parseLine(line)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
@@ -37,7 +37,7 @@ func TestParseLineBad(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestParseLineNotSupported(t *testing.T) {
|
||||
line := "[Not Supported], 7606, 0, 7606, P0, 38, Tesla P4, GPU-xxx, Default, 0, 0, 0\n"
|
||||
line := "[Not Supported], 7606, 0, 7606, P0, 38, Tesla P4, GPU-xxx, Default, 0, 0, 0, 0.0\n"
|
||||
_, fields, err := parseLine(line)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, nil, fields["fan_speed"])
|
||||
|
||||
@@ -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.
|
||||
# note that port will likely need to be changed to 636 for ldaps
|
||||
# valid options: "" | "starttls" | "ldaps"
|
||||
ssl = ""
|
||||
tls = ""
|
||||
|
||||
# skip peer certificate verification. Default is false.
|
||||
insecure_skip_verify = false
|
||||
|
||||
@@ -15,9 +15,11 @@ import (
|
||||
type Openldap struct {
|
||||
Host string
|
||||
Port int
|
||||
Ssl string
|
||||
SSL string `toml:"ssl"` // Deprecated in 1.7; use TLS
|
||||
TLS string `toml:"tls"`
|
||||
InsecureSkipVerify bool
|
||||
SslCa string
|
||||
SSLCA string `toml:"ssl_ca"` // Deprecated in 1.7; use TLSCA
|
||||
TLSCA string `toml:"tls_ca"`
|
||||
BindDn string
|
||||
BindPassword string
|
||||
ReverseMetricNames bool
|
||||
@@ -30,7 +32,7 @@ const sampleConfig string = `
|
||||
# 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
|
||||
# valid options: "" | "starttls" | "ldaps"
|
||||
ssl = ""
|
||||
tls = ""
|
||||
|
||||
# skip peer certificate verification. Default is false.
|
||||
insecure_skip_verify = false
|
||||
@@ -70,9 +72,11 @@ func NewOpenldap() *Openldap {
|
||||
return &Openldap{
|
||||
Host: "localhost",
|
||||
Port: 389,
|
||||
Ssl: "",
|
||||
SSL: "",
|
||||
TLS: "",
|
||||
InsecureSkipVerify: false,
|
||||
SslCa: "",
|
||||
SSLCA: "",
|
||||
TLSCA: "",
|
||||
BindDn: "",
|
||||
BindPassword: "",
|
||||
ReverseMetricNames: false,
|
||||
@@ -81,12 +85,19 @@ func NewOpenldap() *Openldap {
|
||||
|
||||
// gather metrics
|
||||
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 l *ldap.Conn
|
||||
if o.Ssl != "" {
|
||||
if o.TLS != "" {
|
||||
// build tls config
|
||||
clientTLSConfig := tls.ClientConfig{
|
||||
SSLCA: o.SslCa,
|
||||
TLSCA: o.TLSCA,
|
||||
InsecureSkipVerify: o.InsecureSkipVerify,
|
||||
}
|
||||
tlsConfig, err := clientTLSConfig.TLSConfig()
|
||||
@@ -94,13 +105,13 @@ func (o *Openldap) Gather(acc telegraf.Accumulator) error {
|
||||
acc.AddError(err)
|
||||
return nil
|
||||
}
|
||||
if o.Ssl == "ldaps" {
|
||||
if o.TLS == "ldaps" {
|
||||
l, err = ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", o.Host, o.Port), tlsConfig)
|
||||
if err != nil {
|
||||
acc.AddError(err)
|
||||
return nil
|
||||
}
|
||||
} else if o.Ssl == "starttls" {
|
||||
} else if o.TLS == "starttls" {
|
||||
l, err = ldap.Dial("tcp", fmt.Sprintf("%s:%d", o.Host, o.Port))
|
||||
if err != nil {
|
||||
acc.AddError(err)
|
||||
@@ -108,7 +119,7 @@ func (o *Openldap) Gather(acc telegraf.Accumulator) error {
|
||||
}
|
||||
err = l.StartTLS(tlsConfig)
|
||||
} else {
|
||||
acc.AddError(fmt.Errorf("Invalid setting for ssl: %s", o.Ssl))
|
||||
acc.AddError(fmt.Errorf("Invalid setting for ssl: %s", o.TLS))
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package openldap
|
||||
|
||||
import (
|
||||
"gopkg.in/ldap.v2"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/ldap.v2"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -74,7 +75,7 @@ func TestOpenldapStartTLS(t *testing.T) {
|
||||
o := &Openldap{
|
||||
Host: testutil.GetLocalHost(),
|
||||
Port: 389,
|
||||
Ssl: "starttls",
|
||||
SSL: "starttls",
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ func TestOpenldapLDAPS(t *testing.T) {
|
||||
o := &Openldap{
|
||||
Host: testutil.GetLocalHost(),
|
||||
Port: 636,
|
||||
Ssl: "ldaps",
|
||||
SSL: "ldaps",
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
@@ -110,7 +111,7 @@ func TestOpenldapInvalidSSL(t *testing.T) {
|
||||
o := &Openldap{
|
||||
Host: testutil.GetLocalHost(),
|
||||
Port: 636,
|
||||
Ssl: "invalid",
|
||||
SSL: "invalid",
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
@@ -129,7 +130,7 @@ func TestOpenldapBind(t *testing.T) {
|
||||
o := &Openldap{
|
||||
Host: testutil.GetLocalHost(),
|
||||
Port: 389,
|
||||
Ssl: "",
|
||||
SSL: "",
|
||||
InsecureSkipVerify: true,
|
||||
BindDn: "cn=manager,cn=config",
|
||||
BindPassword: "secret",
|
||||
@@ -157,7 +158,7 @@ func TestOpenldapReverseMetrics(t *testing.T) {
|
||||
o := &Openldap{
|
||||
Host: testutil.GetLocalHost(),
|
||||
Port: 389,
|
||||
Ssl: "",
|
||||
SSL: "",
|
||||
InsecureSkipVerify: true,
|
||||
BindDn: "cn=manager,cn=config",
|
||||
BindPassword: "secret",
|
||||
|
||||
@@ -31,6 +31,21 @@ telegraf ALL=(root) NOPASSWD: /sbin/pfctl -s info
|
||||
- searches (integer, count)
|
||||
- inserts (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:
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ func errMissingData(tag string) error {
|
||||
|
||||
type pfctlOutputStanza struct {
|
||||
HeaderRE *regexp.Regexp
|
||||
ParseFunc func([]string, telegraf.Accumulator) error
|
||||
ParseFunc func([]string, map[string]interface{}) error
|
||||
Found bool
|
||||
}
|
||||
|
||||
@@ -76,11 +76,16 @@ var pfctlOutputStanzas = []*pfctlOutputStanza{
|
||||
HeaderRE: regexp.MustCompile("^State Table"),
|
||||
ParseFunc: parseStateTable,
|
||||
},
|
||||
&pfctlOutputStanza{
|
||||
HeaderRE: regexp.MustCompile("^Counters"),
|
||||
ParseFunc: parseCounterTable,
|
||||
},
|
||||
}
|
||||
|
||||
var anyTableHeaderRE = regexp.MustCompile("^[A-Z]")
|
||||
|
||||
func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error {
|
||||
fields := make(map[string]interface{})
|
||||
scanner := bufio.NewScanner(strings.NewReader(pfoutput))
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
@@ -91,10 +96,14 @@ func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error
|
||||
line = scanner.Text()
|
||||
for !anyTableHeaderRE.MatchString(line) {
|
||||
stanzaLines = append(stanzaLines, line)
|
||||
scanner.Scan()
|
||||
line = scanner.Text()
|
||||
more := scanner.Scan()
|
||||
if more {
|
||||
line = scanner.Text()
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if perr := s.ParseFunc(stanzaLines, acc); perr != nil {
|
||||
if perr := s.ParseFunc(stanzaLines, fields); perr != nil {
|
||||
return perr
|
||||
}
|
||||
s.Found = true
|
||||
@@ -106,6 +115,8 @@ func (pf *PF) parsePfctlOutput(pfoutput string, acc telegraf.Accumulator) error
|
||||
return errParseHeader
|
||||
}
|
||||
}
|
||||
|
||||
acc.AddFields(measurement, fields, make(map[string]string))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -124,11 +135,40 @@ var StateTable = []*Entry{
|
||||
|
||||
var stateTableRE = regexp.MustCompile(`^ (.*?)\s+(\d+)`)
|
||||
|
||||
func parseStateTable(lines []string, acc telegraf.Accumulator) error {
|
||||
func parseStateTable(lines []string, fields map[string]interface{}) 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 {
|
||||
entries := stateTableRE.FindStringSubmatch(v)
|
||||
entries := regex.FindStringSubmatch(v)
|
||||
if entries != nil {
|
||||
for _, f := range StateTable {
|
||||
for _, f := range entryTable {
|
||||
if f.PfctlTitle == entries[1] {
|
||||
var err error
|
||||
if f.Value, err = strconv.ParseInt(entries[2], 10, 64); err != nil {
|
||||
@@ -139,15 +179,13 @@ func parseStateTable(lines []string, acc telegraf.Accumulator) error {
|
||||
}
|
||||
}
|
||||
|
||||
fields := make(map[string]interface{})
|
||||
for _, v := range StateTable {
|
||||
for _, v := range entryTable {
|
||||
if v.Value == -1 {
|
||||
return errMissingData(v.PfctlTitle)
|
||||
}
|
||||
fields[v.Field] = v.Value
|
||||
}
|
||||
|
||||
acc.AddFields(measurement, fields, make(map[string]string))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -152,10 +152,25 @@ Counters
|
||||
measurements: []measurementResult{
|
||||
measurementResult{
|
||||
fields: map[string]interface{}{
|
||||
"entries": int64(2),
|
||||
"searches": int64(11325),
|
||||
"inserts": int64(5),
|
||||
"removals": int64(3)},
|
||||
"entries": int64(2),
|
||||
"searches": int64(11325),
|
||||
"inserts": int64(5),
|
||||
"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{},
|
||||
},
|
||||
},
|
||||
@@ -197,10 +212,25 @@ Counters
|
||||
measurements: []measurementResult{
|
||||
measurementResult{
|
||||
fields: map[string]interface{}{
|
||||
"entries": int64(649),
|
||||
"searches": int64(18421725761),
|
||||
"inserts": int64(156762508),
|
||||
"removals": int64(156761859)},
|
||||
"entries": int64(649),
|
||||
"searches": int64(18421725761),
|
||||
"inserts": int64(156762508),
|
||||
"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{},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -175,7 +175,7 @@ func (p *Ping) args(url string) []string {
|
||||
}
|
||||
if p.Timeout > 0 {
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
case "darwin", "freebsd", "netbsd", "openbsd":
|
||||
args = append(args, "-W", strconv.FormatFloat(p.Timeout*1000, 'f', -1, 64))
|
||||
case "linux":
|
||||
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 {
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
case "darwin", "freebsd", "netbsd", "openbsd":
|
||||
args = append(args, "-t", strconv.Itoa(p.Deadline))
|
||||
case "linux":
|
||||
args = append(args, "-w", strconv.Itoa(p.Deadline))
|
||||
@@ -197,10 +197,10 @@ func (p *Ping) args(url string) []string {
|
||||
}
|
||||
if p.Interface != "" {
|
||||
switch runtime.GOOS {
|
||||
case "darwin", "freebsd", "netbsd", "openbsd":
|
||||
args = append(args, "-S", p.Interface)
|
||||
case "linux":
|
||||
args = append(args, "-I", p.Interface)
|
||||
case "freebsd", "darwin":
|
||||
args = append(args, "-S", p.Interface)
|
||||
default:
|
||||
// Not sure the best option here, just assume GNU ping?
|
||||
args = append(args, "-I", p.Interface)
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -28,36 +28,37 @@ func getQueueDirectory() (string, error) {
|
||||
return strings.TrimSpace(string(qd)), nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func qScan(path string, acc telegraf.Accumulator) (int64, int64, int64, error) {
|
||||
var length, size int64
|
||||
var oldest time.Time
|
||||
for _, finfo := range finfos {
|
||||
err := filepath.Walk(path, func(_ string, finfo os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
acc.AddError(fmt.Errorf("error scanning %s: %s", path, err))
|
||||
return nil
|
||||
}
|
||||
if finfo.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
length++
|
||||
size += finfo.Size()
|
||||
|
||||
ctime := statCTime(finfo.Sys())
|
||||
if ctime.IsZero() {
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
if oldest.IsZero() || ctime.Before(oldest) {
|
||||
oldest = ctime
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
var age int64
|
||||
if !oldest.IsZero() {
|
||||
age = int64(time.Now().Sub(oldest) / time.Second)
|
||||
} else if len(finfos) != 0 {
|
||||
} else if length != 0 {
|
||||
// system doesn't support ctime
|
||||
age = -1
|
||||
}
|
||||
@@ -77,8 +78,8 @@ func (p *Postfix) Gather(acc telegraf.Accumulator) error {
|
||||
}
|
||||
}
|
||||
|
||||
for _, q := range []string{"active", "hold", "incoming", "maildrop"} {
|
||||
length, size, age, err := qScan(path.Join(p.QueueDirectory, q))
|
||||
for _, q := range []string{"active", "hold", "incoming", "maildrop", "deferred"} {
|
||||
length, size, age, err := qScan(filepath.Join(p.QueueDirectory, q), acc)
|
||||
if err != nil {
|
||||
acc.AddError(fmt.Errorf("error scanning queue %s: %s", q, err))
|
||||
continue
|
||||
@@ -90,30 +91,6 @@ func (p *Postfix) Gather(acc telegraf.Accumulator) error {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package postfix
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
@@ -16,19 +16,16 @@ func TestGather(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(td)
|
||||
|
||||
for _, q := range []string{"active", "hold", "incoming", "maildrop", "deferred"} {
|
||||
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))
|
||||
for _, q := range []string{"active", "hold", "incoming", "maildrop", "deferred/0/0", "deferred/F/F"} {
|
||||
require.NoError(t, os.MkdirAll(filepath.FromSlash(td+"/"+q), 0755))
|
||||
}
|
||||
|
||||
require.NoError(t, ioutil.WriteFile(path.Join(td, "active", "01"), []byte("abc"), 0644))
|
||||
require.NoError(t, ioutil.WriteFile(path.Join(td, "active", "02"), []byte("defg"), 0644))
|
||||
require.NoError(t, ioutil.WriteFile(path.Join(td, "hold", "01"), []byte("abc"), 0644))
|
||||
require.NoError(t, ioutil.WriteFile(path.Join(td, "incoming", "01"), []byte("abcd"), 0644))
|
||||
require.NoError(t, ioutil.WriteFile(path.Join(td, "deferred", "0", "01"), []byte("abc"), 0644))
|
||||
require.NoError(t, ioutil.WriteFile(path.Join(td, "deferred", "F", "F1"), []byte("abc"), 0644))
|
||||
require.NoError(t, ioutil.WriteFile(filepath.FromSlash(td+"/active/01"), []byte("abc"), 0644))
|
||||
require.NoError(t, ioutil.WriteFile(filepath.FromSlash(td+"/active/02"), []byte("defg"), 0644))
|
||||
require.NoError(t, ioutil.WriteFile(filepath.FromSlash(td+"/hold/01"), []byte("abc"), 0644))
|
||||
require.NoError(t, ioutil.WriteFile(filepath.FromSlash(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(filepath.FromSlash(td+"/deferred/F/F/F1"), []byte("abc"), 0644))
|
||||
|
||||
p := Postfix{
|
||||
QueueDirectory: td,
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/influxdata/telegraf/internal"
|
||||
)
|
||||
|
||||
// Implemention of PIDGatherer that execs pgrep to find processes
|
||||
@@ -62,6 +64,12 @@ func find(path string, args []string) ([]PID, error) {
|
||||
|
||||
func run(path string, args []string) (string, error) {
|
||||
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 {
|
||||
return "", fmt.Errorf("Error running %s: %s", path, err)
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ func (p *Procstat) Gather(acc telegraf.Accumulator) error {
|
||||
p.createProcess = defaultProcess
|
||||
}
|
||||
|
||||
procs, err := p.updateProcesses(p.procs)
|
||||
procs, err := p.updateProcesses(acc, p.procs)
|
||||
if err != nil {
|
||||
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()))
|
||||
@@ -230,8 +230,8 @@ func (p *Procstat) addMetrics(proc Process, acc telegraf.Accumulator) {
|
||||
}
|
||||
|
||||
// Update monitored Processes
|
||||
func (p *Procstat) updateProcesses(prevInfo map[PID]Process) (map[PID]Process, error) {
|
||||
pids, tags, err := p.findPids()
|
||||
func (p *Procstat) updateProcesses(acc telegraf.Accumulator, prevInfo map[PID]Process) (map[PID]Process, error) {
|
||||
pids, tags, err := p.findPids(acc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -281,9 +281,9 @@ func (p *Procstat) getPIDFinder() (PIDFinder, error) {
|
||||
}
|
||||
|
||||
// Get matching PIDs and their initial tags
|
||||
func (p *Procstat) findPids() ([]PID, map[string]string, error) {
|
||||
func (p *Procstat) findPids(acc telegraf.Accumulator) ([]PID, map[string]string, error) {
|
||||
var pids []PID
|
||||
var tags map[string]string
|
||||
tags := make(map[string]string)
|
||||
var err error
|
||||
|
||||
f, err := p.getPIDFinder()
|
||||
@@ -313,7 +313,18 @@ func (p *Procstat) findPids() ([]PID, map[string]string, error) {
|
||||
err = fmt.Errorf("Either exe, pid_file, user, pattern, systemd_unit, or cgroup must be specified")
|
||||
}
|
||||
|
||||
return pids, tags, err
|
||||
rTags := make(map[string]string)
|
||||
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.
|
||||
|
||||
@@ -343,7 +343,8 @@ func TestGather_systemdUnitPIDs(t *testing.T) {
|
||||
createPIDFinder: pidFinder([]PID{}, nil),
|
||||
SystemdUnit: "TestGather_systemdUnitPIDs",
|
||||
}
|
||||
pids, tags, err := p.findPids()
|
||||
var acc testutil.Accumulator
|
||||
pids, tags, err := p.findPids(&acc)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []PID{11408}, pids)
|
||||
assert.Equal(t, "TestGather_systemdUnitPIDs", tags["systemd_unit"])
|
||||
@@ -364,8 +365,20 @@ func TestGather_cgroupPIDs(t *testing.T) {
|
||||
createPIDFinder: pidFinder([]PID{}, nil),
|
||||
CGroup: td,
|
||||
}
|
||||
pids, tags, err := p.findPids()
|
||||
var acc testutil.Accumulator
|
||||
pids, tags, err := p.findPids(&acc)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []PID{1234, 5678}, pids)
|
||||
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))
|
||||
}
|
||||
|
||||
@@ -14,6 +14,13 @@
|
||||
## If no servers are specified, then localhost is used as the host.
|
||||
## If no port is specified, 6379 is used
|
||||
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:
|
||||
|
||||
@@ -13,11 +13,13 @@ import (
|
||||
|
||||
"github.com/go-redis/redis"
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/internal/tls"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
type Redis struct {
|
||||
Servers []string
|
||||
tls.ClientConfig
|
||||
|
||||
clients []Client
|
||||
initialized bool
|
||||
@@ -56,6 +58,13 @@ var sampleConfig = `
|
||||
## If no servers are specified, then localhost is used as the host.
|
||||
## If no port is specified, 6379 is used
|
||||
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 {
|
||||
@@ -109,12 +118,18 @@ func (r *Redis) init(acc telegraf.Accumulator) error {
|
||||
address = u.Host
|
||||
}
|
||||
|
||||
tlsConfig, err := r.ClientConfig.TLSConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client := redis.NewClient(
|
||||
&redis.Options{
|
||||
Addr: address,
|
||||
Password: password,
|
||||
Network: u.Scheme,
|
||||
PoolSize: 1,
|
||||
Addr: address,
|
||||
Password: password,
|
||||
Network: u.Scheme,
|
||||
PoolSize: 1,
|
||||
TLSConfig: tlsConfig,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -218,10 +218,20 @@ func (t *Table) initBuild() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if t.Name == "" {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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.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.4"},
|
||||
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.0.1.5"},
|
||||
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.2.3"},
|
||||
{"snmptranslate", "-Td", "-Ob", ".iso.2.3"},
|
||||
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".999"},
|
||||
@@ -30,6 +30,7 @@ var mockedCommands = [][]string{
|
||||
{"snmptranslate", "-Td", "-Ob", "TEST::testTable"},
|
||||
{"snmptranslate", "-Td", "-Ob", "TEST::connections"},
|
||||
{"snmptranslate", "-Td", "-Ob", "TEST::latency"},
|
||||
{"snmptranslate", "-Td", "-Ob", "TEST::description"},
|
||||
{"snmptranslate", "-Td", "-Ob", "TEST::hostname"},
|
||||
{"snmptranslate", "-Td", "-Ob", "IF-MIB::ifPhysAddress.1"},
|
||||
{"snmptranslate", "-Td", "-Ob", "BRIDGE-MIB::dot1dTpFdbAddress.1"},
|
||||
|
||||
@@ -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\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.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.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.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},
|
||||
@@ -76,10 +76,11 @@ 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::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::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\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\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},
|
||||
"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},
|
||||
"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},
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ var tsc = &testSNMPConnection{
|
||||
".1.0.0.0.1.3.1": "0.456",
|
||||
".1.0.0.0.1.3.2": "0.000",
|
||||
".1.0.0.0.1.3.3": "9.999",
|
||||
".1.0.0.0.1.4.0": 123456,
|
||||
".1.0.0.0.1.5.0": 123456,
|
||||
".1.0.0.1.1": "baz",
|
||||
".1.0.0.1.2": 234,
|
||||
".1.0.0.1.3": []byte("byte slice"),
|
||||
@@ -159,19 +159,23 @@ func TestFieldInit(t *testing.T) {
|
||||
|
||||
func TestTableInit(t *testing.T) {
|
||||
tbl := Table{
|
||||
Oid: ".1.0.0.0",
|
||||
Fields: []Field{{Oid: ".999", Name: "foo"}},
|
||||
Oid: ".1.0.0.0",
|
||||
Fields: []Field{
|
||||
{Oid: ".999", Name: "foo"},
|
||||
{Oid: "TEST::description", Name: "description", IsTag: true},
|
||||
},
|
||||
}
|
||||
err := tbl.init()
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "testTable", tbl.Name)
|
||||
|
||||
assert.Len(t, tbl.Fields, 4)
|
||||
assert.Len(t, tbl.Fields, 5)
|
||||
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.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.4", Name: "description", IsTag: true, initialized: true})
|
||||
}
|
||||
|
||||
func TestSnmpInit(t *testing.T) {
|
||||
@@ -187,10 +191,11 @@ func TestSnmpInit(t *testing.T) {
|
||||
err := s.init()
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, s.Tables[0].Fields, 3)
|
||||
assert.Len(t, s.Tables[0].Fields, 4)
|
||||
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.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{
|
||||
Oid: ".1.0.0.1.1",
|
||||
@@ -579,7 +584,7 @@ func TestGather(t *testing.T) {
|
||||
Fields: []Field{
|
||||
{
|
||||
Name: "myOtherField",
|
||||
Oid: ".1.0.0.0.1.4",
|
||||
Oid: ".1.0.0.0.1.5",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
7
plugins/inputs/snmp/testdata/test.mib
vendored
7
plugins/inputs/snmp/testdata/test.mib
vendored
@@ -22,6 +22,7 @@ TestTableEntry ::=
|
||||
server OCTET STRING,
|
||||
connections INTEGER,
|
||||
latency OCTET STRING,
|
||||
description OCTET STRING,
|
||||
}
|
||||
|
||||
server OBJECT-TYPE
|
||||
@@ -42,6 +43,12 @@ latency OBJECT-TYPE
|
||||
STATUS current
|
||||
::= { testTableEntry 3 }
|
||||
|
||||
description OBJECT-TYPE
|
||||
SYNTAX OCTET STRING
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
::= { testTableEntry 4 }
|
||||
|
||||
hostname OBJECT-TYPE
|
||||
SYNTAX OCTET STRING
|
||||
MAX-ACCESS read-only
|
||||
|
||||
@@ -3,9 +3,11 @@ package socket_listener
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -50,14 +52,17 @@ func TestSocketListener_tcp_tls(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSocketListener_unix_tls(t *testing.T) {
|
||||
defer testEmptyLog(t)()
|
||||
tmpdir, err := ioutil.TempDir("", "telegraf")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
sock := filepath.Join(tmpdir, "socket_listener.TestSocketListener_unix_tls.sock")
|
||||
|
||||
sl := newSocketListener()
|
||||
sl.ServiceAddress = "unix:///tmp/telegraf_test.sock"
|
||||
sl.ServiceAddress = "unix://" + sock
|
||||
sl.ServerConfig = *pki.TLSServerConfig()
|
||||
|
||||
acc := &testutil.Accumulator{}
|
||||
err := sl.Start(acc)
|
||||
err = sl.Start(acc)
|
||||
require.NoError(t, err)
|
||||
defer sl.Stop()
|
||||
|
||||
@@ -65,7 +70,7 @@ func TestSocketListener_unix_tls(t *testing.T) {
|
||||
tlsCfg.InsecureSkipVerify = true
|
||||
require.NoError(t, err)
|
||||
|
||||
secureClient, err := tls.Dial("unix", "/tmp/telegraf_test.sock", tlsCfg)
|
||||
secureClient, err := tls.Dial("unix", sock, tlsCfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
testSocketListener(t, sl, secureClient)
|
||||
@@ -108,38 +113,48 @@ func TestSocketListener_udp(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)()
|
||||
|
||||
os.Create("/tmp/telegraf_test.sock")
|
||||
os.Create(sock)
|
||||
sl := newSocketListener()
|
||||
sl.ServiceAddress = "unix:///tmp/telegraf_test.sock"
|
||||
sl.ServiceAddress = "unix://" + sock
|
||||
sl.ReadBufferSize = 1024
|
||||
|
||||
acc := &testutil.Accumulator{}
|
||||
err := sl.Start(acc)
|
||||
err = sl.Start(acc)
|
||||
require.NoError(t, err)
|
||||
defer sl.Stop()
|
||||
|
||||
client, err := net.Dial("unix", "/tmp/telegraf_test.sock")
|
||||
client, err := net.Dial("unix", sock)
|
||||
require.NoError(t, err)
|
||||
|
||||
testSocketListener(t, sl, client)
|
||||
}
|
||||
|
||||
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)()
|
||||
|
||||
os.Create("/tmp/telegraf_test.sock")
|
||||
os.Create(sock)
|
||||
sl := newSocketListener()
|
||||
sl.ServiceAddress = "unixgram:///tmp/telegraf_test.sock"
|
||||
sl.ServiceAddress = "unixgram://" + sock
|
||||
sl.ReadBufferSize = 1024
|
||||
|
||||
acc := &testutil.Accumulator{}
|
||||
err := sl.Start(acc)
|
||||
err = sl.Start(acc)
|
||||
require.NoError(t, err)
|
||||
defer sl.Stop()
|
||||
|
||||
client, err := net.Dial("unixgram", "/tmp/telegraf_test.sock")
|
||||
client, err := net.Dial("unixgram", sock)
|
||||
require.NoError(t, err)
|
||||
|
||||
testSocketListener(t, sl, client)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Tested from 3.5 to 6.*
|
||||
Tested from 3.5 to 7.*
|
||||
|
||||
### Configuration:
|
||||
|
||||
|
||||
@@ -113,20 +113,7 @@ type Hitratio interface{}
|
||||
// Cache is an exported type that
|
||||
// contains cache metrics
|
||||
type Cache struct {
|
||||
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"`
|
||||
Stats map[string]interface{} `json:"stats"`
|
||||
}
|
||||
|
||||
// NewSolr return a new instance of Solr
|
||||
@@ -424,21 +411,30 @@ func addCacheMetricsToAcc(acc telegraf.Accumulator, core string, mBeansData *MBe
|
||||
return err
|
||||
}
|
||||
for name, metrics := range cacheMetrics {
|
||||
cumulativeHits := getFloat(metrics.Stats.CumulativeHitratio)
|
||||
hitratio := getFloat(metrics.Stats.Hitratio)
|
||||
coreFields := map[string]interface{}{
|
||||
"cumulative_evictions": metrics.Stats.CumulativeEvictions,
|
||||
"cumulative_hitratio": cumulativeHits,
|
||||
"cumulative_hits": metrics.Stats.CumulativeHits,
|
||||
"cumulative_inserts": metrics.Stats.CumulativeInserts,
|
||||
"cumulative_lookups": metrics.Stats.CumulativeLookups,
|
||||
"evictions": metrics.Stats.Evictions,
|
||||
"hitratio": hitratio,
|
||||
"hits": metrics.Stats.Hits,
|
||||
"inserts": metrics.Stats.Inserts,
|
||||
"lookups": metrics.Stats.Lookups,
|
||||
"size": metrics.Stats.Size,
|
||||
"warmup_time": metrics.Stats.WarmupTime,
|
||||
coreFields := make(map[string]interface{})
|
||||
for key, value := range metrics.Stats {
|
||||
splitKey := strings.Split(key, ".")
|
||||
newKey := splitKey[len(splitKey)-1]
|
||||
switch newKey {
|
||||
case "cumulative_evictions",
|
||||
"cumulative_hits",
|
||||
"cumulative_inserts",
|
||||
"cumulative_lookups",
|
||||
"eviction",
|
||||
"hits",
|
||||
"inserts",
|
||||
"lookups",
|
||||
"size",
|
||||
"evictions":
|
||||
coreFields[newKey] = getInt(value)
|
||||
case "hitratio",
|
||||
"cumulative_hitratio":
|
||||
coreFields[newKey] = getFloat(value)
|
||||
case "warmupTime":
|
||||
coreFields["warmup_time"] = getInt(value)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
acc.AddFields(
|
||||
"solr_cache",
|
||||
|
||||
@@ -43,6 +43,17 @@ func TestGatherStats(t *testing.T) {
|
||||
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) {
|
||||
ts := createMockSolr3Server()
|
||||
solr := NewSolr()
|
||||
@@ -150,3 +161,18 @@ 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")
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
60
plugins/inputs/solr/testdata7_test.go
Normal file
60
plugins/inputs/solr/testdata7_test.go
Normal file
@@ -0,0 +1,60 @@
|
||||
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),
|
||||
}
|
||||
98
plugins/inputs/syslog/README.md
Normal file
98
plugins/inputs/syslog/README.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# 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).
|
||||
539
plugins/inputs/syslog/rfc5425_test.go
Normal file
539
plugins/inputs/syslog/rfc5425_test.go
Normal file
@@ -0,0 +1,539 @@
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/influxdata/telegraf/internal"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
pki = testutil.NewPKI("../../../testutil/pki")
|
||||
)
|
||||
|
||||
type testCase5425 struct {
|
||||
name string
|
||||
data []byte
|
||||
wantBestEffort []testutil.Metric
|
||||
wantStrict []testutil.Metric
|
||||
werr int // how many errors we expect in the strict mode?
|
||||
}
|
||||
|
||||
func getTestCasesForRFC5425() []testCase5425 {
|
||||
testCases := []testCase5425{
|
||||
{
|
||||
name: "1st/avg/ok",
|
||||
data: []byte(`188 <29>1 2016-02-21T04:32:57+00:00 web1 someservice 2341 2 [origin][meta sequence="14125553" service="someservice"] "GET /v1/ok HTTP/1.1" 200 145 "-" "hacheck 0.9.0" 24306 127.0.0.1:40124 575`),
|
||||
wantStrict: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"timestamp": time.Unix(1456029177, 0).UnixNano(),
|
||||
"procid": "2341",
|
||||
"msgid": "2",
|
||||
"message": `"GET /v1/ok HTTP/1.1" 200 145 "-" "hacheck 0.9.0" 24306 127.0.0.1:40124 575`,
|
||||
"origin": true,
|
||||
"meta_sequence": "14125553",
|
||||
"meta_service": "someservice",
|
||||
"severity_code": 5,
|
||||
"facility_code": 3,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "notice",
|
||||
"facility": "daemon",
|
||||
"hostname": "web1",
|
||||
"appname": "someservice",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
wantBestEffort: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"timestamp": time.Unix(1456029177, 0).UnixNano(),
|
||||
"procid": "2341",
|
||||
"msgid": "2",
|
||||
"message": `"GET /v1/ok HTTP/1.1" 200 145 "-" "hacheck 0.9.0" 24306 127.0.0.1:40124 575`,
|
||||
"origin": true,
|
||||
"meta_sequence": "14125553",
|
||||
"meta_service": "someservice",
|
||||
"severity_code": 5,
|
||||
"facility_code": 3,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "notice",
|
||||
"facility": "daemon",
|
||||
"hostname": "web1",
|
||||
"appname": "someservice",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "1st/min/ok//2nd/min/ok",
|
||||
data: []byte("16 <1>2 - - - - - -17 <4>11 - - - - - -"),
|
||||
wantStrict: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(2),
|
||||
"severity_code": 1,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(11),
|
||||
"severity_code": 4,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "warning",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime.Add(time.Nanosecond),
|
||||
},
|
||||
},
|
||||
wantBestEffort: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(2),
|
||||
"severity_code": 1,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(11),
|
||||
"severity_code": 4,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "warning",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime.Add(time.Nanosecond),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "1st/utf8/ok",
|
||||
data: []byte("23 <1>1 - - - - - - hellø"),
|
||||
wantStrict: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"message": "hellø",
|
||||
"severity_code": 1,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
wantBestEffort: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"message": "hellø",
|
||||
"severity_code": 1,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "1st/nl/ok", // newline
|
||||
data: []byte("28 <1>3 - - - - - - hello\nworld"),
|
||||
wantStrict: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(3),
|
||||
"message": "hello\nworld",
|
||||
"severity_code": 1,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
wantBestEffort: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(3),
|
||||
"message": "hello\nworld",
|
||||
"severity_code": 1,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "1st/uf/ko", // underflow (msglen less than provided octets)
|
||||
data: []byte("16 <1>2"),
|
||||
wantStrict: nil,
|
||||
wantBestEffort: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(2),
|
||||
"severity_code": 1,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
werr: 1,
|
||||
},
|
||||
{
|
||||
name: "1st/min/ok",
|
||||
data: []byte("16 <1>1 - - - - - -"),
|
||||
wantStrict: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"severity_code": 1,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
wantBestEffort: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"severity_code": 1,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "1st/uf/mf", // The first "underflow" message breaks also the second one
|
||||
data: []byte("16 <1>217 <11>1 - - - - - -"),
|
||||
wantStrict: nil,
|
||||
wantBestEffort: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(217),
|
||||
"severity_code": 1,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
werr: 1,
|
||||
},
|
||||
// {
|
||||
// name: "1st/of/ko", // overflow (msglen greather then max allowed octets)
|
||||
// data: []byte(fmt.Sprintf("8193 <%d>%d %s %s %s %s %s 12 %s", maxP, maxV, maxTS, maxH, maxA, maxPID, maxMID, message7681)),
|
||||
// want: []testutil.Metric{},
|
||||
// },
|
||||
{
|
||||
name: "1st/max/ok",
|
||||
data: []byte(fmt.Sprintf("8192 <%d>%d %s %s %s %s %s - %s", maxP, maxV, maxTS, maxH, maxA, maxPID, maxMID, message7681)),
|
||||
wantStrict: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": maxV,
|
||||
"timestamp": time.Unix(1514764799, 999999000).UnixNano(),
|
||||
"message": message7681,
|
||||
"procid": maxPID,
|
||||
"msgid": maxMID,
|
||||
"facility_code": 23,
|
||||
"severity_code": 7,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "debug",
|
||||
"facility": "local7",
|
||||
"hostname": maxH,
|
||||
"appname": maxA,
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
wantBestEffort: []testutil.Metric{
|
||||
testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": maxV,
|
||||
"timestamp": time.Unix(1514764799, 999999000).UnixNano(),
|
||||
"message": message7681,
|
||||
"procid": maxPID,
|
||||
"msgid": maxMID,
|
||||
"facility_code": 23,
|
||||
"severity_code": 7,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "debug",
|
||||
"facility": "local7",
|
||||
"hostname": maxH,
|
||||
"appname": maxA,
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return testCases
|
||||
}
|
||||
|
||||
func newTCPSyslogReceiver(address string, keepAlive *internal.Duration, maxConn int, bestEffort bool) *Syslog {
|
||||
d := &internal.Duration{
|
||||
Duration: defaultReadTimeout,
|
||||
}
|
||||
s := &Syslog{
|
||||
Address: address,
|
||||
now: func() time.Time {
|
||||
return defaultTime
|
||||
},
|
||||
ReadTimeout: d,
|
||||
BestEffort: bestEffort,
|
||||
Separator: "_",
|
||||
}
|
||||
if keepAlive != nil {
|
||||
s.KeepAlivePeriod = keepAlive
|
||||
}
|
||||
if maxConn > 0 {
|
||||
s.MaxConnections = maxConn
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func testStrictRFC5425(t *testing.T, protocol string, address string, wantTLS bool, keepAlive *internal.Duration) {
|
||||
for _, tc := range getTestCasesForRFC5425() {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Creation of a strict mode receiver
|
||||
receiver := newTCPSyslogReceiver(protocol+"://"+address, keepAlive, 0, false)
|
||||
require.NotNil(t, receiver)
|
||||
if wantTLS {
|
||||
receiver.ServerConfig = *pki.TLSServerConfig()
|
||||
}
|
||||
require.Equal(t, receiver.KeepAlivePeriod, keepAlive)
|
||||
acc := &testutil.Accumulator{}
|
||||
require.NoError(t, receiver.Start(acc))
|
||||
defer receiver.Stop()
|
||||
|
||||
// Connect
|
||||
var conn net.Conn
|
||||
var err error
|
||||
if wantTLS {
|
||||
config, e := pki.TLSClientConfig().TLSConfig()
|
||||
require.NoError(t, e)
|
||||
config.ServerName = "localhost"
|
||||
conn, err = tls.Dial(protocol, address, config)
|
||||
} else {
|
||||
conn, err = net.Dial(protocol, address)
|
||||
defer conn.Close()
|
||||
}
|
||||
require.NotNil(t, conn)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Clear
|
||||
acc.ClearMetrics()
|
||||
acc.Errors = make([]error, 0)
|
||||
|
||||
// Write
|
||||
conn.Write(tc.data)
|
||||
|
||||
// Wait that the the number of data points is accumulated
|
||||
// Since the receiver is running concurrently
|
||||
if tc.wantStrict != nil {
|
||||
acc.Wait(len(tc.wantStrict))
|
||||
}
|
||||
// Wait the parsing error
|
||||
acc.WaitError(tc.werr)
|
||||
|
||||
// Verify
|
||||
if len(acc.Errors) != tc.werr {
|
||||
t.Fatalf("Got unexpected errors. want error = %v, errors = %v\n", tc.werr, acc.Errors)
|
||||
}
|
||||
var got []testutil.Metric
|
||||
for _, metric := range acc.Metrics {
|
||||
got = append(got, *metric)
|
||||
}
|
||||
if !cmp.Equal(tc.wantStrict, got) {
|
||||
t.Fatalf("Got (+) / Want (-)\n %s", cmp.Diff(tc.wantStrict, got))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testBestEffortRFC5425(t *testing.T, protocol string, address string, wantTLS bool, keepAlive *internal.Duration) {
|
||||
for _, tc := range getTestCasesForRFC5425() {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Creation of a best effort mode receiver
|
||||
receiver := newTCPSyslogReceiver(protocol+"://"+address, keepAlive, 0, true)
|
||||
require.NotNil(t, receiver)
|
||||
if wantTLS {
|
||||
receiver.ServerConfig = *pki.TLSServerConfig()
|
||||
}
|
||||
require.Equal(t, receiver.KeepAlivePeriod, keepAlive)
|
||||
acc := &testutil.Accumulator{}
|
||||
require.NoError(t, receiver.Start(acc))
|
||||
defer receiver.Stop()
|
||||
|
||||
// Connect
|
||||
var conn net.Conn
|
||||
var err error
|
||||
if wantTLS {
|
||||
config, e := pki.TLSClientConfig().TLSConfig()
|
||||
require.NoError(t, e)
|
||||
config.ServerName = "localhost"
|
||||
conn, err = tls.Dial(protocol, address, config)
|
||||
} else {
|
||||
conn, err = net.Dial(protocol, address)
|
||||
defer conn.Close()
|
||||
}
|
||||
require.NotNil(t, conn)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Clear
|
||||
acc.ClearMetrics()
|
||||
acc.Errors = make([]error, 0)
|
||||
|
||||
// Write
|
||||
conn.Write(tc.data)
|
||||
|
||||
// Wait that the the number of data points is accumulated
|
||||
// Since the receiver is running concurrently
|
||||
if tc.wantBestEffort != nil {
|
||||
acc.Wait(len(tc.wantBestEffort))
|
||||
}
|
||||
|
||||
// Verify
|
||||
var got []testutil.Metric
|
||||
for _, metric := range acc.Metrics {
|
||||
got = append(got, *metric)
|
||||
}
|
||||
if !cmp.Equal(tc.wantBestEffort, got) {
|
||||
t.Fatalf("Got (+) / Want (-)\n %s", cmp.Diff(tc.wantBestEffort, got))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrict_tcp(t *testing.T) {
|
||||
testStrictRFC5425(t, "tcp", address, false, nil)
|
||||
}
|
||||
|
||||
func TestBestEffort_tcp(t *testing.T) {
|
||||
testBestEffortRFC5425(t, "tcp", address, false, nil)
|
||||
}
|
||||
|
||||
func TestStrict_tcp_tls(t *testing.T) {
|
||||
testStrictRFC5425(t, "tcp", address, true, nil)
|
||||
}
|
||||
|
||||
func TestBestEffort_tcp_tls(t *testing.T) {
|
||||
testBestEffortRFC5425(t, "tcp", address, true, nil)
|
||||
}
|
||||
|
||||
func TestStrictWithKeepAlive_tcp_tls(t *testing.T) {
|
||||
testStrictRFC5425(t, "tcp", address, true, &internal.Duration{Duration: time.Minute})
|
||||
}
|
||||
|
||||
func TestStrictWithZeroKeepAlive_tcp_tls(t *testing.T) {
|
||||
testStrictRFC5425(t, "tcp", address, true, &internal.Duration{Duration: 0})
|
||||
}
|
||||
|
||||
func TestStrict_unix(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "telegraf")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
sock := filepath.Join(tmpdir, "syslog.TestStrict_unix.sock")
|
||||
testStrictRFC5425(t, "unix", sock, false, nil)
|
||||
}
|
||||
|
||||
func TestBestEffort_unix(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "telegraf")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
sock := filepath.Join(tmpdir, "syslog.TestBestEffort_unix.sock")
|
||||
testBestEffortRFC5425(t, "unix", sock, false, nil)
|
||||
}
|
||||
|
||||
func TestStrict_unix_tls(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "telegraf")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
sock := filepath.Join(tmpdir, "syslog.TestStrict_unix_tls.sock")
|
||||
testStrictRFC5425(t, "unix", sock, true, nil)
|
||||
}
|
||||
|
||||
func TestBestEffort_unix_tls(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "telegraf")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
sock := filepath.Join(tmpdir, "syslog.TestBestEffort_unix_tls.sock")
|
||||
testBestEffortRFC5425(t, "unix", sock, true, nil)
|
||||
}
|
||||
408
plugins/inputs/syslog/rfc5426_test.go
Normal file
408
plugins/inputs/syslog/rfc5426_test.go
Normal file
@@ -0,0 +1,408 @@
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type testCase5426 struct {
|
||||
name string
|
||||
data []byte
|
||||
wantBestEffort *testutil.Metric
|
||||
wantStrict *testutil.Metric
|
||||
werr bool
|
||||
}
|
||||
|
||||
func getTestCasesForRFC5426() []testCase5426 {
|
||||
testCases := []testCase5426{
|
||||
{
|
||||
name: "empty",
|
||||
data: []byte(""),
|
||||
werr: true,
|
||||
},
|
||||
{
|
||||
name: "complete",
|
||||
data: []byte("<1>1 - - - - - - A"),
|
||||
wantBestEffort: &testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"message": "A",
|
||||
"facility_code": 0,
|
||||
"severity_code": 1,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
wantStrict: &testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"message": "A",
|
||||
"facility_code": 0,
|
||||
"severity_code": 1,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "one/per/packet",
|
||||
data: []byte("<1>3 - - - - - - A<1>4 - - - - - - B"),
|
||||
wantBestEffort: &testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(3),
|
||||
"message": "A<1>4 - - - - - - B",
|
||||
"severity_code": 1,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
wantStrict: &testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(3),
|
||||
"message": "A<1>4 - - - - - - B",
|
||||
"severity_code": 1,
|
||||
"facility_code": 0,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "average",
|
||||
data: []byte(`<29>1 2016-02-21T04:32:57+00:00 web1 someservice 2341 2 [origin][meta sequence="14125553" service="someservice"] "GET /v1/ok HTTP/1.1" 200 145 "-" "hacheck 0.9.0" 24306 127.0.0.1:40124 575`),
|
||||
wantBestEffort: &testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"timestamp": time.Unix(1456029177, 0).UnixNano(),
|
||||
"procid": "2341",
|
||||
"msgid": "2",
|
||||
"message": `"GET /v1/ok HTTP/1.1" 200 145 "-" "hacheck 0.9.0" 24306 127.0.0.1:40124 575`,
|
||||
"origin": true,
|
||||
"meta_sequence": "14125553",
|
||||
"meta_service": "someservice",
|
||||
"severity_code": 5,
|
||||
"facility_code": 3,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "notice",
|
||||
"facility": "daemon",
|
||||
"hostname": "web1",
|
||||
"appname": "someservice",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
wantStrict: &testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"timestamp": time.Unix(1456029177, 0).UnixNano(),
|
||||
"procid": "2341",
|
||||
"msgid": "2",
|
||||
"message": `"GET /v1/ok HTTP/1.1" 200 145 "-" "hacheck 0.9.0" 24306 127.0.0.1:40124 575`,
|
||||
"origin": true,
|
||||
"meta_sequence": "14125553",
|
||||
"meta_service": "someservice",
|
||||
"severity_code": 5,
|
||||
"facility_code": 3,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "notice",
|
||||
"facility": "daemon",
|
||||
"hostname": "web1",
|
||||
"appname": "someservice",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "max",
|
||||
data: []byte(fmt.Sprintf("<%d>%d %s %s %s %s %s - %s", maxP, maxV, maxTS, maxH, maxA, maxPID, maxMID, message7681)),
|
||||
wantBestEffort: &testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": maxV,
|
||||
"timestamp": time.Unix(1514764799, 999999000).UnixNano(),
|
||||
"message": message7681,
|
||||
"procid": maxPID,
|
||||
"msgid": maxMID,
|
||||
"severity_code": 7,
|
||||
"facility_code": 23,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "debug",
|
||||
"facility": "local7",
|
||||
"hostname": maxH,
|
||||
"appname": maxA,
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
wantStrict: &testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": maxV,
|
||||
"timestamp": time.Unix(1514764799, 999999000).UnixNano(),
|
||||
"message": message7681,
|
||||
"procid": maxPID,
|
||||
"msgid": maxMID,
|
||||
"severity_code": 7,
|
||||
"facility_code": 23,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "debug",
|
||||
"facility": "local7",
|
||||
"hostname": maxH,
|
||||
"appname": maxA,
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "minimal/incomplete",
|
||||
data: []byte("<1>2"),
|
||||
wantBestEffort: &testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(2),
|
||||
"facility_code": 0,
|
||||
"severity_code": 1,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: defaultTime,
|
||||
},
|
||||
werr: true,
|
||||
},
|
||||
}
|
||||
|
||||
return testCases
|
||||
}
|
||||
|
||||
func newUDPSyslogReceiver(address string, bestEffort bool) *Syslog {
|
||||
return &Syslog{
|
||||
Address: address,
|
||||
now: func() time.Time {
|
||||
return defaultTime
|
||||
},
|
||||
BestEffort: bestEffort,
|
||||
Separator: "_",
|
||||
}
|
||||
}
|
||||
|
||||
func testRFC5426(t *testing.T, protocol string, address string, bestEffort bool) {
|
||||
for _, tc := range getTestCasesForRFC5426() {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Create receiver
|
||||
receiver := newUDPSyslogReceiver(protocol+"://"+address, bestEffort)
|
||||
acc := &testutil.Accumulator{}
|
||||
require.NoError(t, receiver.Start(acc))
|
||||
defer receiver.Stop()
|
||||
|
||||
// Clear
|
||||
acc.ClearMetrics()
|
||||
acc.Errors = make([]error, 0)
|
||||
|
||||
// Connect
|
||||
conn, err := net.Dial(protocol, address)
|
||||
require.NotNil(t, conn)
|
||||
defer conn.Close()
|
||||
require.Nil(t, err)
|
||||
|
||||
// Write
|
||||
_, e := conn.Write(tc.data)
|
||||
require.Nil(t, e)
|
||||
|
||||
// Waiting ...
|
||||
if tc.wantStrict == nil && tc.werr || bestEffort && tc.werr {
|
||||
acc.WaitError(1)
|
||||
}
|
||||
if tc.wantBestEffort != nil && bestEffort || tc.wantStrict != nil && !bestEffort {
|
||||
acc.Wait(1) // RFC5426 mandates a syslog message per UDP packet
|
||||
}
|
||||
|
||||
// Compare
|
||||
var got *testutil.Metric
|
||||
var want *testutil.Metric
|
||||
if len(acc.Metrics) > 0 {
|
||||
got = acc.Metrics[0]
|
||||
}
|
||||
if bestEffort {
|
||||
want = tc.wantBestEffort
|
||||
} else {
|
||||
want = tc.wantStrict
|
||||
}
|
||||
if !cmp.Equal(want, got) {
|
||||
t.Fatalf("Got (+) / Want (-)\n %s", cmp.Diff(want, got))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBestEffort_udp(t *testing.T) {
|
||||
testRFC5426(t, "udp", address, true)
|
||||
}
|
||||
|
||||
func TestStrict_udp(t *testing.T) {
|
||||
testRFC5426(t, "udp", address, false)
|
||||
}
|
||||
|
||||
func TestBestEffort_unixgram(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "telegraf")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
sock := filepath.Join(tmpdir, "syslog.TestBestEffort_unixgram.sock")
|
||||
os.Create(sock)
|
||||
testRFC5426(t, "unixgram", sock, true)
|
||||
}
|
||||
|
||||
func TestStrict_unixgram(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "telegraf")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
sock := filepath.Join(tmpdir, "syslog.TestStrict_unixgram.sock")
|
||||
os.Create(sock)
|
||||
testRFC5426(t, "unixgram", sock, false)
|
||||
}
|
||||
|
||||
func TestTimeIncrement_udp(t *testing.T) {
|
||||
var i int64
|
||||
atomic.StoreInt64(&i, 0)
|
||||
getNow := func() time.Time {
|
||||
if atomic.LoadInt64(&i)%2 == 0 {
|
||||
return time.Unix(1, 0)
|
||||
}
|
||||
return time.Unix(1, 1)
|
||||
}
|
||||
|
||||
// Create receiver
|
||||
receiver := &Syslog{
|
||||
Address: "udp://" + address,
|
||||
now: getNow,
|
||||
BestEffort: false,
|
||||
Separator: "_",
|
||||
}
|
||||
acc := &testutil.Accumulator{}
|
||||
require.NoError(t, receiver.Start(acc))
|
||||
defer receiver.Stop()
|
||||
|
||||
// Connect
|
||||
conn, err := net.Dial("udp", address)
|
||||
require.NotNil(t, conn)
|
||||
defer conn.Close()
|
||||
require.Nil(t, err)
|
||||
|
||||
// Write
|
||||
_, e := conn.Write([]byte("<1>1 - - - - - -"))
|
||||
require.Nil(t, e)
|
||||
|
||||
// Wait
|
||||
acc.Wait(1)
|
||||
|
||||
want := &testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"facility_code": 0,
|
||||
"severity_code": 1,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: getNow(),
|
||||
}
|
||||
|
||||
if !cmp.Equal(want, acc.Metrics[0]) {
|
||||
t.Fatalf("Got (+) / Want (-)\n %s", cmp.Diff(want, acc.Metrics[0]))
|
||||
}
|
||||
|
||||
// New one with different time
|
||||
atomic.StoreInt64(&i, atomic.LoadInt64(&i)+1)
|
||||
|
||||
// Clear
|
||||
acc.ClearMetrics()
|
||||
|
||||
// Write
|
||||
_, e = conn.Write([]byte("<1>1 - - - - - -"))
|
||||
require.Nil(t, e)
|
||||
|
||||
// Wait
|
||||
acc.Wait(1)
|
||||
|
||||
want = &testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"facility_code": 0,
|
||||
"severity_code": 1,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: getNow(),
|
||||
}
|
||||
|
||||
if !cmp.Equal(want, acc.Metrics[0]) {
|
||||
t.Fatalf("Got (+) / Want (-)\n %s", cmp.Diff(want, acc.Metrics[0]))
|
||||
}
|
||||
|
||||
// New one with same time as previous one
|
||||
|
||||
// Clear
|
||||
acc.ClearMetrics()
|
||||
|
||||
// Write
|
||||
_, e = conn.Write([]byte("<1>1 - - - - - -"))
|
||||
require.Nil(t, e)
|
||||
|
||||
// Wait
|
||||
acc.Wait(1)
|
||||
|
||||
want = &testutil.Metric{
|
||||
Measurement: "syslog",
|
||||
Fields: map[string]interface{}{
|
||||
"version": uint16(1),
|
||||
"facility_code": 0,
|
||||
"severity_code": 1,
|
||||
},
|
||||
Tags: map[string]string{
|
||||
"severity": "alert",
|
||||
"facility": "kern",
|
||||
},
|
||||
Time: getNow().Add(time.Nanosecond),
|
||||
}
|
||||
|
||||
if !cmp.Equal(want, acc.Metrics[0]) {
|
||||
t.Fatalf("Got (+) / Want (-)\n %s", cmp.Diff(want, acc.Metrics[0]))
|
||||
}
|
||||
}
|
||||
451
plugins/inputs/syslog/syslog.go
Normal file
451
plugins/inputs/syslog/syslog.go
Normal file
@@ -0,0 +1,451 @@
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/go-syslog/rfc5424"
|
||||
"github.com/influxdata/go-syslog/rfc5425"
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/internal"
|
||||
tlsConfig "github.com/influxdata/telegraf/internal/tls"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
const defaultReadTimeout = time.Millisecond * 500
|
||||
const ipMaxPacketSize = 64 * 1024
|
||||
|
||||
// Syslog is a syslog plugin
|
||||
type Syslog struct {
|
||||
tlsConfig.ServerConfig
|
||||
Address string `toml:"server"`
|
||||
KeepAlivePeriod *internal.Duration
|
||||
ReadTimeout *internal.Duration
|
||||
MaxConnections int
|
||||
BestEffort bool
|
||||
Separator string `toml:"sdparam_separator"`
|
||||
|
||||
now func() time.Time
|
||||
lastTime time.Time
|
||||
|
||||
mu sync.Mutex
|
||||
wg sync.WaitGroup
|
||||
io.Closer
|
||||
|
||||
isStream bool
|
||||
tcpListener net.Listener
|
||||
tlsConfig *tls.Config
|
||||
connections map[string]net.Conn
|
||||
connectionsMu sync.Mutex
|
||||
|
||||
udpListener net.PacketConn
|
||||
}
|
||||
|
||||
var sampleConfig = `
|
||||
## 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 = "_"
|
||||
`
|
||||
|
||||
// SampleConfig returns sample configuration message
|
||||
func (s *Syslog) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
||||
|
||||
// Description returns the plugin description
|
||||
func (s *Syslog) Description() string {
|
||||
return "Accepts syslog messages per RFC5425"
|
||||
}
|
||||
|
||||
// Gather ...
|
||||
func (s *Syslog) Gather(_ telegraf.Accumulator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Start starts the service.
|
||||
func (s *Syslog) Start(acc telegraf.Accumulator) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
scheme, host, err := getAddressParts(s.Address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Address = host
|
||||
|
||||
switch scheme {
|
||||
case "tcp", "tcp4", "tcp6", "unix", "unixpacket":
|
||||
s.isStream = true
|
||||
case "udp", "udp4", "udp6", "ip", "ip4", "ip6", "unixgram":
|
||||
s.isStream = false
|
||||
default:
|
||||
return fmt.Errorf("unknown protocol '%s' in '%s'", scheme, s.Address)
|
||||
}
|
||||
|
||||
if scheme == "unix" || scheme == "unixpacket" || scheme == "unixgram" {
|
||||
os.Remove(s.Address)
|
||||
}
|
||||
|
||||
if s.isStream {
|
||||
l, err := net.Listen(scheme, s.Address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Closer = l
|
||||
s.tcpListener = l
|
||||
s.tlsConfig, err = s.TLSConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.wg.Add(1)
|
||||
go s.listenStream(acc)
|
||||
} else {
|
||||
l, err := net.ListenPacket(scheme, s.Address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Closer = l
|
||||
s.udpListener = l
|
||||
|
||||
s.wg.Add(1)
|
||||
go s.listenPacket(acc)
|
||||
}
|
||||
|
||||
if scheme == "unix" || scheme == "unixpacket" || scheme == "unixgram" {
|
||||
s.Closer = unixCloser{path: s.Address, closer: s.Closer}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop cleans up all resources
|
||||
func (s *Syslog) Stop() {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if s.Closer != nil {
|
||||
s.Close()
|
||||
}
|
||||
s.wg.Wait()
|
||||
}
|
||||
|
||||
// getAddressParts returns the address scheme and host
|
||||
// it also sets defaults for them when missing
|
||||
// when the input address does not specify the protocol it returns an error
|
||||
func getAddressParts(a string) (string, string, error) {
|
||||
parts := strings.SplitN(a, "://", 2)
|
||||
if len(parts) != 2 {
|
||||
return "", "", fmt.Errorf("missing protocol within address '%s'", a)
|
||||
}
|
||||
|
||||
u, _ := url.Parse(a)
|
||||
switch u.Scheme {
|
||||
case "unix", "unixpacket", "unixgram":
|
||||
return parts[0], parts[1], nil
|
||||
}
|
||||
|
||||
var host string
|
||||
if u.Hostname() != "" {
|
||||
host = u.Hostname()
|
||||
}
|
||||
host += ":"
|
||||
if u.Port() == "" {
|
||||
host += "6514"
|
||||
} else {
|
||||
host += u.Port()
|
||||
}
|
||||
|
||||
return u.Scheme, host, nil
|
||||
}
|
||||
|
||||
func (s *Syslog) listenPacket(acc telegraf.Accumulator) {
|
||||
defer s.wg.Done()
|
||||
b := make([]byte, ipMaxPacketSize)
|
||||
p := rfc5424.NewParser()
|
||||
for {
|
||||
n, _, err := s.udpListener.ReadFrom(b)
|
||||
if err != nil {
|
||||
if !strings.HasSuffix(err.Error(), ": use of closed network connection") {
|
||||
acc.AddError(err)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if s.ReadTimeout != nil && s.ReadTimeout.Duration > 0 {
|
||||
s.udpListener.SetReadDeadline(time.Now().Add(s.ReadTimeout.Duration))
|
||||
}
|
||||
|
||||
message, err := p.Parse(b[:n], &s.BestEffort)
|
||||
if message != nil {
|
||||
acc.AddFields("syslog", fields(*message, s), tags(*message), s.time())
|
||||
}
|
||||
if err != nil {
|
||||
acc.AddError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Syslog) listenStream(acc telegraf.Accumulator) {
|
||||
defer s.wg.Done()
|
||||
|
||||
s.connections = map[string]net.Conn{}
|
||||
|
||||
for {
|
||||
conn, err := s.tcpListener.Accept()
|
||||
if err != nil {
|
||||
if !strings.HasSuffix(err.Error(), ": use of closed network connection") {
|
||||
acc.AddError(err)
|
||||
}
|
||||
break
|
||||
}
|
||||
var tcpConn, _ = conn.(*net.TCPConn)
|
||||
if s.tlsConfig != nil {
|
||||
conn = tls.Server(conn, s.tlsConfig)
|
||||
}
|
||||
|
||||
s.connectionsMu.Lock()
|
||||
if s.MaxConnections > 0 && len(s.connections) >= s.MaxConnections {
|
||||
s.connectionsMu.Unlock()
|
||||
conn.Close()
|
||||
continue
|
||||
}
|
||||
s.connections[conn.RemoteAddr().String()] = conn
|
||||
s.connectionsMu.Unlock()
|
||||
|
||||
if err := s.setKeepAlive(tcpConn); err != nil {
|
||||
acc.AddError(fmt.Errorf("unable to configure keep alive (%s): %s", s.Address, err))
|
||||
}
|
||||
|
||||
go s.handle(conn, acc)
|
||||
}
|
||||
|
||||
s.connectionsMu.Lock()
|
||||
for _, c := range s.connections {
|
||||
c.Close()
|
||||
}
|
||||
s.connectionsMu.Unlock()
|
||||
}
|
||||
|
||||
func (s *Syslog) removeConnection(c net.Conn) {
|
||||
s.connectionsMu.Lock()
|
||||
delete(s.connections, c.RemoteAddr().String())
|
||||
s.connectionsMu.Unlock()
|
||||
}
|
||||
|
||||
func (s *Syslog) handle(conn net.Conn, acc telegraf.Accumulator) {
|
||||
defer func() {
|
||||
s.removeConnection(conn)
|
||||
conn.Close()
|
||||
}()
|
||||
|
||||
for {
|
||||
data := &bytes.Buffer{}
|
||||
|
||||
// read the data
|
||||
if s.ReadTimeout != nil && s.ReadTimeout.Duration > 0 {
|
||||
conn.SetReadDeadline(time.Now().Add(s.ReadTimeout.Duration))
|
||||
}
|
||||
|
||||
n, err := io.Copy(data, conn)
|
||||
if err != nil {
|
||||
// read timeout reached, parse what we have
|
||||
if er, ok := err.(net.Error); ok && er.Timeout() {
|
||||
if n == 0 {
|
||||
continue
|
||||
}
|
||||
goto parseMsg
|
||||
}
|
||||
// client has closed connection, return
|
||||
if err == io.EOF {
|
||||
if n > 0 {
|
||||
goto parseMsg
|
||||
}
|
||||
return
|
||||
}
|
||||
// other error, log and return
|
||||
s.store(rfc5425.Result{Error: fmt.Errorf("failed reading from syslog client - %s", err.Error())}, acc)
|
||||
return
|
||||
}
|
||||
// handle client disconnect
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
parseMsg:
|
||||
var p *rfc5425.Parser
|
||||
if s.BestEffort {
|
||||
p = rfc5425.NewParser(data, rfc5425.WithBestEffort())
|
||||
} else {
|
||||
p = rfc5425.NewParser(data)
|
||||
}
|
||||
|
||||
p.ParseExecuting(func(r *rfc5425.Result) {
|
||||
s.store(*r, acc)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Syslog) setKeepAlive(c *net.TCPConn) error {
|
||||
if s.KeepAlivePeriod == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if s.KeepAlivePeriod.Duration == 0 {
|
||||
return c.SetKeepAlive(false)
|
||||
}
|
||||
if err := c.SetKeepAlive(true); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.SetKeepAlivePeriod(s.KeepAlivePeriod.Duration)
|
||||
}
|
||||
|
||||
func (s *Syslog) store(res rfc5425.Result, acc telegraf.Accumulator) {
|
||||
if res.Error != nil {
|
||||
acc.AddError(res.Error)
|
||||
}
|
||||
if res.MessageError != nil {
|
||||
acc.AddError(res.MessageError)
|
||||
}
|
||||
if res.Message != nil {
|
||||
msg := *res.Message
|
||||
acc.AddFields("syslog", fields(msg, s), tags(msg), s.time())
|
||||
}
|
||||
}
|
||||
|
||||
func tags(msg rfc5424.SyslogMessage) map[string]string {
|
||||
ts := map[string]string{}
|
||||
|
||||
// Not checking assuming a minimally valid message
|
||||
ts["severity"] = *msg.SeverityShortLevel()
|
||||
ts["facility"] = *msg.FacilityLevel()
|
||||
|
||||
if msg.Hostname() != nil {
|
||||
ts["hostname"] = *msg.Hostname()
|
||||
}
|
||||
|
||||
if msg.Appname() != nil {
|
||||
ts["appname"] = *msg.Appname()
|
||||
}
|
||||
|
||||
return ts
|
||||
}
|
||||
|
||||
func fields(msg rfc5424.SyslogMessage, s *Syslog) map[string]interface{} {
|
||||
// Not checking assuming a minimally valid message
|
||||
flds := map[string]interface{}{
|
||||
"version": msg.Version(),
|
||||
}
|
||||
flds["severity_code"] = int(*msg.Severity())
|
||||
flds["facility_code"] = int(*msg.Facility())
|
||||
|
||||
if msg.Timestamp() != nil {
|
||||
flds["timestamp"] = (*msg.Timestamp()).UnixNano()
|
||||
}
|
||||
|
||||
if msg.ProcID() != nil {
|
||||
flds["procid"] = *msg.ProcID()
|
||||
}
|
||||
|
||||
if msg.MsgID() != nil {
|
||||
flds["msgid"] = *msg.MsgID()
|
||||
}
|
||||
|
||||
if msg.Message() != nil {
|
||||
flds["message"] = strings.TrimSpace(*msg.Message())
|
||||
}
|
||||
|
||||
if msg.StructuredData() != nil {
|
||||
for sdid, sdparams := range *msg.StructuredData() {
|
||||
if len(sdparams) == 0 {
|
||||
// When SD-ID does not have params we indicate its presence with a bool
|
||||
flds[sdid] = true
|
||||
continue
|
||||
}
|
||||
for name, value := range sdparams {
|
||||
// Using whitespace as separator since it is not allowed by the grammar within SDID
|
||||
flds[sdid+s.Separator+name] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return flds
|
||||
}
|
||||
|
||||
type unixCloser struct {
|
||||
path string
|
||||
closer io.Closer
|
||||
}
|
||||
|
||||
func (uc unixCloser) Close() error {
|
||||
err := uc.closer.Close()
|
||||
os.Remove(uc.path) // ignore error
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Syslog) time() time.Time {
|
||||
t := s.now()
|
||||
if t == s.lastTime {
|
||||
t = t.Add(time.Nanosecond)
|
||||
}
|
||||
s.lastTime = t
|
||||
return t
|
||||
}
|
||||
|
||||
func getNanoNow() time.Time {
|
||||
return time.Unix(0, time.Now().UnixNano())
|
||||
}
|
||||
|
||||
func init() {
|
||||
receiver := &Syslog{
|
||||
Address: ":6514",
|
||||
now: getNanoNow,
|
||||
ReadTimeout: &internal.Duration{
|
||||
Duration: defaultReadTimeout,
|
||||
},
|
||||
Separator: "_",
|
||||
}
|
||||
|
||||
inputs.Add("syslog", func() telegraf.Input { return receiver })
|
||||
}
|
||||
68
plugins/inputs/syslog/syslog_test.go
Normal file
68
plugins/inputs/syslog/syslog_test.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package syslog
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
address = ":6514"
|
||||
)
|
||||
|
||||
var defaultTime = time.Unix(0, 0)
|
||||
var maxP = uint8(191)
|
||||
var maxV = uint16(999)
|
||||
var maxTS = "2017-12-31T23:59:59.999999+00:00"
|
||||
var maxH = "abcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabc"
|
||||
var maxA = "abcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdef"
|
||||
var maxPID = "abcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzabcdefghilmnopqrstuvzab"
|
||||
var maxMID = "abcdefghilmnopqrstuvzabcdefghilm"
|
||||
var message7681 = strings.Repeat("l", 7681)
|
||||
|
||||
func TestAddress(t *testing.T) {
|
||||
var err error
|
||||
var rec *Syslog
|
||||
|
||||
rec = &Syslog{
|
||||
Address: "localhost:6514",
|
||||
}
|
||||
err = rec.Start(&testutil.Accumulator{})
|
||||
require.EqualError(t, err, "missing protocol within address 'localhost:6514'")
|
||||
require.Error(t, err)
|
||||
|
||||
rec = &Syslog{
|
||||
Address: "unsupported://example.com:6514",
|
||||
}
|
||||
err = rec.Start(&testutil.Accumulator{})
|
||||
require.EqualError(t, err, "unknown protocol 'unsupported' in 'example.com:6514'")
|
||||
require.Error(t, err)
|
||||
|
||||
tmpdir, err := ioutil.TempDir("", "telegraf")
|
||||
defer os.RemoveAll(tmpdir)
|
||||
require.NoError(t, err)
|
||||
sock := filepath.Join(tmpdir, "syslog.TestAddress.sock")
|
||||
|
||||
rec = &Syslog{
|
||||
Address: "unixgram://" + sock,
|
||||
}
|
||||
err = rec.Start(&testutil.Accumulator{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, sock, rec.Address)
|
||||
rec.Stop()
|
||||
|
||||
// Default port is 6514
|
||||
rec = &Syslog{
|
||||
Address: "tcp://localhost",
|
||||
}
|
||||
err = rec.Start(&testutil.Accumulator{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "localhost:6514", rec.Address)
|
||||
rec.Stop()
|
||||
}
|
||||
@@ -16,7 +16,7 @@ https://en.wikipedia.org/wiki/Df_(Unix) for more details.
|
||||
# mount_points = ["/"]
|
||||
|
||||
## Ignore mount points by filesystem type.
|
||||
ignore_fs = ["tmpfs", "devtmpfs", "devfs"]
|
||||
ignore_fs = ["tmpfs", "devtmpfs", "devfs", "overlay", "aufs", "squashfs"]
|
||||
```
|
||||
|
||||
#### Docker container
|
||||
|
||||
30
plugins/inputs/system/SWAP_README.md
Normal file
30
plugins/inputs/system/SWAP_README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Swap Input Plugin
|
||||
|
||||
The swap plugin collects system swap metrics.
|
||||
|
||||
For a more information on what swap memory is, read [All about Linux swap space](https://www.linux.com/news/all-about-linux-swap-space).
|
||||
|
||||
### Configuration:
|
||||
|
||||
```toml
|
||||
# Read metrics about swap memory usage
|
||||
[[inputs.swap]]
|
||||
# no configuration
|
||||
```
|
||||
|
||||
### Metrics:
|
||||
|
||||
- swap
|
||||
- fields:
|
||||
- free (int)
|
||||
- total (int)
|
||||
- used (int)
|
||||
- used_percent (float)
|
||||
- in (int)
|
||||
- out (int)
|
||||
|
||||
### Example Output:
|
||||
|
||||
```
|
||||
swap total=20855394304i,used_percent=45.43883523785713,used=9476448256i,free=1715331072i 1511894782000000000
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user