Use dynatrace-metric-utils (#9295)
This commit is contained in:
parent
d6ac4abfb8
commit
298670ae18
|
|
@ -63,6 +63,7 @@ following works:
|
|||
- github.com/docker/docker [Apache License 2.0](https://github.com/docker/docker/blob/master/LICENSE)
|
||||
- github.com/docker/go-connections [Apache License 2.0](https://github.com/docker/go-connections/blob/master/LICENSE)
|
||||
- github.com/docker/go-units [Apache License 2.0](https://github.com/docker/go-units/blob/master/LICENSE)
|
||||
- github.com/dynatrace-oss/dynatrace-metric-utils-go [Apache License 2.0](https://github.com/dynatrace-oss/dynatrace-metric-utils-go/blob/master/LICENSE)
|
||||
- github.com/eapache/go-resiliency [MIT License](https://github.com/eapache/go-resiliency/blob/master/LICENSE)
|
||||
- github.com/eapache/go-xerial-snappy [MIT License](https://github.com/eapache/go-xerial-snappy/blob/master/LICENSE)
|
||||
- github.com/eapache/queue [MIT License](https://github.com/eapache/queue/blob/master/LICENSE)
|
||||
|
|
|
|||
1
go.mod
1
go.mod
|
|
@ -45,6 +45,7 @@ require (
|
|||
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1
|
||||
github.com/dimchansky/utfbom v1.1.1
|
||||
github.com/docker/docker v20.10.5+incompatible
|
||||
github.com/dynatrace-oss/dynatrace-metric-utils-go v0.1.0
|
||||
github.com/eclipse/paho.mqtt.golang v1.3.0
|
||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
|
||||
github.com/go-logfmt/logfmt v0.5.0
|
||||
|
|
|
|||
20
go.sum
20
go.sum
|
|
@ -239,7 +239,6 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4Yn
|
|||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
|
||||
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
||||
|
|
@ -401,6 +400,8 @@ github.com/dropbox/godropbox v0.0.0-20180512210157-31879d3884b9/go.mod h1:glr97h
|
|||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dynatrace-oss/dynatrace-metric-utils-go v0.1.0 h1:ldKn47mFgWCoiJRXA32psdEACPKffX9O1Msh1K8M+f0=
|
||||
github.com/dynatrace-oss/dynatrace-metric-utils-go v0.1.0/go.mod h1:qw0E9EJ0PnSlhWawDNuqE0zhc1hqOBUCFIAj3dd9DNw=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q=
|
||||
github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
|
|
@ -463,7 +464,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
|
|||
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo=
|
||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
|
|
@ -620,7 +620,6 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
|||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
|
|
@ -629,7 +628,6 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
|||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.1 h1:jAbXjIeW2ZSW2AwFxlGTDoc2CjI2XujLkV3ArsZFCvc=
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
|
|
@ -1114,7 +1112,6 @@ github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go
|
|||
github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
|
|
@ -1265,9 +1262,6 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
|||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
|
|
@ -1287,7 +1281,6 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
|
|||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
|
|
@ -1602,8 +1595,6 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -1690,10 +1681,6 @@ golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgw
|
|||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190906203814-12febf440ab1/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
|
|
@ -1729,7 +1716,6 @@ golang.org/x/tools v0.0.0-20200822203824-307de81be3f4/go.mod h1:njjCfa9FT2d7l9Bc
|
|||
golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
@ -1800,7 +1786,6 @@ google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfG
|
|||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200815001618-f69a88009b70/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a h1:pOwg4OoaRYScjmR4LlLgdtnyoHYTSAVhhqe5uPdpII8=
|
||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
|
|
@ -1836,7 +1821,6 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
|
|
|
|||
|
|
@ -1,49 +1,135 @@
|
|||
# Dynatrace Output Plugin
|
||||
|
||||
This plugin is sending telegraf metrics to [Dynatrace](https://www.dynatrace.com). It has two operational modes.
|
||||
This plugin sends Telegraf metrics to [Dynatrace](https://www.dynatrace.com) via the [Dynatrace Metrics API V2](https://www.dynatrace.com/support/help/dynatrace-api/environment-api/metric-v2/). It may be run alongside the Dynatrace OneAgent for automatic authentication or it may be run standalone on a host without a OneAgent by specifying a URL and API Token.
|
||||
More information on the plugin can be found in the [Dynatrace documentation](https://www.dynatrace.com/support/help/how-to-use-dynatrace/metrics/metric-ingestion/ingestion-methods/telegraf/).
|
||||
|
||||
Telegraf minimum version: Telegraf 1.16
|
||||
Plugin minimum tested version: 1.16
|
||||
## Requirements
|
||||
|
||||
## Running alongside Dynatrace OneAgent
|
||||
You will either need a Dynatrace OneAgent (version 1.201 or higher) installed on the same host as Telegraf; or a Dynatrace environment with version 1.202 or higher. Monotonic counters (e.g. `diskio.reads`, `system.uptime`) require Dynatrace 208 or later.
|
||||
|
||||
if you run the Telegraf agent on a host or VM that is monitored by the Dynatrace OneAgent then you only need to enable the plugin but need no further configuration. The Dynatrace telegraf output plugin will send all metrics to the OneAgent which will use its secure and load balanced connection to send the metrics to your Dynatrace SaaS or Managed environment.
|
||||
- Telegraf minimum version: Telegraf 1.16
|
||||
|
||||
## Getting Started
|
||||
|
||||
Setting up Telegraf is explained in the [Telegraf Documentation](https://docs.influxdata.com/telegraf/latest/introduction/getting-started/).
|
||||
The Dynatrace exporter may be enabled by adding an `[[outputs.dynatrace]]` section to your `telegraf.conf` config file.
|
||||
All configurations are optional, but if a `url` other than the OneAgent metric ingestion endpoint is specified then an `api_token` is required.
|
||||
To see all available options, see [Configuration](#configuration) below.
|
||||
|
||||
### Running alongside Dynatrace OneAgent
|
||||
|
||||
If you run the Telegraf agent on a host or VM that is monitored by the Dynatrace OneAgent then you only need to enable the plugin, but need no further configuration. The Dynatrace Telegraf output plugin will send all metrics to the OneAgent which will use its secure and load balanced connection to send the metrics to your Dynatrace SaaS or Managed environment.
|
||||
Depending on your environment, you might have to enable metrics ingestion on the OneAgent first as described in the [Dynatrace documentation](https://www.dynatrace.com/support/help/how-to-use-dynatrace/metrics/metric-ingestion/ingestion-methods/telegraf/).
|
||||
|
||||
Note: The name and identifier of the host running Telegraf will be added as a dimension to every metric. If this is undesirable, then the output plugin may be used in standalone mode using the directions below.
|
||||
|
||||
```toml
|
||||
[[outputs.dynatrace]]
|
||||
## No options are required. By default, metrics will be exported via the OneAgent on the local host.
|
||||
```
|
||||
|
||||
## Running standalone
|
||||
|
||||
If you run the Telegraf agent on a host or VM without a OneAgent you will need to configure the environment API endpoint to send the metrics to and an API token for security.
|
||||
|
||||
The endpoint for the Dynatrace Metrics API is
|
||||
You will also need to configure an API token for secure access. Find out how to create a token in the [Dynatrace documentation](https://www.dynatrace.com/support/help/dynatrace-api/basics/dynatrace-api-authentication/) or simply navigate to **Settings > Integration > Dynatrace API** in your Dynatrace environment and create a token with Dynatrace API and create a new token with
|
||||
'Ingest metrics' (`metrics.ingest`) scope enabled. It is recommended to limit Token scope to only this permission.
|
||||
|
||||
* Managed https://{your-domain}/e/{your-environment-id}/api/v2/metrics/ingest
|
||||
* SaaS https://{your-environment-id}.live.dynatrace.com/api/v2/metrics/ingest
|
||||
The endpoint for the Dynatrace Metrics API v2 is
|
||||
|
||||
You can learn more about how to use the Dynatrace API [here](https://www.dynatrace.com/support/help/dynatrace-api/)
|
||||
* on Dynatrace Managed: `https://{your-domain}/e/{your-environment-id}/api/v2/metrics/ingest`
|
||||
* on Dynatrace SaaS: `https://{your-environment-id}.live.dynatrace.com/api/v2/metrics/ingest`
|
||||
|
||||
You will also need to configure an API token for secure access. Find out how to create a token [here](https://www.dynatrace.com/support/help/dynatrace-api/environment-api/tokens/) or simply navigate to **Settings > Integration > Dynatrace API** in your Dynatrace environment and create a token with Dynatrace API and create a new token with
|
||||
'Ingest metrics data points' access scope enabled.
|
||||
```toml
|
||||
[[outputs.dynatrace]]
|
||||
## If no OneAgent is running on the host, url and api_token need to be set
|
||||
|
||||
## Dynatrace Metrics Ingest v2 endpoint to receive metrics
|
||||
url = "https://{your-environment-id}.live.dynatrace.com/api/v2/metrics/ingest"
|
||||
|
||||
## API token is required if a URL is specified and should be restricted to the 'Ingest metrics' scope
|
||||
api_token = "your API token here" // hard-coded for illustration only, should be read from environment
|
||||
```
|
||||
|
||||
You can learn more about how to use the Dynatrace API [here](https://www.dynatrace.com/support/help/dynatrace-api/).
|
||||
|
||||
## Configuration
|
||||
|
||||
### `url`
|
||||
|
||||
*required*: `false`
|
||||
|
||||
*default*: Local OneAgent endpoint
|
||||
|
||||
Set your Dynatrace environment URL (e.g.: `https://{your-environment-id}.live.dynatrace.com/api/v2/metrics/ingest`) if you do not use a OneAgent or wish to export metrics directly to a Dynatrace metrics v2 endpoint. If a URL is set to anything other than the local OneAgent endpoint, then an API token is required.
|
||||
|
||||
```toml
|
||||
[[outputs.dynatrace]]
|
||||
## Leave empty or use the local ingest endpoint of your OneAgent monitored host (e.g.: http://127.0.0.1:14499/metrics/ingest).
|
||||
## Set Dynatrace environment URL (e.g.: https://YOUR_DOMAIN/api/v2/metrics/ingest) if you do not use a OneAgent
|
||||
url = ""
|
||||
api_token = ""
|
||||
## Optional prefix for metric names (e.g.: "telegraf.")
|
||||
prefix = "telegraf."
|
||||
## Optional prefix for metric names (e.g.: "telegraf")
|
||||
prefix = "telegraf"
|
||||
## Flag for skipping the tls certificate check, just for testing purposes, should be false by default
|
||||
insecure_skip_verify = false
|
||||
## If you want to convert values represented as gauges to counters, add the metric names here
|
||||
additional_counters = [ ]
|
||||
|
||||
url = "https://{your-environment-id}.live.dynatrace.com/api/v2/metrics/ingest"
|
||||
```
|
||||
|
||||
## Requirements
|
||||
### `api_token`
|
||||
|
||||
You will either need a Dynatrace OneAgent (version 1.201 or higher) installed on the same host as Telegraf; or a Dynatrace environment with version 1.202 or higher. Monotonic counters (e.g. diskio.reads, system.uptime) require release 208 or later.
|
||||
You will either need a Dynatrace OneAgent (version 1.201 or higher) installed on the same host as Telegraf; or a Dynatrace environment with version 1.202 or higher
|
||||
*required*: `false` unless `url` is specified
|
||||
|
||||
API token is required if a URL other than the OneAgent endpoint is specified and it should be restricted to the 'Ingest metrics' scope.
|
||||
|
||||
```toml
|
||||
api_token = "your API token here"
|
||||
```
|
||||
|
||||
### `prefix`
|
||||
|
||||
*required*: `false`
|
||||
|
||||
Optional prefix to be prepended to all metric names (will be separated with a `.`).
|
||||
|
||||
```toml
|
||||
prefix = "telegraf"
|
||||
```
|
||||
|
||||
### `insecure_skip_verify`
|
||||
|
||||
*required*: `false`
|
||||
|
||||
Setting this option to true skips TLS verification for testing or when using self-signed certificates.
|
||||
|
||||
```toml
|
||||
insecure_skip_verify = false
|
||||
```
|
||||
|
||||
### `additional_counters`
|
||||
|
||||
*required*: `false`
|
||||
|
||||
If you want to convert values represented as gauges to counters, add the metric names here.
|
||||
|
||||
```toml
|
||||
additional_counters = [ ]
|
||||
```
|
||||
|
||||
### `default_dimensions`
|
||||
|
||||
*required*: `false`
|
||||
|
||||
Default dimensions that will be added to every exported metric.
|
||||
|
||||
```toml
|
||||
default_dimensions = {
|
||||
key = "value"
|
||||
}
|
||||
```
|
||||
|
||||
## Limitations
|
||||
Telegraf measurements which can't be converted to a float64 are skipped.
|
||||
|
||||
Telegraf measurements which can't be converted to a number are skipped.
|
||||
|
|
|
|||
|
|
@ -4,11 +4,7 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -16,17 +12,10 @@ import (
|
|||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/plugins/common/tls"
|
||||
"github.com/influxdata/telegraf/plugins/outputs"
|
||||
)
|
||||
|
||||
const (
|
||||
oneAgentMetricsURL = "http://127.0.0.1:14499/metrics/ingest"
|
||||
dtIngestAPILineLimit = 1000
|
||||
)
|
||||
|
||||
var (
|
||||
reNameAllowedCharList = regexp.MustCompile("[^A-Za-z0-9.-]+")
|
||||
maxDimKeyLen = 100
|
||||
maxMetricKeyLen = 250
|
||||
dtMetric "github.com/dynatrace-oss/dynatrace-metric-utils-go/metric"
|
||||
"github.com/dynatrace-oss/dynatrace-metric-utils-go/metric/apiconstants"
|
||||
"github.com/dynatrace-oss/dynatrace-metric-utils-go/metric/dimensions"
|
||||
)
|
||||
|
||||
// Dynatrace Configuration for the Dynatrace output plugin
|
||||
|
|
@ -37,12 +26,12 @@ type Dynatrace struct {
|
|||
Log telegraf.Logger `toml:"-"`
|
||||
Timeout config.Duration `toml:"timeout"`
|
||||
AddCounterMetrics []string `toml:"additional_counters"`
|
||||
State map[string]string
|
||||
SendCounter int
|
||||
|
||||
tls.ClientConfig
|
||||
|
||||
client *http.Client
|
||||
|
||||
loggedMetrics map[string]bool // New empty set
|
||||
}
|
||||
|
||||
const sampleConfig = `
|
||||
|
|
@ -61,8 +50,8 @@ const sampleConfig = `
|
|||
## The API token needs data ingest scope permission. When using OneAgent, no API token is required.
|
||||
api_token = ""
|
||||
|
||||
## Optional prefix for metric names (e.g.: "telegraf.")
|
||||
prefix = "telegraf."
|
||||
## Optional prefix for metric names (e.g.: "telegraf")
|
||||
prefix = "telegraf"
|
||||
|
||||
## Optional TLS Config
|
||||
# tls_ca = "/etc/telegraf/ca.pem"
|
||||
|
|
@ -101,163 +90,97 @@ func (d *Dynatrace) Description() string {
|
|||
return "Send telegraf metrics to a Dynatrace environment"
|
||||
}
|
||||
|
||||
// Normalizes a metric keys or metric dimension identifiers
|
||||
// according to Dynatrace format.
|
||||
func (d *Dynatrace) normalize(s string, max int) (string, error) {
|
||||
s = reNameAllowedCharList.ReplaceAllString(s, "_")
|
||||
|
||||
// Strip Digits and underscores if they are at the beginning of the string
|
||||
normalizedString := strings.TrimLeft(s, "_0123456789")
|
||||
|
||||
for strings.HasPrefix(normalizedString, "_") {
|
||||
normalizedString = normalizedString[1:]
|
||||
}
|
||||
|
||||
if len(normalizedString) > max {
|
||||
normalizedString = normalizedString[:max]
|
||||
}
|
||||
|
||||
for strings.HasSuffix(normalizedString, "_") {
|
||||
normalizedString = normalizedString[:len(normalizedString)-1]
|
||||
}
|
||||
|
||||
normalizedString = strings.ReplaceAll(normalizedString, "..", "_")
|
||||
|
||||
if len(normalizedString) == 0 {
|
||||
return "", fmt.Errorf("error normalizing the string: %s", s)
|
||||
}
|
||||
return normalizedString, nil
|
||||
}
|
||||
|
||||
func (d *Dynatrace) escape(v string) string {
|
||||
return strconv.Quote(v)
|
||||
}
|
||||
|
||||
func (d *Dynatrace) Write(metrics []telegraf.Metric) error {
|
||||
var buf bytes.Buffer
|
||||
metricCounter := 1
|
||||
var tagb bytes.Buffer
|
||||
if len(metrics) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, metric := range metrics {
|
||||
// first write the tags into a buffer
|
||||
tagb.Reset()
|
||||
if len(metric.Tags()) > 0 {
|
||||
keys := make([]string, 0, len(metric.Tags()))
|
||||
for k := range metric.Tags() {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
// sort tag keys to expect the same order in ech run
|
||||
sort.Strings(keys)
|
||||
lines := []string{}
|
||||
|
||||
for _, k := range keys {
|
||||
tagKey, err := d.normalize(k, maxDimKeyLen)
|
||||
if err != nil {
|
||||
for _, tm := range metrics {
|
||||
dims := []dimensions.Dimension{}
|
||||
for _, tag := range tm.TagList() {
|
||||
// Ignore special tags for histogram and summary types.
|
||||
switch tm.Type() {
|
||||
case telegraf.Histogram:
|
||||
if tag.Key == "le" || tag.Key == "gt" {
|
||||
continue
|
||||
}
|
||||
if len(metric.Tags()[k]) > 0 {
|
||||
fmt.Fprintf(&tagb, ",%s=%s", strings.ToLower(tagKey), d.escape(metric.Tags()[k]))
|
||||
case telegraf.Summary:
|
||||
if tag.Key == "quantile" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
dims = append(dims, dimensions.NewDimension(tag.Key, tag.Value))
|
||||
}
|
||||
if len(metric.Fields()) > 0 {
|
||||
for k, v := range metric.Fields() {
|
||||
var value string
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
continue
|
||||
case float64:
|
||||
if !math.IsNaN(v) && !math.IsInf(v, 0) {
|
||||
value = fmt.Sprintf("%f", v)
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
case uint64:
|
||||
value = strconv.FormatUint(v, 10)
|
||||
case int64:
|
||||
value = strconv.FormatInt(v, 10)
|
||||
case bool:
|
||||
if v {
|
||||
value = "1"
|
||||
} else {
|
||||
value = "0"
|
||||
}
|
||||
default:
|
||||
d.Log.Debugf("Dynatrace type not supported! %s", v)
|
||||
continue
|
||||
|
||||
metricType := tm.Type()
|
||||
for _, field := range tm.FieldList() {
|
||||
metricName := tm.Name() + "." + field.Key
|
||||
for _, i := range d.AddCounterMetrics {
|
||||
if metricName == i {
|
||||
metricType = telegraf.Counter
|
||||
}
|
||||
}
|
||||
|
||||
// metric name
|
||||
metricKey, err := d.normalize(k, maxMetricKeyLen)
|
||||
if err != nil {
|
||||
continue
|
||||
typeOpt := getTypeOption(metricType, field)
|
||||
|
||||
if typeOpt == nil {
|
||||
// Unsupported type. Log only once per unsupported metric name
|
||||
if !d.loggedMetrics[metricName] {
|
||||
d.Log.Warnf("Unsupported type for %s", metricName)
|
||||
d.loggedMetrics[metricName] = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
metricID, err := d.normalize(d.Prefix+metric.Name()+"."+metricKey, maxMetricKeyLen)
|
||||
// write metric name combined with its field
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
// write metric id,tags and value
|
||||
name := tm.Name() + "." + field.Key
|
||||
dm, err := dtMetric.NewMetric(
|
||||
name,
|
||||
dtMetric.WithPrefix(d.Prefix),
|
||||
dtMetric.WithDimensions(
|
||||
dimensions.MergeLists(
|
||||
// dimensions.NewNormalizedDimensionList(e.opts.DefaultDimensions...),
|
||||
dimensions.NewNormalizedDimensionList(dims...),
|
||||
),
|
||||
),
|
||||
typeOpt,
|
||||
)
|
||||
|
||||
metricType := metric.Type()
|
||||
for _, i := range d.AddCounterMetrics {
|
||||
if metric.Name()+"."+metricKey == i {
|
||||
metricType = telegraf.Counter
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
d.Log.Warn(fmt.Sprintf("failed to normalize metric: %s - %s", name, err.Error()))
|
||||
continue
|
||||
}
|
||||
|
||||
switch metricType {
|
||||
case telegraf.Counter:
|
||||
var delta float64
|
||||
line, err := dm.Serialize()
|
||||
|
||||
// Check if LastValue exists
|
||||
if lastvalue, ok := d.State[metricID+tagb.String()]; ok {
|
||||
// Convert Strings to Floats
|
||||
floatLastValue, err := strconv.ParseFloat(lastvalue, 32)
|
||||
if err != nil {
|
||||
d.Log.Debugf("Could not parse last value: %s", lastvalue)
|
||||
}
|
||||
floatCurrentValue, err := strconv.ParseFloat(value, 32)
|
||||
if err != nil {
|
||||
d.Log.Debugf("Could not parse current value: %s", value)
|
||||
}
|
||||
if floatCurrentValue >= floatLastValue {
|
||||
delta = floatCurrentValue - floatLastValue
|
||||
fmt.Fprintf(&buf, "%s%s count,delta=%f\n", metricID, tagb.String(), delta)
|
||||
}
|
||||
}
|
||||
d.State[metricID+tagb.String()] = value
|
||||
if err != nil {
|
||||
d.Log.Warn(fmt.Sprintf("failed to serialize metric: %s - %s", name, err.Error()))
|
||||
continue
|
||||
}
|
||||
|
||||
default:
|
||||
fmt.Fprintf(&buf, "%s%s %v\n", metricID, tagb.String(), value)
|
||||
}
|
||||
lines = append(lines, line)
|
||||
}
|
||||
}
|
||||
|
||||
if metricCounter%dtIngestAPILineLimit == 0 {
|
||||
err = d.send(buf.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf.Reset()
|
||||
}
|
||||
metricCounter++
|
||||
limit := apiconstants.GetPayloadLinesLimit()
|
||||
for i := 0; i < len(lines); i += limit {
|
||||
batch := lines[i:min(i+limit, len(lines))]
|
||||
|
||||
output := strings.Join(batch, "\n")
|
||||
if output != "" {
|
||||
if err := d.send(output); err != nil {
|
||||
return fmt.Errorf("error processing data:, %s", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
d.SendCounter++
|
||||
// in typical interval of 10s, we will clean the counter state once in 24h which is 8640 iterations
|
||||
|
||||
if d.SendCounter%8640 == 0 {
|
||||
d.State = make(map[string]string)
|
||||
}
|
||||
return d.send(buf.Bytes())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Dynatrace) send(msg []byte) error {
|
||||
func (d *Dynatrace) send(msg string) error {
|
||||
var err error
|
||||
req, err := http.NewRequest("POST", d.URL, bytes.NewBuffer(msg))
|
||||
req, err := http.NewRequest("POST", d.URL, bytes.NewBufferString(msg))
|
||||
if err != nil {
|
||||
d.Log.Errorf("Dynatrace error: %s", err.Error())
|
||||
return fmt.Errorf("error while creating HTTP request:, %s", err.Error())
|
||||
|
|
@ -292,12 +215,11 @@ func (d *Dynatrace) send(msg []byte) error {
|
|||
}
|
||||
|
||||
func (d *Dynatrace) Init() error {
|
||||
d.State = make(map[string]string)
|
||||
if len(d.URL) == 0 {
|
||||
d.Log.Infof("Dynatrace URL is empty, defaulting to OneAgent metrics interface")
|
||||
d.URL = oneAgentMetricsURL
|
||||
d.URL = apiconstants.GetDefaultOneAgentEndpoint()
|
||||
}
|
||||
if d.URL != oneAgentMetricsURL && len(d.APIToken) == 0 {
|
||||
if d.URL != apiconstants.GetDefaultOneAgentEndpoint() && len(d.APIToken) == 0 {
|
||||
d.Log.Errorf("Dynatrace api_token is a required field for Dynatrace output")
|
||||
return fmt.Errorf("api_token is a required field for Dynatrace output")
|
||||
}
|
||||
|
|
@ -320,8 +242,45 @@ func (d *Dynatrace) Init() error {
|
|||
func init() {
|
||||
outputs.Add("dynatrace", func() telegraf.Output {
|
||||
return &Dynatrace{
|
||||
Timeout: config.Duration(time.Second * 5),
|
||||
SendCounter: 0,
|
||||
Timeout: config.Duration(time.Second * 5),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func getTypeOption(metricType telegraf.ValueType, field *telegraf.Field) dtMetric.MetricOption {
|
||||
if metricType == telegraf.Counter {
|
||||
switch v := field.Value.(type) {
|
||||
case float64:
|
||||
return dtMetric.WithFloatCounterValueTotal(v)
|
||||
case uint64:
|
||||
return dtMetric.WithIntCounterValueTotal(int64(v))
|
||||
case int64:
|
||||
return dtMetric.WithIntCounterValueTotal(v)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
switch v := field.Value.(type) {
|
||||
case float64:
|
||||
return dtMetric.WithFloatGaugeValue(v)
|
||||
case uint64:
|
||||
return dtMetric.WithIntGaugeValue(int64(v))
|
||||
case int64:
|
||||
return dtMetric.WithIntGaugeValue(32)
|
||||
case bool:
|
||||
if v {
|
||||
return dtMetric.WithIntGaugeValue(1)
|
||||
}
|
||||
return dtMetric.WithIntGaugeValue(0)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a <= b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"regexp"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/dynatrace-oss/dynatrace-metric-utils-go/metric/apiconstants"
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/metric"
|
||||
|
|
@ -18,7 +20,8 @@ import (
|
|||
func TestNilMetrics(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(`{"linesOk":10,"linesInvalid":0,"error":null}`)
|
||||
err := json.NewEncoder(w).Encode(`{"linesOk":10,"linesInvalid":0,"error":null}`)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
|
|
@ -42,7 +45,8 @@ func TestNilMetrics(t *testing.T) {
|
|||
func TestEmptyMetricsSlice(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(`{"linesOk":10,"linesInvalid":0,"error":null}`)
|
||||
err := json.NewEncoder(w).Encode(`{"linesOk":10,"linesInvalid":0,"error":null}`)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
|
|
@ -65,7 +69,8 @@ func TestEmptyMetricsSlice(t *testing.T) {
|
|||
func TestMockURL(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(`{"linesOk":10,"linesInvalid":0,"error":null}`)
|
||||
err := json.NewEncoder(w).Encode(`{"linesOk":10,"linesInvalid":0,"error":null}`)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
|
|
@ -88,9 +93,10 @@ func TestMissingURL(t *testing.T) {
|
|||
|
||||
d.Log = testutil.Logger{}
|
||||
err := d.Init()
|
||||
require.Equal(t, oneAgentMetricsURL, d.URL)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, apiconstants.GetDefaultOneAgentEndpoint(), d.URL)
|
||||
err = d.Connect()
|
||||
require.Equal(t, oneAgentMetricsURL, d.URL)
|
||||
require.Equal(t, apiconstants.GetDefaultOneAgentEndpoint(), d.URL)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
|
@ -99,9 +105,10 @@ func TestMissingAPITokenMissingURL(t *testing.T) {
|
|||
|
||||
d.Log = testutil.Logger{}
|
||||
err := d.Init()
|
||||
require.Equal(t, oneAgentMetricsURL, d.URL)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, apiconstants.GetDefaultOneAgentEndpoint(), d.URL)
|
||||
err = d.Connect()
|
||||
require.Equal(t, oneAgentMetricsURL, d.URL)
|
||||
require.Equal(t, apiconstants.GetDefaultOneAgentEndpoint(), d.URL)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
|
@ -118,16 +125,15 @@ func TestSendMetric(t *testing.T) {
|
|||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// check the encoded result
|
||||
bodyBytes, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
bodyString := string(bodyBytes)
|
||||
expected := "mymeasurement.myfield,host=\"192.168.0.1\",nix=\"nix\" 3.140000\nmymeasurement.value,host=\"192.168.0.1\" 3.140000\n"
|
||||
expected := "mymeasurement.myfield,host=192.168.0.1 gauge,3.14\nmymeasurement.value,host=192.168.0.2 count,3.14"
|
||||
if bodyString != expected {
|
||||
t.Errorf("Metric encoding failed. expected: %s but got: %s", expected, bodyString)
|
||||
t.Errorf("Metric encoding failed. expected: %#v but got: %#v", expected, bodyString)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(`{"linesOk":10,"linesInvalid":0,"error":null}`)
|
||||
err = json.NewEncoder(w).Encode(`{"linesOk":10,"linesInvalid":0,"error":null}`)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
|
|
@ -145,16 +151,17 @@ func TestSendMetric(t *testing.T) {
|
|||
|
||||
m1 := metric.New(
|
||||
"mymeasurement",
|
||||
map[string]string{"host": "192.168.0.1", "nix": "nix"},
|
||||
map[string]string{"host": "192.168.0.1"},
|
||||
map[string]interface{}{"myfield": float64(3.14)},
|
||||
time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC),
|
||||
)
|
||||
|
||||
m2 := metric.New(
|
||||
"mymeasurement",
|
||||
map[string]string{"host": "192.168.0.1"},
|
||||
map[string]string{"host": "192.168.0.2"},
|
||||
map[string]interface{}{"value": float64(3.14)},
|
||||
time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC),
|
||||
telegraf.Counter,
|
||||
)
|
||||
|
||||
metrics := []telegraf.Metric{m1, m2}
|
||||
|
|
@ -167,16 +174,16 @@ func TestSendSingleMetricWithUnorderedTags(t *testing.T) {
|
|||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// check the encoded result
|
||||
bodyBytes, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
bodyString := string(bodyBytes)
|
||||
expected := "mymeasurement.myfield,a=\"test\",b=\"test\",c=\"test\" 3.140000\n"
|
||||
if bodyString != expected {
|
||||
t.Errorf("Metric encoding failed. expected: %s but got: %s", expected, bodyString)
|
||||
}
|
||||
require.Regexp(t, regexp.MustCompile(`^mymeasurement\.myfield`), bodyString)
|
||||
require.Regexp(t, regexp.MustCompile(`a=test`), bodyString)
|
||||
require.Regexp(t, regexp.MustCompile(`b=test`), bodyString)
|
||||
require.Regexp(t, regexp.MustCompile(`c=test`), bodyString)
|
||||
require.Regexp(t, regexp.MustCompile(`gauge,3.14$`), bodyString)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(`{"linesOk":1,"linesInvalid":0,"error":null}`)
|
||||
err = json.NewEncoder(w).Encode(`{"linesOk":1,"linesInvalid":0,"error":null}`)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
|
|
@ -210,15 +217,14 @@ func TestSendMetricWithoutTags(t *testing.T) {
|
|||
w.WriteHeader(http.StatusOK)
|
||||
// check the encoded result
|
||||
bodyBytes, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
bodyString := string(bodyBytes)
|
||||
expected := "mymeasurement.myfield 3.140000\n"
|
||||
expected := "mymeasurement.myfield gauge,3.14"
|
||||
if bodyString != expected {
|
||||
t.Errorf("Metric encoding failed. expected: %s but got: %s", expected, bodyString)
|
||||
t.Errorf("Metric encoding failed. expected: %#v but got: %#v", expected, bodyString)
|
||||
}
|
||||
json.NewEncoder(w).Encode(`{"linesOk":1,"linesInvalid":0,"error":null}`)
|
||||
err = json.NewEncoder(w).Encode(`{"linesOk":1,"linesInvalid":0,"error":null}`)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
|
|
@ -252,15 +258,19 @@ func TestSendMetricWithUpperCaseTagKeys(t *testing.T) {
|
|||
w.WriteHeader(http.StatusOK)
|
||||
// check the encoded result
|
||||
bodyBytes, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
bodyString := string(bodyBytes)
|
||||
expected := "mymeasurement.myfield,aaa=\"test\",b_b=\"test\",ccc=\"test\" 3.140000\n"
|
||||
if bodyString != expected {
|
||||
t.Errorf("Metric encoding failed. expected: %s but got: %s", expected, bodyString)
|
||||
}
|
||||
json.NewEncoder(w).Encode(`{"linesOk":1,"linesInvalid":0,"error":null}`)
|
||||
|
||||
// expected := "mymeasurement.myfield,b_b=test,ccc=test,aaa=test gauge,3.14"
|
||||
// use regex because dimension order isn't guaranteed
|
||||
require.Regexp(t, regexp.MustCompile(`^mymeasurement\.myfield`), bodyString)
|
||||
require.Regexp(t, regexp.MustCompile(`aaa=test`), bodyString)
|
||||
require.Regexp(t, regexp.MustCompile(`b_b=test`), bodyString)
|
||||
require.Regexp(t, regexp.MustCompile(`ccc=test`), bodyString)
|
||||
require.Regexp(t, regexp.MustCompile(`gauge,3.14$`), bodyString)
|
||||
|
||||
err = json.NewEncoder(w).Encode(`{"linesOk":1,"linesInvalid":0,"error":null}`)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
|
|
@ -294,15 +304,13 @@ func TestSendBooleanMetricWithoutTags(t *testing.T) {
|
|||
w.WriteHeader(http.StatusOK)
|
||||
// check the encoded result
|
||||
bodyBytes, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
bodyString := string(bodyBytes)
|
||||
expected := "mymeasurement.myfield 1\n"
|
||||
if bodyString != expected {
|
||||
t.Errorf("Metric encoding failed. expected: %s but got: %s", expected, bodyString)
|
||||
}
|
||||
json.NewEncoder(w).Encode(`{"linesOk":1,"linesInvalid":0,"error":null}`)
|
||||
// use regex because field order isn't guaranteed
|
||||
require.Contains(t, bodyString, "mymeasurement.yes gauge,1")
|
||||
require.Contains(t, bodyString, "mymeasurement.no gauge,0")
|
||||
err = json.NewEncoder(w).Encode(`{"linesOk":1,"linesInvalid":0,"error":null}`)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
|
|
@ -321,7 +329,48 @@ func TestSendBooleanMetricWithoutTags(t *testing.T) {
|
|||
m1 := metric.New(
|
||||
"mymeasurement",
|
||||
map[string]string{},
|
||||
map[string]interface{}{"myfield": bool(true)},
|
||||
map[string]interface{}{"yes": true, "no": false},
|
||||
time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC),
|
||||
)
|
||||
|
||||
metrics := []telegraf.Metric{m1}
|
||||
|
||||
err = d.Write(metrics)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestSendCounterMetricWithoutTags(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
// check the encoded result
|
||||
bodyBytes, err := ioutil.ReadAll(r.Body)
|
||||
require.NoError(t, err)
|
||||
bodyString := string(bodyBytes)
|
||||
expected := "mymeasurement.value gauge,32"
|
||||
if bodyString != expected {
|
||||
t.Errorf("Metric encoding failed. expected: %#v but got: %#v", expected, bodyString)
|
||||
}
|
||||
err = json.NewEncoder(w).Encode(`{"linesOk":1,"linesInvalid":0,"error":null}`)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
d := &Dynatrace{}
|
||||
|
||||
d.URL = ts.URL
|
||||
d.APIToken = "123"
|
||||
d.Log = testutil.Logger{}
|
||||
err := d.Init()
|
||||
require.NoError(t, err)
|
||||
err = d.Connect()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Init metrics
|
||||
|
||||
m1 := metric.New(
|
||||
"mymeasurement",
|
||||
map[string]string{},
|
||||
map[string]interface{}{"value": 32},
|
||||
time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC),
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue