stackdriver: metric label extraction (#8073)
* stackdriver: use label extraction and add debug config * go.mod: update go-metrics-stackdriver * vendor go-metrics-stackdriver
This commit is contained in:
parent
8dd936d738
commit
a936a77f01
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/armon/go-metrics/datadog"
|
||||
"github.com/armon/go-metrics/prometheus"
|
||||
stackdriver "github.com/google/go-metrics-stackdriver"
|
||||
stackdrivervault "github.com/google/go-metrics-stackdriver/vault"
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
log "github.com/hashicorp/go-hclog"
|
||||
|
@ -2457,9 +2458,12 @@ func (c *ServerCommand) setupTelemetry(config *server.Config) (*metricsutil.Metr
|
|||
return nil, fmt.Errorf("Failed to create stackdriver client: %v", err)
|
||||
}
|
||||
sink := stackdriver.NewSink(client, &stackdriver.Config{
|
||||
ProjectID: telConfig.StackdriverProjectID,
|
||||
Location: telConfig.StackdriverLocation,
|
||||
Namespace: telConfig.StackdriverNamespace,
|
||||
LabelExtractor: stackdrivervault.Extractor,
|
||||
Bucketer: stackdrivervault.Bucketer,
|
||||
ProjectID: telConfig.StackdriverProjectID,
|
||||
Location: telConfig.StackdriverLocation,
|
||||
Namespace: telConfig.StackdriverNamespace,
|
||||
DebugLogs: telConfig.StackdriverDebugLogs,
|
||||
})
|
||||
fanout = append(fanout, sink)
|
||||
}
|
||||
|
|
|
@ -278,6 +278,8 @@ type Telemetry struct {
|
|||
StackdriverLocation string `hcl:"stackdriver_location"`
|
||||
// StackdriverNamespace is the namespace identifier, such as a cluster name.
|
||||
StackdriverNamespace string `hcl:"stackdriver_namespace"`
|
||||
// StackdriverDebugLogs will write additional stackdriver related debug logs to stderr.
|
||||
StackdriverDebugLogs bool `hcl:"stackdriver_debug_logs"`
|
||||
}
|
||||
|
||||
func (s *Telemetry) GoString() string {
|
||||
|
@ -1127,6 +1129,7 @@ func (c *Config) Sanitized() map[string]interface{} {
|
|||
"stackdriver_project_id": c.Telemetry.StackdriverProjectID,
|
||||
"stackdriver_location": c.Telemetry.StackdriverLocation,
|
||||
"stackdriver_namespace": c.Telemetry.StackdriverNamespace,
|
||||
"stackdriver_debug_logs": c.Telemetry.StackdriverDebugLogs,
|
||||
}
|
||||
result["telemetry"] = sanitizedTelemetry
|
||||
}
|
||||
|
|
|
@ -562,6 +562,7 @@ func testConfig_Sanitized(t *testing.T) {
|
|||
"stackdriver_location": "",
|
||||
"stackdriver_namespace": "",
|
||||
"stackdriver_project_id": "",
|
||||
"stackdriver_debug_logs": false,
|
||||
"statsd_address": "bar",
|
||||
"statsite_address": ""},
|
||||
}
|
||||
|
|
2
go.mod
2
go.mod
|
@ -47,7 +47,7 @@ require (
|
|||
github.com/gogo/protobuf v1.2.1
|
||||
github.com/golang/protobuf v1.3.2
|
||||
github.com/google/go-github v17.0.0+incompatible
|
||||
github.com/google/go-metrics-stackdriver v0.0.0-20190816035513-b52628e82e2a
|
||||
github.com/google/go-metrics-stackdriver v0.2.0
|
||||
github.com/hashicorp/consul-template v0.22.0
|
||||
github.com/hashicorp/consul/api v1.2.1-0.20200128105449-6681be918a6e
|
||||
github.com/hashicorp/errwrap v1.0.0
|
||||
|
|
2
go.sum
2
go.sum
|
@ -266,6 +266,8 @@ github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4r
|
|||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-metrics-stackdriver v0.0.0-20190816035513-b52628e82e2a h1:qoxSc7PsKuc/RjXf5CB6rRFr5FQSpHM4iIqQfEazLhI=
|
||||
github.com/google/go-metrics-stackdriver v0.0.0-20190816035513-b52628e82e2a/go.mod h1:o93WzqysX0jP/10Y13hfL6aq9RoUvGaVdkrH5awMksE=
|
||||
github.com/google/go-metrics-stackdriver v0.2.0 h1:rbs2sxHAPn2OtUj9JdR/Gij1YKGl0BTVD0augB+HEjE=
|
||||
github.com/google/go-metrics-stackdriver v0.2.0/go.mod h1:KLcPyp3dWJAFD+yHisGlJSZktIsTjb50eB72U2YZ9K0=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck=
|
||||
|
|
|
@ -25,5 +25,9 @@ ss.AddSample([]string{"method", "const"}, 200)
|
|||
|
||||
The [full example](example/main.go) can be run from a cloud shell console to test how metrics are collected and displayed.
|
||||
|
||||
You can also try out the example using Cloud Run!
|
||||
|
||||
[![Run on Google Cloud](https://storage.googleapis.com/cloudrun/button.svg)](https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/google/go-metrics-stackdriver.git&cloudshell_working_dir=example)
|
||||
|
||||
|
||||
__This is not an officially supported Google product.__
|
||||
|
|
|
@ -3,10 +3,11 @@ module github.com/google/go-metrics-stackdriver
|
|||
go 1.12
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.37.2
|
||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878
|
||||
github.com/golang/protobuf v1.3.1
|
||||
google.golang.org/api v0.3.0
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107
|
||||
google.golang.org/grpc v1.19.0
|
||||
cloud.google.com/go v0.39.0
|
||||
github.com/armon/go-metrics v0.3.0
|
||||
github.com/golang/protobuf v1.3.2
|
||||
github.com/google/go-cmp v0.2.0
|
||||
google.golang.org/api v0.5.0
|
||||
google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8
|
||||
google.golang.org/grpc v1.22.0
|
||||
)
|
||||
|
|
|
@ -1,65 +1,30 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.37.2 h1:4y4L7BdHenTfZL0HervofNTHh9Ad6mNX72cQvl+5eH0=
|
||||
cloud.google.com/go v0.37.2/go.mod h1:H8IAquKe2L30IxoupDgqTaQvKSwF/c8prYHynGIWQbA=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
cloud.google.com/go v0.39.0 h1:UgQP9na6OTfp4dsAiz/eFpFA1C6tPdH5wiRdi19tuMw=
|
||||
cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM=
|
||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/armon/go-metrics v0.3.0 h1:B7AQgHi8QSEi4uHu7Sbsga+IJDU+CENgjxoo81vDUqU=
|
||||
github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4 h1:hU4mGcQI4DaAYW+IbTun+2qEZVFxK0ySjQLTbS0VQKc=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.6.2/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
|
@ -68,138 +33,67 @@ github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCS
|
|||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
go.opencensus.io v0.19.1/go.mod h1:gug0GbSHa8Pafr0d2urOSgoXHZ6x/RUlaiT0d9pqb4A=
|
||||
go.opencensus.io v0.19.2 h1:ZZpq6xI6kv/LuE/5s5UQvBU5vMjvRnPb8PvJrIntAnc=
|
||||
go.opencensus.io v0.19.2/go.mod h1:NO/8qkisMZLZ1FCsKNqtJPwc8/TaclWyY0B6wcYNg9M=
|
||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
golang.org/x/build v0.0.0-20190314133821-5284462c4bec/go.mod h1:atTaCNAy0f16Ah5aV1gMSwgiKVHwu/JncqDpuRr7lS4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181218192612-074acd46bca6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.2.0/go.mod h1:IfRCZScioGtypHNTlz3gFk67J8uePVW7uDTBzXuIkhU=
|
||||
google.golang.org/api v0.3.0 h1:UIJY20OEo3+tK5MBlcdx37kmdH6EnRjGkW78mc6+EeA=
|
||||
google.golang.org/api v0.3.0/go.mod h1:IuvZyQh8jgscv8qWfQ4ABd8m7hEudgBFM/EdhA3BnXw=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
google.golang.org/api v0.5.0 h1:lj9SyhMzyoa38fgFF0oO2T6pjs5IzkLPKfVtxpyCRMM=
|
||||
google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181219182458-5a97ab628bfb/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 h1:xtNn7qFlagY2mQNFHMSRPjT2RkOV4OXM7P5TVy9xATo=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8 h1:x913Lq/RebkvUmRSdQ8MNb0GZKn+SR1ESfoetcQSeak=
|
||||
google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw=
|
||||
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
package stackdriver
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -50,10 +50,12 @@ type Sink struct {
|
|||
counters map[string]*counter
|
||||
histograms map[string]*histogram
|
||||
|
||||
bucketer BucketFn
|
||||
taskInfo *taskInfo
|
||||
bucketer BucketFn
|
||||
extractor ExtractLabelsFn
|
||||
taskInfo *taskInfo
|
||||
|
||||
mu sync.Mutex
|
||||
mu sync.Mutex
|
||||
debugLogs bool
|
||||
}
|
||||
|
||||
// Config options for the stackdriver Sink.
|
||||
|
@ -62,9 +64,14 @@ type Config struct {
|
|||
// Optional. GCP instance metadata is used to determine the ProjectID if
|
||||
// not set.
|
||||
ProjectID string
|
||||
// The label extractor provides a way to rewrite metric key into a new key
|
||||
// with multiple labels. This is useful if the instrumented code includes
|
||||
// variable parameters within a metric name.
|
||||
// Optional. Defaults to DefaultLabelExtractor.
|
||||
LabelExtractor ExtractLabelsFn
|
||||
// The bucketer is used to determine histogram bucket boundaries
|
||||
// for the sampled metrics.
|
||||
// Optional. Defaults to DefaultBucketer
|
||||
// for the sampled metrics. This will execute before the LabelExtractor.
|
||||
// Optional. Defaults to DefaultBucketer.
|
||||
Bucketer BucketFn
|
||||
// The interval between sampled metric points. Must be > 1 minute.
|
||||
// https://cloud.google.com/monitoring/custom-metrics/creating-metrics#writing-ts
|
||||
|
@ -88,6 +95,11 @@ type Config struct {
|
|||
// https://cloud.google.com/monitoring/api/resources#tag_generic_task
|
||||
// Optional. Defaults to a combination of hostname+pid.
|
||||
TaskID string
|
||||
|
||||
// Debug logging. Errors will be logged to stderr, but setting this to true
|
||||
// will log additional information that is helpful when debugging errors.
|
||||
// Optional. Defaults to false.
|
||||
DebugLogs bool
|
||||
}
|
||||
|
||||
type taskInfo struct {
|
||||
|
@ -100,21 +112,43 @@ type taskInfo struct {
|
|||
|
||||
// BucketFn returns the histogram bucket thresholds based on the given metric
|
||||
// name.
|
||||
type BucketFn func(string) []float64
|
||||
type BucketFn func([]string) []float64
|
||||
|
||||
// ExtractLabelsFn converts a given metric name and type into a new metric
|
||||
// name and optionally additional labels. Errors will prevent the metric from
|
||||
// writing to stackdriver.
|
||||
type ExtractLabelsFn func([]string, string) ([]string, []metrics.Label, error)
|
||||
|
||||
// DefaultBucketer is the default BucketFn used to determing bucketing values
|
||||
// for metrics.
|
||||
func DefaultBucketer(name string) []float64 {
|
||||
func DefaultBucketer(key []string) []float64 {
|
||||
return []float64{10.0, 25.0, 50.0, 100.0, 150.0, 200.0, 250.0, 300.0, 500.0, 1000.0, 1500.0, 2000.0, 3000.0, 4000.0, 5000.0}
|
||||
}
|
||||
|
||||
// DefaultLabelExtractor is the default ExtractLabelsFn and is a direct
|
||||
// passthrough. Counter and Gauge metrics are renamed to include the type in
|
||||
// their name to avoid duplicate metrics with the same name but different
|
||||
// types (which is allowed by go-metrics but not by Stackdriver).
|
||||
func DefaultLabelExtractor(key []string, kind string) ([]string, []metrics.Label, error) {
|
||||
switch kind {
|
||||
case "counter":
|
||||
return append(key, "counter"), nil, nil
|
||||
case "gauge":
|
||||
return append(key, "gauge"), nil, nil
|
||||
case "histogram":
|
||||
return key, nil, nil
|
||||
}
|
||||
return nil, nil, fmt.Errorf("Unknown metric kind: %s", kind)
|
||||
}
|
||||
|
||||
// NewSink creates a Sink to flush metrics to stackdriver every interval. The
|
||||
// interval should be greater than 1 minute.
|
||||
func NewSink(client *monitoring.MetricClient, config *Config) *Sink {
|
||||
s := &Sink{
|
||||
client: client,
|
||||
bucketer: config.Bucketer,
|
||||
interval: config.ReportingInterval,
|
||||
client: client,
|
||||
extractor: config.LabelExtractor,
|
||||
bucketer: config.Bucketer,
|
||||
interval: config.ReportingInterval,
|
||||
taskInfo: &taskInfo{
|
||||
ProjectID: config.ProjectID,
|
||||
Location: config.Location,
|
||||
|
@ -122,9 +156,13 @@ func NewSink(client *monitoring.MetricClient, config *Config) *Sink {
|
|||
Job: config.Job,
|
||||
TaskID: config.TaskID,
|
||||
},
|
||||
debugLogs: config.DebugLogs,
|
||||
}
|
||||
|
||||
// apply defaults if not configured explicitly
|
||||
if s.extractor == nil {
|
||||
s.extractor = DefaultLabelExtractor
|
||||
}
|
||||
if s.bucketer == nil {
|
||||
s.bucketer = DefaultBucketer
|
||||
}
|
||||
|
@ -249,10 +287,18 @@ func (s *Sink) report(ctx context.Context) {
|
|||
ts := []*monitoringpb.TimeSeries{}
|
||||
|
||||
for _, v := range rCounters {
|
||||
name, labels, err := v.name.labelMap(s.extractor, "counter")
|
||||
if err != nil {
|
||||
log.Printf("Could not extract labels from %s: %v", v.name.hash, err)
|
||||
continue
|
||||
}
|
||||
if s.debugLogs {
|
||||
log.Printf("%v is now %s + (%v)\n", v.name.key, name, labels)
|
||||
}
|
||||
ts = append(ts, &monitoringpb.TimeSeries{
|
||||
Metric: &metricpb.Metric{
|
||||
Type: path.Join("custom.googleapis.com", "go-metrics", v.name.name),
|
||||
Labels: v.name.labelMap(),
|
||||
Type: path.Join("custom.googleapis.com", "go-metrics", name),
|
||||
Labels: labels,
|
||||
},
|
||||
MetricKind: metric.MetricDescriptor_GAUGE,
|
||||
Resource: resource,
|
||||
|
@ -274,10 +320,18 @@ func (s *Sink) report(ctx context.Context) {
|
|||
}
|
||||
|
||||
for _, v := range rGauges {
|
||||
name, labels, err := v.name.labelMap(s.extractor, "gauge")
|
||||
if err != nil {
|
||||
log.Printf("Could not extract labels from %s: %v", v.name.hash, err)
|
||||
continue
|
||||
}
|
||||
if s.debugLogs {
|
||||
log.Printf("%v is now %s + (%v)\n", v.name.key, name, labels)
|
||||
}
|
||||
ts = append(ts, &monitoringpb.TimeSeries{
|
||||
Metric: &metricpb.Metric{
|
||||
Type: path.Join("custom.googleapis.com", "go-metrics", v.name.name),
|
||||
Labels: v.name.labelMap(),
|
||||
Type: path.Join("custom.googleapis.com", "go-metrics", name),
|
||||
Labels: labels,
|
||||
},
|
||||
MetricKind: metric.MetricDescriptor_GAUGE,
|
||||
Resource: resource,
|
||||
|
@ -299,6 +353,15 @@ func (s *Sink) report(ctx context.Context) {
|
|||
}
|
||||
|
||||
for _, v := range rHistograms {
|
||||
name, labels, err := v.name.labelMap(s.extractor, "histogram")
|
||||
if err != nil {
|
||||
log.Printf("Could not extract labels from %s: %v", v.name.hash, err)
|
||||
continue
|
||||
}
|
||||
if s.debugLogs {
|
||||
log.Printf("%v is now %s + (%v)\n", v.name.key, name, labels)
|
||||
}
|
||||
|
||||
var count int64
|
||||
count = 0
|
||||
for _, i := range v.counts {
|
||||
|
@ -307,8 +370,8 @@ func (s *Sink) report(ctx context.Context) {
|
|||
|
||||
ts = append(ts, &monitoringpb.TimeSeries{
|
||||
Metric: &metricpb.Metric{
|
||||
Type: path.Join("custom.googleapis.com", "go-metrics", v.name.name),
|
||||
Labels: v.name.labelMap(),
|
||||
Type: path.Join("custom.googleapis.com", "go-metrics", name),
|
||||
Labels: labels,
|
||||
},
|
||||
MetricKind: metric.MetricDescriptor_CUMULATIVE,
|
||||
Resource: resource,
|
||||
|
@ -353,13 +416,19 @@ func (s *Sink) report(ctx context.Context) {
|
|||
end = len(ts)
|
||||
}
|
||||
|
||||
err := s.client.CreateTimeSeries(ctx, &monitoringpb.CreateTimeSeriesRequest{
|
||||
req := &monitoringpb.CreateTimeSeriesRequest{
|
||||
Name: fmt.Sprintf("projects/%s", s.taskInfo.ProjectID),
|
||||
TimeSeries: ts[i:end],
|
||||
})
|
||||
}
|
||||
err := s.client.CreateTimeSeries(ctx, req)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Failed to write time series data: %v", err)
|
||||
if s.debugLogs {
|
||||
for i, a := range req.TimeSeries {
|
||||
log.Printf("request timeseries[%d]: %v", i, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -381,7 +450,7 @@ func (s *Sink) SetGaugeWithLabels(key []string, val float32, labels []metrics.La
|
|||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
s.gauges[n.key] = g
|
||||
s.gauges[n.hash] = g
|
||||
}
|
||||
|
||||
// Should emit a Key/Value pair for each call.
|
||||
|
@ -401,11 +470,11 @@ func (s *Sink) IncrCounterWithLabels(key []string, val float32, labels []metrics
|
|||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
c, ok := s.counters[n.key]
|
||||
c, ok := s.counters[n.hash]
|
||||
if ok {
|
||||
c.value += float64(val)
|
||||
} else {
|
||||
s.counters[n.key] = &counter{
|
||||
s.counters[n.hash] = &counter{
|
||||
name: n,
|
||||
value: float64(val),
|
||||
}
|
||||
|
@ -424,13 +493,13 @@ func (s *Sink) AddSampleWithLabels(key []string, val float32, labels []metrics.L
|
|||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
h, ok := s.histograms[n.key]
|
||||
h, ok := s.histograms[n.hash]
|
||||
if ok {
|
||||
h.addSample(val)
|
||||
} else {
|
||||
h = newHistogram(n, s.bucketer)
|
||||
h = newHistogram(n, key, s.bucketer)
|
||||
h.addSample(val)
|
||||
s.histograms[n.key] = h
|
||||
s.histograms[n.hash] = h
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -438,42 +507,45 @@ var _ metrics.MetricSink = (*Sink)(nil)
|
|||
|
||||
// Series holds the naming for a timeseries metric.
|
||||
type series struct {
|
||||
key string
|
||||
name string
|
||||
key []string
|
||||
labels []metrics.Label
|
||||
hash string
|
||||
}
|
||||
|
||||
var forbiddenChars = regexp.MustCompile("[ .=\\-/]")
|
||||
|
||||
func newSeries(key []string, labels []metrics.Label) *series {
|
||||
buf := &bytes.Buffer{}
|
||||
replacer := strings.NewReplacer(" ", "_")
|
||||
|
||||
if len(key) > 0 {
|
||||
replacer.WriteString(buf, key[0])
|
||||
}
|
||||
for _, k := range key[1:] {
|
||||
replacer.WriteString(buf, ".")
|
||||
replacer.WriteString(buf, k)
|
||||
}
|
||||
|
||||
name := buf.String()
|
||||
|
||||
hash := strings.Join(key, "_")
|
||||
hash = forbiddenChars.ReplaceAllString(hash, "_")
|
||||
for _, label := range labels {
|
||||
replacer.WriteString(buf, fmt.Sprintf(";%s=%s", label.Name, label.Value))
|
||||
hash += fmt.Sprintf(";%s=%s", label.Name, label.Value)
|
||||
}
|
||||
|
||||
return &series{
|
||||
key: buf.String(),
|
||||
name: name,
|
||||
key: key,
|
||||
labels: labels,
|
||||
hash: hash,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *series) labelMap() map[string]string {
|
||||
func (s *series) labelMap(extractor ExtractLabelsFn, kind string) (string, map[string]string, error) {
|
||||
// extract labels from the key
|
||||
key, extractedLabels, err := extractor(s.key, kind)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
name := strings.Join(key, "_")
|
||||
name = forbiddenChars.ReplaceAllString(name, "_")
|
||||
|
||||
o := make(map[string]string, len(s.labels))
|
||||
for _, v := range s.labels {
|
||||
o[v.Name] = v.Value
|
||||
}
|
||||
return o
|
||||
for _, v := range extractedLabels {
|
||||
o[v.Name] = v.Value
|
||||
}
|
||||
return name, o, nil
|
||||
}
|
||||
|
||||
// https://cloud.google.com/monitoring/api/ref_v3/rest/v3/TimeSeries#point
|
||||
|
@ -495,10 +567,10 @@ type histogram struct {
|
|||
counts []int64
|
||||
}
|
||||
|
||||
func newHistogram(name *series, bucketer BucketFn) *histogram {
|
||||
func newHistogram(name *series, key []string, bucketer BucketFn) *histogram {
|
||||
h := &histogram{
|
||||
name: name,
|
||||
buckets: bucketer(name.name),
|
||||
buckets: bucketer(key),
|
||||
}
|
||||
h.counts = make([]int64, len(h.buckets))
|
||||
return h
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
// Copyright 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package vault provides helper functions to improve the go-metrics to stackdriver metric
|
||||
// conversions specific to HashiCorp Vault.
|
||||
package vault
|
||||
|
||||
import "github.com/armon/go-metrics"
|
||||
|
||||
// Extractor extracts known patterns from the key into metrics.Label for better metric grouping
|
||||
// and to help avoid the limit of 500 custom metric descriptors per project
|
||||
// (https://cloud.google.com/monitoring/quotas).
|
||||
func Extractor(key []string, kind string) ([]string, []metrics.Label, error) {
|
||||
// Metrics documented at https://www.vaultproject.io/docs/internals/telemetry.html should be
|
||||
// extracted here into a base metric name with appropriate labels extracted from the 'key'.
|
||||
switch len(key) {
|
||||
case 3: // metrics of format: *.*.*
|
||||
// vault.database.<method>
|
||||
if key[0] == "vault" && key[1] == "database" {
|
||||
return typeWrap(key[:2], kind), []metrics.Label{
|
||||
{
|
||||
Name: "method",
|
||||
Value: key[2],
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
// vault.token.create_root
|
||||
if key[0] == "vault" && key[1] == "token" && key[2] == "create_root" {
|
||||
return typeWrap(key, kind), nil, nil
|
||||
}
|
||||
|
||||
// vault.barrier.<method>
|
||||
// vault.token.<method>
|
||||
// vault.policy.<method>
|
||||
if key[0] == "vault" && (key[1] == "barrier" || key[1] == "token" || key[1] == "policy") {
|
||||
return typeWrap(key[:2], kind), []metrics.Label{
|
||||
{
|
||||
Name: "method",
|
||||
Value: key[2],
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
// vault.<backend>.<method>
|
||||
if key[0] == "vault" && (key[2] == "put" || key[2] == "get" || key[2] == "delete" || key[2] == "list") {
|
||||
return typeWrap(key[:2], kind), []metrics.Label{
|
||||
{
|
||||
Name: "method",
|
||||
Value: key[2],
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
case 4: // metrics of format: *.*.*.*
|
||||
// vault.route.<method>.<mount>
|
||||
if key[0] == "vault" && key[1] == "route" {
|
||||
return typeWrap(key[:2], kind), []metrics.Label{
|
||||
{
|
||||
Name: "method",
|
||||
Value: key[2],
|
||||
},
|
||||
{
|
||||
Name: "mount",
|
||||
Value: key[3],
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
// vault.audit.<type>.*
|
||||
if key[0] == "vault" && key[1] == "audit" {
|
||||
return typeWrap([]string{"vault", "audit", key[3]}, kind), []metrics.Label{
|
||||
{
|
||||
Name: "type",
|
||||
Value: key[2],
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
// vault.rollback.attempt.<mount>
|
||||
if key[0] == "vault" && key[1] == "rollback" && key[2] == "attempt" {
|
||||
return typeWrap(key[:3], kind), []metrics.Label{
|
||||
{
|
||||
Name: "mount",
|
||||
Value: key[3],
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
// vault.<backend>.lock.<method>
|
||||
if key[0] == "vault" && key[2] == "lock" {
|
||||
return typeWrap(key[:3], kind), []metrics.Label{
|
||||
{
|
||||
Name: "method",
|
||||
Value: key[3],
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
// vault.database.<name>.<method>
|
||||
// note: there are vault.database.<method>.error counters. Those are handled separately.
|
||||
if key[0] == "vault" && key[1] == "database" && key[3] != "error" {
|
||||
return typeWrap(key[:2], kind), []metrics.Label{
|
||||
{
|
||||
Name: "name",
|
||||
Value: key[2],
|
||||
},
|
||||
{
|
||||
Name: "method",
|
||||
Value: key[3],
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
//ivault.database.<method>.error
|
||||
if key[0] == "vault" && key[1] == "database" && key[3] == "error" {
|
||||
return typeWrap([]string{"vault", "database", "error"}, kind), []metrics.Label{
|
||||
{
|
||||
Name: "method",
|
||||
Value: key[2],
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
case 5:
|
||||
// vault.database.<name>.<method>.error
|
||||
if key[0] == "vault" && key[1] == "database" && key[4] == "error" {
|
||||
return typeWrap([]string{key[0], key[1], key[4]}, kind), []metrics.Label{
|
||||
{
|
||||
Name: "name",
|
||||
Value: key[2],
|
||||
},
|
||||
{
|
||||
Name: "method",
|
||||
Value: key[3],
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
default:
|
||||
// unknown key pattern, keep it as-is.
|
||||
}
|
||||
return typeWrap(key, kind), nil, nil
|
||||
}
|
||||
|
||||
func typeWrap(key []string, kind string) []string {
|
||||
out := []string{}
|
||||
for _, a := range key {
|
||||
out = append(out, a)
|
||||
}
|
||||
switch kind {
|
||||
case "counter":
|
||||
return append(out, kind)
|
||||
case "gauge":
|
||||
return append(out, kind)
|
||||
default:
|
||||
return out
|
||||
}
|
||||
}
|
||||
|
||||
// Bucketer specifies the bucket boundaries that should be used for the given metric key.
|
||||
func Bucketer(key []string) []float64 {
|
||||
// These were chosen to give some reasonable boundaires for RPC times in the 10-100ms range and
|
||||
// then rough values for 1-5 seconds.
|
||||
// TODO: investigate better boundaires for different metrics.
|
||||
return []float64{10.0, 25.0, 50.0, 100.0, 150.0, 200.0, 250.0, 300.0, 500.0, 1000.0, 1500.0, 2000.0, 3000.0, 4000.0, 5000.0}
|
||||
}
|
|
@ -276,8 +276,9 @@ github.com/golang/protobuf/ptypes/wrappers
|
|||
github.com/golang/snappy
|
||||
# github.com/google/go-github v17.0.0+incompatible
|
||||
github.com/google/go-github/github
|
||||
# github.com/google/go-metrics-stackdriver v0.0.0-20190816035513-b52628e82e2a
|
||||
# github.com/google/go-metrics-stackdriver v0.2.0
|
||||
github.com/google/go-metrics-stackdriver
|
||||
github.com/google/go-metrics-stackdriver/vault
|
||||
# github.com/google/go-querystring v1.0.0
|
||||
github.com/google/go-querystring/query
|
||||
# github.com/google/gofuzz v1.0.0
|
||||
|
|
Loading…
Reference in New Issue