Bump github.com/prometheus/client_golang and related
+ github.com/prometheus/client_golang v0.9.1 -> v1.0.0 + github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 -> v0.2.0 + github.com/prometheus/common v0.0.0-20170220103846-49fee292b27b -> v0.4.1 Sync with the version used in k8s. Other changes in go.mod is caused by `go mod tidy`
This commit is contained in:
parent
b71d99e0ea
commit
3b75b98f8f
33
go.mod
33
go.mod
@ -5,79 +5,71 @@ go 1.13
|
|||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.26.0
|
cloud.google.com/go v0.26.0
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||||
github.com/Microsoft/hcsshim v0.8.7 // indirect
|
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 // indirect
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
|
||||||
github.com/Rican7/retry v0.1.1-0.20160712041035-272ad122d6e5
|
github.com/Rican7/retry v0.1.1-0.20160712041035-272ad122d6e5
|
||||||
github.com/SeanDolphin/bqschema v0.0.0-20150424181127-f92a08f515e1
|
github.com/SeanDolphin/bqschema v0.0.0-20150424181127-f92a08f515e1
|
||||||
github.com/Shopify/sarama v1.8.0
|
github.com/Shopify/sarama v1.8.0
|
||||||
github.com/Shopify/toxiproxy v2.1.4+incompatible // indirect
|
github.com/Shopify/toxiproxy v2.1.4+incompatible // indirect
|
||||||
github.com/abbot/go-http-auth v0.0.0-20140618235127-c0ef4539dfab
|
github.com/abbot/go-http-auth v0.0.0-20140618235127-c0ef4539dfab
|
||||||
github.com/aws/aws-sdk-go v1.6.10
|
github.com/aws/aws-sdk-go v1.6.10
|
||||||
github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f // indirect
|
|
||||||
github.com/blang/semver v3.1.0+incompatible
|
github.com/blang/semver v3.1.0+incompatible
|
||||||
github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b // indirect
|
github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b // indirect
|
||||||
github.com/containerd/cgroups v0.0.0-20200108155730-918ed86e29cc // indirect
|
github.com/cilium/ebpf v0.0.0-20191113100448-d9fb101ca1fb // indirect
|
||||||
|
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 // indirect
|
||||||
github.com/containerd/containerd v1.3.3
|
github.com/containerd/containerd v1.3.3
|
||||||
github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41 // indirect
|
|
||||||
github.com/containerd/fifo v0.0.0-20191213151349-ff969a566b00 // indirect
|
|
||||||
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c // indirect
|
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c // indirect
|
||||||
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd
|
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect
|
||||||
github.com/cyphar/filepath-securejoin v0.2.2-0.20170720062807-ae69057f2299 // indirect
|
github.com/cyphar/filepath-securejoin v0.2.2-0.20170720062807-ae69057f2299 // indirect
|
||||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible // indirect
|
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible // indirect
|
||||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0
|
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0
|
||||||
github.com/docker/go-connections v0.3.0
|
github.com/docker/go-connections v0.3.0
|
||||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
|
|
||||||
github.com/docker/go-units v0.4.0
|
github.com/docker/go-units v0.4.0
|
||||||
github.com/eapache/go-resiliency v1.0.1-0.20160104191539-b86b1ec0dd42 // indirect
|
github.com/eapache/go-resiliency v1.0.1-0.20160104191539-b86b1ec0dd42 // indirect
|
||||||
github.com/eapache/queue v1.0.2 // indirect
|
github.com/eapache/queue v1.0.2 // indirect
|
||||||
github.com/euank/go-kmsg-parser v2.0.0+incompatible
|
github.com/euank/go-kmsg-parser v2.0.0+incompatible
|
||||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7
|
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7
|
||||||
github.com/go-ini/ini v1.9.0 // indirect
|
github.com/go-ini/ini v1.9.0 // indirect
|
||||||
github.com/gogo/googleapis v1.3.1 // indirect
|
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e // indirect
|
||||||
github.com/gogo/protobuf v1.3.1
|
github.com/gogo/protobuf v1.3.1
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 // indirect
|
|
||||||
github.com/golang/snappy v0.0.0-20150730031844-723cc1e459b8 // indirect
|
github.com/golang/snappy v0.0.0-20150730031844-723cc1e459b8 // indirect
|
||||||
github.com/google/go-cmp v0.3.1 // indirect
|
github.com/google/go-cmp v0.3.1
|
||||||
github.com/google/uuid v1.1.1 // indirect
|
github.com/google/uuid v1.1.1 // indirect
|
||||||
github.com/gorilla/mux v1.7.3 // indirect
|
github.com/gorilla/mux v1.7.3 // indirect
|
||||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect
|
|
||||||
github.com/hashicorp/golang-lru v0.5.3 // indirect
|
|
||||||
github.com/influxdb/influxdb v0.9.6-0.20151125225445-9eab56311373
|
github.com/influxdb/influxdb v0.9.6-0.20151125225445-9eab56311373
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 // indirect
|
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 // indirect
|
||||||
github.com/karrick/godirwalk v1.7.5
|
github.com/karrick/godirwalk v1.7.5
|
||||||
github.com/kevinburke/go-bindata v3.18.0+incompatible // indirect
|
|
||||||
github.com/klauspost/crc32 v0.0.0-20151223135126-a3b15ae34567 // indirect
|
github.com/klauspost/crc32 v0.0.0-20151223135126-a3b15ae34567 // indirect
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||||
github.com/kr/pretty v0.0.0-20140723054909-088c856450c0
|
github.com/kr/pretty v0.0.0-20140723054909-088c856450c0
|
||||||
github.com/kr/text v0.0.0-20130911015532-6807e777504f // indirect
|
github.com/kr/text v0.0.0-20130911015532-6807e777504f // indirect
|
||||||
github.com/mattn/go-shellwords v1.0.4-0.20180201004752-39dbbfa24bbc // indirect
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||||
github.com/mesos/mesos-go v0.0.7-0.20180413204204-29de6ff97b48
|
github.com/mesos/mesos-go v0.0.7-0.20180413204204-29de6ff97b48
|
||||||
github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989
|
github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989
|
||||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
|
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
|
||||||
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
github.com/mrunalp/fileutils v0.0.0-20160930181131-4ee1cc9a8058 // indirect
|
github.com/mrunalp/fileutils v0.0.0-20160930181131-4ee1cc9a8058 // indirect
|
||||||
github.com/onsi/ginkgo v1.10.3 // indirect
|
github.com/onsi/ginkgo v1.10.3 // indirect
|
||||||
github.com/onsi/gomega v1.7.1 // indirect
|
github.com/onsi/gomega v1.7.1 // indirect
|
||||||
|
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
|
||||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||||
github.com/opencontainers/runc v1.0.0-rc10
|
github.com/opencontainers/runc v1.0.0-rc10
|
||||||
github.com/opencontainers/runtime-spec v1.0.1
|
github.com/opencontainers/runtime-spec v1.0.1
|
||||||
github.com/opencontainers/selinux v1.3.3 // indirect
|
github.com/opencontainers/selinux v1.3.3 // indirect
|
||||||
github.com/pborman/uuid v0.0.0-20150824212802-cccd189d45f7 // indirect
|
|
||||||
github.com/pkg/errors v0.8.1
|
github.com/pkg/errors v0.8.1
|
||||||
github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13 // indirect
|
github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13 // indirect
|
||||||
github.com/prometheus/client_golang v0.9.1
|
github.com/prometheus/client_golang v1.0.0
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4
|
github.com/prometheus/client_model v0.2.0
|
||||||
github.com/prometheus/common v0.0.0-20170220103846-49fee292b27b
|
github.com/prometheus/common v0.4.1
|
||||||
|
github.com/prometheus/procfs v0.0.5 // indirect
|
||||||
github.com/seccomp/libseccomp-golang v0.0.0-20150813023252-1b506fc7c24e // indirect
|
github.com/seccomp/libseccomp-golang v0.0.0-20150813023252-1b506fc7c24e // indirect
|
||||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 // indirect
|
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 // indirect
|
||||||
github.com/vishvananda/netlink v0.0.0-20150820014904-1e2e08e8a2dc // indirect
|
github.com/vishvananda/netlink v0.0.0-20150820014904-1e2e08e8a2dc // indirect
|
||||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
|
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
|
||||||
go.opencensus.io v0.22.2 // indirect
|
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
|
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
|
|
||||||
golang.org/x/sys v0.0.0-20200107162124-548cf772de50
|
golang.org/x/sys v0.0.0-20200107162124-548cf772de50
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
|
||||||
google.golang.org/api v0.0.0-20150730141719-0c2979aeaa5b
|
google.golang.org/api v0.0.0-20150730141719-0c2979aeaa5b
|
||||||
@ -85,6 +77,7 @@ require (
|
|||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb // indirect
|
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb // indirect
|
||||||
google.golang.org/grpc v1.26.0
|
google.golang.org/grpc v1.26.0
|
||||||
gopkg.in/olivere/elastic.v2 v2.0.12
|
gopkg.in/olivere/elastic.v2 v2.0.12
|
||||||
|
gotest.tools v2.2.0+incompatible // indirect
|
||||||
k8s.io/klog v0.3.0
|
k8s.io/klog v0.3.0
|
||||||
k8s.io/utils v0.0.0-20200122174043-1e243dd1a584
|
k8s.io/utils v0.0.0-20200122174043-1e243dd1a584
|
||||||
)
|
)
|
||||||
|
195
go.sum
195
go.sum
@ -1,19 +1,10 @@
|
|||||||
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
|
|
||||||
cloud.google.com/go v0.1.1-0.20160913182117-3b1ae45394a2 h1:8Pau1HNsqG3bybGrTxn2oaH64hozvPKX+V5WySSKK8c=
|
|
||||||
cloud.google.com/go v0.1.1-0.20160913182117-3b1ae45394a2/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
|
||||||
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
|
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/Microsoft/go-winio v0.3.2 h1:LeyJggTk0QTKMB5S8jTaikRI5jIGFk2ITFRGNRTST2Q=
|
|
||||||
github.com/Microsoft/go-winio v0.3.2/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
|
||||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
|
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
|
||||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||||
github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg=
|
|
||||||
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
|
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
|
||||||
github.com/Rican7/retry v0.1.1-0.20160712041035-272ad122d6e5 h1:6olZmdYuK84eO0PeCQX1iy2EFWlOl8G+JNBi4vFmcU8=
|
github.com/Rican7/retry v0.1.1-0.20160712041035-272ad122d6e5 h1:6olZmdYuK84eO0PeCQX1iy2EFWlOl8G+JNBi4vFmcU8=
|
||||||
github.com/Rican7/retry v0.1.1-0.20160712041035-272ad122d6e5/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg=
|
github.com/Rican7/retry v0.1.1-0.20160712041035-272ad122d6e5/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg=
|
||||||
github.com/SeanDolphin/bqschema v0.0.0-20150424181127-f92a08f515e1 h1:4EBKNUkI0tKxZb75f41jFGQQBPG4A/qbbgmgJ1MTTvw=
|
github.com/SeanDolphin/bqschema v0.0.0-20150424181127-f92a08f515e1 h1:4EBKNUkI0tKxZb75f41jFGQQBPG4A/qbbgmgJ1MTTvw=
|
||||||
@ -24,10 +15,13 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWso
|
|||||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
github.com/abbot/go-http-auth v0.0.0-20140618235127-c0ef4539dfab h1:/CCup82s4yOdPAC2kijHUejVUNgpWHUmyVY0lek8PIM=
|
github.com/abbot/go-http-auth v0.0.0-20140618235127-c0ef4539dfab h1:/CCup82s4yOdPAC2kijHUejVUNgpWHUmyVY0lek8PIM=
|
||||||
github.com/abbot/go-http-auth v0.0.0-20140618235127-c0ef4539dfab/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM=
|
github.com/abbot/go-http-auth v0.0.0-20140618235127-c0ef4539dfab/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM=
|
||||||
|
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/aws/aws-sdk-go v1.6.10 h1:CVUS2yoWO3h14JctzBlGheGrEtAfvfjzyQT15+BPqNI=
|
github.com/aws/aws-sdk-go v1.6.10 h1:CVUS2yoWO3h14JctzBlGheGrEtAfvfjzyQT15+BPqNI=
|
||||||
github.com/aws/aws-sdk-go v1.6.10/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k=
|
github.com/aws/aws-sdk-go v1.6.10/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k=
|
||||||
github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f h1:L/FlB1krOjojJSmUaiAiOMiIdRWylhc9QcHg0vHBuzA=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||||
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/blang/semver v3.1.0+incompatible h1:7hqmJYuaEK3qwVjWubYiht3j93YI0WQBuysxHIfUriU=
|
github.com/blang/semver v3.1.0+incompatible h1:7hqmJYuaEK3qwVjWubYiht3j93YI0WQBuysxHIfUriU=
|
||||||
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
@ -36,65 +30,29 @@ github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b/go.mod
|
|||||||
github.com/cilium/ebpf v0.0.0-20191113100448-d9fb101ca1fb h1:bQ0NJ9dAB8vsw7ffajBDX/7Wr64BdLWeJkYY36UkeRY=
|
github.com/cilium/ebpf v0.0.0-20191113100448-d9fb101ca1fb h1:bQ0NJ9dAB8vsw7ffajBDX/7Wr64BdLWeJkYY36UkeRY=
|
||||||
github.com/cilium/ebpf v0.0.0-20191113100448-d9fb101ca1fb/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
|
github.com/cilium/ebpf v0.0.0-20191113100448-d9fb101ca1fb/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s=
|
|
||||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
|
||||||
github.com/containerd/cgroups v0.0.0-20200108155730-918ed86e29cc h1:Euk3pMvf7cw8tKEi8ZlMHCrnd5iBlz8hWBUVNL44hmQ=
|
|
||||||
github.com/containerd/cgroups v0.0.0-20200108155730-918ed86e29cc/go.mod h1:6KyBUkSDshoWUZPkqlFXQzOMWNtlcJ1stduPAd2MRes=
|
|
||||||
github.com/containerd/console v0.0.0-20170925154832-84eeaae905fa h1:GnRy2maqb8vcJhYRN5L+5WyYNKfUG4otiz2zxE182ng=
|
|
||||||
github.com/containerd/console v0.0.0-20170925154832-84eeaae905fa/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
|
||||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 h1:uict5mhHFTzKLUCufdSLym7z/J0CbBJT59lYbP9wtbg=
|
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 h1:uict5mhHFTzKLUCufdSLym7z/J0CbBJT59lYbP9wtbg=
|
||||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||||
github.com/containerd/containerd v1.0.2 h1:AcqeeOunmUuo2CvPPtHMhWn7mi54clu+j9yqXKxGFtk=
|
|
||||||
github.com/containerd/containerd v1.0.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
|
||||||
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
|
||||||
github.com/containerd/containerd v1.3.2 h1:ForxmXkA6tPIvffbrDAcPUIB32QgXkt2XFj+F0UxetA=
|
|
||||||
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
|
||||||
github.com/containerd/containerd v1.3.3 h1:LoIzb5y9x5l8VKAlyrbusNPXqBY0+kviRloxFUMFwKc=
|
github.com/containerd/containerd v1.3.3 h1:LoIzb5y9x5l8VKAlyrbusNPXqBY0+kviRloxFUMFwKc=
|
||||||
github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
|
||||||
github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41 h1:kIFnQBO7rQ0XkMe6xEwbybYHBEaWmh/f++laI6Emt7M=
|
|
||||||
github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY=
|
|
||||||
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
|
||||||
github.com/containerd/fifo v0.0.0-20191213151349-ff969a566b00 h1:lsjC5ENBl+Zgf38+B0ymougXFp0BaubeIVETltYZTQw=
|
|
||||||
github.com/containerd/fifo v0.0.0-20191213151349-ff969a566b00/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
|
|
||||||
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
|
||||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
|
||||||
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c h1:+RqLdWzn0xFunb+sxXaEzHOg8NuEG/eaI+9C1xXX8Mw=
|
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c h1:+RqLdWzn0xFunb+sxXaEzHOg8NuEG/eaI+9C1xXX8Mw=
|
||||||
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
|
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
|
||||||
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
|
|
||||||
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd h1:bRLyitWw3PT/2YuVaCKTPg0cA5dOFKFwKtkfcP2dLsA=
|
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd h1:bRLyitWw3PT/2YuVaCKTPg0cA5dOFKFwKtkfcP2dLsA=
|
||||||
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=
|
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=
|
||||||
github.com/coreos/go-systemd v0.0.0-20160527140244-4484981625c1 h1:hu0LKsi9FSTm1/lYVREY/hVON+GOkj1dN3JHiNE7+s8=
|
|
||||||
github.com/coreos/go-systemd v0.0.0-20160527140244-4484981625c1/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd/v22 v22.0.0-20191111152658-2d78030078ef/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
|
||||||
github.com/cyphar/filepath-securejoin v0.2.2-0.20170720062807-ae69057f2299 h1:nUfv7MlU7+tVPAYFEolaOth6D88fAgKsxmYCPhBvD5U=
|
github.com/cyphar/filepath-securejoin v0.2.2-0.20170720062807-ae69057f2299 h1:nUfv7MlU7+tVPAYFEolaOth6D88fAgKsxmYCPhBvD5U=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.2-0.20170720062807-ae69057f2299/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
github.com/cyphar/filepath-securejoin v0.2.2-0.20170720062807-ae69057f2299/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/docker/distribution v2.6.0-rc.1.0.20170726174610-edc3ab29cdff+incompatible h1:357nGVUC8gSpeSc2Axup8HfrfTLLUfWfCsCUhiQSKIg=
|
|
||||||
github.com/docker/distribution v2.6.0-rc.1.0.20170726174610-edc3ab29cdff+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
|
||||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible h1:dvc1KSkIYTVjZgHf/CTC2diTYC8PzhaA5sFISRfNVrE=
|
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible h1:dvc1KSkIYTVjZgHf/CTC2diTYC8PzhaA5sFISRfNVrE=
|
||||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
|
||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
|
||||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 h1:w3NnFcKR5241cfmQU5ZZAsf0xcpId6mWOupTvJlUX2U=
|
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 h1:w3NnFcKR5241cfmQU5ZZAsf0xcpId6mWOupTvJlUX2U=
|
||||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker v1.4.2-0.20180612054059-a9fbbdc8dd87 h1:25yKDyt5jahmGFDjYSofLaQskWh5A5TW7h6abNj2uW0=
|
|
||||||
github.com/docker/docker v1.4.2-0.20180612054059-a9fbbdc8dd87/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
|
||||||
github.com/docker/go-connections v0.3.0 h1:3lOnM9cSzgGwx8VfK/NGOW5fLQ0GjIlCkaktF+n1M6o=
|
github.com/docker/go-connections v0.3.0 h1:3lOnM9cSzgGwx8VfK/NGOW5fLQ0GjIlCkaktF+n1M6o=
|
||||||
github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
|
||||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
|
||||||
github.com/docker/go-units v0.2.1-0.20151230175859-0bbddae09c5a h1:42qf1j6VWt3GUQzr0Hy8EL3DhNzLBiuWw5wQjNBlFyo=
|
|
||||||
github.com/docker/go-units v0.2.1-0.20151230175859-0bbddae09c5a/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
|
||||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
|
||||||
github.com/eapache/go-resiliency v1.0.1-0.20160104191539-b86b1ec0dd42 h1:6obbp/qkZVAZ9jiUZFo5Oa+TXX2ztNDFYdVUUd9z7Cw=
|
github.com/eapache/go-resiliency v1.0.1-0.20160104191539-b86b1ec0dd42 h1:6obbp/qkZVAZ9jiUZFo5Oa+TXX2ztNDFYdVUUd9z7Cw=
|
||||||
github.com/eapache/go-resiliency v1.0.1-0.20160104191539-b86b1ec0dd42/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
github.com/eapache/go-resiliency v1.0.1-0.20160104191539-b86b1ec0dd42/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||||
github.com/eapache/queue v1.0.2 h1:jRJXCx6uciOfN69MfZCC9EZlGRqqHhwlyb6GBeNow+c=
|
github.com/eapache/queue v1.0.2 h1:jRJXCx6uciOfN69MfZCC9EZlGRqqHhwlyb6GBeNow+c=
|
||||||
@ -109,27 +67,20 @@ github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwL
|
|||||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||||
github.com/go-ini/ini v1.9.0 h1:SVBHBs+26QqWy5m0NyygV8lfVQT/Dq2PeKTiKzcXKAc=
|
github.com/go-ini/ini v1.9.0 h1:SVBHBs+26QqWy5m0NyygV8lfVQT/Dq2PeKTiKzcXKAc=
|
||||||
github.com/go-ini/ini v1.9.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
github.com/go-ini/ini v1.9.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||||
github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55 h1:oIgNYSrSUbNH5DJh6DMhU1PiOKOYIHNxrV3djLsLpEI=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
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/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8=
|
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8=
|
||||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/gogo/googleapis v1.3.1 h1:CzMaKrvF6Qa7XtRii064vKBQiyvmY8H8vG1xa1/W1JA=
|
|
||||||
github.com/gogo/googleapis v1.3.1/go.mod h1:d+q1s/xVJxZGKWwC/6UfPIF33J+G1Tq4GYv9Y+Tg/EU=
|
|
||||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE=
|
|
||||||
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
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/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
|
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA=
|
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
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/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
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/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
@ -145,120 +96,87 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa
|
|||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI=
|
|
||||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
|
|
||||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
|
||||||
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
|
||||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
|
||||||
github.com/influxdb/influxdb v0.9.6-0.20151125225445-9eab56311373 h1:+8XPwrWoNps4WbLfhNhH0ct8LUJAP1q+faViiEpSHYc=
|
github.com/influxdb/influxdb v0.9.6-0.20151125225445-9eab56311373 h1:+8XPwrWoNps4WbLfhNhH0ct8LUJAP1q+faViiEpSHYc=
|
||||||
github.com/influxdb/influxdb v0.9.6-0.20151125225445-9eab56311373/go.mod h1:GpjLgHRqWhDGlPAg7+Rj6NAYuzPojBM8XLG5Ouvvq+Q=
|
github.com/influxdb/influxdb v0.9.6-0.20151125225445-9eab56311373/go.mod h1:GpjLgHRqWhDGlPAg7+Rj6NAYuzPojBM8XLG5Ouvvq+Q=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE=
|
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/karrick/godirwalk v1.7.5 h1:VbzFqwXwNbAZoA6W5odrLr+hKK197CcENcPh6E/gJ0M=
|
github.com/karrick/godirwalk v1.7.5 h1:VbzFqwXwNbAZoA6W5odrLr+hKK197CcENcPh6E/gJ0M=
|
||||||
github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
|
github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
|
||||||
github.com/kevinburke/go-bindata v3.16.0+incompatible h1:TFzFZop2KxGhqNwsyjgmIh5JOrpG940MZlm5gNbxr8g=
|
|
||||||
github.com/kevinburke/go-bindata v3.16.0+incompatible/go.mod h1:/pEEZ72flUW2p0yi30bslSp9YqD9pysLxunQDdb2CPM=
|
|
||||||
github.com/kevinburke/go-bindata v3.17.0+incompatible h1:eXG58bFD2FVMYilP6PfjjSwKy4YTHmifsI8TURmlVVg=
|
|
||||||
github.com/kevinburke/go-bindata v3.17.0+incompatible/go.mod h1:/pEEZ72flUW2p0yi30bslSp9YqD9pysLxunQDdb2CPM=
|
|
||||||
github.com/kevinburke/go-bindata v3.18.0+incompatible h1:NfOP49jFW7KyBl7UwTg0xkhSfHjESEwe2VMrcnSHG20=
|
|
||||||
github.com/kevinburke/go-bindata v3.18.0+incompatible/go.mod h1:/pEEZ72flUW2p0yi30bslSp9YqD9pysLxunQDdb2CPM=
|
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/crc32 v0.0.0-20151223135126-a3b15ae34567 h1:XYpiFCF4D9K+RQVtYlk8GaLkjDQMD4KnDLbPI5FSR0w=
|
github.com/klauspost/crc32 v0.0.0-20151223135126-a3b15ae34567 h1:XYpiFCF4D9K+RQVtYlk8GaLkjDQMD4KnDLbPI5FSR0w=
|
||||||
github.com/klauspost/crc32 v0.0.0-20151223135126-a3b15ae34567/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
|
github.com/klauspost/crc32 v0.0.0-20151223135126-a3b15ae34567/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/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/pretty v0.0.0-20140723054909-088c856450c0 h1:j835k0S+JUJDs7JQUEfSBBXIDmvxppNo9+hsahkCmWE=
|
github.com/kr/pretty v0.0.0-20140723054909-088c856450c0 h1:j835k0S+JUJDs7JQUEfSBBXIDmvxppNo9+hsahkCmWE=
|
||||||
github.com/kr/pretty v0.0.0-20140723054909-088c856450c0/go.mod h1:Bvhd+E3laJ0AVkG0c9rmtZcnhV0HQ3+c3YxxqTvc/gA=
|
github.com/kr/pretty v0.0.0-20140723054909-088c856450c0/go.mod h1:Bvhd+E3laJ0AVkG0c9rmtZcnhV0HQ3+c3YxxqTvc/gA=
|
||||||
github.com/kr/text v0.0.0-20130911015532-6807e777504f h1:JaNmHIV9Eby6srQVWuiQ6n8ko2o/lG6udSRCbFZe1fs=
|
github.com/kr/text v0.0.0-20130911015532-6807e777504f h1:JaNmHIV9Eby6srQVWuiQ6n8ko2o/lG6udSRCbFZe1fs=
|
||||||
github.com/kr/text v0.0.0-20130911015532-6807e777504f/go.mod h1:sjUstKUATFIcff4qlB53Kml0wQPtJVc/3fWrmuUmcfA=
|
github.com/kr/text v0.0.0-20130911015532-6807e777504f/go.mod h1:sjUstKUATFIcff4qlB53Kml0wQPtJVc/3fWrmuUmcfA=
|
||||||
github.com/mattn/go-shellwords v1.0.4-0.20180201004752-39dbbfa24bbc h1:YJaBvUfcd0OW6ep7UHQFjkXJkj1z0K1pAZwhO9OHm0Y=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/mattn/go-shellwords v1.0.4-0.20180201004752-39dbbfa24bbc/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
github.com/mesos/mesos-go v0.0.7-0.20180413204204-29de6ff97b48 h1:YIHidb4LpHLt+cW1ezhU9T8ed6/K8sWbban61KMgeWI=
|
github.com/mesos/mesos-go v0.0.7-0.20180413204204-29de6ff97b48 h1:YIHidb4LpHLt+cW1ezhU9T8ed6/K8sWbban61KMgeWI=
|
||||||
github.com/mesos/mesos-go v0.0.7-0.20180413204204-29de6ff97b48/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV59fDr4=
|
github.com/mesos/mesos-go v0.0.7-0.20180413204204-29de6ff97b48/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV59fDr4=
|
||||||
github.com/mindprince/gonvml v0.0.0-20171110221305-fee913ce8fb2 h1:v3dy+FJr7gS7nLgYG7YjX/pmUWuFdudcpnoRNHt2heo=
|
|
||||||
github.com/mindprince/gonvml v0.0.0-20171110221305-fee913ce8fb2/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY=
|
|
||||||
github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989 h1:PS1dLCGtD8bb9RPKJrc8bS7qHL6JnW1CZvwzH9dPoUs=
|
github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989 h1:PS1dLCGtD8bb9RPKJrc8bS7qHL6JnW1CZvwzH9dPoUs=
|
||||||
github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY=
|
github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY=
|
||||||
github.com/mistifyio/go-zfs v2.1.2-0.20170901132433-166dd29edf05+incompatible h1:AqI6iSRQ93q8L+B0awSpC5abFebb1adJpMIjBToRyEs=
|
|
||||||
github.com/mistifyio/go-zfs v2.1.2-0.20170901132433-166dd29edf05+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
|
||||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk=
|
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk=
|
||||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||||
|
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||||
github.com/mrunalp/fileutils v0.0.0-20160930181131-4ee1cc9a8058 h1:A4y2IxU1GcIzlcmUlQ6yr/mrvYZhqo+HakAPwgwaa6s=
|
github.com/mrunalp/fileutils v0.0.0-20160930181131-4ee1cc9a8058 h1:A4y2IxU1GcIzlcmUlQ6yr/mrvYZhqo+HakAPwgwaa6s=
|
||||||
github.com/mrunalp/fileutils v0.0.0-20160930181131-4ee1cc9a8058/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
|
github.com/mrunalp/fileutils v0.0.0-20160930181131-4ee1cc9a8058/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
|
||||||
|
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.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
|
||||||
github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY=
|
github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY=
|
||||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
|
||||||
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
|
||||||
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
||||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
github.com/opencontainers/image-spec v1.0.0-rc6.0.20170604055404-372ad780f634 h1:XtqnM27uh9C9wpnBaUKQNCPxjQj8fOhOiTQreFMStnw=
|
|
||||||
github.com/opencontainers/image-spec v1.0.0-rc6.0.20170604055404-372ad780f634/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
|
||||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||||
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
|
||||||
github.com/opencontainers/runc v1.0.0-rc10 h1:AbmCEuSZXVflng0/cboQkpdEOeBsPMjz6tmq4Pv8MZw=
|
github.com/opencontainers/runc v1.0.0-rc10 h1:AbmCEuSZXVflng0/cboQkpdEOeBsPMjz6tmq4Pv8MZw=
|
||||||
github.com/opencontainers/runc v1.0.0-rc10/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
github.com/opencontainers/runc v1.0.0-rc10/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||||
github.com/opencontainers/runc v1.0.0-rc8.0.20190906011214-a6606a7ae9d9 h1:6SR6yKKWHiKAFdwRpJyyptFIomFRqf1zRqZfQZzWiRs=
|
|
||||||
github.com/opencontainers/runc v1.0.0-rc8.0.20190906011214-a6606a7ae9d9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
|
||||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
|
||||||
github.com/opencontainers/runtime-spec v1.0.0 h1:O6L965K88AilqnxeYPks/75HLpp4IG+FjeSCI3cVdRg=
|
|
||||||
github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
|
||||||
github.com/opencontainers/runtime-spec v1.0.1 h1:wY4pOY8fBdSIvs9+IDHC55thBuEulhzfSgKeC1yFvzQ=
|
github.com/opencontainers/runtime-spec v1.0.1 h1:wY4pOY8fBdSIvs9+IDHC55thBuEulhzfSgKeC1yFvzQ=
|
||||||
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
|
||||||
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52 h1:B8hYj3NxHmjsC3T+tnlZ1UhInqUgnyF1zlGPmzNg2Qk=
|
|
||||||
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
|
|
||||||
github.com/opencontainers/selinux v1.3.2 h1:DR4lL9SYVjgcTZKEZIncvDU06fKSc/eygjmNGOA3E1s=
|
|
||||||
github.com/opencontainers/selinux v1.3.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
|
||||||
github.com/opencontainers/selinux v1.3.3 h1:RX0wAeqtvVSYQcr017X3pFXPkLEtB6V4NjRD7gVQgg4=
|
github.com/opencontainers/selinux v1.3.3 h1:RX0wAeqtvVSYQcr017X3pFXPkLEtB6V4NjRD7gVQgg4=
|
||||||
github.com/opencontainers/selinux v1.3.3/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
github.com/opencontainers/selinux v1.3.3/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
||||||
github.com/pborman/uuid v0.0.0-20150824212802-cccd189d45f7 h1:7Nb5cK6zZrR39niF9np62PLldWkL0R0XJGDbmsRQ96E=
|
|
||||||
github.com/pborman/uuid v0.0.0-20150824212802-cccd189d45f7/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
|
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
github.com/pkg/errors v0.8.1/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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13 h1:AUK/hm/tPsiNNASdb3J8fySVRZoI7fnK5mlOvdFD43o=
|
github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13 h1:AUK/hm/tPsiNNASdb3J8fySVRZoI7fnK5mlOvdFD43o=
|
||||||
github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
|
github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
|
||||||
github.com/prometheus/client_golang v0.9.1 h1:K47Rk0v/fkEfwfQet2KWhscE0cJzjgCCDBG2KHZoVno=
|
|
||||||
github.com/prometheus/client_golang v0.9.1/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_model v0.0.0-20170216185247-6f3806018612 h1:13pIdM2tpaDi4OVe24fgoIS7ZTqMt0QI+bwQsX5hq+g=
|
github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM=
|
||||||
github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/common v0.0.0-20170220103846-49fee292b27b h1:nure2StBXEgV+CtAOZSggLGJ7bfuSfvuitPnwEQSKWQ=
|
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||||
github.com/prometheus/common v0.0.0-20170220103846-49fee292b27b/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/procfs v0.0.0-20170419201554-1e2146578273 h1:ENydzdHgPjSMaz3vOpXYRvs/63br0Rbc/RkLZIf5wMs=
|
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
|
||||||
github.com/prometheus/procfs v0.0.0-20170419201554-1e2146578273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
|
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
|
||||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
|
||||||
github.com/seccomp/libseccomp-golang v0.0.0-20150813023252-1b506fc7c24e h1:HJbgNpzYMeTLPpkMwbPNTPlhNd9r4xQtqcZG6qoIGgs=
|
github.com/seccomp/libseccomp-golang v0.0.0-20150813023252-1b506fc7c24e h1:HJbgNpzYMeTLPpkMwbPNTPlhNd9r4xQtqcZG6qoIGgs=
|
||||||
github.com/seccomp/libseccomp-golang v0.0.0-20150813023252-1b506fc7c24e/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
github.com/seccomp/libseccomp-golang v0.0.0-20150813023252-1b506fc7c24e/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
|
||||||
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
@ -266,37 +184,22 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykE
|
|||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
|
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
|
||||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
|
||||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||||
github.com/stretchr/objx v0.1.1/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.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
|
||||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=
|
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=
|
||||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
|
||||||
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
|
||||||
github.com/vishvananda/netlink v0.0.0-20150820014904-1e2e08e8a2dc h1:0HAHLwEY4k1VqaO1SzBi4XxT0KA06Cv+QW2LXknBk9g=
|
github.com/vishvananda/netlink v0.0.0-20150820014904-1e2e08e8a2dc h1:0HAHLwEY4k1VqaO1SzBi4XxT0KA06Cv+QW2LXknBk9g=
|
||||||
github.com/vishvananda/netlink v0.0.0-20150820014904-1e2e08e8a2dc/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
github.com/vishvananda/netlink v0.0.0-20150820014904-1e2e08e8a2dc/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
|
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
|
||||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
|
||||||
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
|
||||||
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
|
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
|
||||||
go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs=
|
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
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/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
@ -305,46 +208,30 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
|
|||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
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-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-20180906233101-161cd47e91fd/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-20190213061140-3a22650c66bd/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/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
|
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/oauth2 v0.0.0-20150321034511-ca8a464d23d5 h1:bpIUL4dMPi7n8APD2NQjvqcXU7ovORMqC49ExSvBkDw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20150321034511-ca8a464d23d5/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
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-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/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 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
|
|
||||||
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/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/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-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-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-20180909124046-d0be0721c37e/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 h1:rM0ROo5vb9AdYJi1110yjWGMej9ITfKddS89P3Fkhug=
|
|
||||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
|
|
||||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200107162124-548cf772de50 h1:YvQ10rzcqWXLlJZ3XCUoO25savxmscf4+SC+ZqiCHhA=
|
golang.org/x/sys v0.0.0-20200107162124-548cf772de50 h1:YvQ10rzcqWXLlJZ3XCUoO25savxmscf4+SC+ZqiCHhA=
|
||||||
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
@ -364,30 +251,21 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
|
|||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/genproto v0.0.0-20170731182057-09f6ed296fc6 h1:72GtwBPfq6av9X0Ru2HtAopsPW+d+vh1K1zaxanTdE8=
|
|
||||||
google.golang.org/genproto v0.0.0-20170731182057-09f6ed296fc6/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69 h1:4rNOqY4ULrKzS6twXa619uQgI7h9PaVd4ZhjFQ7C5zs=
|
|
||||||
google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb h1:ADPHZzpzM4tk4V4S5cnCrr5SwzvlrPRmqqCuJDB8UTs=
|
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb h1:ADPHZzpzM4tk4V4S5cnCrr5SwzvlrPRmqqCuJDB8UTs=
|
||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||||
google.golang.org/grpc v1.7.0 h1:VcvMlnRMpb70sBq6RF2LWnHakw+w6pO9ttP6kmXWhug=
|
|
||||||
google.golang.org/grpc v1.7.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
|
||||||
google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0=
|
|
||||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
|
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
|
||||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
|
||||||
gopkg.in/olivere/elastic.v2 v2.0.12 h1:gdSDg3k/R4dkC3I14sqwLKDQjcfPLZ9SoFzc4vbfAtQ=
|
gopkg.in/olivere/elastic.v2 v2.0.12 h1:gdSDg3k/R4dkC3I14sqwLKDQjcfPLZ9SoFzc4vbfAtQ=
|
||||||
gopkg.in/olivere/elastic.v2 v2.0.12/go.mod h1:CTVyl1gckiFw1aLZYxC00g3f9jnHmhoOKcWF7W3c6n4=
|
gopkg.in/olivere/elastic.v2 v2.0.12/go.mod h1:CTVyl1gckiFw1aLZYxC00g3f9jnHmhoOKcWF7W3c6n4=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
@ -402,10 +280,5 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE=
|
k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE=
|
||||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||||
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
|
|
||||||
k8s.io/utils v0.0.0-20190712204705-3dccf664f023 h1:1H4Jyzb0z2X0GfBMTwRjnt5ejffRHrGftUgJcV/ZfDc=
|
|
||||||
k8s.io/utils v0.0.0-20190712204705-3dccf664f023/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
|
||||||
k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31 h1:KCcLuc/HD1RogJgEbZi9ObRuLv1bgiRCfAbidLKrUpg=
|
|
||||||
k8s.io/utils v0.0.0-20200117235808-5f6fbceb4c31/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
|
||||||
k8s.io/utils v0.0.0-20200122174043-1e243dd1a584 h1:3tT5mBZNurtd5BoYrPBII3Sa8n7T2w405qdTQvr3vmY=
|
k8s.io/utils v0.0.0-20200122174043-1e243dd1a584 h1:3tT5mBZNurtd5BoYrPBII3Sa8n7T2w405qdTQvr3vmY=
|
||||||
k8s.io/utils v0.0.0-20200122174043-1e243dd1a584/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
k8s.io/utils v0.0.0-20200122174043-1e243dd1a584/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/google/cadvisor/container"
|
"github.com/google/cadvisor/container"
|
||||||
info "github.com/google/cadvisor/info/v1"
|
info "github.com/google/cadvisor/info/v1"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type testSubcontainersInfoProvider struct{}
|
type testSubcontainersInfoProvider struct{}
|
||||||
@ -431,7 +432,7 @@ func TestPrometheusCollector(t *testing.T) {
|
|||||||
|
|
||||||
func testPrometheusCollector(t *testing.T, c *PrometheusCollector, metricsFile string) {
|
func testPrometheusCollector(t *testing.T, c *PrometheusCollector, metricsFile string) {
|
||||||
rw := httptest.NewRecorder()
|
rw := httptest.NewRecorder()
|
||||||
prometheus.Handler().ServeHTTP(rw, &http.Request{})
|
promhttp.Handler().ServeHTTP(rw, &http.Request{})
|
||||||
|
|
||||||
wantMetrics, err := ioutil.ReadFile(metricsFile)
|
wantMetrics, err := ioutil.ReadFile(metricsFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
20
vendor/github.com/beorn7/perks/LICENSE
generated
vendored
Normal file
20
vendor/github.com/beorn7/perks/LICENSE
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
Copyright (C) 2013 Blake Mizerany
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
36
vendor/github.com/beorn7/perks/quantile/stream.go
generated
vendored
36
vendor/github.com/beorn7/perks/quantile/stream.go
generated
vendored
@ -77,15 +77,20 @@ func NewHighBiased(epsilon float64) *Stream {
|
|||||||
// is guaranteed to be within (Quantile±Epsilon).
|
// is guaranteed to be within (Quantile±Epsilon).
|
||||||
//
|
//
|
||||||
// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties.
|
// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties.
|
||||||
func NewTargeted(targets map[float64]float64) *Stream {
|
func NewTargeted(targetMap map[float64]float64) *Stream {
|
||||||
|
// Convert map to slice to avoid slow iterations on a map.
|
||||||
|
// ƒ is called on the hot path, so converting the map to a slice
|
||||||
|
// beforehand results in significant CPU savings.
|
||||||
|
targets := targetMapToSlice(targetMap)
|
||||||
|
|
||||||
ƒ := func(s *stream, r float64) float64 {
|
ƒ := func(s *stream, r float64) float64 {
|
||||||
var m = math.MaxFloat64
|
var m = math.MaxFloat64
|
||||||
var f float64
|
var f float64
|
||||||
for quantile, epsilon := range targets {
|
for _, t := range targets {
|
||||||
if quantile*s.n <= r {
|
if t.quantile*s.n <= r {
|
||||||
f = (2 * epsilon * r) / quantile
|
f = (2 * t.epsilon * r) / t.quantile
|
||||||
} else {
|
} else {
|
||||||
f = (2 * epsilon * (s.n - r)) / (1 - quantile)
|
f = (2 * t.epsilon * (s.n - r)) / (1 - t.quantile)
|
||||||
}
|
}
|
||||||
if f < m {
|
if f < m {
|
||||||
m = f
|
m = f
|
||||||
@ -96,6 +101,25 @@ func NewTargeted(targets map[float64]float64) *Stream {
|
|||||||
return newStream(ƒ)
|
return newStream(ƒ)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type target struct {
|
||||||
|
quantile float64
|
||||||
|
epsilon float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func targetMapToSlice(targetMap map[float64]float64) []target {
|
||||||
|
targets := make([]target, 0, len(targetMap))
|
||||||
|
|
||||||
|
for quantile, epsilon := range targetMap {
|
||||||
|
t := target{
|
||||||
|
quantile: quantile,
|
||||||
|
epsilon: epsilon,
|
||||||
|
}
|
||||||
|
targets = append(targets, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
return targets
|
||||||
|
}
|
||||||
|
|
||||||
// Stream computes quantiles for a stream of float64s. It is not thread-safe by
|
// Stream computes quantiles for a stream of float64s. It is not thread-safe by
|
||||||
// design. Take care when using across multiple goroutines.
|
// design. Take care when using across multiple goroutines.
|
||||||
type Stream struct {
|
type Stream struct {
|
||||||
@ -133,7 +157,7 @@ func (s *Stream) Query(q float64) float64 {
|
|||||||
if l == 0 {
|
if l == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
i := int(float64(l) * q)
|
i := int(math.Ceil(float64(l) * q))
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
i -= 1
|
i -= 1
|
||||||
}
|
}
|
||||||
|
27
vendor/github.com/google/go-cmp/LICENSE
generated
vendored
Normal file
27
vendor/github.com/google/go-cmp/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2017 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
616
vendor/github.com/google/go-cmp/cmp/compare.go
generated
vendored
Normal file
616
vendor/github.com/google/go-cmp/cmp/compare.go
generated
vendored
Normal file
@ -0,0 +1,616 @@
|
|||||||
|
// Copyright 2017, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
// Package cmp determines equality of values.
|
||||||
|
//
|
||||||
|
// This package is intended to be a more powerful and safer alternative to
|
||||||
|
// reflect.DeepEqual for comparing whether two values are semantically equal.
|
||||||
|
//
|
||||||
|
// The primary features of cmp are:
|
||||||
|
//
|
||||||
|
// • When the default behavior of equality does not suit the needs of the test,
|
||||||
|
// custom equality functions can override the equality operation.
|
||||||
|
// For example, an equality function may report floats as equal so long as they
|
||||||
|
// are within some tolerance of each other.
|
||||||
|
//
|
||||||
|
// • Types that have an Equal method may use that method to determine equality.
|
||||||
|
// This allows package authors to determine the equality operation for the types
|
||||||
|
// that they define.
|
||||||
|
//
|
||||||
|
// • If no custom equality functions are used and no Equal method is defined,
|
||||||
|
// equality is determined by recursively comparing the primitive kinds on both
|
||||||
|
// values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, unexported
|
||||||
|
// fields are not compared by default; they result in panics unless suppressed
|
||||||
|
// by using an Ignore option (see cmpopts.IgnoreUnexported) or explicitly compared
|
||||||
|
// using the AllowUnexported option.
|
||||||
|
package cmp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp/internal/diff"
|
||||||
|
"github.com/google/go-cmp/cmp/internal/flags"
|
||||||
|
"github.com/google/go-cmp/cmp/internal/function"
|
||||||
|
"github.com/google/go-cmp/cmp/internal/value"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Equal reports whether x and y are equal by recursively applying the
|
||||||
|
// following rules in the given order to x and y and all of their sub-values:
|
||||||
|
//
|
||||||
|
// • Let S be the set of all Ignore, Transformer, and Comparer options that
|
||||||
|
// remain after applying all path filters, value filters, and type filters.
|
||||||
|
// If at least one Ignore exists in S, then the comparison is ignored.
|
||||||
|
// If the number of Transformer and Comparer options in S is greater than one,
|
||||||
|
// then Equal panics because it is ambiguous which option to use.
|
||||||
|
// If S contains a single Transformer, then use that to transform the current
|
||||||
|
// values and recursively call Equal on the output values.
|
||||||
|
// If S contains a single Comparer, then use that to compare the current values.
|
||||||
|
// Otherwise, evaluation proceeds to the next rule.
|
||||||
|
//
|
||||||
|
// • If the values have an Equal method of the form "(T) Equal(T) bool" or
|
||||||
|
// "(T) Equal(I) bool" where T is assignable to I, then use the result of
|
||||||
|
// x.Equal(y) even if x or y is nil. Otherwise, no such method exists and
|
||||||
|
// evaluation proceeds to the next rule.
|
||||||
|
//
|
||||||
|
// • Lastly, try to compare x and y based on their basic kinds.
|
||||||
|
// Simple kinds like booleans, integers, floats, complex numbers, strings, and
|
||||||
|
// channels are compared using the equivalent of the == operator in Go.
|
||||||
|
// Functions are only equal if they are both nil, otherwise they are unequal.
|
||||||
|
//
|
||||||
|
// Structs are equal if recursively calling Equal on all fields report equal.
|
||||||
|
// If a struct contains unexported fields, Equal panics unless an Ignore option
|
||||||
|
// (e.g., cmpopts.IgnoreUnexported) ignores that field or the AllowUnexported
|
||||||
|
// option explicitly permits comparing the unexported field.
|
||||||
|
//
|
||||||
|
// Slices are equal if they are both nil or both non-nil, where recursively
|
||||||
|
// calling Equal on all non-ignored slice or array elements report equal.
|
||||||
|
// Empty non-nil slices and nil slices are not equal; to equate empty slices,
|
||||||
|
// consider using cmpopts.EquateEmpty.
|
||||||
|
//
|
||||||
|
// Maps are equal if they are both nil or both non-nil, where recursively
|
||||||
|
// calling Equal on all non-ignored map entries report equal.
|
||||||
|
// Map keys are equal according to the == operator.
|
||||||
|
// To use custom comparisons for map keys, consider using cmpopts.SortMaps.
|
||||||
|
// Empty non-nil maps and nil maps are not equal; to equate empty maps,
|
||||||
|
// consider using cmpopts.EquateEmpty.
|
||||||
|
//
|
||||||
|
// Pointers and interfaces are equal if they are both nil or both non-nil,
|
||||||
|
// where they have the same underlying concrete type and recursively
|
||||||
|
// calling Equal on the underlying values reports equal.
|
||||||
|
func Equal(x, y interface{}, opts ...Option) bool {
|
||||||
|
vx := reflect.ValueOf(x)
|
||||||
|
vy := reflect.ValueOf(y)
|
||||||
|
|
||||||
|
// If the inputs are different types, auto-wrap them in an empty interface
|
||||||
|
// so that they have the same parent type.
|
||||||
|
var t reflect.Type
|
||||||
|
if !vx.IsValid() || !vy.IsValid() || vx.Type() != vy.Type() {
|
||||||
|
t = reflect.TypeOf((*interface{})(nil)).Elem()
|
||||||
|
if vx.IsValid() {
|
||||||
|
vvx := reflect.New(t).Elem()
|
||||||
|
vvx.Set(vx)
|
||||||
|
vx = vvx
|
||||||
|
}
|
||||||
|
if vy.IsValid() {
|
||||||
|
vvy := reflect.New(t).Elem()
|
||||||
|
vvy.Set(vy)
|
||||||
|
vy = vvy
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t = vx.Type()
|
||||||
|
}
|
||||||
|
|
||||||
|
s := newState(opts)
|
||||||
|
s.compareAny(&pathStep{t, vx, vy})
|
||||||
|
return s.result.Equal()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Diff returns a human-readable report of the differences between two values.
|
||||||
|
// It returns an empty string if and only if Equal returns true for the same
|
||||||
|
// input values and options.
|
||||||
|
//
|
||||||
|
// The output is displayed as a literal in pseudo-Go syntax.
|
||||||
|
// At the start of each line, a "-" prefix indicates an element removed from x,
|
||||||
|
// a "+" prefix to indicates an element added to y, and the lack of a prefix
|
||||||
|
// indicates an element common to both x and y. If possible, the output
|
||||||
|
// uses fmt.Stringer.String or error.Error methods to produce more humanly
|
||||||
|
// readable outputs. In such cases, the string is prefixed with either an
|
||||||
|
// 's' or 'e' character, respectively, to indicate that the method was called.
|
||||||
|
//
|
||||||
|
// Do not depend on this output being stable. If you need the ability to
|
||||||
|
// programmatically interpret the difference, consider using a custom Reporter.
|
||||||
|
func Diff(x, y interface{}, opts ...Option) string {
|
||||||
|
r := new(defaultReporter)
|
||||||
|
eq := Equal(x, y, Options(opts), Reporter(r))
|
||||||
|
d := r.String()
|
||||||
|
if (d == "") != eq {
|
||||||
|
panic("inconsistent difference and equality results")
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
type state struct {
|
||||||
|
// These fields represent the "comparison state".
|
||||||
|
// Calling statelessCompare must not result in observable changes to these.
|
||||||
|
result diff.Result // The current result of comparison
|
||||||
|
curPath Path // The current path in the value tree
|
||||||
|
reporters []reporter // Optional reporters
|
||||||
|
|
||||||
|
// recChecker checks for infinite cycles applying the same set of
|
||||||
|
// transformers upon the output of itself.
|
||||||
|
recChecker recChecker
|
||||||
|
|
||||||
|
// dynChecker triggers pseudo-random checks for option correctness.
|
||||||
|
// It is safe for statelessCompare to mutate this value.
|
||||||
|
dynChecker dynChecker
|
||||||
|
|
||||||
|
// These fields, once set by processOption, will not change.
|
||||||
|
exporters map[reflect.Type]bool // Set of structs with unexported field visibility
|
||||||
|
opts Options // List of all fundamental and filter options
|
||||||
|
}
|
||||||
|
|
||||||
|
func newState(opts []Option) *state {
|
||||||
|
// Always ensure a validator option exists to validate the inputs.
|
||||||
|
s := &state{opts: Options{validator{}}}
|
||||||
|
s.processOption(Options(opts))
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) processOption(opt Option) {
|
||||||
|
switch opt := opt.(type) {
|
||||||
|
case nil:
|
||||||
|
case Options:
|
||||||
|
for _, o := range opt {
|
||||||
|
s.processOption(o)
|
||||||
|
}
|
||||||
|
case coreOption:
|
||||||
|
type filtered interface {
|
||||||
|
isFiltered() bool
|
||||||
|
}
|
||||||
|
if fopt, ok := opt.(filtered); ok && !fopt.isFiltered() {
|
||||||
|
panic(fmt.Sprintf("cannot use an unfiltered option: %v", opt))
|
||||||
|
}
|
||||||
|
s.opts = append(s.opts, opt)
|
||||||
|
case visibleStructs:
|
||||||
|
if s.exporters == nil {
|
||||||
|
s.exporters = make(map[reflect.Type]bool)
|
||||||
|
}
|
||||||
|
for t := range opt {
|
||||||
|
s.exporters[t] = true
|
||||||
|
}
|
||||||
|
case reporter:
|
||||||
|
s.reporters = append(s.reporters, opt)
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unknown option %T", opt))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// statelessCompare compares two values and returns the result.
|
||||||
|
// This function is stateless in that it does not alter the current result,
|
||||||
|
// or output to any registered reporters.
|
||||||
|
func (s *state) statelessCompare(step PathStep) diff.Result {
|
||||||
|
// We do not save and restore the curPath because all of the compareX
|
||||||
|
// methods should properly push and pop from the path.
|
||||||
|
// It is an implementation bug if the contents of curPath differs from
|
||||||
|
// when calling this function to when returning from it.
|
||||||
|
|
||||||
|
oldResult, oldReporters := s.result, s.reporters
|
||||||
|
s.result = diff.Result{} // Reset result
|
||||||
|
s.reporters = nil // Remove reporters to avoid spurious printouts
|
||||||
|
s.compareAny(step)
|
||||||
|
res := s.result
|
||||||
|
s.result, s.reporters = oldResult, oldReporters
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) compareAny(step PathStep) {
|
||||||
|
// Update the path stack.
|
||||||
|
s.curPath.push(step)
|
||||||
|
defer s.curPath.pop()
|
||||||
|
for _, r := range s.reporters {
|
||||||
|
r.PushStep(step)
|
||||||
|
defer r.PopStep()
|
||||||
|
}
|
||||||
|
s.recChecker.Check(s.curPath)
|
||||||
|
|
||||||
|
// Obtain the current type and values.
|
||||||
|
t := step.Type()
|
||||||
|
vx, vy := step.Values()
|
||||||
|
|
||||||
|
// Rule 1: Check whether an option applies on this node in the value tree.
|
||||||
|
if s.tryOptions(t, vx, vy) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rule 2: Check whether the type has a valid Equal method.
|
||||||
|
if s.tryMethod(t, vx, vy) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rule 3: Compare based on the underlying kind.
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
s.report(vx.Bool() == vy.Bool(), 0)
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
s.report(vx.Int() == vy.Int(), 0)
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
s.report(vx.Uint() == vy.Uint(), 0)
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
s.report(vx.Float() == vy.Float(), 0)
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
s.report(vx.Complex() == vy.Complex(), 0)
|
||||||
|
case reflect.String:
|
||||||
|
s.report(vx.String() == vy.String(), 0)
|
||||||
|
case reflect.Chan, reflect.UnsafePointer:
|
||||||
|
s.report(vx.Pointer() == vy.Pointer(), 0)
|
||||||
|
case reflect.Func:
|
||||||
|
s.report(vx.IsNil() && vy.IsNil(), 0)
|
||||||
|
case reflect.Struct:
|
||||||
|
s.compareStruct(t, vx, vy)
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
s.compareSlice(t, vx, vy)
|
||||||
|
case reflect.Map:
|
||||||
|
s.compareMap(t, vx, vy)
|
||||||
|
case reflect.Ptr:
|
||||||
|
s.comparePtr(t, vx, vy)
|
||||||
|
case reflect.Interface:
|
||||||
|
s.compareInterface(t, vx, vy)
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("%v kind not handled", t.Kind()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) tryOptions(t reflect.Type, vx, vy reflect.Value) bool {
|
||||||
|
// Evaluate all filters and apply the remaining options.
|
||||||
|
if opt := s.opts.filter(s, t, vx, vy); opt != nil {
|
||||||
|
opt.apply(s, vx, vy)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) tryMethod(t reflect.Type, vx, vy reflect.Value) bool {
|
||||||
|
// Check if this type even has an Equal method.
|
||||||
|
m, ok := t.MethodByName("Equal")
|
||||||
|
if !ok || !function.IsType(m.Type, function.EqualAssignable) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
eq := s.callTTBFunc(m.Func, vx, vy)
|
||||||
|
s.report(eq, reportByMethod)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) callTRFunc(f, v reflect.Value, step Transform) reflect.Value {
|
||||||
|
v = sanitizeValue(v, f.Type().In(0))
|
||||||
|
if !s.dynChecker.Next() {
|
||||||
|
return f.Call([]reflect.Value{v})[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the function twice and ensure that we get the same results back.
|
||||||
|
// We run in goroutines so that the race detector (if enabled) can detect
|
||||||
|
// unsafe mutations to the input.
|
||||||
|
c := make(chan reflect.Value)
|
||||||
|
go detectRaces(c, f, v)
|
||||||
|
got := <-c
|
||||||
|
want := f.Call([]reflect.Value{v})[0]
|
||||||
|
if step.vx, step.vy = got, want; !s.statelessCompare(step).Equal() {
|
||||||
|
// To avoid false-positives with non-reflexive equality operations,
|
||||||
|
// we sanity check whether a value is equal to itself.
|
||||||
|
if step.vx, step.vy = want, want; !s.statelessCompare(step).Equal() {
|
||||||
|
return want
|
||||||
|
}
|
||||||
|
panic(fmt.Sprintf("non-deterministic function detected: %s", function.NameOf(f)))
|
||||||
|
}
|
||||||
|
return want
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) callTTBFunc(f, x, y reflect.Value) bool {
|
||||||
|
x = sanitizeValue(x, f.Type().In(0))
|
||||||
|
y = sanitizeValue(y, f.Type().In(1))
|
||||||
|
if !s.dynChecker.Next() {
|
||||||
|
return f.Call([]reflect.Value{x, y})[0].Bool()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swapping the input arguments is sufficient to check that
|
||||||
|
// f is symmetric and deterministic.
|
||||||
|
// We run in goroutines so that the race detector (if enabled) can detect
|
||||||
|
// unsafe mutations to the input.
|
||||||
|
c := make(chan reflect.Value)
|
||||||
|
go detectRaces(c, f, y, x)
|
||||||
|
got := <-c
|
||||||
|
want := f.Call([]reflect.Value{x, y})[0].Bool()
|
||||||
|
if !got.IsValid() || got.Bool() != want {
|
||||||
|
panic(fmt.Sprintf("non-deterministic or non-symmetric function detected: %s", function.NameOf(f)))
|
||||||
|
}
|
||||||
|
return want
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectRaces(c chan<- reflect.Value, f reflect.Value, vs ...reflect.Value) {
|
||||||
|
var ret reflect.Value
|
||||||
|
defer func() {
|
||||||
|
recover() // Ignore panics, let the other call to f panic instead
|
||||||
|
c <- ret
|
||||||
|
}()
|
||||||
|
ret = f.Call(vs)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanitizeValue converts nil interfaces of type T to those of type R,
|
||||||
|
// assuming that T is assignable to R.
|
||||||
|
// Otherwise, it returns the input value as is.
|
||||||
|
func sanitizeValue(v reflect.Value, t reflect.Type) reflect.Value {
|
||||||
|
// TODO(dsnet): Workaround for reflect bug (https://golang.org/issue/22143).
|
||||||
|
if !flags.AtLeastGo110 {
|
||||||
|
if v.Kind() == reflect.Interface && v.IsNil() && v.Type() != t {
|
||||||
|
return reflect.New(t).Elem()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) compareStruct(t reflect.Type, vx, vy reflect.Value) {
|
||||||
|
var vax, vay reflect.Value // Addressable versions of vx and vy
|
||||||
|
|
||||||
|
step := StructField{&structField{}}
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
step.typ = t.Field(i).Type
|
||||||
|
step.vx = vx.Field(i)
|
||||||
|
step.vy = vy.Field(i)
|
||||||
|
step.name = t.Field(i).Name
|
||||||
|
step.idx = i
|
||||||
|
step.unexported = !isExported(step.name)
|
||||||
|
if step.unexported {
|
||||||
|
if step.name == "_" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Defer checking of unexported fields until later to give an
|
||||||
|
// Ignore a chance to ignore the field.
|
||||||
|
if !vax.IsValid() || !vay.IsValid() {
|
||||||
|
// For retrieveUnexportedField to work, the parent struct must
|
||||||
|
// be addressable. Create a new copy of the values if
|
||||||
|
// necessary to make them addressable.
|
||||||
|
vax = makeAddressable(vx)
|
||||||
|
vay = makeAddressable(vy)
|
||||||
|
}
|
||||||
|
step.mayForce = s.exporters[t]
|
||||||
|
step.pvx = vax
|
||||||
|
step.pvy = vay
|
||||||
|
step.field = t.Field(i)
|
||||||
|
}
|
||||||
|
s.compareAny(step)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) compareSlice(t reflect.Type, vx, vy reflect.Value) {
|
||||||
|
isSlice := t.Kind() == reflect.Slice
|
||||||
|
if isSlice && (vx.IsNil() || vy.IsNil()) {
|
||||||
|
s.report(vx.IsNil() && vy.IsNil(), 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Support cyclic data structures.
|
||||||
|
|
||||||
|
step := SliceIndex{&sliceIndex{pathStep: pathStep{typ: t.Elem()}}}
|
||||||
|
withIndexes := func(ix, iy int) SliceIndex {
|
||||||
|
if ix >= 0 {
|
||||||
|
step.vx, step.xkey = vx.Index(ix), ix
|
||||||
|
} else {
|
||||||
|
step.vx, step.xkey = reflect.Value{}, -1
|
||||||
|
}
|
||||||
|
if iy >= 0 {
|
||||||
|
step.vy, step.ykey = vy.Index(iy), iy
|
||||||
|
} else {
|
||||||
|
step.vy, step.ykey = reflect.Value{}, -1
|
||||||
|
}
|
||||||
|
return step
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore options are able to ignore missing elements in a slice.
|
||||||
|
// However, detecting these reliably requires an optimal differencing
|
||||||
|
// algorithm, for which diff.Difference is not.
|
||||||
|
//
|
||||||
|
// Instead, we first iterate through both slices to detect which elements
|
||||||
|
// would be ignored if standing alone. The index of non-discarded elements
|
||||||
|
// are stored in a separate slice, which diffing is then performed on.
|
||||||
|
var indexesX, indexesY []int
|
||||||
|
var ignoredX, ignoredY []bool
|
||||||
|
for ix := 0; ix < vx.Len(); ix++ {
|
||||||
|
ignored := s.statelessCompare(withIndexes(ix, -1)).NumDiff == 0
|
||||||
|
if !ignored {
|
||||||
|
indexesX = append(indexesX, ix)
|
||||||
|
}
|
||||||
|
ignoredX = append(ignoredX, ignored)
|
||||||
|
}
|
||||||
|
for iy := 0; iy < vy.Len(); iy++ {
|
||||||
|
ignored := s.statelessCompare(withIndexes(-1, iy)).NumDiff == 0
|
||||||
|
if !ignored {
|
||||||
|
indexesY = append(indexesY, iy)
|
||||||
|
}
|
||||||
|
ignoredY = append(ignoredY, ignored)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute an edit-script for slices vx and vy (excluding ignored elements).
|
||||||
|
edits := diff.Difference(len(indexesX), len(indexesY), func(ix, iy int) diff.Result {
|
||||||
|
return s.statelessCompare(withIndexes(indexesX[ix], indexesY[iy]))
|
||||||
|
})
|
||||||
|
|
||||||
|
// Replay the ignore-scripts and the edit-script.
|
||||||
|
var ix, iy int
|
||||||
|
for ix < vx.Len() || iy < vy.Len() {
|
||||||
|
var e diff.EditType
|
||||||
|
switch {
|
||||||
|
case ix < len(ignoredX) && ignoredX[ix]:
|
||||||
|
e = diff.UniqueX
|
||||||
|
case iy < len(ignoredY) && ignoredY[iy]:
|
||||||
|
e = diff.UniqueY
|
||||||
|
default:
|
||||||
|
e, edits = edits[0], edits[1:]
|
||||||
|
}
|
||||||
|
switch e {
|
||||||
|
case diff.UniqueX:
|
||||||
|
s.compareAny(withIndexes(ix, -1))
|
||||||
|
ix++
|
||||||
|
case diff.UniqueY:
|
||||||
|
s.compareAny(withIndexes(-1, iy))
|
||||||
|
iy++
|
||||||
|
default:
|
||||||
|
s.compareAny(withIndexes(ix, iy))
|
||||||
|
ix++
|
||||||
|
iy++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) compareMap(t reflect.Type, vx, vy reflect.Value) {
|
||||||
|
if vx.IsNil() || vy.IsNil() {
|
||||||
|
s.report(vx.IsNil() && vy.IsNil(), 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Support cyclic data structures.
|
||||||
|
|
||||||
|
// We combine and sort the two map keys so that we can perform the
|
||||||
|
// comparisons in a deterministic order.
|
||||||
|
step := MapIndex{&mapIndex{pathStep: pathStep{typ: t.Elem()}}}
|
||||||
|
for _, k := range value.SortKeys(append(vx.MapKeys(), vy.MapKeys()...)) {
|
||||||
|
step.vx = vx.MapIndex(k)
|
||||||
|
step.vy = vy.MapIndex(k)
|
||||||
|
step.key = k
|
||||||
|
if !step.vx.IsValid() && !step.vy.IsValid() {
|
||||||
|
// It is possible for both vx and vy to be invalid if the
|
||||||
|
// key contained a NaN value in it.
|
||||||
|
//
|
||||||
|
// Even with the ability to retrieve NaN keys in Go 1.12,
|
||||||
|
// there still isn't a sensible way to compare the values since
|
||||||
|
// a NaN key may map to multiple unordered values.
|
||||||
|
// The most reasonable way to compare NaNs would be to compare the
|
||||||
|
// set of values. However, this is impossible to do efficiently
|
||||||
|
// since set equality is provably an O(n^2) operation given only
|
||||||
|
// an Equal function. If we had a Less function or Hash function,
|
||||||
|
// this could be done in O(n*log(n)) or O(n), respectively.
|
||||||
|
//
|
||||||
|
// Rather than adding complex logic to deal with NaNs, make it
|
||||||
|
// the user's responsibility to compare such obscure maps.
|
||||||
|
const help = "consider providing a Comparer to compare the map"
|
||||||
|
panic(fmt.Sprintf("%#v has map key with NaNs\n%s", s.curPath, help))
|
||||||
|
}
|
||||||
|
s.compareAny(step)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) comparePtr(t reflect.Type, vx, vy reflect.Value) {
|
||||||
|
if vx.IsNil() || vy.IsNil() {
|
||||||
|
s.report(vx.IsNil() && vy.IsNil(), 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Support cyclic data structures.
|
||||||
|
|
||||||
|
vx, vy = vx.Elem(), vy.Elem()
|
||||||
|
s.compareAny(Indirect{&indirect{pathStep{t.Elem(), vx, vy}}})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) compareInterface(t reflect.Type, vx, vy reflect.Value) {
|
||||||
|
if vx.IsNil() || vy.IsNil() {
|
||||||
|
s.report(vx.IsNil() && vy.IsNil(), 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
vx, vy = vx.Elem(), vy.Elem()
|
||||||
|
if vx.Type() != vy.Type() {
|
||||||
|
s.report(false, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.compareAny(TypeAssertion{&typeAssertion{pathStep{vx.Type(), vx, vy}}})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) report(eq bool, rf resultFlags) {
|
||||||
|
if rf&reportByIgnore == 0 {
|
||||||
|
if eq {
|
||||||
|
s.result.NumSame++
|
||||||
|
rf |= reportEqual
|
||||||
|
} else {
|
||||||
|
s.result.NumDiff++
|
||||||
|
rf |= reportUnequal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, r := range s.reporters {
|
||||||
|
r.Report(Result{flags: rf})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recChecker tracks the state needed to periodically perform checks that
|
||||||
|
// user provided transformers are not stuck in an infinitely recursive cycle.
|
||||||
|
type recChecker struct{ next int }
|
||||||
|
|
||||||
|
// Check scans the Path for any recursive transformers and panics when any
|
||||||
|
// recursive transformers are detected. Note that the presence of a
|
||||||
|
// recursive Transformer does not necessarily imply an infinite cycle.
|
||||||
|
// As such, this check only activates after some minimal number of path steps.
|
||||||
|
func (rc *recChecker) Check(p Path) {
|
||||||
|
const minLen = 1 << 16
|
||||||
|
if rc.next == 0 {
|
||||||
|
rc.next = minLen
|
||||||
|
}
|
||||||
|
if len(p) < rc.next {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rc.next <<= 1
|
||||||
|
|
||||||
|
// Check whether the same transformer has appeared at least twice.
|
||||||
|
var ss []string
|
||||||
|
m := map[Option]int{}
|
||||||
|
for _, ps := range p {
|
||||||
|
if t, ok := ps.(Transform); ok {
|
||||||
|
t := t.Option()
|
||||||
|
if m[t] == 1 { // Transformer was used exactly once before
|
||||||
|
tf := t.(*transformer).fnc.Type()
|
||||||
|
ss = append(ss, fmt.Sprintf("%v: %v => %v", t, tf.In(0), tf.Out(0)))
|
||||||
|
}
|
||||||
|
m[t]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(ss) > 0 {
|
||||||
|
const warning = "recursive set of Transformers detected"
|
||||||
|
const help = "consider using cmpopts.AcyclicTransformer"
|
||||||
|
set := strings.Join(ss, "\n\t")
|
||||||
|
panic(fmt.Sprintf("%s:\n\t%s\n%s", warning, set, help))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dynChecker tracks the state needed to periodically perform checks that
|
||||||
|
// user provided functions are symmetric and deterministic.
|
||||||
|
// The zero value is safe for immediate use.
|
||||||
|
type dynChecker struct{ curr, next int }
|
||||||
|
|
||||||
|
// Next increments the state and reports whether a check should be performed.
|
||||||
|
//
|
||||||
|
// Checks occur every Nth function call, where N is a triangular number:
|
||||||
|
// 0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ...
|
||||||
|
// See https://en.wikipedia.org/wiki/Triangular_number
|
||||||
|
//
|
||||||
|
// This sequence ensures that the cost of checks drops significantly as
|
||||||
|
// the number of functions calls grows larger.
|
||||||
|
func (dc *dynChecker) Next() bool {
|
||||||
|
ok := dc.curr == dc.next
|
||||||
|
if ok {
|
||||||
|
dc.curr = 0
|
||||||
|
dc.next++
|
||||||
|
}
|
||||||
|
dc.curr++
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeAddressable returns a value that is always addressable.
|
||||||
|
// It returns the input verbatim if it is already addressable,
|
||||||
|
// otherwise it creates a new value and returns an addressable copy.
|
||||||
|
func makeAddressable(v reflect.Value) reflect.Value {
|
||||||
|
if v.CanAddr() {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
vc := reflect.New(v.Type()).Elem()
|
||||||
|
vc.Set(v)
|
||||||
|
return vc
|
||||||
|
}
|
15
vendor/github.com/google/go-cmp/cmp/export_panic.go
generated
vendored
Normal file
15
vendor/github.com/google/go-cmp/cmp/export_panic.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright 2017, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
// +build purego
|
||||||
|
|
||||||
|
package cmp
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
const supportAllowUnexported = false
|
||||||
|
|
||||||
|
func retrieveUnexportedField(reflect.Value, reflect.StructField) reflect.Value {
|
||||||
|
panic("retrieveUnexportedField is not implemented")
|
||||||
|
}
|
23
vendor/github.com/google/go-cmp/cmp/export_unsafe.go
generated
vendored
Normal file
23
vendor/github.com/google/go-cmp/cmp/export_unsafe.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2017, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
// +build !purego
|
||||||
|
|
||||||
|
package cmp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const supportAllowUnexported = true
|
||||||
|
|
||||||
|
// retrieveUnexportedField uses unsafe to forcibly retrieve any field from
|
||||||
|
// a struct such that the value has read-write permissions.
|
||||||
|
//
|
||||||
|
// The parent struct, v, must be addressable, while f must be a StructField
|
||||||
|
// describing the field to retrieve.
|
||||||
|
func retrieveUnexportedField(v reflect.Value, f reflect.StructField) reflect.Value {
|
||||||
|
return reflect.NewAt(f.Type, unsafe.Pointer(v.UnsafeAddr()+f.Offset)).Elem()
|
||||||
|
}
|
17
vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go
generated
vendored
Normal file
17
vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2017, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
// +build !cmp_debug
|
||||||
|
|
||||||
|
package diff
|
||||||
|
|
||||||
|
var debug debugger
|
||||||
|
|
||||||
|
type debugger struct{}
|
||||||
|
|
||||||
|
func (debugger) Begin(_, _ int, f EqualFunc, _, _ *EditScript) EqualFunc {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
func (debugger) Update() {}
|
||||||
|
func (debugger) Finish() {}
|
122
vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
generated
vendored
Normal file
122
vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
// Copyright 2017, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
// +build cmp_debug
|
||||||
|
|
||||||
|
package diff
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The algorithm can be seen running in real-time by enabling debugging:
|
||||||
|
// go test -tags=cmp_debug -v
|
||||||
|
//
|
||||||
|
// Example output:
|
||||||
|
// === RUN TestDifference/#34
|
||||||
|
// ┌───────────────────────────────┐
|
||||||
|
// │ \ · · · · · · · · · · · · · · │
|
||||||
|
// │ · # · · · · · · · · · · · · · │
|
||||||
|
// │ · \ · · · · · · · · · · · · · │
|
||||||
|
// │ · · \ · · · · · · · · · · · · │
|
||||||
|
// │ · · · X # · · · · · · · · · · │
|
||||||
|
// │ · · · # \ · · · · · · · · · · │
|
||||||
|
// │ · · · · · # # · · · · · · · · │
|
||||||
|
// │ · · · · · # \ · · · · · · · · │
|
||||||
|
// │ · · · · · · · \ · · · · · · · │
|
||||||
|
// │ · · · · · · · · \ · · · · · · │
|
||||||
|
// │ · · · · · · · · · \ · · · · · │
|
||||||
|
// │ · · · · · · · · · · \ · · # · │
|
||||||
|
// │ · · · · · · · · · · · \ # # · │
|
||||||
|
// │ · · · · · · · · · · · # # # · │
|
||||||
|
// │ · · · · · · · · · · # # # # · │
|
||||||
|
// │ · · · · · · · · · # # # # # · │
|
||||||
|
// │ · · · · · · · · · · · · · · \ │
|
||||||
|
// └───────────────────────────────┘
|
||||||
|
// [.Y..M.XY......YXYXY.|]
|
||||||
|
//
|
||||||
|
// The grid represents the edit-graph where the horizontal axis represents
|
||||||
|
// list X and the vertical axis represents list Y. The start of the two lists
|
||||||
|
// is the top-left, while the ends are the bottom-right. The '·' represents
|
||||||
|
// an unexplored node in the graph. The '\' indicates that the two symbols
|
||||||
|
// from list X and Y are equal. The 'X' indicates that two symbols are similar
|
||||||
|
// (but not exactly equal) to each other. The '#' indicates that the two symbols
|
||||||
|
// are different (and not similar). The algorithm traverses this graph trying to
|
||||||
|
// make the paths starting in the top-left and the bottom-right connect.
|
||||||
|
//
|
||||||
|
// The series of '.', 'X', 'Y', and 'M' characters at the bottom represents
|
||||||
|
// the currently established path from the forward and reverse searches,
|
||||||
|
// separated by a '|' character.
|
||||||
|
|
||||||
|
const (
|
||||||
|
updateDelay = 100 * time.Millisecond
|
||||||
|
finishDelay = 500 * time.Millisecond
|
||||||
|
ansiTerminal = true // ANSI escape codes used to move terminal cursor
|
||||||
|
)
|
||||||
|
|
||||||
|
var debug debugger
|
||||||
|
|
||||||
|
type debugger struct {
|
||||||
|
sync.Mutex
|
||||||
|
p1, p2 EditScript
|
||||||
|
fwdPath, revPath *EditScript
|
||||||
|
grid []byte
|
||||||
|
lines int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dbg *debugger) Begin(nx, ny int, f EqualFunc, p1, p2 *EditScript) EqualFunc {
|
||||||
|
dbg.Lock()
|
||||||
|
dbg.fwdPath, dbg.revPath = p1, p2
|
||||||
|
top := "┌─" + strings.Repeat("──", nx) + "┐\n"
|
||||||
|
row := "│ " + strings.Repeat("· ", nx) + "│\n"
|
||||||
|
btm := "└─" + strings.Repeat("──", nx) + "┘\n"
|
||||||
|
dbg.grid = []byte(top + strings.Repeat(row, ny) + btm)
|
||||||
|
dbg.lines = strings.Count(dbg.String(), "\n")
|
||||||
|
fmt.Print(dbg)
|
||||||
|
|
||||||
|
// Wrap the EqualFunc so that we can intercept each result.
|
||||||
|
return func(ix, iy int) (r Result) {
|
||||||
|
cell := dbg.grid[len(top)+iy*len(row):][len("│ ")+len("· ")*ix:][:len("·")]
|
||||||
|
for i := range cell {
|
||||||
|
cell[i] = 0 // Zero out the multiple bytes of UTF-8 middle-dot
|
||||||
|
}
|
||||||
|
switch r = f(ix, iy); {
|
||||||
|
case r.Equal():
|
||||||
|
cell[0] = '\\'
|
||||||
|
case r.Similar():
|
||||||
|
cell[0] = 'X'
|
||||||
|
default:
|
||||||
|
cell[0] = '#'
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dbg *debugger) Update() {
|
||||||
|
dbg.print(updateDelay)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dbg *debugger) Finish() {
|
||||||
|
dbg.print(finishDelay)
|
||||||
|
dbg.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dbg *debugger) String() string {
|
||||||
|
dbg.p1, dbg.p2 = *dbg.fwdPath, dbg.p2[:0]
|
||||||
|
for i := len(*dbg.revPath) - 1; i >= 0; i-- {
|
||||||
|
dbg.p2 = append(dbg.p2, (*dbg.revPath)[i])
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s[%v|%v]\n\n", dbg.grid, dbg.p1, dbg.p2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dbg *debugger) print(d time.Duration) {
|
||||||
|
if ansiTerminal {
|
||||||
|
fmt.Printf("\x1b[%dA", dbg.lines) // Reset terminal cursor
|
||||||
|
}
|
||||||
|
fmt.Print(dbg)
|
||||||
|
time.Sleep(d)
|
||||||
|
}
|
372
vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
generated
vendored
Normal file
372
vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
generated
vendored
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
// Copyright 2017, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
// Package diff implements an algorithm for producing edit-scripts.
|
||||||
|
// The edit-script is a sequence of operations needed to transform one list
|
||||||
|
// of symbols into another (or vice-versa). The edits allowed are insertions,
|
||||||
|
// deletions, and modifications. The summation of all edits is called the
|
||||||
|
// Levenshtein distance as this problem is well-known in computer science.
|
||||||
|
//
|
||||||
|
// This package prioritizes performance over accuracy. That is, the run time
|
||||||
|
// is more important than obtaining a minimal Levenshtein distance.
|
||||||
|
package diff
|
||||||
|
|
||||||
|
// EditType represents a single operation within an edit-script.
|
||||||
|
type EditType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Identity indicates that a symbol pair is identical in both list X and Y.
|
||||||
|
Identity EditType = iota
|
||||||
|
// UniqueX indicates that a symbol only exists in X and not Y.
|
||||||
|
UniqueX
|
||||||
|
// UniqueY indicates that a symbol only exists in Y and not X.
|
||||||
|
UniqueY
|
||||||
|
// Modified indicates that a symbol pair is a modification of each other.
|
||||||
|
Modified
|
||||||
|
)
|
||||||
|
|
||||||
|
// EditScript represents the series of differences between two lists.
|
||||||
|
type EditScript []EditType
|
||||||
|
|
||||||
|
// String returns a human-readable string representing the edit-script where
|
||||||
|
// Identity, UniqueX, UniqueY, and Modified are represented by the
|
||||||
|
// '.', 'X', 'Y', and 'M' characters, respectively.
|
||||||
|
func (es EditScript) String() string {
|
||||||
|
b := make([]byte, len(es))
|
||||||
|
for i, e := range es {
|
||||||
|
switch e {
|
||||||
|
case Identity:
|
||||||
|
b[i] = '.'
|
||||||
|
case UniqueX:
|
||||||
|
b[i] = 'X'
|
||||||
|
case UniqueY:
|
||||||
|
b[i] = 'Y'
|
||||||
|
case Modified:
|
||||||
|
b[i] = 'M'
|
||||||
|
default:
|
||||||
|
panic("invalid edit-type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// stats returns a histogram of the number of each type of edit operation.
|
||||||
|
func (es EditScript) stats() (s struct{ NI, NX, NY, NM int }) {
|
||||||
|
for _, e := range es {
|
||||||
|
switch e {
|
||||||
|
case Identity:
|
||||||
|
s.NI++
|
||||||
|
case UniqueX:
|
||||||
|
s.NX++
|
||||||
|
case UniqueY:
|
||||||
|
s.NY++
|
||||||
|
case Modified:
|
||||||
|
s.NM++
|
||||||
|
default:
|
||||||
|
panic("invalid edit-type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dist is the Levenshtein distance and is guaranteed to be 0 if and only if
|
||||||
|
// lists X and Y are equal.
|
||||||
|
func (es EditScript) Dist() int { return len(es) - es.stats().NI }
|
||||||
|
|
||||||
|
// LenX is the length of the X list.
|
||||||
|
func (es EditScript) LenX() int { return len(es) - es.stats().NY }
|
||||||
|
|
||||||
|
// LenY is the length of the Y list.
|
||||||
|
func (es EditScript) LenY() int { return len(es) - es.stats().NX }
|
||||||
|
|
||||||
|
// EqualFunc reports whether the symbols at indexes ix and iy are equal.
|
||||||
|
// When called by Difference, the index is guaranteed to be within nx and ny.
|
||||||
|
type EqualFunc func(ix int, iy int) Result
|
||||||
|
|
||||||
|
// Result is the result of comparison.
|
||||||
|
// NumSame is the number of sub-elements that are equal.
|
||||||
|
// NumDiff is the number of sub-elements that are not equal.
|
||||||
|
type Result struct{ NumSame, NumDiff int }
|
||||||
|
|
||||||
|
// BoolResult returns a Result that is either Equal or not Equal.
|
||||||
|
func BoolResult(b bool) Result {
|
||||||
|
if b {
|
||||||
|
return Result{NumSame: 1} // Equal, Similar
|
||||||
|
} else {
|
||||||
|
return Result{NumDiff: 2} // Not Equal, not Similar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal indicates whether the symbols are equal. Two symbols are equal
|
||||||
|
// if and only if NumDiff == 0. If Equal, then they are also Similar.
|
||||||
|
func (r Result) Equal() bool { return r.NumDiff == 0 }
|
||||||
|
|
||||||
|
// Similar indicates whether two symbols are similar and may be represented
|
||||||
|
// by using the Modified type. As a special case, we consider binary comparisons
|
||||||
|
// (i.e., those that return Result{1, 0} or Result{0, 1}) to be similar.
|
||||||
|
//
|
||||||
|
// The exact ratio of NumSame to NumDiff to determine similarity may change.
|
||||||
|
func (r Result) Similar() bool {
|
||||||
|
// Use NumSame+1 to offset NumSame so that binary comparisons are similar.
|
||||||
|
return r.NumSame+1 >= r.NumDiff
|
||||||
|
}
|
||||||
|
|
||||||
|
// Difference reports whether two lists of lengths nx and ny are equal
|
||||||
|
// given the definition of equality provided as f.
|
||||||
|
//
|
||||||
|
// This function returns an edit-script, which is a sequence of operations
|
||||||
|
// needed to convert one list into the other. The following invariants for
|
||||||
|
// the edit-script are maintained:
|
||||||
|
// • eq == (es.Dist()==0)
|
||||||
|
// • nx == es.LenX()
|
||||||
|
// • ny == es.LenY()
|
||||||
|
//
|
||||||
|
// This algorithm is not guaranteed to be an optimal solution (i.e., one that
|
||||||
|
// produces an edit-script with a minimal Levenshtein distance). This algorithm
|
||||||
|
// favors performance over optimality. The exact output is not guaranteed to
|
||||||
|
// be stable and may change over time.
|
||||||
|
func Difference(nx, ny int, f EqualFunc) (es EditScript) {
|
||||||
|
// This algorithm is based on traversing what is known as an "edit-graph".
|
||||||
|
// See Figure 1 from "An O(ND) Difference Algorithm and Its Variations"
|
||||||
|
// by Eugene W. Myers. Since D can be as large as N itself, this is
|
||||||
|
// effectively O(N^2). Unlike the algorithm from that paper, we are not
|
||||||
|
// interested in the optimal path, but at least some "decent" path.
|
||||||
|
//
|
||||||
|
// For example, let X and Y be lists of symbols:
|
||||||
|
// X = [A B C A B B A]
|
||||||
|
// Y = [C B A B A C]
|
||||||
|
//
|
||||||
|
// The edit-graph can be drawn as the following:
|
||||||
|
// A B C A B B A
|
||||||
|
// ┌─────────────┐
|
||||||
|
// C │_|_|\|_|_|_|_│ 0
|
||||||
|
// B │_|\|_|_|\|\|_│ 1
|
||||||
|
// A │\|_|_|\|_|_|\│ 2
|
||||||
|
// B │_|\|_|_|\|\|_│ 3
|
||||||
|
// A │\|_|_|\|_|_|\│ 4
|
||||||
|
// C │ | |\| | | | │ 5
|
||||||
|
// └─────────────┘ 6
|
||||||
|
// 0 1 2 3 4 5 6 7
|
||||||
|
//
|
||||||
|
// List X is written along the horizontal axis, while list Y is written
|
||||||
|
// along the vertical axis. At any point on this grid, if the symbol in
|
||||||
|
// list X matches the corresponding symbol in list Y, then a '\' is drawn.
|
||||||
|
// The goal of any minimal edit-script algorithm is to find a path from the
|
||||||
|
// top-left corner to the bottom-right corner, while traveling through the
|
||||||
|
// fewest horizontal or vertical edges.
|
||||||
|
// A horizontal edge is equivalent to inserting a symbol from list X.
|
||||||
|
// A vertical edge is equivalent to inserting a symbol from list Y.
|
||||||
|
// A diagonal edge is equivalent to a matching symbol between both X and Y.
|
||||||
|
|
||||||
|
// Invariants:
|
||||||
|
// • 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx
|
||||||
|
// • 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny
|
||||||
|
//
|
||||||
|
// In general:
|
||||||
|
// • fwdFrontier.X < revFrontier.X
|
||||||
|
// • fwdFrontier.Y < revFrontier.Y
|
||||||
|
// Unless, it is time for the algorithm to terminate.
|
||||||
|
fwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)}
|
||||||
|
revPath := path{-1, point{nx, ny}, make(EditScript, 0)}
|
||||||
|
fwdFrontier := fwdPath.point // Forward search frontier
|
||||||
|
revFrontier := revPath.point // Reverse search frontier
|
||||||
|
|
||||||
|
// Search budget bounds the cost of searching for better paths.
|
||||||
|
// The longest sequence of non-matching symbols that can be tolerated is
|
||||||
|
// approximately the square-root of the search budget.
|
||||||
|
searchBudget := 4 * (nx + ny) // O(n)
|
||||||
|
|
||||||
|
// The algorithm below is a greedy, meet-in-the-middle algorithm for
|
||||||
|
// computing sub-optimal edit-scripts between two lists.
|
||||||
|
//
|
||||||
|
// The algorithm is approximately as follows:
|
||||||
|
// • Searching for differences switches back-and-forth between
|
||||||
|
// a search that starts at the beginning (the top-left corner), and
|
||||||
|
// a search that starts at the end (the bottom-right corner). The goal of
|
||||||
|
// the search is connect with the search from the opposite corner.
|
||||||
|
// • As we search, we build a path in a greedy manner, where the first
|
||||||
|
// match seen is added to the path (this is sub-optimal, but provides a
|
||||||
|
// decent result in practice). When matches are found, we try the next pair
|
||||||
|
// of symbols in the lists and follow all matches as far as possible.
|
||||||
|
// • When searching for matches, we search along a diagonal going through
|
||||||
|
// through the "frontier" point. If no matches are found, we advance the
|
||||||
|
// frontier towards the opposite corner.
|
||||||
|
// • This algorithm terminates when either the X coordinates or the
|
||||||
|
// Y coordinates of the forward and reverse frontier points ever intersect.
|
||||||
|
//
|
||||||
|
// This algorithm is correct even if searching only in the forward direction
|
||||||
|
// or in the reverse direction. We do both because it is commonly observed
|
||||||
|
// that two lists commonly differ because elements were added to the front
|
||||||
|
// or end of the other list.
|
||||||
|
//
|
||||||
|
// Running the tests with the "cmp_debug" build tag prints a visualization
|
||||||
|
// of the algorithm running in real-time. This is educational for
|
||||||
|
// understanding how the algorithm works. See debug_enable.go.
|
||||||
|
f = debug.Begin(nx, ny, f, &fwdPath.es, &revPath.es)
|
||||||
|
for {
|
||||||
|
// Forward search from the beginning.
|
||||||
|
if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ {
|
||||||
|
// Search in a diagonal pattern for a match.
|
||||||
|
z := zigzag(i)
|
||||||
|
p := point{fwdFrontier.X + z, fwdFrontier.Y - z}
|
||||||
|
switch {
|
||||||
|
case p.X >= revPath.X || p.Y < fwdPath.Y:
|
||||||
|
stop1 = true // Hit top-right corner
|
||||||
|
case p.Y >= revPath.Y || p.X < fwdPath.X:
|
||||||
|
stop2 = true // Hit bottom-left corner
|
||||||
|
case f(p.X, p.Y).Equal():
|
||||||
|
// Match found, so connect the path to this point.
|
||||||
|
fwdPath.connect(p, f)
|
||||||
|
fwdPath.append(Identity)
|
||||||
|
// Follow sequence of matches as far as possible.
|
||||||
|
for fwdPath.X < revPath.X && fwdPath.Y < revPath.Y {
|
||||||
|
if !f(fwdPath.X, fwdPath.Y).Equal() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fwdPath.append(Identity)
|
||||||
|
}
|
||||||
|
fwdFrontier = fwdPath.point
|
||||||
|
stop1, stop2 = true, true
|
||||||
|
default:
|
||||||
|
searchBudget-- // Match not found
|
||||||
|
}
|
||||||
|
debug.Update()
|
||||||
|
}
|
||||||
|
// Advance the frontier towards reverse point.
|
||||||
|
if revPath.X-fwdFrontier.X >= revPath.Y-fwdFrontier.Y {
|
||||||
|
fwdFrontier.X++
|
||||||
|
} else {
|
||||||
|
fwdFrontier.Y++
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse search from the end.
|
||||||
|
if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ {
|
||||||
|
// Search in a diagonal pattern for a match.
|
||||||
|
z := zigzag(i)
|
||||||
|
p := point{revFrontier.X - z, revFrontier.Y + z}
|
||||||
|
switch {
|
||||||
|
case fwdPath.X >= p.X || revPath.Y < p.Y:
|
||||||
|
stop1 = true // Hit bottom-left corner
|
||||||
|
case fwdPath.Y >= p.Y || revPath.X < p.X:
|
||||||
|
stop2 = true // Hit top-right corner
|
||||||
|
case f(p.X-1, p.Y-1).Equal():
|
||||||
|
// Match found, so connect the path to this point.
|
||||||
|
revPath.connect(p, f)
|
||||||
|
revPath.append(Identity)
|
||||||
|
// Follow sequence of matches as far as possible.
|
||||||
|
for fwdPath.X < revPath.X && fwdPath.Y < revPath.Y {
|
||||||
|
if !f(revPath.X-1, revPath.Y-1).Equal() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
revPath.append(Identity)
|
||||||
|
}
|
||||||
|
revFrontier = revPath.point
|
||||||
|
stop1, stop2 = true, true
|
||||||
|
default:
|
||||||
|
searchBudget-- // Match not found
|
||||||
|
}
|
||||||
|
debug.Update()
|
||||||
|
}
|
||||||
|
// Advance the frontier towards forward point.
|
||||||
|
if revFrontier.X-fwdPath.X >= revFrontier.Y-fwdPath.Y {
|
||||||
|
revFrontier.X--
|
||||||
|
} else {
|
||||||
|
revFrontier.Y--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join the forward and reverse paths and then append the reverse path.
|
||||||
|
fwdPath.connect(revPath.point, f)
|
||||||
|
for i := len(revPath.es) - 1; i >= 0; i-- {
|
||||||
|
t := revPath.es[i]
|
||||||
|
revPath.es = revPath.es[:i]
|
||||||
|
fwdPath.append(t)
|
||||||
|
}
|
||||||
|
debug.Finish()
|
||||||
|
return fwdPath.es
|
||||||
|
}
|
||||||
|
|
||||||
|
type path struct {
|
||||||
|
dir int // +1 if forward, -1 if reverse
|
||||||
|
point // Leading point of the EditScript path
|
||||||
|
es EditScript
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect appends any necessary Identity, Modified, UniqueX, or UniqueY types
|
||||||
|
// to the edit-script to connect p.point to dst.
|
||||||
|
func (p *path) connect(dst point, f EqualFunc) {
|
||||||
|
if p.dir > 0 {
|
||||||
|
// Connect in forward direction.
|
||||||
|
for dst.X > p.X && dst.Y > p.Y {
|
||||||
|
switch r := f(p.X, p.Y); {
|
||||||
|
case r.Equal():
|
||||||
|
p.append(Identity)
|
||||||
|
case r.Similar():
|
||||||
|
p.append(Modified)
|
||||||
|
case dst.X-p.X >= dst.Y-p.Y:
|
||||||
|
p.append(UniqueX)
|
||||||
|
default:
|
||||||
|
p.append(UniqueY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for dst.X > p.X {
|
||||||
|
p.append(UniqueX)
|
||||||
|
}
|
||||||
|
for dst.Y > p.Y {
|
||||||
|
p.append(UniqueY)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Connect in reverse direction.
|
||||||
|
for p.X > dst.X && p.Y > dst.Y {
|
||||||
|
switch r := f(p.X-1, p.Y-1); {
|
||||||
|
case r.Equal():
|
||||||
|
p.append(Identity)
|
||||||
|
case r.Similar():
|
||||||
|
p.append(Modified)
|
||||||
|
case p.Y-dst.Y >= p.X-dst.X:
|
||||||
|
p.append(UniqueY)
|
||||||
|
default:
|
||||||
|
p.append(UniqueX)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for p.X > dst.X {
|
||||||
|
p.append(UniqueX)
|
||||||
|
}
|
||||||
|
for p.Y > dst.Y {
|
||||||
|
p.append(UniqueY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *path) append(t EditType) {
|
||||||
|
p.es = append(p.es, t)
|
||||||
|
switch t {
|
||||||
|
case Identity, Modified:
|
||||||
|
p.add(p.dir, p.dir)
|
||||||
|
case UniqueX:
|
||||||
|
p.add(p.dir, 0)
|
||||||
|
case UniqueY:
|
||||||
|
p.add(0, p.dir)
|
||||||
|
}
|
||||||
|
debug.Update()
|
||||||
|
}
|
||||||
|
|
||||||
|
type point struct{ X, Y int }
|
||||||
|
|
||||||
|
func (p *point) add(dx, dy int) { p.X += dx; p.Y += dy }
|
||||||
|
|
||||||
|
// zigzag maps a consecutive sequence of integers to a zig-zag sequence.
|
||||||
|
// [0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...]
|
||||||
|
func zigzag(x int) int {
|
||||||
|
if x&1 != 0 {
|
||||||
|
x = ^x
|
||||||
|
}
|
||||||
|
return x >> 1
|
||||||
|
}
|
9
vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go
generated
vendored
Normal file
9
vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2019, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
package flags
|
||||||
|
|
||||||
|
// Deterministic controls whether the output of Diff should be deterministic.
|
||||||
|
// This is only used for testing.
|
||||||
|
var Deterministic bool
|
10
vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go
generated
vendored
Normal file
10
vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Copyright 2019, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
// +build !go1.10
|
||||||
|
|
||||||
|
package flags
|
||||||
|
|
||||||
|
// AtLeastGo110 reports whether the Go toolchain is at least Go 1.10.
|
||||||
|
const AtLeastGo110 = false
|
10
vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go
generated
vendored
Normal file
10
vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Copyright 2019, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
// +build go1.10
|
||||||
|
|
||||||
|
package flags
|
||||||
|
|
||||||
|
// AtLeastGo110 reports whether the Go toolchain is at least Go 1.10.
|
||||||
|
const AtLeastGo110 = true
|
99
vendor/github.com/google/go-cmp/cmp/internal/function/func.go
generated
vendored
Normal file
99
vendor/github.com/google/go-cmp/cmp/internal/function/func.go
generated
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// Copyright 2017, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
// Package function provides functionality for identifying function types.
|
||||||
|
package function
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type funcType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ funcType = iota
|
||||||
|
|
||||||
|
tbFunc // func(T) bool
|
||||||
|
ttbFunc // func(T, T) bool
|
||||||
|
trbFunc // func(T, R) bool
|
||||||
|
tibFunc // func(T, I) bool
|
||||||
|
trFunc // func(T) R
|
||||||
|
|
||||||
|
Equal = ttbFunc // func(T, T) bool
|
||||||
|
EqualAssignable = tibFunc // func(T, I) bool; encapsulates func(T, T) bool
|
||||||
|
Transformer = trFunc // func(T) R
|
||||||
|
ValueFilter = ttbFunc // func(T, T) bool
|
||||||
|
Less = ttbFunc // func(T, T) bool
|
||||||
|
ValuePredicate = tbFunc // func(T) bool
|
||||||
|
KeyValuePredicate = trbFunc // func(T, R) bool
|
||||||
|
)
|
||||||
|
|
||||||
|
var boolType = reflect.TypeOf(true)
|
||||||
|
|
||||||
|
// IsType reports whether the reflect.Type is of the specified function type.
|
||||||
|
func IsType(t reflect.Type, ft funcType) bool {
|
||||||
|
if t == nil || t.Kind() != reflect.Func || t.IsVariadic() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
ni, no := t.NumIn(), t.NumOut()
|
||||||
|
switch ft {
|
||||||
|
case tbFunc: // func(T) bool
|
||||||
|
if ni == 1 && no == 1 && t.Out(0) == boolType {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case ttbFunc: // func(T, T) bool
|
||||||
|
if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case trbFunc: // func(T, R) bool
|
||||||
|
if ni == 2 && no == 1 && t.Out(0) == boolType {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case tibFunc: // func(T, I) bool
|
||||||
|
if ni == 2 && no == 1 && t.In(0).AssignableTo(t.In(1)) && t.Out(0) == boolType {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case trFunc: // func(T) R
|
||||||
|
if ni == 1 && no == 1 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastIdentRx = regexp.MustCompile(`[_\p{L}][_\p{L}\p{N}]*$`)
|
||||||
|
|
||||||
|
// NameOf returns the name of the function value.
|
||||||
|
func NameOf(v reflect.Value) string {
|
||||||
|
fnc := runtime.FuncForPC(v.Pointer())
|
||||||
|
if fnc == nil {
|
||||||
|
return "<unknown>"
|
||||||
|
}
|
||||||
|
fullName := fnc.Name() // e.g., "long/path/name/mypkg.(*MyType).(long/path/name/mypkg.myMethod)-fm"
|
||||||
|
|
||||||
|
// Method closures have a "-fm" suffix.
|
||||||
|
fullName = strings.TrimSuffix(fullName, "-fm")
|
||||||
|
|
||||||
|
var name string
|
||||||
|
for len(fullName) > 0 {
|
||||||
|
inParen := strings.HasSuffix(fullName, ")")
|
||||||
|
fullName = strings.TrimSuffix(fullName, ")")
|
||||||
|
|
||||||
|
s := lastIdentRx.FindString(fullName)
|
||||||
|
if s == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
name = s + "." + name
|
||||||
|
fullName = strings.TrimSuffix(fullName, s)
|
||||||
|
|
||||||
|
if i := strings.LastIndexByte(fullName, '('); inParen && i >= 0 {
|
||||||
|
fullName = fullName[:i]
|
||||||
|
}
|
||||||
|
fullName = strings.TrimSuffix(fullName, ".")
|
||||||
|
}
|
||||||
|
return strings.TrimSuffix(name, ".")
|
||||||
|
}
|
23
vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go
generated
vendored
Normal file
23
vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2018, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
// +build purego
|
||||||
|
|
||||||
|
package value
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
// Pointer is an opaque typed pointer and is guaranteed to be comparable.
|
||||||
|
type Pointer struct {
|
||||||
|
p uintptr
|
||||||
|
t reflect.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointerOf returns a Pointer from v, which must be a
|
||||||
|
// reflect.Ptr, reflect.Slice, or reflect.Map.
|
||||||
|
func PointerOf(v reflect.Value) Pointer {
|
||||||
|
// NOTE: Storing a pointer as an uintptr is technically incorrect as it
|
||||||
|
// assumes that the GC implementation does not use a moving collector.
|
||||||
|
return Pointer{v.Pointer(), v.Type()}
|
||||||
|
}
|
26
vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go
generated
vendored
Normal file
26
vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2018, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
// +build !purego
|
||||||
|
|
||||||
|
package value
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Pointer is an opaque typed pointer and is guaranteed to be comparable.
|
||||||
|
type Pointer struct {
|
||||||
|
p unsafe.Pointer
|
||||||
|
t reflect.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointerOf returns a Pointer from v, which must be a
|
||||||
|
// reflect.Ptr, reflect.Slice, or reflect.Map.
|
||||||
|
func PointerOf(v reflect.Value) Pointer {
|
||||||
|
// The proper representation of a pointer is unsafe.Pointer,
|
||||||
|
// which is necessary if the GC ever uses a moving collector.
|
||||||
|
return Pointer{unsafe.Pointer(v.Pointer()), v.Type()}
|
||||||
|
}
|
106
vendor/github.com/google/go-cmp/cmp/internal/value/sort.go
generated
vendored
Normal file
106
vendor/github.com/google/go-cmp/cmp/internal/value/sort.go
generated
vendored
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
// Copyright 2017, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
package value
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SortKeys sorts a list of map keys, deduplicating keys if necessary.
|
||||||
|
// The type of each value must be comparable.
|
||||||
|
func SortKeys(vs []reflect.Value) []reflect.Value {
|
||||||
|
if len(vs) == 0 {
|
||||||
|
return vs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the map keys.
|
||||||
|
sort.SliceStable(vs, func(i, j int) bool { return isLess(vs[i], vs[j]) })
|
||||||
|
|
||||||
|
// Deduplicate keys (fails for NaNs).
|
||||||
|
vs2 := vs[:1]
|
||||||
|
for _, v := range vs[1:] {
|
||||||
|
if isLess(vs2[len(vs2)-1], v) {
|
||||||
|
vs2 = append(vs2, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vs2
|
||||||
|
}
|
||||||
|
|
||||||
|
// isLess is a generic function for sorting arbitrary map keys.
|
||||||
|
// The inputs must be of the same type and must be comparable.
|
||||||
|
func isLess(x, y reflect.Value) bool {
|
||||||
|
switch x.Type().Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return !x.Bool() && y.Bool()
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return x.Int() < y.Int()
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return x.Uint() < y.Uint()
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
// NOTE: This does not sort -0 as less than +0
|
||||||
|
// since Go maps treat -0 and +0 as equal keys.
|
||||||
|
fx, fy := x.Float(), y.Float()
|
||||||
|
return fx < fy || math.IsNaN(fx) && !math.IsNaN(fy)
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
cx, cy := x.Complex(), y.Complex()
|
||||||
|
rx, ix, ry, iy := real(cx), imag(cx), real(cy), imag(cy)
|
||||||
|
if rx == ry || (math.IsNaN(rx) && math.IsNaN(ry)) {
|
||||||
|
return ix < iy || math.IsNaN(ix) && !math.IsNaN(iy)
|
||||||
|
}
|
||||||
|
return rx < ry || math.IsNaN(rx) && !math.IsNaN(ry)
|
||||||
|
case reflect.Ptr, reflect.UnsafePointer, reflect.Chan:
|
||||||
|
return x.Pointer() < y.Pointer()
|
||||||
|
case reflect.String:
|
||||||
|
return x.String() < y.String()
|
||||||
|
case reflect.Array:
|
||||||
|
for i := 0; i < x.Len(); i++ {
|
||||||
|
if isLess(x.Index(i), y.Index(i)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if isLess(y.Index(i), x.Index(i)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
case reflect.Struct:
|
||||||
|
for i := 0; i < x.NumField(); i++ {
|
||||||
|
if isLess(x.Field(i), y.Field(i)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if isLess(y.Field(i), x.Field(i)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
case reflect.Interface:
|
||||||
|
vx, vy := x.Elem(), y.Elem()
|
||||||
|
if !vx.IsValid() || !vy.IsValid() {
|
||||||
|
return !vx.IsValid() && vy.IsValid()
|
||||||
|
}
|
||||||
|
tx, ty := vx.Type(), vy.Type()
|
||||||
|
if tx == ty {
|
||||||
|
return isLess(x.Elem(), y.Elem())
|
||||||
|
}
|
||||||
|
if tx.Kind() != ty.Kind() {
|
||||||
|
return vx.Kind() < vy.Kind()
|
||||||
|
}
|
||||||
|
if tx.String() != ty.String() {
|
||||||
|
return tx.String() < ty.String()
|
||||||
|
}
|
||||||
|
if tx.PkgPath() != ty.PkgPath() {
|
||||||
|
return tx.PkgPath() < ty.PkgPath()
|
||||||
|
}
|
||||||
|
// This can happen in rare situations, so we fallback to just comparing
|
||||||
|
// the unique pointer for a reflect.Type. This guarantees deterministic
|
||||||
|
// ordering within a program, but it is obviously not stable.
|
||||||
|
return reflect.ValueOf(vx.Type()).Pointer() < reflect.ValueOf(vy.Type()).Pointer()
|
||||||
|
default:
|
||||||
|
// Must be Func, Map, or Slice; which are not comparable.
|
||||||
|
panic(fmt.Sprintf("%T is not comparable", x.Type()))
|
||||||
|
}
|
||||||
|
}
|
48
vendor/github.com/google/go-cmp/cmp/internal/value/zero.go
generated
vendored
Normal file
48
vendor/github.com/google/go-cmp/cmp/internal/value/zero.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright 2017, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
package value
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsZero reports whether v is the zero value.
|
||||||
|
// This does not rely on Interface and so can be used on unexported fields.
|
||||||
|
func IsZero(v reflect.Value) bool {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return v.Bool() == false
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return v.Int() == 0
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return v.Uint() == 0
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return math.Float64bits(v.Float()) == 0
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
return math.Float64bits(real(v.Complex())) == 0 && math.Float64bits(imag(v.Complex())) == 0
|
||||||
|
case reflect.String:
|
||||||
|
return v.String() == ""
|
||||||
|
case reflect.UnsafePointer:
|
||||||
|
return v.Pointer() == 0
|
||||||
|
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
|
||||||
|
return v.IsNil()
|
||||||
|
case reflect.Array:
|
||||||
|
for i := 0; i < v.Len(); i++ {
|
||||||
|
if !IsZero(v.Index(i)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
case reflect.Struct:
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
if !IsZero(v.Field(i)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
524
vendor/github.com/google/go-cmp/cmp/options.go
generated
vendored
Normal file
524
vendor/github.com/google/go-cmp/cmp/options.go
generated
vendored
Normal file
@ -0,0 +1,524 @@
|
|||||||
|
// Copyright 2017, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
package cmp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp/internal/function"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Option configures for specific behavior of Equal and Diff. In particular,
|
||||||
|
// the fundamental Option functions (Ignore, Transformer, and Comparer),
|
||||||
|
// configure how equality is determined.
|
||||||
|
//
|
||||||
|
// The fundamental options may be composed with filters (FilterPath and
|
||||||
|
// FilterValues) to control the scope over which they are applied.
|
||||||
|
//
|
||||||
|
// The cmp/cmpopts package provides helper functions for creating options that
|
||||||
|
// may be used with Equal and Diff.
|
||||||
|
type Option interface {
|
||||||
|
// filter applies all filters and returns the option that remains.
|
||||||
|
// Each option may only read s.curPath and call s.callTTBFunc.
|
||||||
|
//
|
||||||
|
// An Options is returned only if multiple comparers or transformers
|
||||||
|
// can apply simultaneously and will only contain values of those types
|
||||||
|
// or sub-Options containing values of those types.
|
||||||
|
filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption
|
||||||
|
}
|
||||||
|
|
||||||
|
// applicableOption represents the following types:
|
||||||
|
// Fundamental: ignore | validator | *comparer | *transformer
|
||||||
|
// Grouping: Options
|
||||||
|
type applicableOption interface {
|
||||||
|
Option
|
||||||
|
|
||||||
|
// apply executes the option, which may mutate s or panic.
|
||||||
|
apply(s *state, vx, vy reflect.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// coreOption represents the following types:
|
||||||
|
// Fundamental: ignore | validator | *comparer | *transformer
|
||||||
|
// Filters: *pathFilter | *valuesFilter
|
||||||
|
type coreOption interface {
|
||||||
|
Option
|
||||||
|
isCore()
|
||||||
|
}
|
||||||
|
|
||||||
|
type core struct{}
|
||||||
|
|
||||||
|
func (core) isCore() {}
|
||||||
|
|
||||||
|
// Options is a list of Option values that also satisfies the Option interface.
|
||||||
|
// Helper comparison packages may return an Options value when packing multiple
|
||||||
|
// Option values into a single Option. When this package processes an Options,
|
||||||
|
// it will be implicitly expanded into a flat list.
|
||||||
|
//
|
||||||
|
// Applying a filter on an Options is equivalent to applying that same filter
|
||||||
|
// on all individual options held within.
|
||||||
|
type Options []Option
|
||||||
|
|
||||||
|
func (opts Options) filter(s *state, t reflect.Type, vx, vy reflect.Value) (out applicableOption) {
|
||||||
|
for _, opt := range opts {
|
||||||
|
switch opt := opt.filter(s, t, vx, vy); opt.(type) {
|
||||||
|
case ignore:
|
||||||
|
return ignore{} // Only ignore can short-circuit evaluation
|
||||||
|
case validator:
|
||||||
|
out = validator{} // Takes precedence over comparer or transformer
|
||||||
|
case *comparer, *transformer, Options:
|
||||||
|
switch out.(type) {
|
||||||
|
case nil:
|
||||||
|
out = opt
|
||||||
|
case validator:
|
||||||
|
// Keep validator
|
||||||
|
case *comparer, *transformer, Options:
|
||||||
|
out = Options{out, opt} // Conflicting comparers or transformers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts Options) apply(s *state, _, _ reflect.Value) {
|
||||||
|
const warning = "ambiguous set of applicable options"
|
||||||
|
const help = "consider using filters to ensure at most one Comparer or Transformer may apply"
|
||||||
|
var ss []string
|
||||||
|
for _, opt := range flattenOptions(nil, opts) {
|
||||||
|
ss = append(ss, fmt.Sprint(opt))
|
||||||
|
}
|
||||||
|
set := strings.Join(ss, "\n\t")
|
||||||
|
panic(fmt.Sprintf("%s at %#v:\n\t%s\n%s", warning, s.curPath, set, help))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts Options) String() string {
|
||||||
|
var ss []string
|
||||||
|
for _, opt := range opts {
|
||||||
|
ss = append(ss, fmt.Sprint(opt))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Options{%s}", strings.Join(ss, ", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterPath returns a new Option where opt is only evaluated if filter f
|
||||||
|
// returns true for the current Path in the value tree.
|
||||||
|
//
|
||||||
|
// This filter is called even if a slice element or map entry is missing and
|
||||||
|
// provides an opportunity to ignore such cases. The filter function must be
|
||||||
|
// symmetric such that the filter result is identical regardless of whether the
|
||||||
|
// missing value is from x or y.
|
||||||
|
//
|
||||||
|
// The option passed in may be an Ignore, Transformer, Comparer, Options, or
|
||||||
|
// a previously filtered Option.
|
||||||
|
func FilterPath(f func(Path) bool, opt Option) Option {
|
||||||
|
if f == nil {
|
||||||
|
panic("invalid path filter function")
|
||||||
|
}
|
||||||
|
if opt := normalizeOption(opt); opt != nil {
|
||||||
|
return &pathFilter{fnc: f, opt: opt}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type pathFilter struct {
|
||||||
|
core
|
||||||
|
fnc func(Path) bool
|
||||||
|
opt Option
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f pathFilter) filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption {
|
||||||
|
if f.fnc(s.curPath) {
|
||||||
|
return f.opt.filter(s, t, vx, vy)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f pathFilter) String() string {
|
||||||
|
return fmt.Sprintf("FilterPath(%s, %v)", function.NameOf(reflect.ValueOf(f.fnc)), f.opt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterValues returns a new Option where opt is only evaluated if filter f,
|
||||||
|
// which is a function of the form "func(T, T) bool", returns true for the
|
||||||
|
// current pair of values being compared. If either value is invalid or
|
||||||
|
// the type of the values is not assignable to T, then this filter implicitly
|
||||||
|
// returns false.
|
||||||
|
//
|
||||||
|
// The filter function must be
|
||||||
|
// symmetric (i.e., agnostic to the order of the inputs) and
|
||||||
|
// deterministic (i.e., produces the same result when given the same inputs).
|
||||||
|
// If T is an interface, it is possible that f is called with two values with
|
||||||
|
// different concrete types that both implement T.
|
||||||
|
//
|
||||||
|
// The option passed in may be an Ignore, Transformer, Comparer, Options, or
|
||||||
|
// a previously filtered Option.
|
||||||
|
func FilterValues(f interface{}, opt Option) Option {
|
||||||
|
v := reflect.ValueOf(f)
|
||||||
|
if !function.IsType(v.Type(), function.ValueFilter) || v.IsNil() {
|
||||||
|
panic(fmt.Sprintf("invalid values filter function: %T", f))
|
||||||
|
}
|
||||||
|
if opt := normalizeOption(opt); opt != nil {
|
||||||
|
vf := &valuesFilter{fnc: v, opt: opt}
|
||||||
|
if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {
|
||||||
|
vf.typ = ti
|
||||||
|
}
|
||||||
|
return vf
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type valuesFilter struct {
|
||||||
|
core
|
||||||
|
typ reflect.Type // T
|
||||||
|
fnc reflect.Value // func(T, T) bool
|
||||||
|
opt Option
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f valuesFilter) filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption {
|
||||||
|
if !vx.IsValid() || !vx.CanInterface() || !vy.IsValid() || !vy.CanInterface() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if (f.typ == nil || t.AssignableTo(f.typ)) && s.callTTBFunc(f.fnc, vx, vy) {
|
||||||
|
return f.opt.filter(s, t, vx, vy)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f valuesFilter) String() string {
|
||||||
|
return fmt.Sprintf("FilterValues(%s, %v)", function.NameOf(f.fnc), f.opt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore is an Option that causes all comparisons to be ignored.
|
||||||
|
// This value is intended to be combined with FilterPath or FilterValues.
|
||||||
|
// It is an error to pass an unfiltered Ignore option to Equal.
|
||||||
|
func Ignore() Option { return ignore{} }
|
||||||
|
|
||||||
|
type ignore struct{ core }
|
||||||
|
|
||||||
|
func (ignore) isFiltered() bool { return false }
|
||||||
|
func (ignore) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption { return ignore{} }
|
||||||
|
func (ignore) apply(s *state, _, _ reflect.Value) { s.report(true, reportByIgnore) }
|
||||||
|
func (ignore) String() string { return "Ignore()" }
|
||||||
|
|
||||||
|
// validator is a sentinel Option type to indicate that some options could not
|
||||||
|
// be evaluated due to unexported fields, missing slice elements, or
|
||||||
|
// missing map entries. Both values are validator only for unexported fields.
|
||||||
|
type validator struct{ core }
|
||||||
|
|
||||||
|
func (validator) filter(_ *state, _ reflect.Type, vx, vy reflect.Value) applicableOption {
|
||||||
|
if !vx.IsValid() || !vy.IsValid() {
|
||||||
|
return validator{}
|
||||||
|
}
|
||||||
|
if !vx.CanInterface() || !vy.CanInterface() {
|
||||||
|
return validator{}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (validator) apply(s *state, vx, vy reflect.Value) {
|
||||||
|
// Implies missing slice element or map entry.
|
||||||
|
if !vx.IsValid() || !vy.IsValid() {
|
||||||
|
s.report(vx.IsValid() == vy.IsValid(), 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unable to Interface implies unexported field without visibility access.
|
||||||
|
if !vx.CanInterface() || !vy.CanInterface() {
|
||||||
|
const help = "consider using a custom Comparer; if you control the implementation of type, you can also consider AllowUnexported or cmpopts.IgnoreUnexported"
|
||||||
|
panic(fmt.Sprintf("cannot handle unexported field: %#v\n%s", s.curPath, help))
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("not reachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// identRx represents a valid identifier according to the Go specification.
|
||||||
|
const identRx = `[_\p{L}][_\p{L}\p{N}]*`
|
||||||
|
|
||||||
|
var identsRx = regexp.MustCompile(`^` + identRx + `(\.` + identRx + `)*$`)
|
||||||
|
|
||||||
|
// Transformer returns an Option that applies a transformation function that
|
||||||
|
// converts values of a certain type into that of another.
|
||||||
|
//
|
||||||
|
// The transformer f must be a function "func(T) R" that converts values of
|
||||||
|
// type T to those of type R and is implicitly filtered to input values
|
||||||
|
// assignable to T. The transformer must not mutate T in any way.
|
||||||
|
//
|
||||||
|
// To help prevent some cases of infinite recursive cycles applying the
|
||||||
|
// same transform to the output of itself (e.g., in the case where the
|
||||||
|
// input and output types are the same), an implicit filter is added such that
|
||||||
|
// a transformer is applicable only if that exact transformer is not already
|
||||||
|
// in the tail of the Path since the last non-Transform step.
|
||||||
|
// For situations where the implicit filter is still insufficient,
|
||||||
|
// consider using cmpopts.AcyclicTransformer, which adds a filter
|
||||||
|
// to prevent the transformer from being recursively applied upon itself.
|
||||||
|
//
|
||||||
|
// The name is a user provided label that is used as the Transform.Name in the
|
||||||
|
// transformation PathStep (and eventually shown in the Diff output).
|
||||||
|
// The name must be a valid identifier or qualified identifier in Go syntax.
|
||||||
|
// If empty, an arbitrary name is used.
|
||||||
|
func Transformer(name string, f interface{}) Option {
|
||||||
|
v := reflect.ValueOf(f)
|
||||||
|
if !function.IsType(v.Type(), function.Transformer) || v.IsNil() {
|
||||||
|
panic(fmt.Sprintf("invalid transformer function: %T", f))
|
||||||
|
}
|
||||||
|
if name == "" {
|
||||||
|
name = function.NameOf(v)
|
||||||
|
if !identsRx.MatchString(name) {
|
||||||
|
name = "λ" // Lambda-symbol as placeholder name
|
||||||
|
}
|
||||||
|
} else if !identsRx.MatchString(name) {
|
||||||
|
panic(fmt.Sprintf("invalid name: %q", name))
|
||||||
|
}
|
||||||
|
tr := &transformer{name: name, fnc: reflect.ValueOf(f)}
|
||||||
|
if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {
|
||||||
|
tr.typ = ti
|
||||||
|
}
|
||||||
|
return tr
|
||||||
|
}
|
||||||
|
|
||||||
|
type transformer struct {
|
||||||
|
core
|
||||||
|
name string
|
||||||
|
typ reflect.Type // T
|
||||||
|
fnc reflect.Value // func(T) R
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr *transformer) isFiltered() bool { return tr.typ != nil }
|
||||||
|
|
||||||
|
func (tr *transformer) filter(s *state, t reflect.Type, _, _ reflect.Value) applicableOption {
|
||||||
|
for i := len(s.curPath) - 1; i >= 0; i-- {
|
||||||
|
if t, ok := s.curPath[i].(Transform); !ok {
|
||||||
|
break // Hit most recent non-Transform step
|
||||||
|
} else if tr == t.trans {
|
||||||
|
return nil // Cannot directly use same Transform
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tr.typ == nil || t.AssignableTo(tr.typ) {
|
||||||
|
return tr
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr *transformer) apply(s *state, vx, vy reflect.Value) {
|
||||||
|
step := Transform{&transform{pathStep{typ: tr.fnc.Type().Out(0)}, tr}}
|
||||||
|
vvx := s.callTRFunc(tr.fnc, vx, step)
|
||||||
|
vvy := s.callTRFunc(tr.fnc, vy, step)
|
||||||
|
step.vx, step.vy = vvx, vvy
|
||||||
|
s.compareAny(step)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr transformer) String() string {
|
||||||
|
return fmt.Sprintf("Transformer(%s, %s)", tr.name, function.NameOf(tr.fnc))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comparer returns an Option that determines whether two values are equal
|
||||||
|
// to each other.
|
||||||
|
//
|
||||||
|
// The comparer f must be a function "func(T, T) bool" and is implicitly
|
||||||
|
// filtered to input values assignable to T. If T is an interface, it is
|
||||||
|
// possible that f is called with two values of different concrete types that
|
||||||
|
// both implement T.
|
||||||
|
//
|
||||||
|
// The equality function must be:
|
||||||
|
// • Symmetric: equal(x, y) == equal(y, x)
|
||||||
|
// • Deterministic: equal(x, y) == equal(x, y)
|
||||||
|
// • Pure: equal(x, y) does not modify x or y
|
||||||
|
func Comparer(f interface{}) Option {
|
||||||
|
v := reflect.ValueOf(f)
|
||||||
|
if !function.IsType(v.Type(), function.Equal) || v.IsNil() {
|
||||||
|
panic(fmt.Sprintf("invalid comparer function: %T", f))
|
||||||
|
}
|
||||||
|
cm := &comparer{fnc: v}
|
||||||
|
if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {
|
||||||
|
cm.typ = ti
|
||||||
|
}
|
||||||
|
return cm
|
||||||
|
}
|
||||||
|
|
||||||
|
type comparer struct {
|
||||||
|
core
|
||||||
|
typ reflect.Type // T
|
||||||
|
fnc reflect.Value // func(T, T) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *comparer) isFiltered() bool { return cm.typ != nil }
|
||||||
|
|
||||||
|
func (cm *comparer) filter(_ *state, t reflect.Type, _, _ reflect.Value) applicableOption {
|
||||||
|
if cm.typ == nil || t.AssignableTo(cm.typ) {
|
||||||
|
return cm
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *comparer) apply(s *state, vx, vy reflect.Value) {
|
||||||
|
eq := s.callTTBFunc(cm.fnc, vx, vy)
|
||||||
|
s.report(eq, reportByFunc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm comparer) String() string {
|
||||||
|
return fmt.Sprintf("Comparer(%s)", function.NameOf(cm.fnc))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowUnexported returns an Option that forcibly allows operations on
|
||||||
|
// unexported fields in certain structs, which are specified by passing in a
|
||||||
|
// value of each struct type.
|
||||||
|
//
|
||||||
|
// Users of this option must understand that comparing on unexported fields
|
||||||
|
// from external packages is not safe since changes in the internal
|
||||||
|
// implementation of some external package may cause the result of Equal
|
||||||
|
// to unexpectedly change. However, it may be valid to use this option on types
|
||||||
|
// defined in an internal package where the semantic meaning of an unexported
|
||||||
|
// field is in the control of the user.
|
||||||
|
//
|
||||||
|
// In many cases, a custom Comparer should be used instead that defines
|
||||||
|
// equality as a function of the public API of a type rather than the underlying
|
||||||
|
// unexported implementation.
|
||||||
|
//
|
||||||
|
// For example, the reflect.Type documentation defines equality to be determined
|
||||||
|
// by the == operator on the interface (essentially performing a shallow pointer
|
||||||
|
// comparison) and most attempts to compare *regexp.Regexp types are interested
|
||||||
|
// in only checking that the regular expression strings are equal.
|
||||||
|
// Both of these are accomplished using Comparers:
|
||||||
|
//
|
||||||
|
// Comparer(func(x, y reflect.Type) bool { return x == y })
|
||||||
|
// Comparer(func(x, y *regexp.Regexp) bool { return x.String() == y.String() })
|
||||||
|
//
|
||||||
|
// In other cases, the cmpopts.IgnoreUnexported option can be used to ignore
|
||||||
|
// all unexported fields on specified struct types.
|
||||||
|
func AllowUnexported(types ...interface{}) Option {
|
||||||
|
if !supportAllowUnexported {
|
||||||
|
panic("AllowUnexported is not supported on purego builds, Google App Engine Standard, or GopherJS")
|
||||||
|
}
|
||||||
|
m := make(map[reflect.Type]bool)
|
||||||
|
for _, typ := range types {
|
||||||
|
t := reflect.TypeOf(typ)
|
||||||
|
if t.Kind() != reflect.Struct {
|
||||||
|
panic(fmt.Sprintf("invalid struct type: %T", typ))
|
||||||
|
}
|
||||||
|
m[t] = true
|
||||||
|
}
|
||||||
|
return visibleStructs(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
type visibleStructs map[reflect.Type]bool
|
||||||
|
|
||||||
|
func (visibleStructs) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result represents the comparison result for a single node and
|
||||||
|
// is provided by cmp when calling Result (see Reporter).
|
||||||
|
type Result struct {
|
||||||
|
_ [0]func() // Make Result incomparable
|
||||||
|
flags resultFlags
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal reports whether the node was determined to be equal or not.
|
||||||
|
// As a special case, ignored nodes are considered equal.
|
||||||
|
func (r Result) Equal() bool {
|
||||||
|
return r.flags&(reportEqual|reportByIgnore) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByIgnore reports whether the node is equal because it was ignored.
|
||||||
|
// This never reports true if Equal reports false.
|
||||||
|
func (r Result) ByIgnore() bool {
|
||||||
|
return r.flags&reportByIgnore != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByMethod reports whether the Equal method determined equality.
|
||||||
|
func (r Result) ByMethod() bool {
|
||||||
|
return r.flags&reportByMethod != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByFunc reports whether a Comparer function determined equality.
|
||||||
|
func (r Result) ByFunc() bool {
|
||||||
|
return r.flags&reportByFunc != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type resultFlags uint
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ resultFlags = (1 << iota) / 2
|
||||||
|
|
||||||
|
reportEqual
|
||||||
|
reportUnequal
|
||||||
|
reportByIgnore
|
||||||
|
reportByMethod
|
||||||
|
reportByFunc
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reporter is an Option that can be passed to Equal. When Equal traverses
|
||||||
|
// the value trees, it calls PushStep as it descends into each node in the
|
||||||
|
// tree and PopStep as it ascend out of the node. The leaves of the tree are
|
||||||
|
// either compared (determined to be equal or not equal) or ignored and reported
|
||||||
|
// as such by calling the Report method.
|
||||||
|
func Reporter(r interface {
|
||||||
|
// PushStep is called when a tree-traversal operation is performed.
|
||||||
|
// The PathStep itself is only valid until the step is popped.
|
||||||
|
// The PathStep.Values are valid for the duration of the entire traversal
|
||||||
|
// and must not be mutated.
|
||||||
|
//
|
||||||
|
// Equal always calls PushStep at the start to provide an operation-less
|
||||||
|
// PathStep used to report the root values.
|
||||||
|
//
|
||||||
|
// Within a slice, the exact set of inserted, removed, or modified elements
|
||||||
|
// is unspecified and may change in future implementations.
|
||||||
|
// The entries of a map are iterated through in an unspecified order.
|
||||||
|
PushStep(PathStep)
|
||||||
|
|
||||||
|
// Report is called exactly once on leaf nodes to report whether the
|
||||||
|
// comparison identified the node as equal, unequal, or ignored.
|
||||||
|
// A leaf node is one that is immediately preceded by and followed by
|
||||||
|
// a pair of PushStep and PopStep calls.
|
||||||
|
Report(Result)
|
||||||
|
|
||||||
|
// PopStep ascends back up the value tree.
|
||||||
|
// There is always a matching pop call for every push call.
|
||||||
|
PopStep()
|
||||||
|
}) Option {
|
||||||
|
return reporter{r}
|
||||||
|
}
|
||||||
|
|
||||||
|
type reporter struct{ reporterIface }
|
||||||
|
type reporterIface interface {
|
||||||
|
PushStep(PathStep)
|
||||||
|
Report(Result)
|
||||||
|
PopStep()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (reporter) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalizeOption normalizes the input options such that all Options groups
|
||||||
|
// are flattened and groups with a single element are reduced to that element.
|
||||||
|
// Only coreOptions and Options containing coreOptions are allowed.
|
||||||
|
func normalizeOption(src Option) Option {
|
||||||
|
switch opts := flattenOptions(nil, Options{src}); len(opts) {
|
||||||
|
case 0:
|
||||||
|
return nil
|
||||||
|
case 1:
|
||||||
|
return opts[0]
|
||||||
|
default:
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// flattenOptions copies all options in src to dst as a flat list.
|
||||||
|
// Only coreOptions and Options containing coreOptions are allowed.
|
||||||
|
func flattenOptions(dst, src Options) Options {
|
||||||
|
for _, opt := range src {
|
||||||
|
switch opt := opt.(type) {
|
||||||
|
case nil:
|
||||||
|
continue
|
||||||
|
case Options:
|
||||||
|
dst = flattenOptions(dst, opt)
|
||||||
|
case coreOption:
|
||||||
|
dst = append(dst, opt)
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("invalid option type: %T", opt))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst
|
||||||
|
}
|
308
vendor/github.com/google/go-cmp/cmp/path.go
generated
vendored
Normal file
308
vendor/github.com/google/go-cmp/cmp/path.go
generated
vendored
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
// Copyright 2017, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
package cmp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Path is a list of PathSteps describing the sequence of operations to get
|
||||||
|
// from some root type to the current position in the value tree.
|
||||||
|
// The first Path element is always an operation-less PathStep that exists
|
||||||
|
// simply to identify the initial type.
|
||||||
|
//
|
||||||
|
// When traversing structs with embedded structs, the embedded struct will
|
||||||
|
// always be accessed as a field before traversing the fields of the
|
||||||
|
// embedded struct themselves. That is, an exported field from the
|
||||||
|
// embedded struct will never be accessed directly from the parent struct.
|
||||||
|
type Path []PathStep
|
||||||
|
|
||||||
|
// PathStep is a union-type for specific operations to traverse
|
||||||
|
// a value's tree structure. Users of this package never need to implement
|
||||||
|
// these types as values of this type will be returned by this package.
|
||||||
|
//
|
||||||
|
// Implementations of this interface are
|
||||||
|
// StructField, SliceIndex, MapIndex, Indirect, TypeAssertion, and Transform.
|
||||||
|
type PathStep interface {
|
||||||
|
String() string
|
||||||
|
|
||||||
|
// Type is the resulting type after performing the path step.
|
||||||
|
Type() reflect.Type
|
||||||
|
|
||||||
|
// Values is the resulting values after performing the path step.
|
||||||
|
// The type of each valid value is guaranteed to be identical to Type.
|
||||||
|
//
|
||||||
|
// In some cases, one or both may be invalid or have restrictions:
|
||||||
|
// • For StructField, both are not interface-able if the current field
|
||||||
|
// is unexported and the struct type is not explicitly permitted by
|
||||||
|
// AllowUnexported to traverse unexported fields.
|
||||||
|
// • For SliceIndex, one may be invalid if an element is missing from
|
||||||
|
// either the x or y slice.
|
||||||
|
// • For MapIndex, one may be invalid if an entry is missing from
|
||||||
|
// either the x or y map.
|
||||||
|
//
|
||||||
|
// The provided values must not be mutated.
|
||||||
|
Values() (vx, vy reflect.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ PathStep = StructField{}
|
||||||
|
_ PathStep = SliceIndex{}
|
||||||
|
_ PathStep = MapIndex{}
|
||||||
|
_ PathStep = Indirect{}
|
||||||
|
_ PathStep = TypeAssertion{}
|
||||||
|
_ PathStep = Transform{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (pa *Path) push(s PathStep) {
|
||||||
|
*pa = append(*pa, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pa *Path) pop() {
|
||||||
|
*pa = (*pa)[:len(*pa)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last returns the last PathStep in the Path.
|
||||||
|
// If the path is empty, this returns a non-nil PathStep that reports a nil Type.
|
||||||
|
func (pa Path) Last() PathStep {
|
||||||
|
return pa.Index(-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index returns the ith step in the Path and supports negative indexing.
|
||||||
|
// A negative index starts counting from the tail of the Path such that -1
|
||||||
|
// refers to the last step, -2 refers to the second-to-last step, and so on.
|
||||||
|
// If index is invalid, this returns a non-nil PathStep that reports a nil Type.
|
||||||
|
func (pa Path) Index(i int) PathStep {
|
||||||
|
if i < 0 {
|
||||||
|
i = len(pa) + i
|
||||||
|
}
|
||||||
|
if i < 0 || i >= len(pa) {
|
||||||
|
return pathStep{}
|
||||||
|
}
|
||||||
|
return pa[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the simplified path to a node.
|
||||||
|
// The simplified path only contains struct field accesses.
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
// MyMap.MySlices.MyField
|
||||||
|
func (pa Path) String() string {
|
||||||
|
var ss []string
|
||||||
|
for _, s := range pa {
|
||||||
|
if _, ok := s.(StructField); ok {
|
||||||
|
ss = append(ss, s.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.TrimPrefix(strings.Join(ss, ""), ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GoString returns the path to a specific node using Go syntax.
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
// (*root.MyMap["key"].(*mypkg.MyStruct).MySlices)[2][3].MyField
|
||||||
|
func (pa Path) GoString() string {
|
||||||
|
var ssPre, ssPost []string
|
||||||
|
var numIndirect int
|
||||||
|
for i, s := range pa {
|
||||||
|
var nextStep PathStep
|
||||||
|
if i+1 < len(pa) {
|
||||||
|
nextStep = pa[i+1]
|
||||||
|
}
|
||||||
|
switch s := s.(type) {
|
||||||
|
case Indirect:
|
||||||
|
numIndirect++
|
||||||
|
pPre, pPost := "(", ")"
|
||||||
|
switch nextStep.(type) {
|
||||||
|
case Indirect:
|
||||||
|
continue // Next step is indirection, so let them batch up
|
||||||
|
case StructField:
|
||||||
|
numIndirect-- // Automatic indirection on struct fields
|
||||||
|
case nil:
|
||||||
|
pPre, pPost = "", "" // Last step; no need for parenthesis
|
||||||
|
}
|
||||||
|
if numIndirect > 0 {
|
||||||
|
ssPre = append(ssPre, pPre+strings.Repeat("*", numIndirect))
|
||||||
|
ssPost = append(ssPost, pPost)
|
||||||
|
}
|
||||||
|
numIndirect = 0
|
||||||
|
continue
|
||||||
|
case Transform:
|
||||||
|
ssPre = append(ssPre, s.trans.name+"(")
|
||||||
|
ssPost = append(ssPost, ")")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ssPost = append(ssPost, s.String())
|
||||||
|
}
|
||||||
|
for i, j := 0, len(ssPre)-1; i < j; i, j = i+1, j-1 {
|
||||||
|
ssPre[i], ssPre[j] = ssPre[j], ssPre[i]
|
||||||
|
}
|
||||||
|
return strings.Join(ssPre, "") + strings.Join(ssPost, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
type pathStep struct {
|
||||||
|
typ reflect.Type
|
||||||
|
vx, vy reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps pathStep) Type() reflect.Type { return ps.typ }
|
||||||
|
func (ps pathStep) Values() (vx, vy reflect.Value) { return ps.vx, ps.vy }
|
||||||
|
func (ps pathStep) String() string {
|
||||||
|
if ps.typ == nil {
|
||||||
|
return "<nil>"
|
||||||
|
}
|
||||||
|
s := ps.typ.String()
|
||||||
|
if s == "" || strings.ContainsAny(s, "{}\n") {
|
||||||
|
return "root" // Type too simple or complex to print
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("{%s}", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StructField represents a struct field access on a field called Name.
|
||||||
|
type StructField struct{ *structField }
|
||||||
|
type structField struct {
|
||||||
|
pathStep
|
||||||
|
name string
|
||||||
|
idx int
|
||||||
|
|
||||||
|
// These fields are used for forcibly accessing an unexported field.
|
||||||
|
// pvx, pvy, and field are only valid if unexported is true.
|
||||||
|
unexported bool
|
||||||
|
mayForce bool // Forcibly allow visibility
|
||||||
|
pvx, pvy reflect.Value // Parent values
|
||||||
|
field reflect.StructField // Field information
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sf StructField) Type() reflect.Type { return sf.typ }
|
||||||
|
func (sf StructField) Values() (vx, vy reflect.Value) {
|
||||||
|
if !sf.unexported {
|
||||||
|
return sf.vx, sf.vy // CanInterface reports true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forcibly obtain read-write access to an unexported struct field.
|
||||||
|
if sf.mayForce {
|
||||||
|
vx = retrieveUnexportedField(sf.pvx, sf.field)
|
||||||
|
vy = retrieveUnexportedField(sf.pvy, sf.field)
|
||||||
|
return vx, vy // CanInterface reports true
|
||||||
|
}
|
||||||
|
return sf.vx, sf.vy // CanInterface reports false
|
||||||
|
}
|
||||||
|
func (sf StructField) String() string { return fmt.Sprintf(".%s", sf.name) }
|
||||||
|
|
||||||
|
// Name is the field name.
|
||||||
|
func (sf StructField) Name() string { return sf.name }
|
||||||
|
|
||||||
|
// Index is the index of the field in the parent struct type.
|
||||||
|
// See reflect.Type.Field.
|
||||||
|
func (sf StructField) Index() int { return sf.idx }
|
||||||
|
|
||||||
|
// SliceIndex is an index operation on a slice or array at some index Key.
|
||||||
|
type SliceIndex struct{ *sliceIndex }
|
||||||
|
type sliceIndex struct {
|
||||||
|
pathStep
|
||||||
|
xkey, ykey int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (si SliceIndex) Type() reflect.Type { return si.typ }
|
||||||
|
func (si SliceIndex) Values() (vx, vy reflect.Value) { return si.vx, si.vy }
|
||||||
|
func (si SliceIndex) String() string {
|
||||||
|
switch {
|
||||||
|
case si.xkey == si.ykey:
|
||||||
|
return fmt.Sprintf("[%d]", si.xkey)
|
||||||
|
case si.ykey == -1:
|
||||||
|
// [5->?] means "I don't know where X[5] went"
|
||||||
|
return fmt.Sprintf("[%d->?]", si.xkey)
|
||||||
|
case si.xkey == -1:
|
||||||
|
// [?->3] means "I don't know where Y[3] came from"
|
||||||
|
return fmt.Sprintf("[?->%d]", si.ykey)
|
||||||
|
default:
|
||||||
|
// [5->3] means "X[5] moved to Y[3]"
|
||||||
|
return fmt.Sprintf("[%d->%d]", si.xkey, si.ykey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Key is the index key; it may return -1 if in a split state
|
||||||
|
func (si SliceIndex) Key() int {
|
||||||
|
if si.xkey != si.ykey {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return si.xkey
|
||||||
|
}
|
||||||
|
|
||||||
|
// SplitKeys are the indexes for indexing into slices in the
|
||||||
|
// x and y values, respectively. These indexes may differ due to the
|
||||||
|
// insertion or removal of an element in one of the slices, causing
|
||||||
|
// all of the indexes to be shifted. If an index is -1, then that
|
||||||
|
// indicates that the element does not exist in the associated slice.
|
||||||
|
//
|
||||||
|
// Key is guaranteed to return -1 if and only if the indexes returned
|
||||||
|
// by SplitKeys are not the same. SplitKeys will never return -1 for
|
||||||
|
// both indexes.
|
||||||
|
func (si SliceIndex) SplitKeys() (ix, iy int) { return si.xkey, si.ykey }
|
||||||
|
|
||||||
|
// MapIndex is an index operation on a map at some index Key.
|
||||||
|
type MapIndex struct{ *mapIndex }
|
||||||
|
type mapIndex struct {
|
||||||
|
pathStep
|
||||||
|
key reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mi MapIndex) Type() reflect.Type { return mi.typ }
|
||||||
|
func (mi MapIndex) Values() (vx, vy reflect.Value) { return mi.vx, mi.vy }
|
||||||
|
func (mi MapIndex) String() string { return fmt.Sprintf("[%#v]", mi.key) }
|
||||||
|
|
||||||
|
// Key is the value of the map key.
|
||||||
|
func (mi MapIndex) Key() reflect.Value { return mi.key }
|
||||||
|
|
||||||
|
// Indirect represents pointer indirection on the parent type.
|
||||||
|
type Indirect struct{ *indirect }
|
||||||
|
type indirect struct {
|
||||||
|
pathStep
|
||||||
|
}
|
||||||
|
|
||||||
|
func (in Indirect) Type() reflect.Type { return in.typ }
|
||||||
|
func (in Indirect) Values() (vx, vy reflect.Value) { return in.vx, in.vy }
|
||||||
|
func (in Indirect) String() string { return "*" }
|
||||||
|
|
||||||
|
// TypeAssertion represents a type assertion on an interface.
|
||||||
|
type TypeAssertion struct{ *typeAssertion }
|
||||||
|
type typeAssertion struct {
|
||||||
|
pathStep
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ta TypeAssertion) Type() reflect.Type { return ta.typ }
|
||||||
|
func (ta TypeAssertion) Values() (vx, vy reflect.Value) { return ta.vx, ta.vy }
|
||||||
|
func (ta TypeAssertion) String() string { return fmt.Sprintf(".(%v)", ta.typ) }
|
||||||
|
|
||||||
|
// Transform is a transformation from the parent type to the current type.
|
||||||
|
type Transform struct{ *transform }
|
||||||
|
type transform struct {
|
||||||
|
pathStep
|
||||||
|
trans *transformer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tf Transform) Type() reflect.Type { return tf.typ }
|
||||||
|
func (tf Transform) Values() (vx, vy reflect.Value) { return tf.vx, tf.vy }
|
||||||
|
func (tf Transform) String() string { return fmt.Sprintf("%s()", tf.trans.name) }
|
||||||
|
|
||||||
|
// Name is the name of the Transformer.
|
||||||
|
func (tf Transform) Name() string { return tf.trans.name }
|
||||||
|
|
||||||
|
// Func is the function pointer to the transformer function.
|
||||||
|
func (tf Transform) Func() reflect.Value { return tf.trans.fnc }
|
||||||
|
|
||||||
|
// Option returns the originally constructed Transformer option.
|
||||||
|
// The == operator can be used to detect the exact option used.
|
||||||
|
func (tf Transform) Option() Option { return tf.trans }
|
||||||
|
|
||||||
|
// isExported reports whether the identifier is exported.
|
||||||
|
func isExported(id string) bool {
|
||||||
|
r, _ := utf8.DecodeRuneInString(id)
|
||||||
|
return unicode.IsUpper(r)
|
||||||
|
}
|
51
vendor/github.com/google/go-cmp/cmp/report.go
generated
vendored
Normal file
51
vendor/github.com/google/go-cmp/cmp/report.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Copyright 2017, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
package cmp
|
||||||
|
|
||||||
|
// defaultReporter implements the reporter interface.
|
||||||
|
//
|
||||||
|
// As Equal serially calls the PushStep, Report, and PopStep methods, the
|
||||||
|
// defaultReporter constructs a tree-based representation of the compared value
|
||||||
|
// and the result of each comparison (see valueNode).
|
||||||
|
//
|
||||||
|
// When the String method is called, the FormatDiff method transforms the
|
||||||
|
// valueNode tree into a textNode tree, which is a tree-based representation
|
||||||
|
// of the textual output (see textNode).
|
||||||
|
//
|
||||||
|
// Lastly, the textNode.String method produces the final report as a string.
|
||||||
|
type defaultReporter struct {
|
||||||
|
root *valueNode
|
||||||
|
curr *valueNode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *defaultReporter) PushStep(ps PathStep) {
|
||||||
|
r.curr = r.curr.PushStep(ps)
|
||||||
|
if r.root == nil {
|
||||||
|
r.root = r.curr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (r *defaultReporter) Report(rs Result) {
|
||||||
|
r.curr.Report(rs)
|
||||||
|
}
|
||||||
|
func (r *defaultReporter) PopStep() {
|
||||||
|
r.curr = r.curr.PopStep()
|
||||||
|
}
|
||||||
|
|
||||||
|
// String provides a full report of the differences detected as a structured
|
||||||
|
// literal in pseudo-Go syntax. String may only be called after the entire tree
|
||||||
|
// has been traversed.
|
||||||
|
func (r *defaultReporter) String() string {
|
||||||
|
assert(r.root != nil && r.curr == nil)
|
||||||
|
if r.root.NumDiff == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return formatOptions{}.FormatDiff(r.root).String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func assert(ok bool) {
|
||||||
|
if !ok {
|
||||||
|
panic("assertion failure")
|
||||||
|
}
|
||||||
|
}
|
296
vendor/github.com/google/go-cmp/cmp/report_compare.go
generated
vendored
Normal file
296
vendor/github.com/google/go-cmp/cmp/report_compare.go
generated
vendored
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
// Copyright 2019, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
package cmp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp/internal/value"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: Enforce limits?
|
||||||
|
// * Enforce maximum number of records to print per node?
|
||||||
|
// * Enforce maximum size in bytes allowed?
|
||||||
|
// * As a heuristic, use less verbosity for equal nodes than unequal nodes.
|
||||||
|
// TODO: Enforce unique outputs?
|
||||||
|
// * Avoid Stringer methods if it results in same output?
|
||||||
|
// * Print pointer address if outputs still equal?
|
||||||
|
|
||||||
|
// numContextRecords is the number of surrounding equal records to print.
|
||||||
|
const numContextRecords = 2
|
||||||
|
|
||||||
|
type diffMode byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
diffUnknown diffMode = 0
|
||||||
|
diffIdentical diffMode = ' '
|
||||||
|
diffRemoved diffMode = '-'
|
||||||
|
diffInserted diffMode = '+'
|
||||||
|
)
|
||||||
|
|
||||||
|
type typeMode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// emitType always prints the type.
|
||||||
|
emitType typeMode = iota
|
||||||
|
// elideType never prints the type.
|
||||||
|
elideType
|
||||||
|
// autoType prints the type only for composite kinds
|
||||||
|
// (i.e., structs, slices, arrays, and maps).
|
||||||
|
autoType
|
||||||
|
)
|
||||||
|
|
||||||
|
type formatOptions struct {
|
||||||
|
// DiffMode controls the output mode of FormatDiff.
|
||||||
|
//
|
||||||
|
// If diffUnknown, then produce a diff of the x and y values.
|
||||||
|
// If diffIdentical, then emit values as if they were equal.
|
||||||
|
// If diffRemoved, then only emit x values (ignoring y values).
|
||||||
|
// If diffInserted, then only emit y values (ignoring x values).
|
||||||
|
DiffMode diffMode
|
||||||
|
|
||||||
|
// TypeMode controls whether to print the type for the current node.
|
||||||
|
//
|
||||||
|
// As a general rule of thumb, we always print the type of the next node
|
||||||
|
// after an interface, and always elide the type of the next node after
|
||||||
|
// a slice or map node.
|
||||||
|
TypeMode typeMode
|
||||||
|
|
||||||
|
// formatValueOptions are options specific to printing reflect.Values.
|
||||||
|
formatValueOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts formatOptions) WithDiffMode(d diffMode) formatOptions {
|
||||||
|
opts.DiffMode = d
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
func (opts formatOptions) WithTypeMode(t typeMode) formatOptions {
|
||||||
|
opts.TypeMode = t
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatDiff converts a valueNode tree into a textNode tree, where the later
|
||||||
|
// is a textual representation of the differences detected in the former.
|
||||||
|
func (opts formatOptions) FormatDiff(v *valueNode) textNode {
|
||||||
|
// Check whether we have specialized formatting for this node.
|
||||||
|
// This is not necessary, but helpful for producing more readable outputs.
|
||||||
|
if opts.CanFormatDiffSlice(v) {
|
||||||
|
return opts.FormatDiffSlice(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// For leaf nodes, format the value based on the reflect.Values alone.
|
||||||
|
if v.MaxDepth == 0 {
|
||||||
|
switch opts.DiffMode {
|
||||||
|
case diffUnknown, diffIdentical:
|
||||||
|
// Format Equal.
|
||||||
|
if v.NumDiff == 0 {
|
||||||
|
outx := opts.FormatValue(v.ValueX, visitedPointers{})
|
||||||
|
outy := opts.FormatValue(v.ValueY, visitedPointers{})
|
||||||
|
if v.NumIgnored > 0 && v.NumSame == 0 {
|
||||||
|
return textEllipsis
|
||||||
|
} else if outx.Len() < outy.Len() {
|
||||||
|
return outx
|
||||||
|
} else {
|
||||||
|
return outy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format unequal.
|
||||||
|
assert(opts.DiffMode == diffUnknown)
|
||||||
|
var list textList
|
||||||
|
outx := opts.WithTypeMode(elideType).FormatValue(v.ValueX, visitedPointers{})
|
||||||
|
outy := opts.WithTypeMode(elideType).FormatValue(v.ValueY, visitedPointers{})
|
||||||
|
if outx != nil {
|
||||||
|
list = append(list, textRecord{Diff: '-', Value: outx})
|
||||||
|
}
|
||||||
|
if outy != nil {
|
||||||
|
list = append(list, textRecord{Diff: '+', Value: outy})
|
||||||
|
}
|
||||||
|
return opts.WithTypeMode(emitType).FormatType(v.Type, list)
|
||||||
|
case diffRemoved:
|
||||||
|
return opts.FormatValue(v.ValueX, visitedPointers{})
|
||||||
|
case diffInserted:
|
||||||
|
return opts.FormatValue(v.ValueY, visitedPointers{})
|
||||||
|
default:
|
||||||
|
panic("invalid diff mode")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Descend into the child value node.
|
||||||
|
if v.TransformerName != "" {
|
||||||
|
out := opts.WithTypeMode(emitType).FormatDiff(v.Value)
|
||||||
|
out = textWrap{"Inverse(" + v.TransformerName + ", ", out, ")"}
|
||||||
|
return opts.FormatType(v.Type, out)
|
||||||
|
} else {
|
||||||
|
switch k := v.Type.Kind(); k {
|
||||||
|
case reflect.Struct, reflect.Array, reflect.Slice, reflect.Map:
|
||||||
|
return opts.FormatType(v.Type, opts.formatDiffList(v.Records, k))
|
||||||
|
case reflect.Ptr:
|
||||||
|
return textWrap{"&", opts.FormatDiff(v.Value), ""}
|
||||||
|
case reflect.Interface:
|
||||||
|
return opts.WithTypeMode(emitType).FormatDiff(v.Value)
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("%v cannot have children", k))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts formatOptions) formatDiffList(recs []reportRecord, k reflect.Kind) textNode {
|
||||||
|
// Derive record name based on the data structure kind.
|
||||||
|
var name string
|
||||||
|
var formatKey func(reflect.Value) string
|
||||||
|
switch k {
|
||||||
|
case reflect.Struct:
|
||||||
|
name = "field"
|
||||||
|
opts = opts.WithTypeMode(autoType)
|
||||||
|
formatKey = func(v reflect.Value) string { return v.String() }
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
name = "element"
|
||||||
|
opts = opts.WithTypeMode(elideType)
|
||||||
|
formatKey = func(reflect.Value) string { return "" }
|
||||||
|
case reflect.Map:
|
||||||
|
name = "entry"
|
||||||
|
opts = opts.WithTypeMode(elideType)
|
||||||
|
formatKey = formatMapKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle unification.
|
||||||
|
switch opts.DiffMode {
|
||||||
|
case diffIdentical, diffRemoved, diffInserted:
|
||||||
|
var list textList
|
||||||
|
var deferredEllipsis bool // Add final "..." to indicate records were dropped
|
||||||
|
for _, r := range recs {
|
||||||
|
// Elide struct fields that are zero value.
|
||||||
|
if k == reflect.Struct {
|
||||||
|
var isZero bool
|
||||||
|
switch opts.DiffMode {
|
||||||
|
case diffIdentical:
|
||||||
|
isZero = value.IsZero(r.Value.ValueX) || value.IsZero(r.Value.ValueY)
|
||||||
|
case diffRemoved:
|
||||||
|
isZero = value.IsZero(r.Value.ValueX)
|
||||||
|
case diffInserted:
|
||||||
|
isZero = value.IsZero(r.Value.ValueY)
|
||||||
|
}
|
||||||
|
if isZero {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Elide ignored nodes.
|
||||||
|
if r.Value.NumIgnored > 0 && r.Value.NumSame+r.Value.NumDiff == 0 {
|
||||||
|
deferredEllipsis = !(k == reflect.Slice || k == reflect.Array)
|
||||||
|
if !deferredEllipsis {
|
||||||
|
list.AppendEllipsis(diffStats{})
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if out := opts.FormatDiff(r.Value); out != nil {
|
||||||
|
list = append(list, textRecord{Key: formatKey(r.Key), Value: out})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if deferredEllipsis {
|
||||||
|
list.AppendEllipsis(diffStats{})
|
||||||
|
}
|
||||||
|
return textWrap{"{", list, "}"}
|
||||||
|
case diffUnknown:
|
||||||
|
default:
|
||||||
|
panic("invalid diff mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle differencing.
|
||||||
|
var list textList
|
||||||
|
groups := coalesceAdjacentRecords(name, recs)
|
||||||
|
for i, ds := range groups {
|
||||||
|
// Handle equal records.
|
||||||
|
if ds.NumDiff() == 0 {
|
||||||
|
// Compute the number of leading and trailing records to print.
|
||||||
|
var numLo, numHi int
|
||||||
|
numEqual := ds.NumIgnored + ds.NumIdentical
|
||||||
|
for numLo < numContextRecords && numLo+numHi < numEqual && i != 0 {
|
||||||
|
if r := recs[numLo].Value; r.NumIgnored > 0 && r.NumSame+r.NumDiff == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
numLo++
|
||||||
|
}
|
||||||
|
for numHi < numContextRecords && numLo+numHi < numEqual && i != len(groups)-1 {
|
||||||
|
if r := recs[numEqual-numHi-1].Value; r.NumIgnored > 0 && r.NumSame+r.NumDiff == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
numHi++
|
||||||
|
}
|
||||||
|
if numEqual-(numLo+numHi) == 1 && ds.NumIgnored == 0 {
|
||||||
|
numHi++ // Avoid pointless coalescing of a single equal record
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format the equal values.
|
||||||
|
for _, r := range recs[:numLo] {
|
||||||
|
out := opts.WithDiffMode(diffIdentical).FormatDiff(r.Value)
|
||||||
|
list = append(list, textRecord{Key: formatKey(r.Key), Value: out})
|
||||||
|
}
|
||||||
|
if numEqual > numLo+numHi {
|
||||||
|
ds.NumIdentical -= numLo + numHi
|
||||||
|
list.AppendEllipsis(ds)
|
||||||
|
}
|
||||||
|
for _, r := range recs[numEqual-numHi : numEqual] {
|
||||||
|
out := opts.WithDiffMode(diffIdentical).FormatDiff(r.Value)
|
||||||
|
list = append(list, textRecord{Key: formatKey(r.Key), Value: out})
|
||||||
|
}
|
||||||
|
recs = recs[numEqual:]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle unequal records.
|
||||||
|
for _, r := range recs[:ds.NumDiff()] {
|
||||||
|
switch {
|
||||||
|
case opts.CanFormatDiffSlice(r.Value):
|
||||||
|
out := opts.FormatDiffSlice(r.Value)
|
||||||
|
list = append(list, textRecord{Key: formatKey(r.Key), Value: out})
|
||||||
|
case r.Value.NumChildren == r.Value.MaxDepth:
|
||||||
|
outx := opts.WithDiffMode(diffRemoved).FormatDiff(r.Value)
|
||||||
|
outy := opts.WithDiffMode(diffInserted).FormatDiff(r.Value)
|
||||||
|
if outx != nil {
|
||||||
|
list = append(list, textRecord{Diff: diffRemoved, Key: formatKey(r.Key), Value: outx})
|
||||||
|
}
|
||||||
|
if outy != nil {
|
||||||
|
list = append(list, textRecord{Diff: diffInserted, Key: formatKey(r.Key), Value: outy})
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
out := opts.FormatDiff(r.Value)
|
||||||
|
list = append(list, textRecord{Key: formatKey(r.Key), Value: out})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recs = recs[ds.NumDiff():]
|
||||||
|
}
|
||||||
|
assert(len(recs) == 0)
|
||||||
|
return textWrap{"{", list, "}"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// coalesceAdjacentRecords coalesces the list of records into groups of
|
||||||
|
// adjacent equal, or unequal counts.
|
||||||
|
func coalesceAdjacentRecords(name string, recs []reportRecord) (groups []diffStats) {
|
||||||
|
var prevCase int // Arbitrary index into which case last occurred
|
||||||
|
lastStats := func(i int) *diffStats {
|
||||||
|
if prevCase != i {
|
||||||
|
groups = append(groups, diffStats{Name: name})
|
||||||
|
prevCase = i
|
||||||
|
}
|
||||||
|
return &groups[len(groups)-1]
|
||||||
|
}
|
||||||
|
for _, r := range recs {
|
||||||
|
switch rv := r.Value; {
|
||||||
|
case rv.NumIgnored > 0 && rv.NumSame+rv.NumDiff == 0:
|
||||||
|
lastStats(1).NumIgnored++
|
||||||
|
case rv.NumDiff == 0:
|
||||||
|
lastStats(1).NumIdentical++
|
||||||
|
case rv.NumDiff > 0 && !rv.ValueY.IsValid():
|
||||||
|
lastStats(2).NumRemoved++
|
||||||
|
case rv.NumDiff > 0 && !rv.ValueX.IsValid():
|
||||||
|
lastStats(2).NumInserted++
|
||||||
|
default:
|
||||||
|
lastStats(2).NumModified++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return groups
|
||||||
|
}
|
278
vendor/github.com/google/go-cmp/cmp/report_reflect.go
generated
vendored
Normal file
278
vendor/github.com/google/go-cmp/cmp/report_reflect.go
generated
vendored
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
// Copyright 2019, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
package cmp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp/internal/flags"
|
||||||
|
"github.com/google/go-cmp/cmp/internal/value"
|
||||||
|
)
|
||||||
|
|
||||||
|
type formatValueOptions struct {
|
||||||
|
// AvoidStringer controls whether to avoid calling custom stringer
|
||||||
|
// methods like error.Error or fmt.Stringer.String.
|
||||||
|
AvoidStringer bool
|
||||||
|
|
||||||
|
// ShallowPointers controls whether to avoid descending into pointers.
|
||||||
|
// Useful when printing map keys, where pointer comparison is performed
|
||||||
|
// on the pointer address rather than the pointed-at value.
|
||||||
|
ShallowPointers bool
|
||||||
|
|
||||||
|
// PrintAddresses controls whether to print the address of all pointers,
|
||||||
|
// slice elements, and maps.
|
||||||
|
PrintAddresses bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatType prints the type as if it were wrapping s.
|
||||||
|
// This may return s as-is depending on the current type and TypeMode mode.
|
||||||
|
func (opts formatOptions) FormatType(t reflect.Type, s textNode) textNode {
|
||||||
|
// Check whether to emit the type or not.
|
||||||
|
switch opts.TypeMode {
|
||||||
|
case autoType:
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Struct, reflect.Slice, reflect.Array, reflect.Map:
|
||||||
|
if s.Equal(textNil) {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
case elideType:
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the type label, applying special handling for unnamed types.
|
||||||
|
typeName := t.String()
|
||||||
|
if t.Name() == "" {
|
||||||
|
// According to Go grammar, certain type literals contain symbols that
|
||||||
|
// do not strongly bind to the next lexicographical token (e.g., *T).
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Chan, reflect.Func, reflect.Ptr:
|
||||||
|
typeName = "(" + typeName + ")"
|
||||||
|
}
|
||||||
|
typeName = strings.Replace(typeName, "struct {", "struct{", -1)
|
||||||
|
typeName = strings.Replace(typeName, "interface {", "interface{", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid wrap the value in parenthesis if unnecessary.
|
||||||
|
if s, ok := s.(textWrap); ok {
|
||||||
|
hasParens := strings.HasPrefix(s.Prefix, "(") && strings.HasSuffix(s.Suffix, ")")
|
||||||
|
hasBraces := strings.HasPrefix(s.Prefix, "{") && strings.HasSuffix(s.Suffix, "}")
|
||||||
|
if hasParens || hasBraces {
|
||||||
|
return textWrap{typeName, s, ""}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return textWrap{typeName + "(", s, ")"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatValue prints the reflect.Value, taking extra care to avoid descending
|
||||||
|
// into pointers already in m. As pointers are visited, m is also updated.
|
||||||
|
func (opts formatOptions) FormatValue(v reflect.Value, m visitedPointers) (out textNode) {
|
||||||
|
if !v.IsValid() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
t := v.Type()
|
||||||
|
|
||||||
|
// Check whether there is an Error or String method to call.
|
||||||
|
if !opts.AvoidStringer && v.CanInterface() {
|
||||||
|
// Avoid calling Error or String methods on nil receivers since many
|
||||||
|
// implementations crash when doing so.
|
||||||
|
if (t.Kind() != reflect.Ptr && t.Kind() != reflect.Interface) || !v.IsNil() {
|
||||||
|
switch v := v.Interface().(type) {
|
||||||
|
case error:
|
||||||
|
return textLine("e" + formatString(v.Error()))
|
||||||
|
case fmt.Stringer:
|
||||||
|
return textLine("s" + formatString(v.String()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether to explicitly wrap the result with the type.
|
||||||
|
var skipType bool
|
||||||
|
defer func() {
|
||||||
|
if !skipType {
|
||||||
|
out = opts.FormatType(t, out)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
var ptr string
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return textLine(fmt.Sprint(v.Bool()))
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return textLine(fmt.Sprint(v.Int()))
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
// Unnamed uints are usually bytes or words, so use hexadecimal.
|
||||||
|
if t.PkgPath() == "" || t.Kind() == reflect.Uintptr {
|
||||||
|
return textLine(formatHex(v.Uint()))
|
||||||
|
}
|
||||||
|
return textLine(fmt.Sprint(v.Uint()))
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return textLine(fmt.Sprint(v.Float()))
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
return textLine(fmt.Sprint(v.Complex()))
|
||||||
|
case reflect.String:
|
||||||
|
return textLine(formatString(v.String()))
|
||||||
|
case reflect.UnsafePointer, reflect.Chan, reflect.Func:
|
||||||
|
return textLine(formatPointer(v))
|
||||||
|
case reflect.Struct:
|
||||||
|
var list textList
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
vv := v.Field(i)
|
||||||
|
if value.IsZero(vv) {
|
||||||
|
continue // Elide fields with zero values
|
||||||
|
}
|
||||||
|
s := opts.WithTypeMode(autoType).FormatValue(vv, m)
|
||||||
|
list = append(list, textRecord{Key: t.Field(i).Name, Value: s})
|
||||||
|
}
|
||||||
|
return textWrap{"{", list, "}"}
|
||||||
|
case reflect.Slice:
|
||||||
|
if v.IsNil() {
|
||||||
|
return textNil
|
||||||
|
}
|
||||||
|
if opts.PrintAddresses {
|
||||||
|
ptr = formatPointer(v)
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case reflect.Array:
|
||||||
|
var list textList
|
||||||
|
for i := 0; i < v.Len(); i++ {
|
||||||
|
vi := v.Index(i)
|
||||||
|
if vi.CanAddr() { // Check for cyclic elements
|
||||||
|
p := vi.Addr()
|
||||||
|
if m.Visit(p) {
|
||||||
|
var out textNode
|
||||||
|
out = textLine(formatPointer(p))
|
||||||
|
out = opts.WithTypeMode(emitType).FormatType(p.Type(), out)
|
||||||
|
out = textWrap{"*", out, ""}
|
||||||
|
list = append(list, textRecord{Value: out})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s := opts.WithTypeMode(elideType).FormatValue(vi, m)
|
||||||
|
list = append(list, textRecord{Value: s})
|
||||||
|
}
|
||||||
|
return textWrap{ptr + "{", list, "}"}
|
||||||
|
case reflect.Map:
|
||||||
|
if v.IsNil() {
|
||||||
|
return textNil
|
||||||
|
}
|
||||||
|
if m.Visit(v) {
|
||||||
|
return textLine(formatPointer(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
var list textList
|
||||||
|
for _, k := range value.SortKeys(v.MapKeys()) {
|
||||||
|
sk := formatMapKey(k)
|
||||||
|
sv := opts.WithTypeMode(elideType).FormatValue(v.MapIndex(k), m)
|
||||||
|
list = append(list, textRecord{Key: sk, Value: sv})
|
||||||
|
}
|
||||||
|
if opts.PrintAddresses {
|
||||||
|
ptr = formatPointer(v)
|
||||||
|
}
|
||||||
|
return textWrap{ptr + "{", list, "}"}
|
||||||
|
case reflect.Ptr:
|
||||||
|
if v.IsNil() {
|
||||||
|
return textNil
|
||||||
|
}
|
||||||
|
if m.Visit(v) || opts.ShallowPointers {
|
||||||
|
return textLine(formatPointer(v))
|
||||||
|
}
|
||||||
|
if opts.PrintAddresses {
|
||||||
|
ptr = formatPointer(v)
|
||||||
|
}
|
||||||
|
skipType = true // Let the underlying value print the type instead
|
||||||
|
return textWrap{"&" + ptr, opts.FormatValue(v.Elem(), m), ""}
|
||||||
|
case reflect.Interface:
|
||||||
|
if v.IsNil() {
|
||||||
|
return textNil
|
||||||
|
}
|
||||||
|
// Interfaces accept different concrete types,
|
||||||
|
// so configure the underlying value to explicitly print the type.
|
||||||
|
skipType = true // Print the concrete type instead
|
||||||
|
return opts.WithTypeMode(emitType).FormatValue(v.Elem(), m)
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("%v kind not handled", v.Kind()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatMapKey formats v as if it were a map key.
|
||||||
|
// The result is guaranteed to be a single line.
|
||||||
|
func formatMapKey(v reflect.Value) string {
|
||||||
|
var opts formatOptions
|
||||||
|
opts.TypeMode = elideType
|
||||||
|
opts.ShallowPointers = true
|
||||||
|
s := opts.FormatValue(v, visitedPointers{}).String()
|
||||||
|
return strings.TrimSpace(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatString prints s as a double-quoted or backtick-quoted string.
|
||||||
|
func formatString(s string) string {
|
||||||
|
// Use quoted string if it the same length as a raw string literal.
|
||||||
|
// Otherwise, attempt to use the raw string form.
|
||||||
|
qs := strconv.Quote(s)
|
||||||
|
if len(qs) == 1+len(s)+1 {
|
||||||
|
return qs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disallow newlines to ensure output is a single line.
|
||||||
|
// Only allow printable runes for readability purposes.
|
||||||
|
rawInvalid := func(r rune) bool {
|
||||||
|
return r == '`' || r == '\n' || !(unicode.IsPrint(r) || r == '\t')
|
||||||
|
}
|
||||||
|
if strings.IndexFunc(s, rawInvalid) < 0 {
|
||||||
|
return "`" + s + "`"
|
||||||
|
}
|
||||||
|
return qs
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatHex prints u as a hexadecimal integer in Go notation.
|
||||||
|
func formatHex(u uint64) string {
|
||||||
|
var f string
|
||||||
|
switch {
|
||||||
|
case u <= 0xff:
|
||||||
|
f = "0x%02x"
|
||||||
|
case u <= 0xffff:
|
||||||
|
f = "0x%04x"
|
||||||
|
case u <= 0xffffff:
|
||||||
|
f = "0x%06x"
|
||||||
|
case u <= 0xffffffff:
|
||||||
|
f = "0x%08x"
|
||||||
|
case u <= 0xffffffffff:
|
||||||
|
f = "0x%010x"
|
||||||
|
case u <= 0xffffffffffff:
|
||||||
|
f = "0x%012x"
|
||||||
|
case u <= 0xffffffffffffff:
|
||||||
|
f = "0x%014x"
|
||||||
|
case u <= 0xffffffffffffffff:
|
||||||
|
f = "0x%016x"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(f, u)
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatPointer prints the address of the pointer.
|
||||||
|
func formatPointer(v reflect.Value) string {
|
||||||
|
p := v.Pointer()
|
||||||
|
if flags.Deterministic {
|
||||||
|
p = 0xdeadf00f // Only used for stable testing purposes
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("⟪0x%x⟫", p)
|
||||||
|
}
|
||||||
|
|
||||||
|
type visitedPointers map[value.Pointer]struct{}
|
||||||
|
|
||||||
|
// Visit inserts pointer v into the visited map and reports whether it had
|
||||||
|
// already been visited before.
|
||||||
|
func (m visitedPointers) Visit(v reflect.Value) bool {
|
||||||
|
p := value.PointerOf(v)
|
||||||
|
_, visited := m[p]
|
||||||
|
m[p] = struct{}{}
|
||||||
|
return visited
|
||||||
|
}
|
333
vendor/github.com/google/go-cmp/cmp/report_slices.go
generated
vendored
Normal file
333
vendor/github.com/google/go-cmp/cmp/report_slices.go
generated
vendored
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
// Copyright 2019, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
package cmp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp/internal/diff"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CanFormatDiffSlice reports whether we support custom formatting for nodes
|
||||||
|
// that are slices of primitive kinds or strings.
|
||||||
|
func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool {
|
||||||
|
switch {
|
||||||
|
case opts.DiffMode != diffUnknown:
|
||||||
|
return false // Must be formatting in diff mode
|
||||||
|
case v.NumDiff == 0:
|
||||||
|
return false // No differences detected
|
||||||
|
case v.NumIgnored+v.NumCompared+v.NumTransformed > 0:
|
||||||
|
// TODO: Handle the case where someone uses bytes.Equal on a large slice.
|
||||||
|
return false // Some custom option was used to determined equality
|
||||||
|
case !v.ValueX.IsValid() || !v.ValueY.IsValid():
|
||||||
|
return false // Both values must be valid
|
||||||
|
}
|
||||||
|
|
||||||
|
switch t := v.Type; t.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
case reflect.Array, reflect.Slice:
|
||||||
|
// Only slices of primitive types have specialized handling.
|
||||||
|
switch t.Elem().Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||||
|
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
|
||||||
|
reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a sufficient number of elements already differ,
|
||||||
|
// use specialized formatting even if length requirement is not met.
|
||||||
|
if v.NumDiff > v.NumSame {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use specialized string diffing for longer slices or strings.
|
||||||
|
const minLength = 64
|
||||||
|
return v.ValueX.Len() >= minLength && v.ValueY.Len() >= minLength
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatDiffSlice prints a diff for the slices (or strings) represented by v.
|
||||||
|
// This provides custom-tailored logic to make printing of differences in
|
||||||
|
// textual strings and slices of primitive kinds more readable.
|
||||||
|
func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
|
||||||
|
assert(opts.DiffMode == diffUnknown)
|
||||||
|
t, vx, vy := v.Type, v.ValueX, v.ValueY
|
||||||
|
|
||||||
|
// Auto-detect the type of the data.
|
||||||
|
var isLinedText, isText, isBinary bool
|
||||||
|
var sx, sy string
|
||||||
|
switch {
|
||||||
|
case t.Kind() == reflect.String:
|
||||||
|
sx, sy = vx.String(), vy.String()
|
||||||
|
isText = true // Initial estimate, verify later
|
||||||
|
case t.Kind() == reflect.Slice && t.Elem() == reflect.TypeOf(byte(0)):
|
||||||
|
sx, sy = string(vx.Bytes()), string(vy.Bytes())
|
||||||
|
isBinary = true // Initial estimate, verify later
|
||||||
|
case t.Kind() == reflect.Array:
|
||||||
|
// Arrays need to be addressable for slice operations to work.
|
||||||
|
vx2, vy2 := reflect.New(t).Elem(), reflect.New(t).Elem()
|
||||||
|
vx2.Set(vx)
|
||||||
|
vy2.Set(vy)
|
||||||
|
vx, vy = vx2, vy2
|
||||||
|
}
|
||||||
|
if isText || isBinary {
|
||||||
|
var numLines, lastLineIdx, maxLineLen int
|
||||||
|
isBinary = false
|
||||||
|
for i, r := range sx + sy {
|
||||||
|
if !(unicode.IsPrint(r) || unicode.IsSpace(r)) || r == utf8.RuneError {
|
||||||
|
isBinary = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if r == '\n' {
|
||||||
|
if maxLineLen < i-lastLineIdx {
|
||||||
|
maxLineLen = i - lastLineIdx
|
||||||
|
}
|
||||||
|
lastLineIdx = i + 1
|
||||||
|
numLines++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isText = !isBinary
|
||||||
|
isLinedText = isText && numLines >= 4 && maxLineLen <= 256
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format the string into printable records.
|
||||||
|
var list textList
|
||||||
|
var delim string
|
||||||
|
switch {
|
||||||
|
// If the text appears to be multi-lined text,
|
||||||
|
// then perform differencing across individual lines.
|
||||||
|
case isLinedText:
|
||||||
|
ssx := strings.Split(sx, "\n")
|
||||||
|
ssy := strings.Split(sy, "\n")
|
||||||
|
list = opts.formatDiffSlice(
|
||||||
|
reflect.ValueOf(ssx), reflect.ValueOf(ssy), 1, "line",
|
||||||
|
func(v reflect.Value, d diffMode) textRecord {
|
||||||
|
s := formatString(v.Index(0).String())
|
||||||
|
return textRecord{Diff: d, Value: textLine(s)}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
delim = "\n"
|
||||||
|
// If the text appears to be single-lined text,
|
||||||
|
// then perform differencing in approximately fixed-sized chunks.
|
||||||
|
// The output is printed as quoted strings.
|
||||||
|
case isText:
|
||||||
|
list = opts.formatDiffSlice(
|
||||||
|
reflect.ValueOf(sx), reflect.ValueOf(sy), 64, "byte",
|
||||||
|
func(v reflect.Value, d diffMode) textRecord {
|
||||||
|
s := formatString(v.String())
|
||||||
|
return textRecord{Diff: d, Value: textLine(s)}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
delim = ""
|
||||||
|
// If the text appears to be binary data,
|
||||||
|
// then perform differencing in approximately fixed-sized chunks.
|
||||||
|
// The output is inspired by hexdump.
|
||||||
|
case isBinary:
|
||||||
|
list = opts.formatDiffSlice(
|
||||||
|
reflect.ValueOf(sx), reflect.ValueOf(sy), 16, "byte",
|
||||||
|
func(v reflect.Value, d diffMode) textRecord {
|
||||||
|
var ss []string
|
||||||
|
for i := 0; i < v.Len(); i++ {
|
||||||
|
ss = append(ss, formatHex(v.Index(i).Uint()))
|
||||||
|
}
|
||||||
|
s := strings.Join(ss, ", ")
|
||||||
|
comment := commentString(fmt.Sprintf("%c|%v|", d, formatASCII(v.String())))
|
||||||
|
return textRecord{Diff: d, Value: textLine(s), Comment: comment}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
// For all other slices of primitive types,
|
||||||
|
// then perform differencing in approximately fixed-sized chunks.
|
||||||
|
// The size of each chunk depends on the width of the element kind.
|
||||||
|
default:
|
||||||
|
var chunkSize int
|
||||||
|
if t.Elem().Kind() == reflect.Bool {
|
||||||
|
chunkSize = 16
|
||||||
|
} else {
|
||||||
|
switch t.Elem().Bits() {
|
||||||
|
case 8:
|
||||||
|
chunkSize = 16
|
||||||
|
case 16:
|
||||||
|
chunkSize = 12
|
||||||
|
case 32:
|
||||||
|
chunkSize = 8
|
||||||
|
default:
|
||||||
|
chunkSize = 8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = opts.formatDiffSlice(
|
||||||
|
vx, vy, chunkSize, t.Elem().Kind().String(),
|
||||||
|
func(v reflect.Value, d diffMode) textRecord {
|
||||||
|
var ss []string
|
||||||
|
for i := 0; i < v.Len(); i++ {
|
||||||
|
switch t.Elem().Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
ss = append(ss, fmt.Sprint(v.Index(i).Int()))
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
ss = append(ss, formatHex(v.Index(i).Uint()))
|
||||||
|
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
|
||||||
|
ss = append(ss, fmt.Sprint(v.Index(i).Interface()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s := strings.Join(ss, ", ")
|
||||||
|
return textRecord{Diff: d, Value: textLine(s)}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap the output with appropriate type information.
|
||||||
|
var out textNode = textWrap{"{", list, "}"}
|
||||||
|
if !isText {
|
||||||
|
// The "{...}" byte-sequence literal is not valid Go syntax for strings.
|
||||||
|
// Emit the type for extra clarity (e.g. "string{...}").
|
||||||
|
if t.Kind() == reflect.String {
|
||||||
|
opts = opts.WithTypeMode(emitType)
|
||||||
|
}
|
||||||
|
return opts.FormatType(t, out)
|
||||||
|
}
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
out = textWrap{"strings.Join(", out, fmt.Sprintf(", %q)", delim)}
|
||||||
|
if t != reflect.TypeOf(string("")) {
|
||||||
|
out = opts.FormatType(t, out)
|
||||||
|
}
|
||||||
|
case reflect.Slice:
|
||||||
|
out = textWrap{"bytes.Join(", out, fmt.Sprintf(", %q)", delim)}
|
||||||
|
if t != reflect.TypeOf([]byte(nil)) {
|
||||||
|
out = opts.FormatType(t, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatASCII formats s as an ASCII string.
|
||||||
|
// This is useful for printing binary strings in a semi-legible way.
|
||||||
|
func formatASCII(s string) string {
|
||||||
|
b := bytes.Repeat([]byte{'.'}, len(s))
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
if ' ' <= s[i] && s[i] <= '~' {
|
||||||
|
b[i] = s[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts formatOptions) formatDiffSlice(
|
||||||
|
vx, vy reflect.Value, chunkSize int, name string,
|
||||||
|
makeRec func(reflect.Value, diffMode) textRecord,
|
||||||
|
) (list textList) {
|
||||||
|
es := diff.Difference(vx.Len(), vy.Len(), func(ix int, iy int) diff.Result {
|
||||||
|
return diff.BoolResult(vx.Index(ix).Interface() == vy.Index(iy).Interface())
|
||||||
|
})
|
||||||
|
|
||||||
|
appendChunks := func(v reflect.Value, d diffMode) int {
|
||||||
|
n0 := v.Len()
|
||||||
|
for v.Len() > 0 {
|
||||||
|
n := chunkSize
|
||||||
|
if n > v.Len() {
|
||||||
|
n = v.Len()
|
||||||
|
}
|
||||||
|
list = append(list, makeRec(v.Slice(0, n), d))
|
||||||
|
v = v.Slice(n, v.Len())
|
||||||
|
}
|
||||||
|
return n0 - v.Len()
|
||||||
|
}
|
||||||
|
|
||||||
|
groups := coalesceAdjacentEdits(name, es)
|
||||||
|
groups = coalesceInterveningIdentical(groups, chunkSize/4)
|
||||||
|
for i, ds := range groups {
|
||||||
|
// Print equal.
|
||||||
|
if ds.NumDiff() == 0 {
|
||||||
|
// Compute the number of leading and trailing equal bytes to print.
|
||||||
|
var numLo, numHi int
|
||||||
|
numEqual := ds.NumIgnored + ds.NumIdentical
|
||||||
|
for numLo < chunkSize*numContextRecords && numLo+numHi < numEqual && i != 0 {
|
||||||
|
numLo++
|
||||||
|
}
|
||||||
|
for numHi < chunkSize*numContextRecords && numLo+numHi < numEqual && i != len(groups)-1 {
|
||||||
|
numHi++
|
||||||
|
}
|
||||||
|
if numEqual-(numLo+numHi) <= chunkSize && ds.NumIgnored == 0 {
|
||||||
|
numHi = numEqual - numLo // Avoid pointless coalescing of single equal row
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the equal bytes.
|
||||||
|
appendChunks(vx.Slice(0, numLo), diffIdentical)
|
||||||
|
if numEqual > numLo+numHi {
|
||||||
|
ds.NumIdentical -= numLo + numHi
|
||||||
|
list.AppendEllipsis(ds)
|
||||||
|
}
|
||||||
|
appendChunks(vx.Slice(numEqual-numHi, numEqual), diffIdentical)
|
||||||
|
vx = vx.Slice(numEqual, vx.Len())
|
||||||
|
vy = vy.Slice(numEqual, vy.Len())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print unequal.
|
||||||
|
nx := appendChunks(vx.Slice(0, ds.NumIdentical+ds.NumRemoved+ds.NumModified), diffRemoved)
|
||||||
|
vx = vx.Slice(nx, vx.Len())
|
||||||
|
ny := appendChunks(vy.Slice(0, ds.NumIdentical+ds.NumInserted+ds.NumModified), diffInserted)
|
||||||
|
vy = vy.Slice(ny, vy.Len())
|
||||||
|
}
|
||||||
|
assert(vx.Len() == 0 && vy.Len() == 0)
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
// coalesceAdjacentEdits coalesces the list of edits into groups of adjacent
|
||||||
|
// equal or unequal counts.
|
||||||
|
func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) {
|
||||||
|
var prevCase int // Arbitrary index into which case last occurred
|
||||||
|
lastStats := func(i int) *diffStats {
|
||||||
|
if prevCase != i {
|
||||||
|
groups = append(groups, diffStats{Name: name})
|
||||||
|
prevCase = i
|
||||||
|
}
|
||||||
|
return &groups[len(groups)-1]
|
||||||
|
}
|
||||||
|
for _, e := range es {
|
||||||
|
switch e {
|
||||||
|
case diff.Identity:
|
||||||
|
lastStats(1).NumIdentical++
|
||||||
|
case diff.UniqueX:
|
||||||
|
lastStats(2).NumRemoved++
|
||||||
|
case diff.UniqueY:
|
||||||
|
lastStats(2).NumInserted++
|
||||||
|
case diff.Modified:
|
||||||
|
lastStats(2).NumModified++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return groups
|
||||||
|
}
|
||||||
|
|
||||||
|
// coalesceInterveningIdentical coalesces sufficiently short (<= windowSize)
|
||||||
|
// equal groups into adjacent unequal groups that currently result in a
|
||||||
|
// dual inserted/removed printout. This acts as a high-pass filter to smooth
|
||||||
|
// out high-frequency changes within the windowSize.
|
||||||
|
func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats {
|
||||||
|
groups, groupsOrig := groups[:0], groups
|
||||||
|
for i, ds := range groupsOrig {
|
||||||
|
if len(groups) >= 2 && ds.NumDiff() > 0 {
|
||||||
|
prev := &groups[len(groups)-2] // Unequal group
|
||||||
|
curr := &groups[len(groups)-1] // Equal group
|
||||||
|
next := &groupsOrig[i] // Unequal group
|
||||||
|
hadX, hadY := prev.NumRemoved > 0, prev.NumInserted > 0
|
||||||
|
hasX, hasY := next.NumRemoved > 0, next.NumInserted > 0
|
||||||
|
if ((hadX || hasX) && (hadY || hasY)) && curr.NumIdentical <= windowSize {
|
||||||
|
*prev = prev.Append(*curr).Append(*next)
|
||||||
|
groups = groups[:len(groups)-1] // Truncate off equal group
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
groups = append(groups, ds)
|
||||||
|
}
|
||||||
|
return groups
|
||||||
|
}
|
387
vendor/github.com/google/go-cmp/cmp/report_text.go
generated
vendored
Normal file
387
vendor/github.com/google/go-cmp/cmp/report_text.go
generated
vendored
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
// Copyright 2019, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
package cmp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp/internal/flags"
|
||||||
|
)
|
||||||
|
|
||||||
|
var randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0
|
||||||
|
|
||||||
|
type indentMode int
|
||||||
|
|
||||||
|
func (n indentMode) appendIndent(b []byte, d diffMode) []byte {
|
||||||
|
// The output of Diff is documented as being unstable to provide future
|
||||||
|
// flexibility in changing the output for more humanly readable reports.
|
||||||
|
// This logic intentionally introduces instability to the exact output
|
||||||
|
// so that users can detect accidental reliance on stability early on,
|
||||||
|
// rather than much later when an actual change to the format occurs.
|
||||||
|
if flags.Deterministic || randBool {
|
||||||
|
// Use regular spaces (U+0020).
|
||||||
|
switch d {
|
||||||
|
case diffUnknown, diffIdentical:
|
||||||
|
b = append(b, " "...)
|
||||||
|
case diffRemoved:
|
||||||
|
b = append(b, "- "...)
|
||||||
|
case diffInserted:
|
||||||
|
b = append(b, "+ "...)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Use non-breaking spaces (U+00a0).
|
||||||
|
switch d {
|
||||||
|
case diffUnknown, diffIdentical:
|
||||||
|
b = append(b, " "...)
|
||||||
|
case diffRemoved:
|
||||||
|
b = append(b, "- "...)
|
||||||
|
case diffInserted:
|
||||||
|
b = append(b, "+ "...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return repeatCount(n).appendChar(b, '\t')
|
||||||
|
}
|
||||||
|
|
||||||
|
type repeatCount int
|
||||||
|
|
||||||
|
func (n repeatCount) appendChar(b []byte, c byte) []byte {
|
||||||
|
for ; n > 0; n-- {
|
||||||
|
b = append(b, c)
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// textNode is a simplified tree-based representation of structured text.
|
||||||
|
// Possible node types are textWrap, textList, or textLine.
|
||||||
|
type textNode interface {
|
||||||
|
// Len reports the length in bytes of a single-line version of the tree.
|
||||||
|
// Nested textRecord.Diff and textRecord.Comment fields are ignored.
|
||||||
|
Len() int
|
||||||
|
// Equal reports whether the two trees are structurally identical.
|
||||||
|
// Nested textRecord.Diff and textRecord.Comment fields are compared.
|
||||||
|
Equal(textNode) bool
|
||||||
|
// String returns the string representation of the text tree.
|
||||||
|
// It is not guaranteed that len(x.String()) == x.Len(),
|
||||||
|
// nor that x.String() == y.String() implies that x.Equal(y).
|
||||||
|
String() string
|
||||||
|
|
||||||
|
// formatCompactTo formats the contents of the tree as a single-line string
|
||||||
|
// to the provided buffer. Any nested textRecord.Diff and textRecord.Comment
|
||||||
|
// fields are ignored.
|
||||||
|
//
|
||||||
|
// However, not all nodes in the tree should be collapsed as a single-line.
|
||||||
|
// If a node can be collapsed as a single-line, it is replaced by a textLine
|
||||||
|
// node. Since the top-level node cannot replace itself, this also returns
|
||||||
|
// the current node itself.
|
||||||
|
//
|
||||||
|
// This does not mutate the receiver.
|
||||||
|
formatCompactTo([]byte, diffMode) ([]byte, textNode)
|
||||||
|
// formatExpandedTo formats the contents of the tree as a multi-line string
|
||||||
|
// to the provided buffer. In order for column alignment to operate well,
|
||||||
|
// formatCompactTo must be called before calling formatExpandedTo.
|
||||||
|
formatExpandedTo([]byte, diffMode, indentMode) []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// textWrap is a wrapper that concatenates a prefix and/or a suffix
|
||||||
|
// to the underlying node.
|
||||||
|
type textWrap struct {
|
||||||
|
Prefix string // e.g., "bytes.Buffer{"
|
||||||
|
Value textNode // textWrap | textList | textLine
|
||||||
|
Suffix string // e.g., "}"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s textWrap) Len() int {
|
||||||
|
return len(s.Prefix) + s.Value.Len() + len(s.Suffix)
|
||||||
|
}
|
||||||
|
func (s1 textWrap) Equal(s2 textNode) bool {
|
||||||
|
if s2, ok := s2.(textWrap); ok {
|
||||||
|
return s1.Prefix == s2.Prefix && s1.Value.Equal(s2.Value) && s1.Suffix == s2.Suffix
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func (s textWrap) String() string {
|
||||||
|
var d diffMode
|
||||||
|
var n indentMode
|
||||||
|
_, s2 := s.formatCompactTo(nil, d)
|
||||||
|
b := n.appendIndent(nil, d) // Leading indent
|
||||||
|
b = s2.formatExpandedTo(b, d, n) // Main body
|
||||||
|
b = append(b, '\n') // Trailing newline
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
func (s textWrap) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) {
|
||||||
|
n0 := len(b) // Original buffer length
|
||||||
|
b = append(b, s.Prefix...)
|
||||||
|
b, s.Value = s.Value.formatCompactTo(b, d)
|
||||||
|
b = append(b, s.Suffix...)
|
||||||
|
if _, ok := s.Value.(textLine); ok {
|
||||||
|
return b, textLine(b[n0:])
|
||||||
|
}
|
||||||
|
return b, s
|
||||||
|
}
|
||||||
|
func (s textWrap) formatExpandedTo(b []byte, d diffMode, n indentMode) []byte {
|
||||||
|
b = append(b, s.Prefix...)
|
||||||
|
b = s.Value.formatExpandedTo(b, d, n)
|
||||||
|
b = append(b, s.Suffix...)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// textList is a comma-separated list of textWrap or textLine nodes.
|
||||||
|
// The list may be formatted as multi-lines or single-line at the discretion
|
||||||
|
// of the textList.formatCompactTo method.
|
||||||
|
type textList []textRecord
|
||||||
|
type textRecord struct {
|
||||||
|
Diff diffMode // e.g., 0 or '-' or '+'
|
||||||
|
Key string // e.g., "MyField"
|
||||||
|
Value textNode // textWrap | textLine
|
||||||
|
Comment fmt.Stringer // e.g., "6 identical fields"
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendEllipsis appends a new ellipsis node to the list if none already
|
||||||
|
// exists at the end. If cs is non-zero it coalesces the statistics with the
|
||||||
|
// previous diffStats.
|
||||||
|
func (s *textList) AppendEllipsis(ds diffStats) {
|
||||||
|
hasStats := ds != diffStats{}
|
||||||
|
if len(*s) == 0 || !(*s)[len(*s)-1].Value.Equal(textEllipsis) {
|
||||||
|
if hasStats {
|
||||||
|
*s = append(*s, textRecord{Value: textEllipsis, Comment: ds})
|
||||||
|
} else {
|
||||||
|
*s = append(*s, textRecord{Value: textEllipsis})
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if hasStats {
|
||||||
|
(*s)[len(*s)-1].Comment = (*s)[len(*s)-1].Comment.(diffStats).Append(ds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s textList) Len() (n int) {
|
||||||
|
for i, r := range s {
|
||||||
|
n += len(r.Key)
|
||||||
|
if r.Key != "" {
|
||||||
|
n += len(": ")
|
||||||
|
}
|
||||||
|
n += r.Value.Len()
|
||||||
|
if i < len(s)-1 {
|
||||||
|
n += len(", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s1 textList) Equal(s2 textNode) bool {
|
||||||
|
if s2, ok := s2.(textList); ok {
|
||||||
|
if len(s1) != len(s2) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := range s1 {
|
||||||
|
r1, r2 := s1[i], s2[i]
|
||||||
|
if !(r1.Diff == r2.Diff && r1.Key == r2.Key && r1.Value.Equal(r2.Value) && r1.Comment == r2.Comment) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s textList) String() string {
|
||||||
|
return textWrap{"{", s, "}"}.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s textList) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) {
|
||||||
|
s = append(textList(nil), s...) // Avoid mutating original
|
||||||
|
|
||||||
|
// Determine whether we can collapse this list as a single line.
|
||||||
|
n0 := len(b) // Original buffer length
|
||||||
|
var multiLine bool
|
||||||
|
for i, r := range s {
|
||||||
|
if r.Diff == diffInserted || r.Diff == diffRemoved {
|
||||||
|
multiLine = true
|
||||||
|
}
|
||||||
|
b = append(b, r.Key...)
|
||||||
|
if r.Key != "" {
|
||||||
|
b = append(b, ": "...)
|
||||||
|
}
|
||||||
|
b, s[i].Value = r.Value.formatCompactTo(b, d|r.Diff)
|
||||||
|
if _, ok := s[i].Value.(textLine); !ok {
|
||||||
|
multiLine = true
|
||||||
|
}
|
||||||
|
if r.Comment != nil {
|
||||||
|
multiLine = true
|
||||||
|
}
|
||||||
|
if i < len(s)-1 {
|
||||||
|
b = append(b, ", "...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Force multi-lined output when printing a removed/inserted node that
|
||||||
|
// is sufficiently long.
|
||||||
|
if (d == diffInserted || d == diffRemoved) && len(b[n0:]) > 80 {
|
||||||
|
multiLine = true
|
||||||
|
}
|
||||||
|
if !multiLine {
|
||||||
|
return b, textLine(b[n0:])
|
||||||
|
}
|
||||||
|
return b, s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s textList) formatExpandedTo(b []byte, d diffMode, n indentMode) []byte {
|
||||||
|
alignKeyLens := s.alignLens(
|
||||||
|
func(r textRecord) bool {
|
||||||
|
_, isLine := r.Value.(textLine)
|
||||||
|
return r.Key == "" || !isLine
|
||||||
|
},
|
||||||
|
func(r textRecord) int { return len(r.Key) },
|
||||||
|
)
|
||||||
|
alignValueLens := s.alignLens(
|
||||||
|
func(r textRecord) bool {
|
||||||
|
_, isLine := r.Value.(textLine)
|
||||||
|
return !isLine || r.Value.Equal(textEllipsis) || r.Comment == nil
|
||||||
|
},
|
||||||
|
func(r textRecord) int { return len(r.Value.(textLine)) },
|
||||||
|
)
|
||||||
|
|
||||||
|
// Format the list as a multi-lined output.
|
||||||
|
n++
|
||||||
|
for i, r := range s {
|
||||||
|
b = n.appendIndent(append(b, '\n'), d|r.Diff)
|
||||||
|
if r.Key != "" {
|
||||||
|
b = append(b, r.Key+": "...)
|
||||||
|
}
|
||||||
|
b = alignKeyLens[i].appendChar(b, ' ')
|
||||||
|
|
||||||
|
b = r.Value.formatExpandedTo(b, d|r.Diff, n)
|
||||||
|
if !r.Value.Equal(textEllipsis) {
|
||||||
|
b = append(b, ',')
|
||||||
|
}
|
||||||
|
b = alignValueLens[i].appendChar(b, ' ')
|
||||||
|
|
||||||
|
if r.Comment != nil {
|
||||||
|
b = append(b, " // "+r.Comment.String()...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n--
|
||||||
|
|
||||||
|
return n.appendIndent(append(b, '\n'), d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s textList) alignLens(
|
||||||
|
skipFunc func(textRecord) bool,
|
||||||
|
lenFunc func(textRecord) int,
|
||||||
|
) []repeatCount {
|
||||||
|
var startIdx, endIdx, maxLen int
|
||||||
|
lens := make([]repeatCount, len(s))
|
||||||
|
for i, r := range s {
|
||||||
|
if skipFunc(r) {
|
||||||
|
for j := startIdx; j < endIdx && j < len(s); j++ {
|
||||||
|
lens[j] = repeatCount(maxLen - lenFunc(s[j]))
|
||||||
|
}
|
||||||
|
startIdx, endIdx, maxLen = i+1, i+1, 0
|
||||||
|
} else {
|
||||||
|
if maxLen < lenFunc(r) {
|
||||||
|
maxLen = lenFunc(r)
|
||||||
|
}
|
||||||
|
endIdx = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for j := startIdx; j < endIdx && j < len(s); j++ {
|
||||||
|
lens[j] = repeatCount(maxLen - lenFunc(s[j]))
|
||||||
|
}
|
||||||
|
return lens
|
||||||
|
}
|
||||||
|
|
||||||
|
// textLine is a single-line segment of text and is always a leaf node
|
||||||
|
// in the textNode tree.
|
||||||
|
type textLine []byte
|
||||||
|
|
||||||
|
var (
|
||||||
|
textNil = textLine("nil")
|
||||||
|
textEllipsis = textLine("...")
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s textLine) Len() int {
|
||||||
|
return len(s)
|
||||||
|
}
|
||||||
|
func (s1 textLine) Equal(s2 textNode) bool {
|
||||||
|
if s2, ok := s2.(textLine); ok {
|
||||||
|
return bytes.Equal([]byte(s1), []byte(s2))
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func (s textLine) String() string {
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
func (s textLine) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) {
|
||||||
|
return append(b, s...), s
|
||||||
|
}
|
||||||
|
func (s textLine) formatExpandedTo(b []byte, _ diffMode, _ indentMode) []byte {
|
||||||
|
return append(b, s...)
|
||||||
|
}
|
||||||
|
|
||||||
|
type diffStats struct {
|
||||||
|
Name string
|
||||||
|
NumIgnored int
|
||||||
|
NumIdentical int
|
||||||
|
NumRemoved int
|
||||||
|
NumInserted int
|
||||||
|
NumModified int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s diffStats) NumDiff() int {
|
||||||
|
return s.NumRemoved + s.NumInserted + s.NumModified
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s diffStats) Append(ds diffStats) diffStats {
|
||||||
|
assert(s.Name == ds.Name)
|
||||||
|
s.NumIgnored += ds.NumIgnored
|
||||||
|
s.NumIdentical += ds.NumIdentical
|
||||||
|
s.NumRemoved += ds.NumRemoved
|
||||||
|
s.NumInserted += ds.NumInserted
|
||||||
|
s.NumModified += ds.NumModified
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// String prints a humanly-readable summary of coalesced records.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
// diffStats{Name: "Field", NumIgnored: 5}.String() => "5 ignored fields"
|
||||||
|
func (s diffStats) String() string {
|
||||||
|
var ss []string
|
||||||
|
var sum int
|
||||||
|
labels := [...]string{"ignored", "identical", "removed", "inserted", "modified"}
|
||||||
|
counts := [...]int{s.NumIgnored, s.NumIdentical, s.NumRemoved, s.NumInserted, s.NumModified}
|
||||||
|
for i, n := range counts {
|
||||||
|
if n > 0 {
|
||||||
|
ss = append(ss, fmt.Sprintf("%d %v", n, labels[i]))
|
||||||
|
}
|
||||||
|
sum += n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pluralize the name (adjusting for some obscure English grammar rules).
|
||||||
|
name := s.Name
|
||||||
|
if sum > 1 {
|
||||||
|
name += "s"
|
||||||
|
if strings.HasSuffix(name, "ys") {
|
||||||
|
name = name[:len(name)-2] + "ies" // e.g., "entrys" => "entries"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format the list according to English grammar (with Oxford comma).
|
||||||
|
switch n := len(ss); n {
|
||||||
|
case 0:
|
||||||
|
return ""
|
||||||
|
case 1, 2:
|
||||||
|
return strings.Join(ss, " and ") + " " + name
|
||||||
|
default:
|
||||||
|
return strings.Join(ss[:n-1], ", ") + ", and " + ss[n-1] + " " + name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type commentString string
|
||||||
|
|
||||||
|
func (s commentString) String() string { return string(s) }
|
121
vendor/github.com/google/go-cmp/cmp/report_value.go
generated
vendored
Normal file
121
vendor/github.com/google/go-cmp/cmp/report_value.go
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
// Copyright 2019, The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
|
package cmp
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
// valueNode represents a single node within a report, which is a
|
||||||
|
// structured representation of the value tree, containing information
|
||||||
|
// regarding which nodes are equal or not.
|
||||||
|
type valueNode struct {
|
||||||
|
parent *valueNode
|
||||||
|
|
||||||
|
Type reflect.Type
|
||||||
|
ValueX reflect.Value
|
||||||
|
ValueY reflect.Value
|
||||||
|
|
||||||
|
// NumSame is the number of leaf nodes that are equal.
|
||||||
|
// All descendants are equal only if NumDiff is 0.
|
||||||
|
NumSame int
|
||||||
|
// NumDiff is the number of leaf nodes that are not equal.
|
||||||
|
NumDiff int
|
||||||
|
// NumIgnored is the number of leaf nodes that are ignored.
|
||||||
|
NumIgnored int
|
||||||
|
// NumCompared is the number of leaf nodes that were compared
|
||||||
|
// using an Equal method or Comparer function.
|
||||||
|
NumCompared int
|
||||||
|
// NumTransformed is the number of non-leaf nodes that were transformed.
|
||||||
|
NumTransformed int
|
||||||
|
// NumChildren is the number of transitive descendants of this node.
|
||||||
|
// This counts from zero; thus, leaf nodes have no descendants.
|
||||||
|
NumChildren int
|
||||||
|
// MaxDepth is the maximum depth of the tree. This counts from zero;
|
||||||
|
// thus, leaf nodes have a depth of zero.
|
||||||
|
MaxDepth int
|
||||||
|
|
||||||
|
// Records is a list of struct fields, slice elements, or map entries.
|
||||||
|
Records []reportRecord // If populated, implies Value is not populated
|
||||||
|
|
||||||
|
// Value is the result of a transformation, pointer indirect, of
|
||||||
|
// type assertion.
|
||||||
|
Value *valueNode // If populated, implies Records is not populated
|
||||||
|
|
||||||
|
// TransformerName is the name of the transformer.
|
||||||
|
TransformerName string // If non-empty, implies Value is populated
|
||||||
|
}
|
||||||
|
type reportRecord struct {
|
||||||
|
Key reflect.Value // Invalid for slice element
|
||||||
|
Value *valueNode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (parent *valueNode) PushStep(ps PathStep) (child *valueNode) {
|
||||||
|
vx, vy := ps.Values()
|
||||||
|
child = &valueNode{parent: parent, Type: ps.Type(), ValueX: vx, ValueY: vy}
|
||||||
|
switch s := ps.(type) {
|
||||||
|
case StructField:
|
||||||
|
assert(parent.Value == nil)
|
||||||
|
parent.Records = append(parent.Records, reportRecord{Key: reflect.ValueOf(s.Name()), Value: child})
|
||||||
|
case SliceIndex:
|
||||||
|
assert(parent.Value == nil)
|
||||||
|
parent.Records = append(parent.Records, reportRecord{Value: child})
|
||||||
|
case MapIndex:
|
||||||
|
assert(parent.Value == nil)
|
||||||
|
parent.Records = append(parent.Records, reportRecord{Key: s.Key(), Value: child})
|
||||||
|
case Indirect:
|
||||||
|
assert(parent.Value == nil && parent.Records == nil)
|
||||||
|
parent.Value = child
|
||||||
|
case TypeAssertion:
|
||||||
|
assert(parent.Value == nil && parent.Records == nil)
|
||||||
|
parent.Value = child
|
||||||
|
case Transform:
|
||||||
|
assert(parent.Value == nil && parent.Records == nil)
|
||||||
|
parent.Value = child
|
||||||
|
parent.TransformerName = s.Name()
|
||||||
|
parent.NumTransformed++
|
||||||
|
default:
|
||||||
|
assert(parent == nil) // Must be the root step
|
||||||
|
}
|
||||||
|
return child
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *valueNode) Report(rs Result) {
|
||||||
|
assert(r.MaxDepth == 0) // May only be called on leaf nodes
|
||||||
|
|
||||||
|
if rs.ByIgnore() {
|
||||||
|
r.NumIgnored++
|
||||||
|
} else {
|
||||||
|
if rs.Equal() {
|
||||||
|
r.NumSame++
|
||||||
|
} else {
|
||||||
|
r.NumDiff++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(r.NumSame+r.NumDiff+r.NumIgnored == 1)
|
||||||
|
|
||||||
|
if rs.ByMethod() {
|
||||||
|
r.NumCompared++
|
||||||
|
}
|
||||||
|
if rs.ByFunc() {
|
||||||
|
r.NumCompared++
|
||||||
|
}
|
||||||
|
assert(r.NumCompared <= 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (child *valueNode) PopStep() (parent *valueNode) {
|
||||||
|
if child.parent == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
parent = child.parent
|
||||||
|
parent.NumSame += child.NumSame
|
||||||
|
parent.NumDiff += child.NumDiff
|
||||||
|
parent.NumIgnored += child.NumIgnored
|
||||||
|
parent.NumCompared += child.NumCompared
|
||||||
|
parent.NumTransformed += child.NumTransformed
|
||||||
|
parent.NumChildren += child.NumChildren + 1
|
||||||
|
if parent.MaxDepth < child.MaxDepth+1 {
|
||||||
|
parent.MaxDepth = child.MaxDepth + 1
|
||||||
|
}
|
||||||
|
return parent
|
||||||
|
}
|
29
vendor/github.com/prometheus/client_golang/prometheus/build_info.go
generated
vendored
Normal file
29
vendor/github.com/prometheus/client_golang/prometheus/build_info.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2019 The Prometheus Authors
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// +build go1.12
|
||||||
|
|
||||||
|
package prometheus
|
||||||
|
|
||||||
|
import "runtime/debug"
|
||||||
|
|
||||||
|
// readBuildInfo is a wrapper around debug.ReadBuildInfo for Go 1.12+.
|
||||||
|
func readBuildInfo() (path, version, sum string) {
|
||||||
|
path, version, sum = "unknown", "unknown", "unknown"
|
||||||
|
if bi, ok := debug.ReadBuildInfo(); ok {
|
||||||
|
path = bi.Main.Path
|
||||||
|
version = bi.Main.Version
|
||||||
|
sum = bi.Main.Sum
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
22
vendor/github.com/prometheus/client_golang/prometheus/build_info_pre_1.12.go
generated
vendored
Normal file
22
vendor/github.com/prometheus/client_golang/prometheus/build_info_pre_1.12.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright 2019 The Prometheus Authors
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// +build !go1.12
|
||||||
|
|
||||||
|
package prometheus
|
||||||
|
|
||||||
|
// readBuildInfo is a wrapper around debug.ReadBuildInfo for Go versions before
|
||||||
|
// 1.12. Remove this whole file once the minimum supported Go version is 1.12.
|
||||||
|
func readBuildInfo() (path, version, sum string) {
|
||||||
|
return "unknown", "unknown", "unknown"
|
||||||
|
}
|
2
vendor/github.com/prometheus/client_golang/prometheus/collector.go
generated
vendored
2
vendor/github.com/prometheus/client_golang/prometheus/collector.go
generated
vendored
@ -79,7 +79,7 @@ type Collector interface {
|
|||||||
// of the Describe method. If a Collector sometimes collects no metrics at all
|
// of the Describe method. If a Collector sometimes collects no metrics at all
|
||||||
// (for example vectors like CounterVec, GaugeVec, etc., which only collect
|
// (for example vectors like CounterVec, GaugeVec, etc., which only collect
|
||||||
// metrics after a metric with a fully specified label set has been accessed),
|
// metrics after a metric with a fully specified label set has been accessed),
|
||||||
// it might even get registered as an unchecked Collecter (cf. the Register
|
// it might even get registered as an unchecked Collector (cf. the Register
|
||||||
// method of the Registerer interface). Hence, only use this shortcut
|
// method of the Registerer interface). Hence, only use this shortcut
|
||||||
// implementation of Describe if you are certain to fulfill the contract.
|
// implementation of Describe if you are certain to fulfill the contract.
|
||||||
//
|
//
|
||||||
|
4
vendor/github.com/prometheus/client_golang/prometheus/desc.go
generated
vendored
4
vendor/github.com/prometheus/client_golang/prometheus/desc.go
generated
vendored
@ -93,7 +93,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
|
|||||||
// First add only the const label names and sort them...
|
// First add only the const label names and sort them...
|
||||||
for labelName := range constLabels {
|
for labelName := range constLabels {
|
||||||
if !checkLabelName(labelName) {
|
if !checkLabelName(labelName) {
|
||||||
d.err = fmt.Errorf("%q is not a valid label name", labelName)
|
d.err = fmt.Errorf("%q is not a valid label name for metric %q", labelName, fqName)
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
labelNames = append(labelNames, labelName)
|
labelNames = append(labelNames, labelName)
|
||||||
@ -115,7 +115,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
|
|||||||
// dimension with a different mix between preset and variable labels.
|
// dimension with a different mix between preset and variable labels.
|
||||||
for _, labelName := range variableLabels {
|
for _, labelName := range variableLabels {
|
||||||
if !checkLabelName(labelName) {
|
if !checkLabelName(labelName) {
|
||||||
d.err = fmt.Errorf("%q is not a valid label name", labelName)
|
d.err = fmt.Errorf("%q is not a valid label name for metric %q", labelName, fqName)
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
labelNames = append(labelNames, "$"+labelName)
|
labelNames = append(labelNames, "$"+labelName)
|
||||||
|
7
vendor/github.com/prometheus/client_golang/prometheus/doc.go
generated
vendored
7
vendor/github.com/prometheus/client_golang/prometheus/doc.go
generated
vendored
@ -122,13 +122,13 @@
|
|||||||
// the Collect method. The Describe method has to return separate Desc
|
// the Collect method. The Describe method has to return separate Desc
|
||||||
// instances, representative of the “throw-away” metrics to be created later.
|
// instances, representative of the “throw-away” metrics to be created later.
|
||||||
// NewDesc comes in handy to create those Desc instances. Alternatively, you
|
// NewDesc comes in handy to create those Desc instances. Alternatively, you
|
||||||
// could return no Desc at all, which will marke the Collector “unchecked”. No
|
// could return no Desc at all, which will mark the Collector “unchecked”. No
|
||||||
// checks are porformed at registration time, but metric consistency will still
|
// checks are performed at registration time, but metric consistency will still
|
||||||
// be ensured at scrape time, i.e. any inconsistencies will lead to scrape
|
// be ensured at scrape time, i.e. any inconsistencies will lead to scrape
|
||||||
// errors. Thus, with unchecked Collectors, the responsibility to not collect
|
// errors. Thus, with unchecked Collectors, the responsibility to not collect
|
||||||
// metrics that lead to inconsistencies in the total scrape result lies with the
|
// metrics that lead to inconsistencies in the total scrape result lies with the
|
||||||
// implementer of the Collector. While this is not a desirable state, it is
|
// implementer of the Collector. While this is not a desirable state, it is
|
||||||
// sometimes necessary. The typical use case is a situatios where the exact
|
// sometimes necessary. The typical use case is a situation where the exact
|
||||||
// metrics to be returned by a Collector cannot be predicted at registration
|
// metrics to be returned by a Collector cannot be predicted at registration
|
||||||
// time, but the implementer has sufficient knowledge of the whole system to
|
// time, but the implementer has sufficient knowledge of the whole system to
|
||||||
// guarantee metric consistency.
|
// guarantee metric consistency.
|
||||||
@ -183,7 +183,6 @@
|
|||||||
// method can then expose the gathered metrics in some way. Usually, the metrics
|
// method can then expose the gathered metrics in some way. Usually, the metrics
|
||||||
// are served via HTTP on the /metrics endpoint. That's happening in the example
|
// are served via HTTP on the /metrics endpoint. That's happening in the example
|
||||||
// above. The tools to expose metrics via HTTP are in the promhttp sub-package.
|
// above. The tools to expose metrics via HTTP are in the promhttp sub-package.
|
||||||
// (The top-level functions in the prometheus package are deprecated.)
|
|
||||||
//
|
//
|
||||||
// Pushing to the Pushgateway
|
// Pushing to the Pushgateway
|
||||||
//
|
//
|
||||||
|
121
vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
generated
vendored
121
vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
generated
vendored
@ -14,9 +14,9 @@
|
|||||||
package prometheus
|
package prometheus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,16 +26,41 @@ type goCollector struct {
|
|||||||
gcDesc *Desc
|
gcDesc *Desc
|
||||||
goInfoDesc *Desc
|
goInfoDesc *Desc
|
||||||
|
|
||||||
// metrics to describe and collect
|
// ms... are memstats related.
|
||||||
metrics memStatsMetrics
|
msLast *runtime.MemStats // Previously collected memstats.
|
||||||
|
msLastTimestamp time.Time
|
||||||
|
msMtx sync.Mutex // Protects msLast and msLastTimestamp.
|
||||||
|
msMetrics memStatsMetrics
|
||||||
|
msRead func(*runtime.MemStats) // For mocking in tests.
|
||||||
|
msMaxWait time.Duration // Wait time for fresh memstats.
|
||||||
|
msMaxAge time.Duration // Maximum allowed age of old memstats.
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGoCollector returns a collector which exports metrics about the current Go
|
// NewGoCollector returns a collector that exports metrics about the current Go
|
||||||
// process. This includes memory stats. To collect those, runtime.ReadMemStats
|
// process. This includes memory stats. To collect those, runtime.ReadMemStats
|
||||||
// is called. This causes a stop-the-world, which is very short with Go1.9+
|
// is called. This requires to “stop the world”, which usually only happens for
|
||||||
// (~25µs). However, with older Go versions, the stop-the-world duration depends
|
// garbage collection (GC). Take the following implications into account when
|
||||||
// on the heap size and can be quite significant (~1.7 ms/GiB as per
|
// deciding whether to use the Go collector:
|
||||||
|
//
|
||||||
|
// 1. The performance impact of stopping the world is the more relevant the more
|
||||||
|
// frequently metrics are collected. However, with Go1.9 or later the
|
||||||
|
// stop-the-world time per metrics collection is very short (~25µs) so that the
|
||||||
|
// performance impact will only matter in rare cases. However, with older Go
|
||||||
|
// versions, the stop-the-world duration depends on the heap size and can be
|
||||||
|
// quite significant (~1.7 ms/GiB as per
|
||||||
// https://go-review.googlesource.com/c/go/+/34937).
|
// https://go-review.googlesource.com/c/go/+/34937).
|
||||||
|
//
|
||||||
|
// 2. During an ongoing GC, nothing else can stop the world. Therefore, if the
|
||||||
|
// metrics collection happens to coincide with GC, it will only complete after
|
||||||
|
// GC has finished. Usually, GC is fast enough to not cause problems. However,
|
||||||
|
// with a very large heap, GC might take multiple seconds, which is enough to
|
||||||
|
// cause scrape timeouts in common setups. To avoid this problem, the Go
|
||||||
|
// collector will use the memstats from a previous collection if
|
||||||
|
// runtime.ReadMemStats takes more than 1s. However, if there are no previously
|
||||||
|
// collected memstats, or their collection is more than 5m ago, the collection
|
||||||
|
// will block until runtime.ReadMemStats succeeds. (The problem might be solved
|
||||||
|
// in Go1.13, see https://github.com/golang/go/issues/19812 for the related Go
|
||||||
|
// issue.)
|
||||||
func NewGoCollector() Collector {
|
func NewGoCollector() Collector {
|
||||||
return &goCollector{
|
return &goCollector{
|
||||||
goroutinesDesc: NewDesc(
|
goroutinesDesc: NewDesc(
|
||||||
@ -54,7 +79,11 @@ func NewGoCollector() Collector {
|
|||||||
"go_info",
|
"go_info",
|
||||||
"Information about the Go environment.",
|
"Information about the Go environment.",
|
||||||
nil, Labels{"version": runtime.Version()}),
|
nil, Labels{"version": runtime.Version()}),
|
||||||
metrics: memStatsMetrics{
|
msLast: &runtime.MemStats{},
|
||||||
|
msRead: runtime.ReadMemStats,
|
||||||
|
msMaxWait: time.Second,
|
||||||
|
msMaxAge: 5 * time.Minute,
|
||||||
|
msMetrics: memStatsMetrics{
|
||||||
{
|
{
|
||||||
desc: NewDesc(
|
desc: NewDesc(
|
||||||
memstatNamespace("alloc_bytes"),
|
memstatNamespace("alloc_bytes"),
|
||||||
@ -253,7 +282,7 @@ func NewGoCollector() Collector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func memstatNamespace(s string) string {
|
func memstatNamespace(s string) string {
|
||||||
return fmt.Sprintf("go_memstats_%s", s)
|
return "go_memstats_" + s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe returns all descriptions of the collector.
|
// Describe returns all descriptions of the collector.
|
||||||
@ -262,13 +291,27 @@ func (c *goCollector) Describe(ch chan<- *Desc) {
|
|||||||
ch <- c.threadsDesc
|
ch <- c.threadsDesc
|
||||||
ch <- c.gcDesc
|
ch <- c.gcDesc
|
||||||
ch <- c.goInfoDesc
|
ch <- c.goInfoDesc
|
||||||
for _, i := range c.metrics {
|
for _, i := range c.msMetrics {
|
||||||
ch <- i.desc
|
ch <- i.desc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect returns the current state of all metrics of the collector.
|
// Collect returns the current state of all metrics of the collector.
|
||||||
func (c *goCollector) Collect(ch chan<- Metric) {
|
func (c *goCollector) Collect(ch chan<- Metric) {
|
||||||
|
var (
|
||||||
|
ms = &runtime.MemStats{}
|
||||||
|
done = make(chan struct{})
|
||||||
|
)
|
||||||
|
// Start reading memstats first as it might take a while.
|
||||||
|
go func() {
|
||||||
|
c.msRead(ms)
|
||||||
|
c.msMtx.Lock()
|
||||||
|
c.msLast = ms
|
||||||
|
c.msLastTimestamp = time.Now()
|
||||||
|
c.msMtx.Unlock()
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
|
|
||||||
ch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine()))
|
ch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine()))
|
||||||
n, _ := runtime.ThreadCreateProfile(nil)
|
n, _ := runtime.ThreadCreateProfile(nil)
|
||||||
ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, float64(n))
|
ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, float64(n))
|
||||||
@ -286,9 +329,31 @@ func (c *goCollector) Collect(ch chan<- Metric) {
|
|||||||
|
|
||||||
ch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1)
|
ch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1)
|
||||||
|
|
||||||
ms := &runtime.MemStats{}
|
timer := time.NewTimer(c.msMaxWait)
|
||||||
runtime.ReadMemStats(ms)
|
select {
|
||||||
for _, i := range c.metrics {
|
case <-done: // Our own ReadMemStats succeeded in time. Use it.
|
||||||
|
timer.Stop() // Important for high collection frequencies to not pile up timers.
|
||||||
|
c.msCollect(ch, ms)
|
||||||
|
return
|
||||||
|
case <-timer.C: // Time out, use last memstats if possible. Continue below.
|
||||||
|
}
|
||||||
|
c.msMtx.Lock()
|
||||||
|
if time.Since(c.msLastTimestamp) < c.msMaxAge {
|
||||||
|
// Last memstats are recent enough. Collect from them under the lock.
|
||||||
|
c.msCollect(ch, c.msLast)
|
||||||
|
c.msMtx.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// If we are here, the last memstats are too old or don't exist. We have
|
||||||
|
// to wait until our own ReadMemStats finally completes. For that to
|
||||||
|
// happen, we have to release the lock.
|
||||||
|
c.msMtx.Unlock()
|
||||||
|
<-done
|
||||||
|
c.msCollect(ch, ms)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *goCollector) msCollect(ch chan<- Metric, ms *runtime.MemStats) {
|
||||||
|
for _, i := range c.msMetrics {
|
||||||
ch <- MustNewConstMetric(i.desc, i.valType, i.eval(ms))
|
ch <- MustNewConstMetric(i.desc, i.valType, i.eval(ms))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,3 +364,33 @@ type memStatsMetrics []struct {
|
|||||||
eval func(*runtime.MemStats) float64
|
eval func(*runtime.MemStats) float64
|
||||||
valType ValueType
|
valType ValueType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewBuildInfoCollector returns a collector collecting a single metric
|
||||||
|
// "go_build_info" with the constant value 1 and three labels "path", "version",
|
||||||
|
// and "checksum". Their label values contain the main module path, version, and
|
||||||
|
// checksum, respectively. The labels will only have meaningful values if the
|
||||||
|
// binary is built with Go module support and from source code retrieved from
|
||||||
|
// the source repository (rather than the local file system). This is usually
|
||||||
|
// accomplished by building from outside of GOPATH, specifying the full address
|
||||||
|
// of the main package, e.g. "GO111MODULE=on go run
|
||||||
|
// github.com/prometheus/client_golang/examples/random". If built without Go
|
||||||
|
// module support, all label values will be "unknown". If built with Go module
|
||||||
|
// support but using the source code from the local file system, the "path" will
|
||||||
|
// be set appropriately, but "checksum" will be empty and "version" will be
|
||||||
|
// "(devel)".
|
||||||
|
//
|
||||||
|
// This collector uses only the build information for the main module. See
|
||||||
|
// https://github.com/povilasv/prommod for an example of a collector for the
|
||||||
|
// module dependencies.
|
||||||
|
func NewBuildInfoCollector() Collector {
|
||||||
|
path, version, sum := readBuildInfo()
|
||||||
|
c := &selfCollector{MustNewConstMetric(
|
||||||
|
NewDesc(
|
||||||
|
"go_build_info",
|
||||||
|
"Build information about the main Go module.",
|
||||||
|
nil, Labels{"path": path, "version": version, "checksum": sum},
|
||||||
|
),
|
||||||
|
GaugeValue, 1)}
|
||||||
|
c.init(c.self)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
114
vendor/github.com/prometheus/client_golang/prometheus/histogram.go
generated
vendored
114
vendor/github.com/prometheus/client_golang/prometheus/histogram.go
generated
vendored
@ -204,8 +204,8 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Finally we know the final length of h.upperBounds and can make counts
|
// Finally we know the final length of h.upperBounds and can make buckets
|
||||||
// for both states:
|
// for both counts:
|
||||||
h.counts[0].buckets = make([]uint64, len(h.upperBounds))
|
h.counts[0].buckets = make([]uint64, len(h.upperBounds))
|
||||||
h.counts[1].buckets = make([]uint64, len(h.upperBounds))
|
h.counts[1].buckets = make([]uint64, len(h.upperBounds))
|
||||||
|
|
||||||
@ -224,18 +224,21 @@ type histogramCounts struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type histogram struct {
|
type histogram struct {
|
||||||
// countAndHotIdx is a complicated one. For lock-free yet atomic
|
// countAndHotIdx enables lock-free writes with use of atomic updates.
|
||||||
// observations, we need to save the total count of observations again,
|
// The most significant bit is the hot index [0 or 1] of the count field
|
||||||
// combined with the index of the currently-hot counts struct, so that
|
// below. Observe calls update the hot one. All remaining bits count the
|
||||||
// we can perform the operation on both values atomically. The least
|
// number of Observe calls. Observe starts by incrementing this counter,
|
||||||
// significant bit defines the hot counts struct. The remaining 63 bits
|
// and finish by incrementing the count field in the respective
|
||||||
// represent the total count of observations. This happens under the
|
// histogramCounts, as a marker for completion.
|
||||||
// assumption that the 63bit count will never overflow. Rationale: An
|
|
||||||
// observations takes about 30ns. Let's assume it could happen in
|
|
||||||
// 10ns. Overflowing the counter will then take at least (2^63)*10ns,
|
|
||||||
// which is about 3000 years.
|
|
||||||
//
|
//
|
||||||
// This has to be first in the struct for 64bit alignment. See
|
// Calls of the Write method (which are non-mutating reads from the
|
||||||
|
// perspective of the histogram) swap the hot–cold under the writeMtx
|
||||||
|
// lock. A cooldown is awaited (while locked) by comparing the number of
|
||||||
|
// observations with the initiation count. Once they match, then the
|
||||||
|
// last observation on the now cool one has completed. All cool fields must
|
||||||
|
// be merged into the new hot before releasing writeMtx.
|
||||||
|
//
|
||||||
|
// Fields with atomic access first! See alignment constraint:
|
||||||
// http://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
// http://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
||||||
countAndHotIdx uint64
|
countAndHotIdx uint64
|
||||||
|
|
||||||
@ -243,15 +246,13 @@ type histogram struct {
|
|||||||
desc *Desc
|
desc *Desc
|
||||||
writeMtx sync.Mutex // Only used in the Write method.
|
writeMtx sync.Mutex // Only used in the Write method.
|
||||||
|
|
||||||
upperBounds []float64
|
|
||||||
|
|
||||||
// Two counts, one is "hot" for lock-free observations, the other is
|
// Two counts, one is "hot" for lock-free observations, the other is
|
||||||
// "cold" for writing out a dto.Metric. It has to be an array of
|
// "cold" for writing out a dto.Metric. It has to be an array of
|
||||||
// pointers to guarantee 64bit alignment of the histogramCounts, see
|
// pointers to guarantee 64bit alignment of the histogramCounts, see
|
||||||
// http://golang.org/pkg/sync/atomic/#pkg-note-BUG.
|
// http://golang.org/pkg/sync/atomic/#pkg-note-BUG.
|
||||||
counts [2]*histogramCounts
|
counts [2]*histogramCounts
|
||||||
hotIdx int // Index of currently-hot counts. Only used within Write.
|
|
||||||
|
|
||||||
|
upperBounds []float64
|
||||||
labelPairs []*dto.LabelPair
|
labelPairs []*dto.LabelPair
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,11 +272,11 @@ func (h *histogram) Observe(v float64) {
|
|||||||
// 300 buckets: 154 ns/op linear - binary 61.6 ns/op
|
// 300 buckets: 154 ns/op linear - binary 61.6 ns/op
|
||||||
i := sort.SearchFloat64s(h.upperBounds, v)
|
i := sort.SearchFloat64s(h.upperBounds, v)
|
||||||
|
|
||||||
// We increment h.countAndHotIdx by 2 so that the counter in the upper
|
// We increment h.countAndHotIdx so that the counter in the lower
|
||||||
// 63 bits gets incremented by 1. At the same time, we get the new value
|
// 63 bits gets incremented. At the same time, we get the new value
|
||||||
// back, which we can use to find the currently-hot counts.
|
// back, which we can use to find the currently-hot counts.
|
||||||
n := atomic.AddUint64(&h.countAndHotIdx, 2)
|
n := atomic.AddUint64(&h.countAndHotIdx, 1)
|
||||||
hotCounts := h.counts[n%2]
|
hotCounts := h.counts[n>>63]
|
||||||
|
|
||||||
if i < len(h.upperBounds) {
|
if i < len(h.upperBounds) {
|
||||||
atomic.AddUint64(&hotCounts.buckets[i], 1)
|
atomic.AddUint64(&hotCounts.buckets[i], 1)
|
||||||
@ -293,72 +294,43 @@ func (h *histogram) Observe(v float64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *histogram) Write(out *dto.Metric) error {
|
func (h *histogram) Write(out *dto.Metric) error {
|
||||||
var (
|
// For simplicity, we protect this whole method by a mutex. It is not in
|
||||||
his = &dto.Histogram{}
|
// the hot path, i.e. Observe is called much more often than Write. The
|
||||||
buckets = make([]*dto.Bucket, len(h.upperBounds))
|
// complication of making Write lock-free isn't worth it, if possible at
|
||||||
hotCounts, coldCounts *histogramCounts
|
// all.
|
||||||
count uint64
|
|
||||||
)
|
|
||||||
|
|
||||||
// For simplicity, we mutex the rest of this method. It is not in the
|
|
||||||
// hot path, i.e. Observe is called much more often than Write. The
|
|
||||||
// complication of making Write lock-free isn't worth it.
|
|
||||||
h.writeMtx.Lock()
|
h.writeMtx.Lock()
|
||||||
defer h.writeMtx.Unlock()
|
defer h.writeMtx.Unlock()
|
||||||
|
|
||||||
// This is a bit arcane, which is why the following spells out this if
|
// Adding 1<<63 switches the hot index (from 0 to 1 or from 1 to 0)
|
||||||
// clause in English:
|
// without touching the count bits. See the struct comments for a full
|
||||||
//
|
// description of the algorithm.
|
||||||
// If the currently-hot counts struct is #0, we atomically increment
|
n := atomic.AddUint64(&h.countAndHotIdx, 1<<63)
|
||||||
// h.countAndHotIdx by 1 so that from now on Observe will use the counts
|
// count is contained unchanged in the lower 63 bits.
|
||||||
// struct #1. Furthermore, the atomic increment gives us the new value,
|
count := n & ((1 << 63) - 1)
|
||||||
// which, in its most significant 63 bits, tells us the count of
|
// The most significant bit tells us which counts is hot. The complement
|
||||||
// observations done so far up to and including currently ongoing
|
// is thus the cold one.
|
||||||
// observations still using the counts struct just changed from hot to
|
hotCounts := h.counts[n>>63]
|
||||||
// cold. To have a normal uint64 for the count, we bitshift by 1 and
|
coldCounts := h.counts[(^n)>>63]
|
||||||
// save the result in count. We also set h.hotIdx to 1 for the next
|
|
||||||
// Write call, and we will refer to counts #1 as hotCounts and to counts
|
|
||||||
// #0 as coldCounts.
|
|
||||||
//
|
|
||||||
// If the currently-hot counts struct is #1, we do the corresponding
|
|
||||||
// things the other way round. We have to _decrement_ h.countAndHotIdx
|
|
||||||
// (which is a bit arcane in itself, as we have to express -1 with an
|
|
||||||
// unsigned int...).
|
|
||||||
if h.hotIdx == 0 {
|
|
||||||
count = atomic.AddUint64(&h.countAndHotIdx, 1) >> 1
|
|
||||||
h.hotIdx = 1
|
|
||||||
hotCounts = h.counts[1]
|
|
||||||
coldCounts = h.counts[0]
|
|
||||||
} else {
|
|
||||||
count = atomic.AddUint64(&h.countAndHotIdx, ^uint64(0)) >> 1 // Decrement.
|
|
||||||
h.hotIdx = 0
|
|
||||||
hotCounts = h.counts[0]
|
|
||||||
coldCounts = h.counts[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we have to wait for the now-declared-cold counts to actually cool
|
// Await cooldown.
|
||||||
// down, i.e. wait for all observations still using it to finish. That's
|
for count != atomic.LoadUint64(&coldCounts.count) {
|
||||||
// the case once the count in the cold counts struct is the same as the
|
|
||||||
// one atomically retrieved from the upper 63bits of h.countAndHotIdx.
|
|
||||||
for {
|
|
||||||
if count == atomic.LoadUint64(&coldCounts.count) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
runtime.Gosched() // Let observations get work done.
|
runtime.Gosched() // Let observations get work done.
|
||||||
}
|
}
|
||||||
|
|
||||||
his.SampleCount = proto.Uint64(count)
|
his := &dto.Histogram{
|
||||||
his.SampleSum = proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits)))
|
Bucket: make([]*dto.Bucket, len(h.upperBounds)),
|
||||||
|
SampleCount: proto.Uint64(count),
|
||||||
|
SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))),
|
||||||
|
}
|
||||||
var cumCount uint64
|
var cumCount uint64
|
||||||
for i, upperBound := range h.upperBounds {
|
for i, upperBound := range h.upperBounds {
|
||||||
cumCount += atomic.LoadUint64(&coldCounts.buckets[i])
|
cumCount += atomic.LoadUint64(&coldCounts.buckets[i])
|
||||||
buckets[i] = &dto.Bucket{
|
his.Bucket[i] = &dto.Bucket{
|
||||||
CumulativeCount: proto.Uint64(cumCount),
|
CumulativeCount: proto.Uint64(cumCount),
|
||||||
UpperBound: proto.Float64(upperBound),
|
UpperBound: proto.Float64(upperBound),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
his.Bucket = buckets
|
|
||||||
out.Histogram = his
|
out.Histogram = his
|
||||||
out.Label = h.labelPairs
|
out.Label = h.labelPairs
|
||||||
|
|
||||||
|
504
vendor/github.com/prometheus/client_golang/prometheus/http.go
generated
vendored
504
vendor/github.com/prometheus/client_golang/prometheus/http.go
generated
vendored
@ -1,504 +0,0 @@
|
|||||||
// Copyright 2014 The Prometheus Authors
|
|
||||||
// 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 prometheus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"compress/gzip"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/prometheus/common/expfmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO(beorn7): Remove this whole file. It is a partial mirror of
|
|
||||||
// promhttp/http.go (to avoid circular import chains) where everything HTTP
|
|
||||||
// related should live. The functions here are just for avoiding
|
|
||||||
// breakage. Everything is deprecated.
|
|
||||||
|
|
||||||
const (
|
|
||||||
contentTypeHeader = "Content-Type"
|
|
||||||
contentLengthHeader = "Content-Length"
|
|
||||||
contentEncodingHeader = "Content-Encoding"
|
|
||||||
acceptEncodingHeader = "Accept-Encoding"
|
|
||||||
)
|
|
||||||
|
|
||||||
var gzipPool = sync.Pool{
|
|
||||||
New: func() interface{} {
|
|
||||||
return gzip.NewWriter(nil)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handler returns an HTTP handler for the DefaultGatherer. It is
|
|
||||||
// already instrumented with InstrumentHandler (using "prometheus" as handler
|
|
||||||
// name).
|
|
||||||
//
|
|
||||||
// Deprecated: Please note the issues described in the doc comment of
|
|
||||||
// InstrumentHandler. You might want to consider using promhttp.Handler instead.
|
|
||||||
func Handler() http.Handler {
|
|
||||||
return InstrumentHandler("prometheus", UninstrumentedHandler())
|
|
||||||
}
|
|
||||||
|
|
||||||
// UninstrumentedHandler returns an HTTP handler for the DefaultGatherer.
|
|
||||||
//
|
|
||||||
// Deprecated: Use promhttp.HandlerFor(DefaultGatherer, promhttp.HandlerOpts{})
|
|
||||||
// instead. See there for further documentation.
|
|
||||||
func UninstrumentedHandler() http.Handler {
|
|
||||||
return http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) {
|
|
||||||
mfs, err := DefaultGatherer.Gather()
|
|
||||||
if err != nil {
|
|
||||||
httpError(rsp, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
contentType := expfmt.Negotiate(req.Header)
|
|
||||||
header := rsp.Header()
|
|
||||||
header.Set(contentTypeHeader, string(contentType))
|
|
||||||
|
|
||||||
w := io.Writer(rsp)
|
|
||||||
if gzipAccepted(req.Header) {
|
|
||||||
header.Set(contentEncodingHeader, "gzip")
|
|
||||||
gz := gzipPool.Get().(*gzip.Writer)
|
|
||||||
defer gzipPool.Put(gz)
|
|
||||||
|
|
||||||
gz.Reset(w)
|
|
||||||
defer gz.Close()
|
|
||||||
|
|
||||||
w = gz
|
|
||||||
}
|
|
||||||
|
|
||||||
enc := expfmt.NewEncoder(w, contentType)
|
|
||||||
|
|
||||||
for _, mf := range mfs {
|
|
||||||
if err := enc.Encode(mf); err != nil {
|
|
||||||
httpError(rsp, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var instLabels = []string{"method", "code"}
|
|
||||||
|
|
||||||
type nower interface {
|
|
||||||
Now() time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type nowFunc func() time.Time
|
|
||||||
|
|
||||||
func (n nowFunc) Now() time.Time {
|
|
||||||
return n()
|
|
||||||
}
|
|
||||||
|
|
||||||
var now nower = nowFunc(func() time.Time {
|
|
||||||
return time.Now()
|
|
||||||
})
|
|
||||||
|
|
||||||
// InstrumentHandler wraps the given HTTP handler for instrumentation. It
|
|
||||||
// registers four metric collectors (if not already done) and reports HTTP
|
|
||||||
// metrics to the (newly or already) registered collectors: http_requests_total
|
|
||||||
// (CounterVec), http_request_duration_microseconds (Summary),
|
|
||||||
// http_request_size_bytes (Summary), http_response_size_bytes (Summary). Each
|
|
||||||
// has a constant label named "handler" with the provided handlerName as
|
|
||||||
// value. http_requests_total is a metric vector partitioned by HTTP method
|
|
||||||
// (label name "method") and HTTP status code (label name "code").
|
|
||||||
//
|
|
||||||
// Deprecated: InstrumentHandler has several issues. Use the tooling provided in
|
|
||||||
// package promhttp instead. The issues are the following: (1) It uses Summaries
|
|
||||||
// rather than Histograms. Summaries are not useful if aggregation across
|
|
||||||
// multiple instances is required. (2) It uses microseconds as unit, which is
|
|
||||||
// deprecated and should be replaced by seconds. (3) The size of the request is
|
|
||||||
// calculated in a separate goroutine. Since this calculator requires access to
|
|
||||||
// the request header, it creates a race with any writes to the header performed
|
|
||||||
// during request handling. httputil.ReverseProxy is a prominent example for a
|
|
||||||
// handler performing such writes. (4) It has additional issues with HTTP/2, cf.
|
|
||||||
// https://github.com/prometheus/client_golang/issues/272.
|
|
||||||
func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFunc {
|
|
||||||
return InstrumentHandlerFunc(handlerName, handler.ServeHTTP)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstrumentHandlerFunc wraps the given function for instrumentation. It
|
|
||||||
// otherwise works in the same way as InstrumentHandler (and shares the same
|
|
||||||
// issues).
|
|
||||||
//
|
|
||||||
// Deprecated: InstrumentHandlerFunc is deprecated for the same reasons as
|
|
||||||
// InstrumentHandler is. Use the tooling provided in package promhttp instead.
|
|
||||||
func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
|
|
||||||
return InstrumentHandlerFuncWithOpts(
|
|
||||||
SummaryOpts{
|
|
||||||
Subsystem: "http",
|
|
||||||
ConstLabels: Labels{"handler": handlerName},
|
|
||||||
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
|
||||||
},
|
|
||||||
handlerFunc,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstrumentHandlerWithOpts works like InstrumentHandler (and shares the same
|
|
||||||
// issues) but provides more flexibility (at the cost of a more complex call
|
|
||||||
// syntax). As InstrumentHandler, this function registers four metric
|
|
||||||
// collectors, but it uses the provided SummaryOpts to create them. However, the
|
|
||||||
// fields "Name" and "Help" in the SummaryOpts are ignored. "Name" is replaced
|
|
||||||
// by "requests_total", "request_duration_microseconds", "request_size_bytes",
|
|
||||||
// and "response_size_bytes", respectively. "Help" is replaced by an appropriate
|
|
||||||
// help string. The names of the variable labels of the http_requests_total
|
|
||||||
// CounterVec are "method" (get, post, etc.), and "code" (HTTP status code).
|
|
||||||
//
|
|
||||||
// If InstrumentHandlerWithOpts is called as follows, it mimics exactly the
|
|
||||||
// behavior of InstrumentHandler:
|
|
||||||
//
|
|
||||||
// prometheus.InstrumentHandlerWithOpts(
|
|
||||||
// prometheus.SummaryOpts{
|
|
||||||
// Subsystem: "http",
|
|
||||||
// ConstLabels: prometheus.Labels{"handler": handlerName},
|
|
||||||
// },
|
|
||||||
// handler,
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// Technical detail: "requests_total" is a CounterVec, not a SummaryVec, so it
|
|
||||||
// cannot use SummaryOpts. Instead, a CounterOpts struct is created internally,
|
|
||||||
// and all its fields are set to the equally named fields in the provided
|
|
||||||
// SummaryOpts.
|
|
||||||
//
|
|
||||||
// Deprecated: InstrumentHandlerWithOpts is deprecated for the same reasons as
|
|
||||||
// InstrumentHandler is. Use the tooling provided in package promhttp instead.
|
|
||||||
func InstrumentHandlerWithOpts(opts SummaryOpts, handler http.Handler) http.HandlerFunc {
|
|
||||||
return InstrumentHandlerFuncWithOpts(opts, handler.ServeHTTP)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstrumentHandlerFuncWithOpts works like InstrumentHandlerFunc (and shares
|
|
||||||
// the same issues) but provides more flexibility (at the cost of a more complex
|
|
||||||
// call syntax). See InstrumentHandlerWithOpts for details how the provided
|
|
||||||
// SummaryOpts are used.
|
|
||||||
//
|
|
||||||
// Deprecated: InstrumentHandlerFuncWithOpts is deprecated for the same reasons
|
|
||||||
// as InstrumentHandler is. Use the tooling provided in package promhttp instead.
|
|
||||||
func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
|
|
||||||
reqCnt := NewCounterVec(
|
|
||||||
CounterOpts{
|
|
||||||
Namespace: opts.Namespace,
|
|
||||||
Subsystem: opts.Subsystem,
|
|
||||||
Name: "requests_total",
|
|
||||||
Help: "Total number of HTTP requests made.",
|
|
||||||
ConstLabels: opts.ConstLabels,
|
|
||||||
},
|
|
||||||
instLabels,
|
|
||||||
)
|
|
||||||
if err := Register(reqCnt); err != nil {
|
|
||||||
if are, ok := err.(AlreadyRegisteredError); ok {
|
|
||||||
reqCnt = are.ExistingCollector.(*CounterVec)
|
|
||||||
} else {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
opts.Name = "request_duration_microseconds"
|
|
||||||
opts.Help = "The HTTP request latencies in microseconds."
|
|
||||||
reqDur := NewSummary(opts)
|
|
||||||
if err := Register(reqDur); err != nil {
|
|
||||||
if are, ok := err.(AlreadyRegisteredError); ok {
|
|
||||||
reqDur = are.ExistingCollector.(Summary)
|
|
||||||
} else {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
opts.Name = "request_size_bytes"
|
|
||||||
opts.Help = "The HTTP request sizes in bytes."
|
|
||||||
reqSz := NewSummary(opts)
|
|
||||||
if err := Register(reqSz); err != nil {
|
|
||||||
if are, ok := err.(AlreadyRegisteredError); ok {
|
|
||||||
reqSz = are.ExistingCollector.(Summary)
|
|
||||||
} else {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
opts.Name = "response_size_bytes"
|
|
||||||
opts.Help = "The HTTP response sizes in bytes."
|
|
||||||
resSz := NewSummary(opts)
|
|
||||||
if err := Register(resSz); err != nil {
|
|
||||||
if are, ok := err.(AlreadyRegisteredError); ok {
|
|
||||||
resSz = are.ExistingCollector.(Summary)
|
|
||||||
} else {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
now := time.Now()
|
|
||||||
|
|
||||||
delegate := &responseWriterDelegator{ResponseWriter: w}
|
|
||||||
out := computeApproximateRequestSize(r)
|
|
||||||
|
|
||||||
_, cn := w.(http.CloseNotifier)
|
|
||||||
_, fl := w.(http.Flusher)
|
|
||||||
_, hj := w.(http.Hijacker)
|
|
||||||
_, rf := w.(io.ReaderFrom)
|
|
||||||
var rw http.ResponseWriter
|
|
||||||
if cn && fl && hj && rf {
|
|
||||||
rw = &fancyResponseWriterDelegator{delegate}
|
|
||||||
} else {
|
|
||||||
rw = delegate
|
|
||||||
}
|
|
||||||
handlerFunc(rw, r)
|
|
||||||
|
|
||||||
elapsed := float64(time.Since(now)) / float64(time.Microsecond)
|
|
||||||
|
|
||||||
method := sanitizeMethod(r.Method)
|
|
||||||
code := sanitizeCode(delegate.status)
|
|
||||||
reqCnt.WithLabelValues(method, code).Inc()
|
|
||||||
reqDur.Observe(elapsed)
|
|
||||||
resSz.Observe(float64(delegate.written))
|
|
||||||
reqSz.Observe(float64(<-out))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func computeApproximateRequestSize(r *http.Request) <-chan int {
|
|
||||||
// Get URL length in current goroutine for avoiding a race condition.
|
|
||||||
// HandlerFunc that runs in parallel may modify the URL.
|
|
||||||
s := 0
|
|
||||||
if r.URL != nil {
|
|
||||||
s += len(r.URL.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
out := make(chan int, 1)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
s += len(r.Method)
|
|
||||||
s += len(r.Proto)
|
|
||||||
for name, values := range r.Header {
|
|
||||||
s += len(name)
|
|
||||||
for _, value := range values {
|
|
||||||
s += len(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s += len(r.Host)
|
|
||||||
|
|
||||||
// N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
|
|
||||||
|
|
||||||
if r.ContentLength != -1 {
|
|
||||||
s += int(r.ContentLength)
|
|
||||||
}
|
|
||||||
out <- s
|
|
||||||
close(out)
|
|
||||||
}()
|
|
||||||
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
type responseWriterDelegator struct {
|
|
||||||
http.ResponseWriter
|
|
||||||
|
|
||||||
status int
|
|
||||||
written int64
|
|
||||||
wroteHeader bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *responseWriterDelegator) WriteHeader(code int) {
|
|
||||||
r.status = code
|
|
||||||
r.wroteHeader = true
|
|
||||||
r.ResponseWriter.WriteHeader(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *responseWriterDelegator) Write(b []byte) (int, error) {
|
|
||||||
if !r.wroteHeader {
|
|
||||||
r.WriteHeader(http.StatusOK)
|
|
||||||
}
|
|
||||||
n, err := r.ResponseWriter.Write(b)
|
|
||||||
r.written += int64(n)
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
type fancyResponseWriterDelegator struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fancyResponseWriterDelegator) CloseNotify() <-chan bool {
|
|
||||||
return f.ResponseWriter.(http.CloseNotifier).CloseNotify()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fancyResponseWriterDelegator) Flush() {
|
|
||||||
f.ResponseWriter.(http.Flusher).Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fancyResponseWriterDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
|
||||||
return f.ResponseWriter.(http.Hijacker).Hijack()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fancyResponseWriterDelegator) ReadFrom(r io.Reader) (int64, error) {
|
|
||||||
if !f.wroteHeader {
|
|
||||||
f.WriteHeader(http.StatusOK)
|
|
||||||
}
|
|
||||||
n, err := f.ResponseWriter.(io.ReaderFrom).ReadFrom(r)
|
|
||||||
f.written += n
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func sanitizeMethod(m string) string {
|
|
||||||
switch m {
|
|
||||||
case "GET", "get":
|
|
||||||
return "get"
|
|
||||||
case "PUT", "put":
|
|
||||||
return "put"
|
|
||||||
case "HEAD", "head":
|
|
||||||
return "head"
|
|
||||||
case "POST", "post":
|
|
||||||
return "post"
|
|
||||||
case "DELETE", "delete":
|
|
||||||
return "delete"
|
|
||||||
case "CONNECT", "connect":
|
|
||||||
return "connect"
|
|
||||||
case "OPTIONS", "options":
|
|
||||||
return "options"
|
|
||||||
case "NOTIFY", "notify":
|
|
||||||
return "notify"
|
|
||||||
default:
|
|
||||||
return strings.ToLower(m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sanitizeCode(s int) string {
|
|
||||||
switch s {
|
|
||||||
case 100:
|
|
||||||
return "100"
|
|
||||||
case 101:
|
|
||||||
return "101"
|
|
||||||
|
|
||||||
case 200:
|
|
||||||
return "200"
|
|
||||||
case 201:
|
|
||||||
return "201"
|
|
||||||
case 202:
|
|
||||||
return "202"
|
|
||||||
case 203:
|
|
||||||
return "203"
|
|
||||||
case 204:
|
|
||||||
return "204"
|
|
||||||
case 205:
|
|
||||||
return "205"
|
|
||||||
case 206:
|
|
||||||
return "206"
|
|
||||||
|
|
||||||
case 300:
|
|
||||||
return "300"
|
|
||||||
case 301:
|
|
||||||
return "301"
|
|
||||||
case 302:
|
|
||||||
return "302"
|
|
||||||
case 304:
|
|
||||||
return "304"
|
|
||||||
case 305:
|
|
||||||
return "305"
|
|
||||||
case 307:
|
|
||||||
return "307"
|
|
||||||
|
|
||||||
case 400:
|
|
||||||
return "400"
|
|
||||||
case 401:
|
|
||||||
return "401"
|
|
||||||
case 402:
|
|
||||||
return "402"
|
|
||||||
case 403:
|
|
||||||
return "403"
|
|
||||||
case 404:
|
|
||||||
return "404"
|
|
||||||
case 405:
|
|
||||||
return "405"
|
|
||||||
case 406:
|
|
||||||
return "406"
|
|
||||||
case 407:
|
|
||||||
return "407"
|
|
||||||
case 408:
|
|
||||||
return "408"
|
|
||||||
case 409:
|
|
||||||
return "409"
|
|
||||||
case 410:
|
|
||||||
return "410"
|
|
||||||
case 411:
|
|
||||||
return "411"
|
|
||||||
case 412:
|
|
||||||
return "412"
|
|
||||||
case 413:
|
|
||||||
return "413"
|
|
||||||
case 414:
|
|
||||||
return "414"
|
|
||||||
case 415:
|
|
||||||
return "415"
|
|
||||||
case 416:
|
|
||||||
return "416"
|
|
||||||
case 417:
|
|
||||||
return "417"
|
|
||||||
case 418:
|
|
||||||
return "418"
|
|
||||||
|
|
||||||
case 500:
|
|
||||||
return "500"
|
|
||||||
case 501:
|
|
||||||
return "501"
|
|
||||||
case 502:
|
|
||||||
return "502"
|
|
||||||
case 503:
|
|
||||||
return "503"
|
|
||||||
case 504:
|
|
||||||
return "504"
|
|
||||||
case 505:
|
|
||||||
return "505"
|
|
||||||
|
|
||||||
case 428:
|
|
||||||
return "428"
|
|
||||||
case 429:
|
|
||||||
return "429"
|
|
||||||
case 431:
|
|
||||||
return "431"
|
|
||||||
case 511:
|
|
||||||
return "511"
|
|
||||||
|
|
||||||
default:
|
|
||||||
return strconv.Itoa(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// gzipAccepted returns whether the client will accept gzip-encoded content.
|
|
||||||
func gzipAccepted(header http.Header) bool {
|
|
||||||
a := header.Get(acceptEncodingHeader)
|
|
||||||
parts := strings.Split(a, ",")
|
|
||||||
for _, part := range parts {
|
|
||||||
part = strings.TrimSpace(part)
|
|
||||||
if part == "gzip" || strings.HasPrefix(part, "gzip;") {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// httpError removes any content-encoding header and then calls http.Error with
|
|
||||||
// the provided error and http.StatusInternalServerErrer. Error contents is
|
|
||||||
// supposed to be uncompressed plain text. However, same as with a plain
|
|
||||||
// http.Error, any header settings will be void if the header has already been
|
|
||||||
// sent. The error message will still be written to the writer, but it will
|
|
||||||
// probably be of limited use.
|
|
||||||
func httpError(rsp http.ResponseWriter, err error) {
|
|
||||||
rsp.Header().Del(contentEncodingHeader)
|
|
||||||
http.Error(
|
|
||||||
rsp,
|
|
||||||
"An error has occurred while serving metrics:\n\n"+err.Error(),
|
|
||||||
http.StatusInternalServerError,
|
|
||||||
)
|
|
||||||
}
|
|
61
vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
generated
vendored
61
vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
generated
vendored
@ -16,8 +16,6 @@ package prometheus
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/prometheus/procfs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type processCollector struct {
|
type processCollector struct {
|
||||||
@ -59,20 +57,9 @@ type ProcessCollectorOpts struct {
|
|||||||
// collector for the current process with an empty namespace string and no error
|
// collector for the current process with an empty namespace string and no error
|
||||||
// reporting.
|
// reporting.
|
||||||
//
|
//
|
||||||
// Currently, the collector depends on a Linux-style proc filesystem and
|
// The collector only works on operating systems with a Linux-style proc
|
||||||
// therefore only exports metrics for Linux.
|
// filesystem and on Microsoft Windows. On other operating systems, it will not
|
||||||
//
|
// collect any metrics.
|
||||||
// Note: An older version of this function had the following signature:
|
|
||||||
//
|
|
||||||
// NewProcessCollector(pid int, namespace string) Collector
|
|
||||||
//
|
|
||||||
// Most commonly, it was called as
|
|
||||||
//
|
|
||||||
// NewProcessCollector(os.Getpid(), "")
|
|
||||||
//
|
|
||||||
// The following call of the current version is equivalent to the above:
|
|
||||||
//
|
|
||||||
// NewProcessCollector(ProcessCollectorOpts{})
|
|
||||||
func NewProcessCollector(opts ProcessCollectorOpts) Collector {
|
func NewProcessCollector(opts ProcessCollectorOpts) Collector {
|
||||||
ns := ""
|
ns := ""
|
||||||
if len(opts.Namespace) > 0 {
|
if len(opts.Namespace) > 0 {
|
||||||
@ -126,7 +113,7 @@ func NewProcessCollector(opts ProcessCollectorOpts) Collector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set up process metric collection if supported by the runtime.
|
// Set up process metric collection if supported by the runtime.
|
||||||
if _, err := procfs.NewStat(); err == nil {
|
if canCollectProcess() {
|
||||||
c.collectFn = c.processCollect
|
c.collectFn = c.processCollect
|
||||||
} else {
|
} else {
|
||||||
c.collectFn = func(ch chan<- Metric) {
|
c.collectFn = func(ch chan<- Metric) {
|
||||||
@ -153,46 +140,6 @@ func (c *processCollector) Collect(ch chan<- Metric) {
|
|||||||
c.collectFn(ch)
|
c.collectFn(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *processCollector) processCollect(ch chan<- Metric) {
|
|
||||||
pid, err := c.pidFn()
|
|
||||||
if err != nil {
|
|
||||||
c.reportError(ch, nil, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := procfs.NewProc(pid)
|
|
||||||
if err != nil {
|
|
||||||
c.reportError(ch, nil, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if stat, err := p.NewStat(); err == nil {
|
|
||||||
ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
|
|
||||||
ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
|
|
||||||
ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
|
|
||||||
if startTime, err := stat.StartTime(); err == nil {
|
|
||||||
ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
|
|
||||||
} else {
|
|
||||||
c.reportError(ch, c.startTime, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
c.reportError(ch, nil, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if fds, err := p.FileDescriptorsLen(); err == nil {
|
|
||||||
ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
|
|
||||||
} else {
|
|
||||||
c.reportError(ch, c.openFDs, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if limits, err := p.NewLimits(); err == nil {
|
|
||||||
ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
|
|
||||||
ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(limits.AddressSpace))
|
|
||||||
} else {
|
|
||||||
c.reportError(ch, nil, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) {
|
func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) {
|
||||||
if !c.reportErrors {
|
if !c.reportErrors {
|
||||||
return
|
return
|
||||||
|
65
vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
generated
vendored
Normal file
65
vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Copyright 2019 The Prometheus Authors
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package prometheus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/prometheus/procfs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func canCollectProcess() bool {
|
||||||
|
_, err := procfs.NewDefaultFS()
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *processCollector) processCollect(ch chan<- Metric) {
|
||||||
|
pid, err := c.pidFn()
|
||||||
|
if err != nil {
|
||||||
|
c.reportError(ch, nil, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p, err := procfs.NewProc(pid)
|
||||||
|
if err != nil {
|
||||||
|
c.reportError(ch, nil, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if stat, err := p.Stat(); err == nil {
|
||||||
|
ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
|
||||||
|
ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
|
||||||
|
ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
|
||||||
|
if startTime, err := stat.StartTime(); err == nil {
|
||||||
|
ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
|
||||||
|
} else {
|
||||||
|
c.reportError(ch, c.startTime, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.reportError(ch, nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if fds, err := p.FileDescriptorsLen(); err == nil {
|
||||||
|
ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
|
||||||
|
} else {
|
||||||
|
c.reportError(ch, c.openFDs, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if limits, err := p.Limits(); err == nil {
|
||||||
|
ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
|
||||||
|
ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(limits.AddressSpace))
|
||||||
|
} else {
|
||||||
|
c.reportError(ch, nil, err)
|
||||||
|
}
|
||||||
|
}
|
112
vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go
generated
vendored
Normal file
112
vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go
generated
vendored
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// Copyright 2019 The Prometheus Authors
|
||||||
|
// 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 prometheus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
func canCollectProcess() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
modpsapi = syscall.NewLazyDLL("psapi.dll")
|
||||||
|
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
|
||||||
|
procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
|
||||||
|
procGetProcessHandleCount = modkernel32.NewProc("GetProcessHandleCount")
|
||||||
|
)
|
||||||
|
|
||||||
|
type processMemoryCounters struct {
|
||||||
|
// https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-_process_memory_counters_ex
|
||||||
|
_ uint32
|
||||||
|
PageFaultCount uint32
|
||||||
|
PeakWorkingSetSize uint64
|
||||||
|
WorkingSetSize uint64
|
||||||
|
QuotaPeakPagedPoolUsage uint64
|
||||||
|
QuotaPagedPoolUsage uint64
|
||||||
|
QuotaPeakNonPagedPoolUsage uint64
|
||||||
|
QuotaNonPagedPoolUsage uint64
|
||||||
|
PagefileUsage uint64
|
||||||
|
PeakPagefileUsage uint64
|
||||||
|
PrivateUsage uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProcessMemoryInfo(handle windows.Handle) (processMemoryCounters, error) {
|
||||||
|
mem := processMemoryCounters{}
|
||||||
|
r1, _, err := procGetProcessMemoryInfo.Call(
|
||||||
|
uintptr(handle),
|
||||||
|
uintptr(unsafe.Pointer(&mem)),
|
||||||
|
uintptr(unsafe.Sizeof(mem)),
|
||||||
|
)
|
||||||
|
if r1 != 1 {
|
||||||
|
return mem, err
|
||||||
|
} else {
|
||||||
|
return mem, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProcessHandleCount(handle windows.Handle) (uint32, error) {
|
||||||
|
var count uint32
|
||||||
|
r1, _, err := procGetProcessHandleCount.Call(
|
||||||
|
uintptr(handle),
|
||||||
|
uintptr(unsafe.Pointer(&count)),
|
||||||
|
)
|
||||||
|
if r1 != 1 {
|
||||||
|
return 0, err
|
||||||
|
} else {
|
||||||
|
return count, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *processCollector) processCollect(ch chan<- Metric) {
|
||||||
|
h, err := windows.GetCurrentProcess()
|
||||||
|
if err != nil {
|
||||||
|
c.reportError(ch, nil, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var startTime, exitTime, kernelTime, userTime windows.Filetime
|
||||||
|
err = windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime)
|
||||||
|
if err != nil {
|
||||||
|
c.reportError(ch, nil, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ch <- MustNewConstMetric(c.startTime, GaugeValue, float64(startTime.Nanoseconds()/1e9))
|
||||||
|
ch <- MustNewConstMetric(c.cpuTotal, CounterValue, fileTimeToSeconds(kernelTime)+fileTimeToSeconds(userTime))
|
||||||
|
|
||||||
|
mem, err := getProcessMemoryInfo(h)
|
||||||
|
if err != nil {
|
||||||
|
c.reportError(ch, nil, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(mem.PrivateUsage))
|
||||||
|
ch <- MustNewConstMetric(c.rss, GaugeValue, float64(mem.WorkingSetSize))
|
||||||
|
|
||||||
|
handles, err := getProcessHandleCount(h)
|
||||||
|
if err != nil {
|
||||||
|
c.reportError(ch, nil, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(handles))
|
||||||
|
ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(16*1024*1024)) // Windows has a hard-coded max limit, not per-process.
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileTimeToSeconds(ft windows.Filetime) float64 {
|
||||||
|
return float64(uint64(ft.HighDateTime)<<32+uint64(ft.LowDateTime)) / 1e7
|
||||||
|
}
|
160
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
generated
vendored
160
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
generated
vendored
@ -38,7 +38,6 @@ type delegator interface {
|
|||||||
type responseWriterDelegator struct {
|
type responseWriterDelegator struct {
|
||||||
http.ResponseWriter
|
http.ResponseWriter
|
||||||
|
|
||||||
handler, method string
|
|
||||||
status int
|
status int
|
||||||
written int64
|
written int64
|
||||||
wroteHeader bool
|
wroteHeader bool
|
||||||
@ -75,8 +74,11 @@ type closeNotifierDelegator struct{ *responseWriterDelegator }
|
|||||||
type flusherDelegator struct{ *responseWriterDelegator }
|
type flusherDelegator struct{ *responseWriterDelegator }
|
||||||
type hijackerDelegator struct{ *responseWriterDelegator }
|
type hijackerDelegator struct{ *responseWriterDelegator }
|
||||||
type readerFromDelegator struct{ *responseWriterDelegator }
|
type readerFromDelegator struct{ *responseWriterDelegator }
|
||||||
|
type pusherDelegator struct{ *responseWriterDelegator }
|
||||||
|
|
||||||
func (d closeNotifierDelegator) CloseNotify() <-chan bool {
|
func (d closeNotifierDelegator) CloseNotify() <-chan bool {
|
||||||
|
//lint:ignore SA1019 http.CloseNotifier is deprecated but we don't want to
|
||||||
|
//remove support from client_golang yet.
|
||||||
return d.ResponseWriter.(http.CloseNotifier).CloseNotify()
|
return d.ResponseWriter.(http.CloseNotifier).CloseNotify()
|
||||||
}
|
}
|
||||||
func (d flusherDelegator) Flush() {
|
func (d flusherDelegator) Flush() {
|
||||||
@ -93,6 +95,9 @@ func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) {
|
|||||||
d.written += n
|
d.written += n
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
func (d pusherDelegator) Push(target string, opts *http.PushOptions) error {
|
||||||
|
return d.ResponseWriter.(http.Pusher).Push(target, opts)
|
||||||
|
}
|
||||||
|
|
||||||
var pickDelegator = make([]func(*responseWriterDelegator) delegator, 32)
|
var pickDelegator = make([]func(*responseWriterDelegator) delegator, 32)
|
||||||
|
|
||||||
@ -196,4 +201,157 @@ func init() {
|
|||||||
http.CloseNotifier
|
http.CloseNotifier
|
||||||
}{d, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
|
}{d, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
|
||||||
}
|
}
|
||||||
|
pickDelegator[pusher] = func(d *responseWriterDelegator) delegator { // 16
|
||||||
|
return pusherDelegator{d}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 17
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
http.CloseNotifier
|
||||||
|
}{d, pusherDelegator{d}, closeNotifierDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+flusher] = func(d *responseWriterDelegator) delegator { // 18
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
http.Flusher
|
||||||
|
}{d, pusherDelegator{d}, flusherDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 19
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
http.Flusher
|
||||||
|
http.CloseNotifier
|
||||||
|
}{d, pusherDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+hijacker] = func(d *responseWriterDelegator) delegator { // 20
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
http.Hijacker
|
||||||
|
}{d, pusherDelegator{d}, hijackerDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 21
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
http.Hijacker
|
||||||
|
http.CloseNotifier
|
||||||
|
}{d, pusherDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 22
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
http.Hijacker
|
||||||
|
http.Flusher
|
||||||
|
}{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { //23
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
http.Hijacker
|
||||||
|
http.Flusher
|
||||||
|
http.CloseNotifier
|
||||||
|
}{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+readerFrom] = func(d *responseWriterDelegator) delegator { // 24
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
io.ReaderFrom
|
||||||
|
}{d, pusherDelegator{d}, readerFromDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 25
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
io.ReaderFrom
|
||||||
|
http.CloseNotifier
|
||||||
|
}{d, pusherDelegator{d}, readerFromDelegator{d}, closeNotifierDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 26
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
io.ReaderFrom
|
||||||
|
http.Flusher
|
||||||
|
}{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 27
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
io.ReaderFrom
|
||||||
|
http.Flusher
|
||||||
|
http.CloseNotifier
|
||||||
|
}{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 28
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
io.ReaderFrom
|
||||||
|
http.Hijacker
|
||||||
|
}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 29
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
io.ReaderFrom
|
||||||
|
http.Hijacker
|
||||||
|
http.CloseNotifier
|
||||||
|
}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 30
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
io.ReaderFrom
|
||||||
|
http.Hijacker
|
||||||
|
http.Flusher
|
||||||
|
}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
|
||||||
|
}
|
||||||
|
pickDelegator[pusher+readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 31
|
||||||
|
return struct {
|
||||||
|
*responseWriterDelegator
|
||||||
|
http.Pusher
|
||||||
|
io.ReaderFrom
|
||||||
|
http.Hijacker
|
||||||
|
http.Flusher
|
||||||
|
http.CloseNotifier
|
||||||
|
}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {
|
||||||
|
d := &responseWriterDelegator{
|
||||||
|
ResponseWriter: w,
|
||||||
|
observeWriteHeader: observeWriteHeaderFunc,
|
||||||
|
}
|
||||||
|
|
||||||
|
id := 0
|
||||||
|
//lint:ignore SA1019 http.CloseNotifier is deprecated but we don't want to
|
||||||
|
//remove support from client_golang yet.
|
||||||
|
if _, ok := w.(http.CloseNotifier); ok {
|
||||||
|
id += closeNotifier
|
||||||
|
}
|
||||||
|
if _, ok := w.(http.Flusher); ok {
|
||||||
|
id += flusher
|
||||||
|
}
|
||||||
|
if _, ok := w.(http.Hijacker); ok {
|
||||||
|
id += hijacker
|
||||||
|
}
|
||||||
|
if _, ok := w.(io.ReaderFrom); ok {
|
||||||
|
id += readerFrom
|
||||||
|
}
|
||||||
|
if _, ok := w.(http.Pusher); ok {
|
||||||
|
id += pusher
|
||||||
|
}
|
||||||
|
|
||||||
|
return pickDelegator[id](d)
|
||||||
}
|
}
|
||||||
|
181
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go
generated
vendored
181
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go
generated
vendored
@ -1,181 +0,0 @@
|
|||||||
// Copyright 2017 The Prometheus Authors
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
// +build go1.8
|
|
||||||
|
|
||||||
package promhttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
type pusherDelegator struct{ *responseWriterDelegator }
|
|
||||||
|
|
||||||
func (d pusherDelegator) Push(target string, opts *http.PushOptions) error {
|
|
||||||
return d.ResponseWriter.(http.Pusher).Push(target, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
pickDelegator[pusher] = func(d *responseWriterDelegator) delegator { // 16
|
|
||||||
return pusherDelegator{d}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 17
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
http.CloseNotifier
|
|
||||||
}{d, pusherDelegator{d}, closeNotifierDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+flusher] = func(d *responseWriterDelegator) delegator { // 18
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
http.Flusher
|
|
||||||
}{d, pusherDelegator{d}, flusherDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 19
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
http.Flusher
|
|
||||||
http.CloseNotifier
|
|
||||||
}{d, pusherDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+hijacker] = func(d *responseWriterDelegator) delegator { // 20
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
http.Hijacker
|
|
||||||
}{d, pusherDelegator{d}, hijackerDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 21
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
http.Hijacker
|
|
||||||
http.CloseNotifier
|
|
||||||
}{d, pusherDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 22
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
http.Hijacker
|
|
||||||
http.Flusher
|
|
||||||
}{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { //23
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
http.Hijacker
|
|
||||||
http.Flusher
|
|
||||||
http.CloseNotifier
|
|
||||||
}{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+readerFrom] = func(d *responseWriterDelegator) delegator { // 24
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
io.ReaderFrom
|
|
||||||
}{d, pusherDelegator{d}, readerFromDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 25
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
io.ReaderFrom
|
|
||||||
http.CloseNotifier
|
|
||||||
}{d, pusherDelegator{d}, readerFromDelegator{d}, closeNotifierDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 26
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
io.ReaderFrom
|
|
||||||
http.Flusher
|
|
||||||
}{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 27
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
io.ReaderFrom
|
|
||||||
http.Flusher
|
|
||||||
http.CloseNotifier
|
|
||||||
}{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 28
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
io.ReaderFrom
|
|
||||||
http.Hijacker
|
|
||||||
}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 29
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
io.ReaderFrom
|
|
||||||
http.Hijacker
|
|
||||||
http.CloseNotifier
|
|
||||||
}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 30
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
io.ReaderFrom
|
|
||||||
http.Hijacker
|
|
||||||
http.Flusher
|
|
||||||
}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
|
|
||||||
}
|
|
||||||
pickDelegator[pusher+readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 31
|
|
||||||
return struct {
|
|
||||||
*responseWriterDelegator
|
|
||||||
http.Pusher
|
|
||||||
io.ReaderFrom
|
|
||||||
http.Hijacker
|
|
||||||
http.Flusher
|
|
||||||
http.CloseNotifier
|
|
||||||
}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {
|
|
||||||
d := &responseWriterDelegator{
|
|
||||||
ResponseWriter: w,
|
|
||||||
observeWriteHeader: observeWriteHeaderFunc,
|
|
||||||
}
|
|
||||||
|
|
||||||
id := 0
|
|
||||||
if _, ok := w.(http.CloseNotifier); ok {
|
|
||||||
id += closeNotifier
|
|
||||||
}
|
|
||||||
if _, ok := w.(http.Flusher); ok {
|
|
||||||
id += flusher
|
|
||||||
}
|
|
||||||
if _, ok := w.(http.Hijacker); ok {
|
|
||||||
id += hijacker
|
|
||||||
}
|
|
||||||
if _, ok := w.(io.ReaderFrom); ok {
|
|
||||||
id += readerFrom
|
|
||||||
}
|
|
||||||
if _, ok := w.(http.Pusher); ok {
|
|
||||||
id += pusher
|
|
||||||
}
|
|
||||||
|
|
||||||
return pickDelegator[id](d)
|
|
||||||
}
|
|
44
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_pre_1_8.go
generated
vendored
44
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_pre_1_8.go
generated
vendored
@ -1,44 +0,0 @@
|
|||||||
// Copyright 2017 The Prometheus Authors
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
// +build !go1.8
|
|
||||||
|
|
||||||
package promhttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {
|
|
||||||
d := &responseWriterDelegator{
|
|
||||||
ResponseWriter: w,
|
|
||||||
observeWriteHeader: observeWriteHeaderFunc,
|
|
||||||
}
|
|
||||||
|
|
||||||
id := 0
|
|
||||||
if _, ok := w.(http.CloseNotifier); ok {
|
|
||||||
id += closeNotifier
|
|
||||||
}
|
|
||||||
if _, ok := w.(http.Flusher); ok {
|
|
||||||
id += flusher
|
|
||||||
}
|
|
||||||
if _, ok := w.(http.Hijacker); ok {
|
|
||||||
id += hijacker
|
|
||||||
}
|
|
||||||
if _, ok := w.(io.ReaderFrom); ok {
|
|
||||||
id += readerFrom
|
|
||||||
}
|
|
||||||
|
|
||||||
return pickDelegator[id](d)
|
|
||||||
}
|
|
48
vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
generated
vendored
48
vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
generated
vendored
@ -47,7 +47,6 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
contentTypeHeader = "Content-Type"
|
contentTypeHeader = "Content-Type"
|
||||||
contentLengthHeader = "Content-Length"
|
|
||||||
contentEncodingHeader = "Content-Encoding"
|
contentEncodingHeader = "Content-Encoding"
|
||||||
acceptEncodingHeader = "Accept-Encoding"
|
acceptEncodingHeader = "Accept-Encoding"
|
||||||
)
|
)
|
||||||
@ -85,10 +84,32 @@ func Handler() http.Handler {
|
|||||||
// instrumentation. Use the InstrumentMetricHandler function to apply the same
|
// instrumentation. Use the InstrumentMetricHandler function to apply the same
|
||||||
// kind of instrumentation as it is used by the Handler function.
|
// kind of instrumentation as it is used by the Handler function.
|
||||||
func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
|
func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
|
||||||
var inFlightSem chan struct{}
|
var (
|
||||||
|
inFlightSem chan struct{}
|
||||||
|
errCnt = prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Name: "promhttp_metric_handler_errors_total",
|
||||||
|
Help: "Total number of internal errors encountered by the promhttp metric handler.",
|
||||||
|
},
|
||||||
|
[]string{"cause"},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if opts.MaxRequestsInFlight > 0 {
|
if opts.MaxRequestsInFlight > 0 {
|
||||||
inFlightSem = make(chan struct{}, opts.MaxRequestsInFlight)
|
inFlightSem = make(chan struct{}, opts.MaxRequestsInFlight)
|
||||||
}
|
}
|
||||||
|
if opts.Registry != nil {
|
||||||
|
// Initialize all possibilites that can occur below.
|
||||||
|
errCnt.WithLabelValues("gathering")
|
||||||
|
errCnt.WithLabelValues("encoding")
|
||||||
|
if err := opts.Registry.Register(errCnt); err != nil {
|
||||||
|
if are, ok := err.(prometheus.AlreadyRegisteredError); ok {
|
||||||
|
errCnt = are.ExistingCollector.(*prometheus.CounterVec)
|
||||||
|
} else {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
h := http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) {
|
h := http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) {
|
||||||
if inFlightSem != nil {
|
if inFlightSem != nil {
|
||||||
@ -107,6 +128,7 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
|
|||||||
if opts.ErrorLog != nil {
|
if opts.ErrorLog != nil {
|
||||||
opts.ErrorLog.Println("error gathering metrics:", err)
|
opts.ErrorLog.Println("error gathering metrics:", err)
|
||||||
}
|
}
|
||||||
|
errCnt.WithLabelValues("gathering").Inc()
|
||||||
switch opts.ErrorHandling {
|
switch opts.ErrorHandling {
|
||||||
case PanicOnError:
|
case PanicOnError:
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -147,6 +169,7 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
|
|||||||
if opts.ErrorLog != nil {
|
if opts.ErrorLog != nil {
|
||||||
opts.ErrorLog.Println("error encoding and sending metric family:", err)
|
opts.ErrorLog.Println("error encoding and sending metric family:", err)
|
||||||
}
|
}
|
||||||
|
errCnt.WithLabelValues("encoding").Inc()
|
||||||
switch opts.ErrorHandling {
|
switch opts.ErrorHandling {
|
||||||
case PanicOnError:
|
case PanicOnError:
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -237,9 +260,12 @@ const (
|
|||||||
// Ignore errors and try to serve as many metrics as possible. However,
|
// Ignore errors and try to serve as many metrics as possible. However,
|
||||||
// if no metrics can be served, serve an HTTP status code 500 and the
|
// if no metrics can be served, serve an HTTP status code 500 and the
|
||||||
// last error message in the body. Only use this in deliberate "best
|
// last error message in the body. Only use this in deliberate "best
|
||||||
// effort" metrics collection scenarios. It is recommended to at least
|
// effort" metrics collection scenarios. In this case, it is highly
|
||||||
// log errors (by providing an ErrorLog in HandlerOpts) to not mask
|
// recommended to provide other means of detecting errors: By setting an
|
||||||
// errors completely.
|
// ErrorLog in HandlerOpts, the errors are logged. By providing a
|
||||||
|
// Registry in HandlerOpts, the exposed metrics include an error counter
|
||||||
|
// "promhttp_metric_handler_errors_total", which can be used for
|
||||||
|
// alerts.
|
||||||
ContinueOnError
|
ContinueOnError
|
||||||
// Panic upon the first error encountered (useful for "crash only" apps).
|
// Panic upon the first error encountered (useful for "crash only" apps).
|
||||||
PanicOnError
|
PanicOnError
|
||||||
@ -262,6 +288,18 @@ type HandlerOpts struct {
|
|||||||
// logged regardless of the configured ErrorHandling provided ErrorLog
|
// logged regardless of the configured ErrorHandling provided ErrorLog
|
||||||
// is not nil.
|
// is not nil.
|
||||||
ErrorHandling HandlerErrorHandling
|
ErrorHandling HandlerErrorHandling
|
||||||
|
// If Registry is not nil, it is used to register a metric
|
||||||
|
// "promhttp_metric_handler_errors_total", partitioned by "cause". A
|
||||||
|
// failed registration causes a panic. Note that this error counter is
|
||||||
|
// different from the instrumentation you get from the various
|
||||||
|
// InstrumentHandler... helpers. It counts errors that don't necessarily
|
||||||
|
// result in a non-2xx HTTP status code. There are two typical cases:
|
||||||
|
// (1) Encoding errors that only happen after streaming of the HTTP body
|
||||||
|
// has already started (and the status code 200 has been sent). This
|
||||||
|
// should only happen with custom collectors. (2) Collection errors with
|
||||||
|
// no effect on the HTTP status code because ErrorHandling is set to
|
||||||
|
// ContinueOnError.
|
||||||
|
Registry prometheus.Registerer
|
||||||
// If DisableCompression is true, the handler will never compress the
|
// If DisableCompression is true, the handler will never compress the
|
||||||
// response, even if requested by the client.
|
// response, even if requested by the client.
|
||||||
DisableCompression bool
|
DisableCompression bool
|
||||||
|
122
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
generated
vendored
122
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
generated
vendored
@ -14,7 +14,9 @@
|
|||||||
package promhttp
|
package promhttp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httptrace"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
@ -95,3 +97,123 @@ func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundT
|
|||||||
return resp, err
|
return resp, err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InstrumentTrace is used to offer flexibility in instrumenting the available
|
||||||
|
// httptrace.ClientTrace hook functions. Each function is passed a float64
|
||||||
|
// representing the time in seconds since the start of the http request. A user
|
||||||
|
// may choose to use separately buckets Histograms, or implement custom
|
||||||
|
// instance labels on a per function basis.
|
||||||
|
type InstrumentTrace struct {
|
||||||
|
GotConn func(float64)
|
||||||
|
PutIdleConn func(float64)
|
||||||
|
GotFirstResponseByte func(float64)
|
||||||
|
Got100Continue func(float64)
|
||||||
|
DNSStart func(float64)
|
||||||
|
DNSDone func(float64)
|
||||||
|
ConnectStart func(float64)
|
||||||
|
ConnectDone func(float64)
|
||||||
|
TLSHandshakeStart func(float64)
|
||||||
|
TLSHandshakeDone func(float64)
|
||||||
|
WroteHeaders func(float64)
|
||||||
|
Wait100Continue func(float64)
|
||||||
|
WroteRequest func(float64)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstrumentRoundTripperTrace is a middleware that wraps the provided
|
||||||
|
// RoundTripper and reports times to hook functions provided in the
|
||||||
|
// InstrumentTrace struct. Hook functions that are not present in the provided
|
||||||
|
// InstrumentTrace struct are ignored. Times reported to the hook functions are
|
||||||
|
// time since the start of the request. Only with Go1.9+, those times are
|
||||||
|
// guaranteed to never be negative. (Earlier Go versions are not using a
|
||||||
|
// monotonic clock.) Note that partitioning of Histograms is expensive and
|
||||||
|
// should be used judiciously.
|
||||||
|
//
|
||||||
|
// For hook functions that receive an error as an argument, no observations are
|
||||||
|
// made in the event of a non-nil error value.
|
||||||
|
//
|
||||||
|
// See the example for ExampleInstrumentRoundTripperDuration for example usage.
|
||||||
|
func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc {
|
||||||
|
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
|
||||||
|
start := time.Now()
|
||||||
|
|
||||||
|
trace := &httptrace.ClientTrace{
|
||||||
|
GotConn: func(_ httptrace.GotConnInfo) {
|
||||||
|
if it.GotConn != nil {
|
||||||
|
it.GotConn(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PutIdleConn: func(err error) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if it.PutIdleConn != nil {
|
||||||
|
it.PutIdleConn(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DNSStart: func(_ httptrace.DNSStartInfo) {
|
||||||
|
if it.DNSStart != nil {
|
||||||
|
it.DNSStart(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DNSDone: func(_ httptrace.DNSDoneInfo) {
|
||||||
|
if it.DNSDone != nil {
|
||||||
|
it.DNSDone(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ConnectStart: func(_, _ string) {
|
||||||
|
if it.ConnectStart != nil {
|
||||||
|
it.ConnectStart(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ConnectDone: func(_, _ string, err error) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if it.ConnectDone != nil {
|
||||||
|
it.ConnectDone(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
GotFirstResponseByte: func() {
|
||||||
|
if it.GotFirstResponseByte != nil {
|
||||||
|
it.GotFirstResponseByte(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Got100Continue: func() {
|
||||||
|
if it.Got100Continue != nil {
|
||||||
|
it.Got100Continue(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TLSHandshakeStart: func() {
|
||||||
|
if it.TLSHandshakeStart != nil {
|
||||||
|
it.TLSHandshakeStart(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TLSHandshakeDone: func(_ tls.ConnectionState, err error) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if it.TLSHandshakeDone != nil {
|
||||||
|
it.TLSHandshakeDone(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
WroteHeaders: func() {
|
||||||
|
if it.WroteHeaders != nil {
|
||||||
|
it.WroteHeaders(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Wait100Continue: func() {
|
||||||
|
if it.Wait100Continue != nil {
|
||||||
|
it.Wait100Continue(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
WroteRequest: func(_ httptrace.WroteRequestInfo) {
|
||||||
|
if it.WroteRequest != nil {
|
||||||
|
it.WroteRequest(time.Since(start).Seconds())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
r = r.WithContext(httptrace.WithClientTrace(r.Context(), trace))
|
||||||
|
|
||||||
|
return next.RoundTrip(r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
144
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go
generated
vendored
144
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go
generated
vendored
@ -1,144 +0,0 @@
|
|||||||
// Copyright 2017 The Prometheus Authors
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
// +build go1.8
|
|
||||||
|
|
||||||
package promhttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/tls"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptrace"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// InstrumentTrace is used to offer flexibility in instrumenting the available
|
|
||||||
// httptrace.ClientTrace hook functions. Each function is passed a float64
|
|
||||||
// representing the time in seconds since the start of the http request. A user
|
|
||||||
// may choose to use separately buckets Histograms, or implement custom
|
|
||||||
// instance labels on a per function basis.
|
|
||||||
type InstrumentTrace struct {
|
|
||||||
GotConn func(float64)
|
|
||||||
PutIdleConn func(float64)
|
|
||||||
GotFirstResponseByte func(float64)
|
|
||||||
Got100Continue func(float64)
|
|
||||||
DNSStart func(float64)
|
|
||||||
DNSDone func(float64)
|
|
||||||
ConnectStart func(float64)
|
|
||||||
ConnectDone func(float64)
|
|
||||||
TLSHandshakeStart func(float64)
|
|
||||||
TLSHandshakeDone func(float64)
|
|
||||||
WroteHeaders func(float64)
|
|
||||||
Wait100Continue func(float64)
|
|
||||||
WroteRequest func(float64)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstrumentRoundTripperTrace is a middleware that wraps the provided
|
|
||||||
// RoundTripper and reports times to hook functions provided in the
|
|
||||||
// InstrumentTrace struct. Hook functions that are not present in the provided
|
|
||||||
// InstrumentTrace struct are ignored. Times reported to the hook functions are
|
|
||||||
// time since the start of the request. Only with Go1.9+, those times are
|
|
||||||
// guaranteed to never be negative. (Earlier Go versions are not using a
|
|
||||||
// monotonic clock.) Note that partitioning of Histograms is expensive and
|
|
||||||
// should be used judiciously.
|
|
||||||
//
|
|
||||||
// For hook functions that receive an error as an argument, no observations are
|
|
||||||
// made in the event of a non-nil error value.
|
|
||||||
//
|
|
||||||
// See the example for ExampleInstrumentRoundTripperDuration for example usage.
|
|
||||||
func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc {
|
|
||||||
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
|
|
||||||
start := time.Now()
|
|
||||||
|
|
||||||
trace := &httptrace.ClientTrace{
|
|
||||||
GotConn: func(_ httptrace.GotConnInfo) {
|
|
||||||
if it.GotConn != nil {
|
|
||||||
it.GotConn(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
PutIdleConn: func(err error) {
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if it.PutIdleConn != nil {
|
|
||||||
it.PutIdleConn(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
DNSStart: func(_ httptrace.DNSStartInfo) {
|
|
||||||
if it.DNSStart != nil {
|
|
||||||
it.DNSStart(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
DNSDone: func(_ httptrace.DNSDoneInfo) {
|
|
||||||
if it.DNSDone != nil {
|
|
||||||
it.DNSDone(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ConnectStart: func(_, _ string) {
|
|
||||||
if it.ConnectStart != nil {
|
|
||||||
it.ConnectStart(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ConnectDone: func(_, _ string, err error) {
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if it.ConnectDone != nil {
|
|
||||||
it.ConnectDone(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
GotFirstResponseByte: func() {
|
|
||||||
if it.GotFirstResponseByte != nil {
|
|
||||||
it.GotFirstResponseByte(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Got100Continue: func() {
|
|
||||||
if it.Got100Continue != nil {
|
|
||||||
it.Got100Continue(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TLSHandshakeStart: func() {
|
|
||||||
if it.TLSHandshakeStart != nil {
|
|
||||||
it.TLSHandshakeStart(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TLSHandshakeDone: func(_ tls.ConnectionState, err error) {
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if it.TLSHandshakeDone != nil {
|
|
||||||
it.TLSHandshakeDone(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
WroteHeaders: func() {
|
|
||||||
if it.WroteHeaders != nil {
|
|
||||||
it.WroteHeaders(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Wait100Continue: func() {
|
|
||||||
if it.Wait100Continue != nil {
|
|
||||||
it.Wait100Continue(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
WroteRequest: func(_ httptrace.WroteRequestInfo) {
|
|
||||||
if it.WroteRequest != nil {
|
|
||||||
it.WroteRequest(time.Since(start).Seconds())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
r = r.WithContext(httptrace.WithClientTrace(context.Background(), trace))
|
|
||||||
|
|
||||||
return next.RoundTrip(r)
|
|
||||||
})
|
|
||||||
}
|
|
24
vendor/github.com/prometheus/client_golang/prometheus/registry.go
generated
vendored
24
vendor/github.com/prometheus/client_golang/prometheus/registry.go
generated
vendored
@ -325,10 +325,18 @@ func (r *Registry) Register(c Collector) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if existing, exists := r.collectorsByID[collectorID]; exists {
|
if existing, exists := r.collectorsByID[collectorID]; exists {
|
||||||
|
switch e := existing.(type) {
|
||||||
|
case *wrappingCollector:
|
||||||
return AlreadyRegisteredError{
|
return AlreadyRegisteredError{
|
||||||
ExistingCollector: existing,
|
ExistingCollector: e.unwrapRecursively(),
|
||||||
NewCollector: c,
|
NewCollector: c,
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
return AlreadyRegisteredError{
|
||||||
|
ExistingCollector: e,
|
||||||
|
NewCollector: c,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// If the collectorID is new, but at least one of the descs existed
|
// If the collectorID is new, but at least one of the descs existed
|
||||||
// before, we are in trouble.
|
// before, we are in trouble.
|
||||||
@ -680,7 +688,7 @@ func processMetric(
|
|||||||
// Gatherers is a slice of Gatherer instances that implements the Gatherer
|
// Gatherers is a slice of Gatherer instances that implements the Gatherer
|
||||||
// interface itself. Its Gather method calls Gather on all Gatherers in the
|
// interface itself. Its Gather method calls Gather on all Gatherers in the
|
||||||
// slice in order and returns the merged results. Errors returned from the
|
// slice in order and returns the merged results. Errors returned from the
|
||||||
// Gather calles are all returned in a flattened MultiError. Duplicate and
|
// Gather calls are all returned in a flattened MultiError. Duplicate and
|
||||||
// inconsistent Metrics are skipped (first occurrence in slice order wins) and
|
// inconsistent Metrics are skipped (first occurrence in slice order wins) and
|
||||||
// reported in the returned error.
|
// reported in the returned error.
|
||||||
//
|
//
|
||||||
@ -872,7 +880,13 @@ func checkMetricConsistency(
|
|||||||
h = hashAddByte(h, separatorByte)
|
h = hashAddByte(h, separatorByte)
|
||||||
// Make sure label pairs are sorted. We depend on it for the consistency
|
// Make sure label pairs are sorted. We depend on it for the consistency
|
||||||
// check.
|
// check.
|
||||||
sort.Sort(labelPairSorter(dtoMetric.Label))
|
if !sort.IsSorted(labelPairSorter(dtoMetric.Label)) {
|
||||||
|
// We cannot sort dtoMetric.Label in place as it is immutable by contract.
|
||||||
|
copiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label))
|
||||||
|
copy(copiedLabels, dtoMetric.Label)
|
||||||
|
sort.Sort(labelPairSorter(copiedLabels))
|
||||||
|
dtoMetric.Label = copiedLabels
|
||||||
|
}
|
||||||
for _, lp := range dtoMetric.Label {
|
for _, lp := range dtoMetric.Label {
|
||||||
h = hashAdd(h, lp.GetName())
|
h = hashAdd(h, lp.GetName())
|
||||||
h = hashAddByte(h, separatorByte)
|
h = hashAddByte(h, separatorByte)
|
||||||
@ -903,8 +917,8 @@ func checkDescConsistency(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Is the desc consistent with the content of the metric?
|
// Is the desc consistent with the content of the metric?
|
||||||
lpsFromDesc := make([]*dto.LabelPair, 0, len(dtoMetric.Label))
|
lpsFromDesc := make([]*dto.LabelPair, len(desc.constLabelPairs), len(dtoMetric.Label))
|
||||||
lpsFromDesc = append(lpsFromDesc, desc.constLabelPairs...)
|
copy(lpsFromDesc, desc.constLabelPairs)
|
||||||
for _, l := range desc.variableLabels {
|
for _, l := range desc.variableLabels {
|
||||||
lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{
|
lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{
|
||||||
Name: proto.String(l),
|
Name: proto.String(l),
|
||||||
|
150
vendor/github.com/prometheus/client_golang/prometheus/summary.go
generated
vendored
150
vendor/github.com/prometheus/client_golang/prometheus/summary.go
generated
vendored
@ -16,8 +16,10 @@ package prometheus
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/beorn7/perks/quantile"
|
"github.com/beorn7/perks/quantile"
|
||||||
@ -37,7 +39,7 @@ const quantileLabel = "quantile"
|
|||||||
// A typical use-case is the observation of request latencies. By default, a
|
// A typical use-case is the observation of request latencies. By default, a
|
||||||
// Summary provides the median, the 90th and the 99th percentile of the latency
|
// Summary provides the median, the 90th and the 99th percentile of the latency
|
||||||
// as rank estimations. However, the default behavior will change in the
|
// as rank estimations. However, the default behavior will change in the
|
||||||
// upcoming v0.10 of the library. There will be no rank estimations at all by
|
// upcoming v1.0.0 of the library. There will be no rank estimations at all by
|
||||||
// default. For a sane transition, it is recommended to set the desired rank
|
// default. For a sane transition, it is recommended to set the desired rank
|
||||||
// estimations explicitly.
|
// estimations explicitly.
|
||||||
//
|
//
|
||||||
@ -56,16 +58,8 @@ type Summary interface {
|
|||||||
Observe(float64)
|
Observe(float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefObjectives are the default Summary quantile values.
|
var errQuantileLabelNotAllowed = fmt.Errorf(
|
||||||
//
|
|
||||||
// Deprecated: DefObjectives will not be used as the default objectives in
|
|
||||||
// v0.10 of the library. The default Summary will have no quantiles then.
|
|
||||||
var (
|
|
||||||
DefObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}
|
|
||||||
|
|
||||||
errQuantileLabelNotAllowed = fmt.Errorf(
|
|
||||||
"%q is not allowed as label name in summaries", quantileLabel,
|
"%q is not allowed as label name in summaries", quantileLabel,
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Default values for SummaryOpts.
|
// Default values for SummaryOpts.
|
||||||
@ -84,7 +78,7 @@ const (
|
|||||||
// mandatory to set Name to a non-empty string. While all other fields are
|
// mandatory to set Name to a non-empty string. While all other fields are
|
||||||
// optional and can safely be left at their zero value, it is recommended to set
|
// optional and can safely be left at their zero value, it is recommended to set
|
||||||
// a help string and to explicitly set the Objectives field to the desired value
|
// a help string and to explicitly set the Objectives field to the desired value
|
||||||
// as the default value will change in the upcoming v0.10 of the library.
|
// as the default value will change in the upcoming v1.0.0 of the library.
|
||||||
type SummaryOpts struct {
|
type SummaryOpts struct {
|
||||||
// Namespace, Subsystem, and Name are components of the fully-qualified
|
// Namespace, Subsystem, and Name are components of the fully-qualified
|
||||||
// name of the Summary (created by joining these components with
|
// name of the Summary (created by joining these components with
|
||||||
@ -121,13 +115,8 @@ type SummaryOpts struct {
|
|||||||
// Objectives defines the quantile rank estimates with their respective
|
// Objectives defines the quantile rank estimates with their respective
|
||||||
// absolute error. If Objectives[q] = e, then the value reported for q
|
// absolute error. If Objectives[q] = e, then the value reported for q
|
||||||
// will be the φ-quantile value for some φ between q-e and q+e. The
|
// will be the φ-quantile value for some φ between q-e and q+e. The
|
||||||
// default value is DefObjectives. It is used if Objectives is left at
|
// default value is an empty map, resulting in a summary without
|
||||||
// its zero value (i.e. nil). To create a Summary without Objectives,
|
// quantiles.
|
||||||
// set it to an empty map (i.e. map[float64]float64{}).
|
|
||||||
//
|
|
||||||
// Deprecated: Note that the current value of DefObjectives is
|
|
||||||
// deprecated. It will be replaced by an empty map in v0.10 of the
|
|
||||||
// library. Please explicitly set Objectives to the desired value.
|
|
||||||
Objectives map[float64]float64
|
Objectives map[float64]float64
|
||||||
|
|
||||||
// MaxAge defines the duration for which an observation stays relevant
|
// MaxAge defines the duration for which an observation stays relevant
|
||||||
@ -151,7 +140,7 @@ type SummaryOpts struct {
|
|||||||
BufCap uint32
|
BufCap uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Great fuck-up with the sliding-window decay algorithm... The Merge method of
|
// Problem with the sliding-window decay algorithm... The Merge method of
|
||||||
// perk/quantile is actually not working as advertised - and it might be
|
// perk/quantile is actually not working as advertised - and it might be
|
||||||
// unfixable, as the underlying algorithm is apparently not capable of merging
|
// unfixable, as the underlying algorithm is apparently not capable of merging
|
||||||
// summaries in the first place. To avoid using Merge, we are currently adding
|
// summaries in the first place. To avoid using Merge, we are currently adding
|
||||||
@ -196,7 +185,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if opts.Objectives == nil {
|
if opts.Objectives == nil {
|
||||||
opts.Objectives = DefObjectives
|
opts.Objectives = map[float64]float64{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.MaxAge < 0 {
|
if opts.MaxAge < 0 {
|
||||||
@ -214,6 +203,17 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
|
|||||||
opts.BufCap = DefBufCap
|
opts.BufCap = DefBufCap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(opts.Objectives) == 0 {
|
||||||
|
// Use the lock-free implementation of a Summary without objectives.
|
||||||
|
s := &noObjectivesSummary{
|
||||||
|
desc: desc,
|
||||||
|
labelPairs: makeLabelPairs(desc, labelValues),
|
||||||
|
counts: [2]*summaryCounts{&summaryCounts{}, &summaryCounts{}},
|
||||||
|
}
|
||||||
|
s.init(s) // Init self-collection.
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
s := &summary{
|
s := &summary{
|
||||||
desc: desc,
|
desc: desc,
|
||||||
|
|
||||||
@ -382,6 +382,116 @@ func (s *summary) swapBufs(now time.Time) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type summaryCounts struct {
|
||||||
|
// sumBits contains the bits of the float64 representing the sum of all
|
||||||
|
// observations. sumBits and count have to go first in the struct to
|
||||||
|
// guarantee alignment for atomic operations.
|
||||||
|
// http://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
||||||
|
sumBits uint64
|
||||||
|
count uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type noObjectivesSummary struct {
|
||||||
|
// countAndHotIdx enables lock-free writes with use of atomic updates.
|
||||||
|
// The most significant bit is the hot index [0 or 1] of the count field
|
||||||
|
// below. Observe calls update the hot one. All remaining bits count the
|
||||||
|
// number of Observe calls. Observe starts by incrementing this counter,
|
||||||
|
// and finish by incrementing the count field in the respective
|
||||||
|
// summaryCounts, as a marker for completion.
|
||||||
|
//
|
||||||
|
// Calls of the Write method (which are non-mutating reads from the
|
||||||
|
// perspective of the summary) swap the hot–cold under the writeMtx
|
||||||
|
// lock. A cooldown is awaited (while locked) by comparing the number of
|
||||||
|
// observations with the initiation count. Once they match, then the
|
||||||
|
// last observation on the now cool one has completed. All cool fields must
|
||||||
|
// be merged into the new hot before releasing writeMtx.
|
||||||
|
|
||||||
|
// Fields with atomic access first! See alignment constraint:
|
||||||
|
// http://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
||||||
|
countAndHotIdx uint64
|
||||||
|
|
||||||
|
selfCollector
|
||||||
|
desc *Desc
|
||||||
|
writeMtx sync.Mutex // Only used in the Write method.
|
||||||
|
|
||||||
|
// Two counts, one is "hot" for lock-free observations, the other is
|
||||||
|
// "cold" for writing out a dto.Metric. It has to be an array of
|
||||||
|
// pointers to guarantee 64bit alignment of the histogramCounts, see
|
||||||
|
// http://golang.org/pkg/sync/atomic/#pkg-note-BUG.
|
||||||
|
counts [2]*summaryCounts
|
||||||
|
|
||||||
|
labelPairs []*dto.LabelPair
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *noObjectivesSummary) Desc() *Desc {
|
||||||
|
return s.desc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *noObjectivesSummary) Observe(v float64) {
|
||||||
|
// We increment h.countAndHotIdx so that the counter in the lower
|
||||||
|
// 63 bits gets incremented. At the same time, we get the new value
|
||||||
|
// back, which we can use to find the currently-hot counts.
|
||||||
|
n := atomic.AddUint64(&s.countAndHotIdx, 1)
|
||||||
|
hotCounts := s.counts[n>>63]
|
||||||
|
|
||||||
|
for {
|
||||||
|
oldBits := atomic.LoadUint64(&hotCounts.sumBits)
|
||||||
|
newBits := math.Float64bits(math.Float64frombits(oldBits) + v)
|
||||||
|
if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Increment count last as we take it as a signal that the observation
|
||||||
|
// is complete.
|
||||||
|
atomic.AddUint64(&hotCounts.count, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *noObjectivesSummary) Write(out *dto.Metric) error {
|
||||||
|
// For simplicity, we protect this whole method by a mutex. It is not in
|
||||||
|
// the hot path, i.e. Observe is called much more often than Write. The
|
||||||
|
// complication of making Write lock-free isn't worth it, if possible at
|
||||||
|
// all.
|
||||||
|
s.writeMtx.Lock()
|
||||||
|
defer s.writeMtx.Unlock()
|
||||||
|
|
||||||
|
// Adding 1<<63 switches the hot index (from 0 to 1 or from 1 to 0)
|
||||||
|
// without touching the count bits. See the struct comments for a full
|
||||||
|
// description of the algorithm.
|
||||||
|
n := atomic.AddUint64(&s.countAndHotIdx, 1<<63)
|
||||||
|
// count is contained unchanged in the lower 63 bits.
|
||||||
|
count := n & ((1 << 63) - 1)
|
||||||
|
// The most significant bit tells us which counts is hot. The complement
|
||||||
|
// is thus the cold one.
|
||||||
|
hotCounts := s.counts[n>>63]
|
||||||
|
coldCounts := s.counts[(^n)>>63]
|
||||||
|
|
||||||
|
// Await cooldown.
|
||||||
|
for count != atomic.LoadUint64(&coldCounts.count) {
|
||||||
|
runtime.Gosched() // Let observations get work done.
|
||||||
|
}
|
||||||
|
|
||||||
|
sum := &dto.Summary{
|
||||||
|
SampleCount: proto.Uint64(count),
|
||||||
|
SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))),
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Summary = sum
|
||||||
|
out.Label = s.labelPairs
|
||||||
|
|
||||||
|
// Finally add all the cold counts to the new hot counts and reset the cold counts.
|
||||||
|
atomic.AddUint64(&hotCounts.count, count)
|
||||||
|
atomic.StoreUint64(&coldCounts.count, 0)
|
||||||
|
for {
|
||||||
|
oldBits := atomic.LoadUint64(&hotCounts.sumBits)
|
||||||
|
newBits := math.Float64bits(math.Float64frombits(oldBits) + sum.GetSampleSum())
|
||||||
|
if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {
|
||||||
|
atomic.StoreUint64(&coldCounts.sumBits, 0)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type quantSort []*dto.Quantile
|
type quantSort []*dto.Quantile
|
||||||
|
|
||||||
func (s quantSort) Len() int {
|
func (s quantSort) Len() int {
|
||||||
|
11
vendor/github.com/prometheus/client_golang/prometheus/timer.go
generated
vendored
11
vendor/github.com/prometheus/client_golang/prometheus/timer.go
generated
vendored
@ -39,13 +39,16 @@ func NewTimer(o Observer) *Timer {
|
|||||||
|
|
||||||
// ObserveDuration records the duration passed since the Timer was created with
|
// ObserveDuration records the duration passed since the Timer was created with
|
||||||
// NewTimer. It calls the Observe method of the Observer provided during
|
// NewTimer. It calls the Observe method of the Observer provided during
|
||||||
// construction with the duration in seconds as an argument. ObserveDuration is
|
// construction with the duration in seconds as an argument. The observed
|
||||||
// usually called with a defer statement.
|
// duration is also returned. ObserveDuration is usually called with a defer
|
||||||
|
// statement.
|
||||||
//
|
//
|
||||||
// Note that this method is only guaranteed to never observe negative durations
|
// Note that this method is only guaranteed to never observe negative durations
|
||||||
// if used with Go1.9+.
|
// if used with Go1.9+.
|
||||||
func (t *Timer) ObserveDuration() {
|
func (t *Timer) ObserveDuration() time.Duration {
|
||||||
|
d := time.Since(t.begin)
|
||||||
if t.observer != nil {
|
if t.observer != nil {
|
||||||
t.observer.Observe(time.Since(t.begin).Seconds())
|
t.observer.Observe(d.Seconds())
|
||||||
}
|
}
|
||||||
|
return d
|
||||||
}
|
}
|
||||||
|
21
vendor/github.com/prometheus/client_golang/prometheus/wrap.go
generated
vendored
21
vendor/github.com/prometheus/client_golang/prometheus/wrap.go
generated
vendored
@ -32,6 +32,12 @@ import (
|
|||||||
// WrapRegistererWith provides a way to add fixed labels to a subset of
|
// WrapRegistererWith provides a way to add fixed labels to a subset of
|
||||||
// Collectors. It should not be used to add fixed labels to all metrics exposed.
|
// Collectors. It should not be used to add fixed labels to all metrics exposed.
|
||||||
//
|
//
|
||||||
|
// Conflicts between Collectors registered through the original Registerer with
|
||||||
|
// Collectors registered through the wrapping Registerer will still be
|
||||||
|
// detected. Any AlreadyRegisteredError returned by the Register method of
|
||||||
|
// either Registerer will contain the ExistingCollector in the form it was
|
||||||
|
// provided to the respective registry.
|
||||||
|
//
|
||||||
// The Collector example demonstrates a use of WrapRegistererWith.
|
// The Collector example demonstrates a use of WrapRegistererWith.
|
||||||
func WrapRegistererWith(labels Labels, reg Registerer) Registerer {
|
func WrapRegistererWith(labels Labels, reg Registerer) Registerer {
|
||||||
return &wrappingRegisterer{
|
return &wrappingRegisterer{
|
||||||
@ -54,6 +60,12 @@ func WrapRegistererWith(labels Labels, reg Registerer) Registerer {
|
|||||||
// (see NewGoCollector) and the process collector (see NewProcessCollector). (In
|
// (see NewGoCollector) and the process collector (see NewProcessCollector). (In
|
||||||
// fact, those metrics are already prefixed with “go_” or “process_”,
|
// fact, those metrics are already prefixed with “go_” or “process_”,
|
||||||
// respectively.)
|
// respectively.)
|
||||||
|
//
|
||||||
|
// Conflicts between Collectors registered through the original Registerer with
|
||||||
|
// Collectors registered through the wrapping Registerer will still be
|
||||||
|
// detected. Any AlreadyRegisteredError returned by the Register method of
|
||||||
|
// either Registerer will contain the ExistingCollector in the form it was
|
||||||
|
// provided to the respective registry.
|
||||||
func WrapRegistererWithPrefix(prefix string, reg Registerer) Registerer {
|
func WrapRegistererWithPrefix(prefix string, reg Registerer) Registerer {
|
||||||
return &wrappingRegisterer{
|
return &wrappingRegisterer{
|
||||||
wrappedRegisterer: reg,
|
wrappedRegisterer: reg,
|
||||||
@ -123,6 +135,15 @@ func (c *wrappingCollector) Describe(ch chan<- *Desc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *wrappingCollector) unwrapRecursively() Collector {
|
||||||
|
switch wc := c.wrappedCollector.(type) {
|
||||||
|
case *wrappingCollector:
|
||||||
|
return wc.unwrapRecursively()
|
||||||
|
default:
|
||||||
|
return wc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type wrappingMetric struct {
|
type wrappingMetric struct {
|
||||||
wrappedMetric Metric
|
wrappedMetric Metric
|
||||||
prefix string
|
prefix string
|
||||||
|
248
vendor/github.com/prometheus/client_model/go/metrics.pb.go
generated
vendored
248
vendor/github.com/prometheus/client_model/go/metrics.pb.go
generated
vendored
@ -1,11 +1,14 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// source: metrics.proto
|
// source: metrics.proto
|
||||||
|
|
||||||
package io_prometheus_client // import "github.com/prometheus/client_model/go"
|
package io_prometheus_client
|
||||||
|
|
||||||
import proto "github.com/golang/protobuf/proto"
|
import (
|
||||||
import fmt "fmt"
|
fmt "fmt"
|
||||||
import math "math"
|
proto "github.com/golang/protobuf/proto"
|
||||||
|
timestamp "github.com/golang/protobuf/ptypes/timestamp"
|
||||||
|
math "math"
|
||||||
|
)
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
var _ = proto.Marshal
|
var _ = proto.Marshal
|
||||||
@ -16,7 +19,7 @@ var _ = math.Inf
|
|||||||
// is compatible with the proto package it is being compiled against.
|
// is compatible with the proto package it is being compiled against.
|
||||||
// A compilation error at this line likely means your copy of the
|
// A compilation error at this line likely means your copy of the
|
||||||
// proto package needs to be updated.
|
// proto package needs to be updated.
|
||||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||||
|
|
||||||
type MetricType int32
|
type MetricType int32
|
||||||
|
|
||||||
@ -35,6 +38,7 @@ var MetricType_name = map[int32]string{
|
|||||||
3: "UNTYPED",
|
3: "UNTYPED",
|
||||||
4: "HISTOGRAM",
|
4: "HISTOGRAM",
|
||||||
}
|
}
|
||||||
|
|
||||||
var MetricType_value = map[string]int32{
|
var MetricType_value = map[string]int32{
|
||||||
"COUNTER": 0,
|
"COUNTER": 0,
|
||||||
"GAUGE": 1,
|
"GAUGE": 1,
|
||||||
@ -48,9 +52,11 @@ func (x MetricType) Enum() *MetricType {
|
|||||||
*p = x
|
*p = x
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x MetricType) String() string {
|
func (x MetricType) String() string {
|
||||||
return proto.EnumName(MetricType_name, int32(x))
|
return proto.EnumName(MetricType_name, int32(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *MetricType) UnmarshalJSON(data []byte) error {
|
func (x *MetricType) UnmarshalJSON(data []byte) error {
|
||||||
value, err := proto.UnmarshalJSONEnum(MetricType_value, data, "MetricType")
|
value, err := proto.UnmarshalJSONEnum(MetricType_value, data, "MetricType")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -59,8 +65,9 @@ func (x *MetricType) UnmarshalJSON(data []byte) error {
|
|||||||
*x = MetricType(value)
|
*x = MetricType(value)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MetricType) EnumDescriptor() ([]byte, []int) {
|
func (MetricType) EnumDescriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_metrics_c97c9a2b9560cb8f, []int{0}
|
return fileDescriptor_6039342a2ba47b72, []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
type LabelPair struct {
|
type LabelPair struct {
|
||||||
@ -75,16 +82,17 @@ func (m *LabelPair) Reset() { *m = LabelPair{} }
|
|||||||
func (m *LabelPair) String() string { return proto.CompactTextString(m) }
|
func (m *LabelPair) String() string { return proto.CompactTextString(m) }
|
||||||
func (*LabelPair) ProtoMessage() {}
|
func (*LabelPair) ProtoMessage() {}
|
||||||
func (*LabelPair) Descriptor() ([]byte, []int) {
|
func (*LabelPair) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_metrics_c97c9a2b9560cb8f, []int{0}
|
return fileDescriptor_6039342a2ba47b72, []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LabelPair) XXX_Unmarshal(b []byte) error {
|
func (m *LabelPair) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_LabelPair.Unmarshal(m, b)
|
return xxx_messageInfo_LabelPair.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *LabelPair) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *LabelPair) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_LabelPair.Marshal(b, m, deterministic)
|
return xxx_messageInfo_LabelPair.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *LabelPair) XXX_Merge(src proto.Message) {
|
func (m *LabelPair) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_LabelPair.Merge(dst, src)
|
xxx_messageInfo_LabelPair.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *LabelPair) XXX_Size() int {
|
func (m *LabelPair) XXX_Size() int {
|
||||||
return xxx_messageInfo_LabelPair.Size(m)
|
return xxx_messageInfo_LabelPair.Size(m)
|
||||||
@ -120,16 +128,17 @@ func (m *Gauge) Reset() { *m = Gauge{} }
|
|||||||
func (m *Gauge) String() string { return proto.CompactTextString(m) }
|
func (m *Gauge) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Gauge) ProtoMessage() {}
|
func (*Gauge) ProtoMessage() {}
|
||||||
func (*Gauge) Descriptor() ([]byte, []int) {
|
func (*Gauge) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_metrics_c97c9a2b9560cb8f, []int{1}
|
return fileDescriptor_6039342a2ba47b72, []int{1}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Gauge) XXX_Unmarshal(b []byte) error {
|
func (m *Gauge) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Gauge.Unmarshal(m, b)
|
return xxx_messageInfo_Gauge.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Gauge) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Gauge) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Gauge.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Gauge.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Gauge) XXX_Merge(src proto.Message) {
|
func (m *Gauge) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Gauge.Merge(dst, src)
|
xxx_messageInfo_Gauge.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Gauge) XXX_Size() int {
|
func (m *Gauge) XXX_Size() int {
|
||||||
return xxx_messageInfo_Gauge.Size(m)
|
return xxx_messageInfo_Gauge.Size(m)
|
||||||
@ -149,6 +158,7 @@ func (m *Gauge) GetValue() float64 {
|
|||||||
|
|
||||||
type Counter struct {
|
type Counter struct {
|
||||||
Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"`
|
Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"`
|
||||||
|
Exemplar *Exemplar `protobuf:"bytes,2,opt,name=exemplar" json:"exemplar,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
@ -158,16 +168,17 @@ func (m *Counter) Reset() { *m = Counter{} }
|
|||||||
func (m *Counter) String() string { return proto.CompactTextString(m) }
|
func (m *Counter) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Counter) ProtoMessage() {}
|
func (*Counter) ProtoMessage() {}
|
||||||
func (*Counter) Descriptor() ([]byte, []int) {
|
func (*Counter) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_metrics_c97c9a2b9560cb8f, []int{2}
|
return fileDescriptor_6039342a2ba47b72, []int{2}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Counter) XXX_Unmarshal(b []byte) error {
|
func (m *Counter) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Counter.Unmarshal(m, b)
|
return xxx_messageInfo_Counter.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Counter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Counter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Counter.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Counter.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Counter) XXX_Merge(src proto.Message) {
|
func (m *Counter) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Counter.Merge(dst, src)
|
xxx_messageInfo_Counter.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Counter) XXX_Size() int {
|
func (m *Counter) XXX_Size() int {
|
||||||
return xxx_messageInfo_Counter.Size(m)
|
return xxx_messageInfo_Counter.Size(m)
|
||||||
@ -185,6 +196,13 @@ func (m *Counter) GetValue() float64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Counter) GetExemplar() *Exemplar {
|
||||||
|
if m != nil {
|
||||||
|
return m.Exemplar
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type Quantile struct {
|
type Quantile struct {
|
||||||
Quantile *float64 `protobuf:"fixed64,1,opt,name=quantile" json:"quantile,omitempty"`
|
Quantile *float64 `protobuf:"fixed64,1,opt,name=quantile" json:"quantile,omitempty"`
|
||||||
Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"`
|
Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"`
|
||||||
@ -197,16 +215,17 @@ func (m *Quantile) Reset() { *m = Quantile{} }
|
|||||||
func (m *Quantile) String() string { return proto.CompactTextString(m) }
|
func (m *Quantile) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Quantile) ProtoMessage() {}
|
func (*Quantile) ProtoMessage() {}
|
||||||
func (*Quantile) Descriptor() ([]byte, []int) {
|
func (*Quantile) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_metrics_c97c9a2b9560cb8f, []int{3}
|
return fileDescriptor_6039342a2ba47b72, []int{3}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Quantile) XXX_Unmarshal(b []byte) error {
|
func (m *Quantile) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Quantile.Unmarshal(m, b)
|
return xxx_messageInfo_Quantile.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Quantile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Quantile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Quantile.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Quantile.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Quantile) XXX_Merge(src proto.Message) {
|
func (m *Quantile) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Quantile.Merge(dst, src)
|
xxx_messageInfo_Quantile.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Quantile) XXX_Size() int {
|
func (m *Quantile) XXX_Size() int {
|
||||||
return xxx_messageInfo_Quantile.Size(m)
|
return xxx_messageInfo_Quantile.Size(m)
|
||||||
@ -244,16 +263,17 @@ func (m *Summary) Reset() { *m = Summary{} }
|
|||||||
func (m *Summary) String() string { return proto.CompactTextString(m) }
|
func (m *Summary) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Summary) ProtoMessage() {}
|
func (*Summary) ProtoMessage() {}
|
||||||
func (*Summary) Descriptor() ([]byte, []int) {
|
func (*Summary) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_metrics_c97c9a2b9560cb8f, []int{4}
|
return fileDescriptor_6039342a2ba47b72, []int{4}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Summary) XXX_Unmarshal(b []byte) error {
|
func (m *Summary) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Summary.Unmarshal(m, b)
|
return xxx_messageInfo_Summary.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Summary) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Summary) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Summary.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Summary.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Summary) XXX_Merge(src proto.Message) {
|
func (m *Summary) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Summary.Merge(dst, src)
|
xxx_messageInfo_Summary.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Summary) XXX_Size() int {
|
func (m *Summary) XXX_Size() int {
|
||||||
return xxx_messageInfo_Summary.Size(m)
|
return xxx_messageInfo_Summary.Size(m)
|
||||||
@ -296,16 +316,17 @@ func (m *Untyped) Reset() { *m = Untyped{} }
|
|||||||
func (m *Untyped) String() string { return proto.CompactTextString(m) }
|
func (m *Untyped) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Untyped) ProtoMessage() {}
|
func (*Untyped) ProtoMessage() {}
|
||||||
func (*Untyped) Descriptor() ([]byte, []int) {
|
func (*Untyped) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_metrics_c97c9a2b9560cb8f, []int{5}
|
return fileDescriptor_6039342a2ba47b72, []int{5}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Untyped) XXX_Unmarshal(b []byte) error {
|
func (m *Untyped) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Untyped.Unmarshal(m, b)
|
return xxx_messageInfo_Untyped.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Untyped) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Untyped) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Untyped.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Untyped.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Untyped) XXX_Merge(src proto.Message) {
|
func (m *Untyped) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Untyped.Merge(dst, src)
|
xxx_messageInfo_Untyped.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Untyped) XXX_Size() int {
|
func (m *Untyped) XXX_Size() int {
|
||||||
return xxx_messageInfo_Untyped.Size(m)
|
return xxx_messageInfo_Untyped.Size(m)
|
||||||
@ -336,16 +357,17 @@ func (m *Histogram) Reset() { *m = Histogram{} }
|
|||||||
func (m *Histogram) String() string { return proto.CompactTextString(m) }
|
func (m *Histogram) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Histogram) ProtoMessage() {}
|
func (*Histogram) ProtoMessage() {}
|
||||||
func (*Histogram) Descriptor() ([]byte, []int) {
|
func (*Histogram) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_metrics_c97c9a2b9560cb8f, []int{6}
|
return fileDescriptor_6039342a2ba47b72, []int{6}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Histogram) XXX_Unmarshal(b []byte) error {
|
func (m *Histogram) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Histogram.Unmarshal(m, b)
|
return xxx_messageInfo_Histogram.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Histogram) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Histogram) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Histogram.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Histogram.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Histogram) XXX_Merge(src proto.Message) {
|
func (m *Histogram) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Histogram.Merge(dst, src)
|
xxx_messageInfo_Histogram.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Histogram) XXX_Size() int {
|
func (m *Histogram) XXX_Size() int {
|
||||||
return xxx_messageInfo_Histogram.Size(m)
|
return xxx_messageInfo_Histogram.Size(m)
|
||||||
@ -380,6 +402,7 @@ func (m *Histogram) GetBucket() []*Bucket {
|
|||||||
type Bucket struct {
|
type Bucket struct {
|
||||||
CumulativeCount *uint64 `protobuf:"varint,1,opt,name=cumulative_count,json=cumulativeCount" json:"cumulative_count,omitempty"`
|
CumulativeCount *uint64 `protobuf:"varint,1,opt,name=cumulative_count,json=cumulativeCount" json:"cumulative_count,omitempty"`
|
||||||
UpperBound *float64 `protobuf:"fixed64,2,opt,name=upper_bound,json=upperBound" json:"upper_bound,omitempty"`
|
UpperBound *float64 `protobuf:"fixed64,2,opt,name=upper_bound,json=upperBound" json:"upper_bound,omitempty"`
|
||||||
|
Exemplar *Exemplar `protobuf:"bytes,3,opt,name=exemplar" json:"exemplar,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
@ -389,16 +412,17 @@ func (m *Bucket) Reset() { *m = Bucket{} }
|
|||||||
func (m *Bucket) String() string { return proto.CompactTextString(m) }
|
func (m *Bucket) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Bucket) ProtoMessage() {}
|
func (*Bucket) ProtoMessage() {}
|
||||||
func (*Bucket) Descriptor() ([]byte, []int) {
|
func (*Bucket) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_metrics_c97c9a2b9560cb8f, []int{7}
|
return fileDescriptor_6039342a2ba47b72, []int{7}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Bucket) XXX_Unmarshal(b []byte) error {
|
func (m *Bucket) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Bucket.Unmarshal(m, b)
|
return xxx_messageInfo_Bucket.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Bucket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Bucket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Bucket.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Bucket.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Bucket) XXX_Merge(src proto.Message) {
|
func (m *Bucket) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Bucket.Merge(dst, src)
|
xxx_messageInfo_Bucket.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Bucket) XXX_Size() int {
|
func (m *Bucket) XXX_Size() int {
|
||||||
return xxx_messageInfo_Bucket.Size(m)
|
return xxx_messageInfo_Bucket.Size(m)
|
||||||
@ -423,6 +447,68 @@ func (m *Bucket) GetUpperBound() float64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Bucket) GetExemplar() *Exemplar {
|
||||||
|
if m != nil {
|
||||||
|
return m.Exemplar
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Exemplar struct {
|
||||||
|
Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"`
|
||||||
|
Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"`
|
||||||
|
Timestamp *timestamp.Timestamp `protobuf:"bytes,3,opt,name=timestamp" json:"timestamp,omitempty"`
|
||||||
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Exemplar) Reset() { *m = Exemplar{} }
|
||||||
|
func (m *Exemplar) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Exemplar) ProtoMessage() {}
|
||||||
|
func (*Exemplar) Descriptor() ([]byte, []int) {
|
||||||
|
return fileDescriptor_6039342a2ba47b72, []int{8}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Exemplar) XXX_Unmarshal(b []byte) error {
|
||||||
|
return xxx_messageInfo_Exemplar.Unmarshal(m, b)
|
||||||
|
}
|
||||||
|
func (m *Exemplar) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
|
return xxx_messageInfo_Exemplar.Marshal(b, m, deterministic)
|
||||||
|
}
|
||||||
|
func (m *Exemplar) XXX_Merge(src proto.Message) {
|
||||||
|
xxx_messageInfo_Exemplar.Merge(m, src)
|
||||||
|
}
|
||||||
|
func (m *Exemplar) XXX_Size() int {
|
||||||
|
return xxx_messageInfo_Exemplar.Size(m)
|
||||||
|
}
|
||||||
|
func (m *Exemplar) XXX_DiscardUnknown() {
|
||||||
|
xxx_messageInfo_Exemplar.DiscardUnknown(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
var xxx_messageInfo_Exemplar proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *Exemplar) GetLabel() []*LabelPair {
|
||||||
|
if m != nil {
|
||||||
|
return m.Label
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Exemplar) GetValue() float64 {
|
||||||
|
if m != nil && m.Value != nil {
|
||||||
|
return *m.Value
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Exemplar) GetTimestamp() *timestamp.Timestamp {
|
||||||
|
if m != nil {
|
||||||
|
return m.Timestamp
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type Metric struct {
|
type Metric struct {
|
||||||
Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"`
|
Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"`
|
||||||
Gauge *Gauge `protobuf:"bytes,2,opt,name=gauge" json:"gauge,omitempty"`
|
Gauge *Gauge `protobuf:"bytes,2,opt,name=gauge" json:"gauge,omitempty"`
|
||||||
@ -440,16 +526,17 @@ func (m *Metric) Reset() { *m = Metric{} }
|
|||||||
func (m *Metric) String() string { return proto.CompactTextString(m) }
|
func (m *Metric) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Metric) ProtoMessage() {}
|
func (*Metric) ProtoMessage() {}
|
||||||
func (*Metric) Descriptor() ([]byte, []int) {
|
func (*Metric) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_metrics_c97c9a2b9560cb8f, []int{8}
|
return fileDescriptor_6039342a2ba47b72, []int{9}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Metric) XXX_Unmarshal(b []byte) error {
|
func (m *Metric) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Metric.Unmarshal(m, b)
|
return xxx_messageInfo_Metric.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Metric) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Metric) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Metric.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Metric.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Metric) XXX_Merge(src proto.Message) {
|
func (m *Metric) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Metric.Merge(dst, src)
|
xxx_messageInfo_Metric.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Metric) XXX_Size() int {
|
func (m *Metric) XXX_Size() int {
|
||||||
return xxx_messageInfo_Metric.Size(m)
|
return xxx_messageInfo_Metric.Size(m)
|
||||||
@ -523,16 +610,17 @@ func (m *MetricFamily) Reset() { *m = MetricFamily{} }
|
|||||||
func (m *MetricFamily) String() string { return proto.CompactTextString(m) }
|
func (m *MetricFamily) String() string { return proto.CompactTextString(m) }
|
||||||
func (*MetricFamily) ProtoMessage() {}
|
func (*MetricFamily) ProtoMessage() {}
|
||||||
func (*MetricFamily) Descriptor() ([]byte, []int) {
|
func (*MetricFamily) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_metrics_c97c9a2b9560cb8f, []int{9}
|
return fileDescriptor_6039342a2ba47b72, []int{10}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MetricFamily) XXX_Unmarshal(b []byte) error {
|
func (m *MetricFamily) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_MetricFamily.Unmarshal(m, b)
|
return xxx_messageInfo_MetricFamily.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *MetricFamily) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *MetricFamily) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_MetricFamily.Marshal(b, m, deterministic)
|
return xxx_messageInfo_MetricFamily.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *MetricFamily) XXX_Merge(src proto.Message) {
|
func (m *MetricFamily) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_MetricFamily.Merge(dst, src)
|
xxx_messageInfo_MetricFamily.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *MetricFamily) XXX_Size() int {
|
func (m *MetricFamily) XXX_Size() int {
|
||||||
return xxx_messageInfo_MetricFamily.Size(m)
|
return xxx_messageInfo_MetricFamily.Size(m)
|
||||||
@ -572,6 +660,7 @@ func (m *MetricFamily) GetMetric() []*Metric {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
proto.RegisterEnum("io.prometheus.client.MetricType", MetricType_name, MetricType_value)
|
||||||
proto.RegisterType((*LabelPair)(nil), "io.prometheus.client.LabelPair")
|
proto.RegisterType((*LabelPair)(nil), "io.prometheus.client.LabelPair")
|
||||||
proto.RegisterType((*Gauge)(nil), "io.prometheus.client.Gauge")
|
proto.RegisterType((*Gauge)(nil), "io.prometheus.client.Gauge")
|
||||||
proto.RegisterType((*Counter)(nil), "io.prometheus.client.Counter")
|
proto.RegisterType((*Counter)(nil), "io.prometheus.client.Counter")
|
||||||
@ -580,50 +669,55 @@ func init() {
|
|||||||
proto.RegisterType((*Untyped)(nil), "io.prometheus.client.Untyped")
|
proto.RegisterType((*Untyped)(nil), "io.prometheus.client.Untyped")
|
||||||
proto.RegisterType((*Histogram)(nil), "io.prometheus.client.Histogram")
|
proto.RegisterType((*Histogram)(nil), "io.prometheus.client.Histogram")
|
||||||
proto.RegisterType((*Bucket)(nil), "io.prometheus.client.Bucket")
|
proto.RegisterType((*Bucket)(nil), "io.prometheus.client.Bucket")
|
||||||
|
proto.RegisterType((*Exemplar)(nil), "io.prometheus.client.Exemplar")
|
||||||
proto.RegisterType((*Metric)(nil), "io.prometheus.client.Metric")
|
proto.RegisterType((*Metric)(nil), "io.prometheus.client.Metric")
|
||||||
proto.RegisterType((*MetricFamily)(nil), "io.prometheus.client.MetricFamily")
|
proto.RegisterType((*MetricFamily)(nil), "io.prometheus.client.MetricFamily")
|
||||||
proto.RegisterEnum("io.prometheus.client.MetricType", MetricType_name, MetricType_value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { proto.RegisterFile("metrics.proto", fileDescriptor_metrics_c97c9a2b9560cb8f) }
|
func init() { proto.RegisterFile("metrics.proto", fileDescriptor_6039342a2ba47b72) }
|
||||||
|
|
||||||
var fileDescriptor_metrics_c97c9a2b9560cb8f = []byte{
|
var fileDescriptor_6039342a2ba47b72 = []byte{
|
||||||
// 591 bytes of a gzipped FileDescriptorProto
|
// 665 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0x4f, 0x4f, 0xdb, 0x4e,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcd, 0x6e, 0xd3, 0x4c,
|
||||||
0x14, 0xfc, 0x99, 0xd8, 0x09, 0x7e, 0x86, 0x5f, 0xad, 0x15, 0x07, 0xab, 0x2d, 0x25, 0xcd, 0x89,
|
0x14, 0xfd, 0xdc, 0x38, 0x3f, 0xbe, 0x69, 0x3f, 0xa2, 0x51, 0x17, 0x56, 0xa1, 0x24, 0x78, 0x55,
|
||||||
0xf6, 0x10, 0x54, 0x04, 0xaa, 0x44, 0xdb, 0x03, 0x50, 0x1a, 0x2a, 0xd5, 0x40, 0x37, 0xc9, 0x81,
|
0x58, 0x38, 0xa2, 0x6a, 0x05, 0x2a, 0xb0, 0x68, 0x4b, 0x48, 0x91, 0x48, 0x5b, 0x26, 0xc9, 0xa2,
|
||||||
0x5e, 0xac, 0x8d, 0x59, 0x25, 0x56, 0xbd, 0xb6, 0x6b, 0xef, 0x22, 0xe5, 0xdc, 0x43, 0xbf, 0x47,
|
0xb0, 0x88, 0x1c, 0x77, 0x70, 0x2c, 0x3c, 0xb1, 0xb1, 0x67, 0x2a, 0xb2, 0x66, 0xc1, 0x16, 0x5e,
|
||||||
0xbf, 0x68, 0xab, 0xfd, 0xe3, 0x18, 0x24, 0xc3, 0xa9, 0xb7, 0xb7, 0xf3, 0x66, 0xde, 0x8e, 0x77,
|
0x81, 0x17, 0x05, 0xcd, 0x8f, 0x6d, 0x2a, 0xb9, 0x95, 0x40, 0xec, 0x66, 0xee, 0x3d, 0xe7, 0xfa,
|
||||||
0xc7, 0x0b, 0x9b, 0x8c, 0xf2, 0x32, 0x89, 0xab, 0x61, 0x51, 0xe6, 0x3c, 0x47, 0x5b, 0x49, 0x2e,
|
0xcc, 0xf8, 0x9c, 0x81, 0x0d, 0x4a, 0x58, 0x1a, 0xfa, 0x99, 0x9b, 0xa4, 0x31, 0x8b, 0xd1, 0x66,
|
||||||
0x2b, 0x46, 0xf9, 0x82, 0x8a, 0x6a, 0x18, 0xa7, 0x09, 0xcd, 0xf8, 0xe0, 0x10, 0xdc, 0x2f, 0x64,
|
0x18, 0x8b, 0x15, 0x25, 0x6c, 0x41, 0x78, 0xe6, 0xfa, 0x51, 0x48, 0x96, 0x6c, 0xab, 0x1b, 0xc4,
|
||||||
0x46, 0xd3, 0x2b, 0x92, 0x94, 0x08, 0x81, 0x9d, 0x11, 0x46, 0x03, 0xab, 0x6f, 0xed, 0xba, 0x58,
|
0x71, 0x10, 0x91, 0xbe, 0xc4, 0xcc, 0xf9, 0x87, 0x3e, 0x0b, 0x29, 0xc9, 0x98, 0x47, 0x13, 0x45,
|
||||||
0xd5, 0x68, 0x0b, 0x9c, 0x5b, 0x92, 0x0a, 0x1a, 0xac, 0x29, 0x50, 0x2f, 0x06, 0xdb, 0xe0, 0x8c,
|
0x73, 0xf6, 0xc1, 0x7a, 0xe3, 0xcd, 0x49, 0x74, 0xee, 0x85, 0x29, 0x42, 0x60, 0x2e, 0x3d, 0x4a,
|
||||||
0x88, 0x98, 0xdf, 0x69, 0x4b, 0x8d, 0x55, 0xb7, 0x77, 0xa0, 0x77, 0x9a, 0x8b, 0x8c, 0xd3, 0xf2,
|
0x6c, 0xa3, 0x67, 0xec, 0x58, 0x58, 0xae, 0xd1, 0x26, 0xd4, 0xaf, 0xbc, 0x88, 0x13, 0x7b, 0x4d,
|
||||||
0x01, 0xc2, 0x7b, 0x58, 0xff, 0x2a, 0x48, 0xc6, 0x93, 0x94, 0xa2, 0xa7, 0xb0, 0xfe, 0xc3, 0xd4,
|
0x16, 0xd5, 0xc6, 0xd9, 0x86, 0xfa, 0xd0, 0xe3, 0xc1, 0x6f, 0x6d, 0xc1, 0x31, 0xf2, 0xf6, 0x7b,
|
||||||
0x86, 0xb4, 0x5a, 0xdf, 0xdf, 0x7d, 0xa5, 0xfe, 0x65, 0x41, 0x6f, 0x2c, 0x18, 0x23, 0xe5, 0x12,
|
0x68, 0x1e, 0xc7, 0x7c, 0xc9, 0x48, 0x5a, 0x0d, 0x40, 0x07, 0xd0, 0x22, 0x9f, 0x09, 0x4d, 0x22,
|
||||||
0xbd, 0x84, 0x8d, 0x8a, 0xb0, 0x22, 0xa5, 0x51, 0x2c, 0x77, 0x54, 0x13, 0x6c, 0xec, 0x69, 0x4c,
|
0x2f, 0x95, 0x83, 0xdb, 0xbb, 0xf7, 0xdd, 0xaa, 0x03, 0xb8, 0x03, 0x8d, 0xc2, 0x05, 0xde, 0x79,
|
||||||
0x99, 0x40, 0xdb, 0x00, 0x86, 0x52, 0x09, 0x66, 0x26, 0xb9, 0x1a, 0x19, 0x0b, 0x86, 0x8e, 0xee,
|
0x0e, 0xad, 0xb7, 0xdc, 0x5b, 0xb2, 0x30, 0x22, 0x68, 0x0b, 0x5a, 0x9f, 0xf4, 0x5a, 0x7f, 0xa0,
|
||||||
0xec, 0xdf, 0xe9, 0x77, 0x76, 0xbd, 0xfd, 0x17, 0xc3, 0xb6, 0xb3, 0x1a, 0xd6, 0x8e, 0x1b, 0x7f,
|
0xd8, 0x5f, 0x57, 0x5e, 0x48, 0xfb, 0x6a, 0x40, 0x73, 0xcc, 0x29, 0xf5, 0xd2, 0x15, 0x7a, 0x00,
|
||||||
0xf2, 0x43, 0xa7, 0x19, 0x5f, 0x16, 0xf4, 0xe6, 0x81, 0x0f, 0xfd, 0x69, 0x81, 0x7b, 0x9e, 0x54,
|
0xeb, 0x99, 0x47, 0x93, 0x88, 0xcc, 0x7c, 0xa1, 0x56, 0x4e, 0x30, 0x71, 0x5b, 0xd5, 0xe4, 0x01,
|
||||||
0x3c, 0x9f, 0x97, 0x84, 0xfd, 0x03, 0xb3, 0x07, 0xd0, 0x9d, 0x89, 0xf8, 0x3b, 0xe5, 0xc6, 0xea,
|
0xd0, 0x36, 0x80, 0x86, 0x64, 0x9c, 0xea, 0x49, 0x96, 0xaa, 0x8c, 0x39, 0x15, 0xe7, 0x28, 0xbe,
|
||||||
0xf3, 0x76, 0xab, 0x27, 0x8a, 0x83, 0x0d, 0x77, 0x30, 0x81, 0xae, 0x46, 0xd0, 0x2b, 0xf0, 0x63,
|
0x5f, 0xeb, 0xd5, 0x6e, 0x3e, 0x47, 0xae, 0xb8, 0xd4, 0xe7, 0x74, 0xa1, 0x39, 0x5d, 0xb2, 0x55,
|
||||||
0xc1, 0x44, 0x4a, 0x78, 0x72, 0x7b, 0xdf, 0xc5, 0x93, 0x06, 0xd7, 0x4e, 0x76, 0xc0, 0x13, 0x45,
|
0x42, 0x2e, 0x6f, 0xb8, 0xc5, 0x2f, 0x06, 0x58, 0x27, 0x61, 0xc6, 0xe2, 0x20, 0xf5, 0xe8, 0x3f,
|
||||||
0x41, 0xcb, 0x68, 0x96, 0x8b, 0xec, 0xc6, 0x58, 0x01, 0x05, 0x9d, 0x48, 0x64, 0xf0, 0x67, 0x0d,
|
0x10, 0xbb, 0x07, 0x8d, 0x39, 0xf7, 0x3f, 0x12, 0xa6, 0xa5, 0xde, 0xab, 0x96, 0x7a, 0x24, 0x31,
|
||||||
0xba, 0xa1, 0xca, 0x18, 0x3a, 0x04, 0x27, 0x95, 0x31, 0x0a, 0x2c, 0xe5, 0x6a, 0xa7, 0xdd, 0xd5,
|
0x58, 0x63, 0x9d, 0x6f, 0x06, 0x34, 0x54, 0x09, 0x3d, 0x84, 0x8e, 0xcf, 0x29, 0x8f, 0x3c, 0x16,
|
||||||
0x2a, 0x69, 0x58, 0xb3, 0xd1, 0x1b, 0x70, 0xe6, 0x32, 0x46, 0x6a, 0xb8, 0xb7, 0xff, 0xac, 0x5d,
|
0x5e, 0x5d, 0x97, 0x71, 0xa7, 0xac, 0x2b, 0x29, 0x5d, 0x68, 0xf3, 0x24, 0x21, 0xe9, 0x6c, 0x1e,
|
||||||
0xa6, 0x92, 0x86, 0x35, 0x13, 0xbd, 0x85, 0x5e, 0xac, 0xa3, 0x15, 0x74, 0x94, 0x68, 0xbb, 0x5d,
|
0xf3, 0xe5, 0xa5, 0xd6, 0x02, 0xb2, 0x74, 0x24, 0x2a, 0xd7, 0x1c, 0x50, 0xfb, 0x43, 0x07, 0x7c,
|
||||||
0x64, 0xf2, 0x87, 0x6b, 0xb6, 0x14, 0x56, 0x3a, 0x33, 0x81, 0xfd, 0x98, 0xd0, 0x04, 0x0b, 0xd7,
|
0x37, 0xa0, 0x95, 0x97, 0xd1, 0x3e, 0xd4, 0x23, 0xe1, 0x60, 0xdb, 0x90, 0x87, 0xea, 0x56, 0x4f,
|
||||||
0x6c, 0x29, 0x14, 0xfa, 0x8e, 0x03, 0xe7, 0x31, 0xa1, 0x09, 0x02, 0xae, 0xd9, 0xe8, 0x03, 0xb8,
|
0x29, 0x4c, 0x8e, 0x15, 0xba, 0xda, 0x1d, 0xe8, 0x29, 0x58, 0x45, 0x42, 0xb4, 0xac, 0x2d, 0x57,
|
||||||
0x8b, 0xfa, 0xea, 0x83, 0x9e, 0x92, 0x3e, 0x70, 0x30, 0xab, 0x84, 0xe0, 0x46, 0x21, 0xc3, 0xc2,
|
0x65, 0xc8, 0xcd, 0x33, 0xe4, 0x4e, 0x72, 0x04, 0x2e, 0xc1, 0xce, 0xcf, 0x35, 0x68, 0x8c, 0x64,
|
||||||
0x13, 0x46, 0x2b, 0x4e, 0x58, 0x11, 0xb1, 0x2a, 0xe8, 0xf6, 0xad, 0xdd, 0x0e, 0xf6, 0x56, 0x58,
|
0x22, 0xff, 0x56, 0xd1, 0x63, 0xa8, 0x07, 0x22, 0x53, 0x3a, 0x10, 0x77, 0xab, 0x69, 0x32, 0x76,
|
||||||
0x58, 0x0d, 0x7e, 0x5b, 0xb0, 0xa1, 0x6f, 0xe0, 0x13, 0x61, 0x49, 0xba, 0x6c, 0xfd, 0x83, 0x11,
|
0x58, 0x21, 0xd1, 0x13, 0x68, 0xfa, 0x2a, 0x67, 0x5a, 0xec, 0x76, 0x35, 0x49, 0x87, 0x11, 0xe7,
|
||||||
0xd8, 0x0b, 0x9a, 0x16, 0xe6, 0x07, 0x56, 0x35, 0x3a, 0x00, 0x5b, 0x7a, 0x54, 0x47, 0xf8, 0xff,
|
0x68, 0x41, 0xcc, 0x54, 0x08, 0x6c, 0xf3, 0x36, 0xa2, 0x4e, 0x0a, 0xce, 0xd1, 0x82, 0xc8, 0x95,
|
||||||
0x7e, 0xbf, 0xdd, 0x95, 0x9e, 0x3c, 0x59, 0x16, 0x14, 0x2b, 0xb6, 0x0c, 0x9f, 0x7e, 0x53, 0x02,
|
0x69, 0xed, 0xfa, 0x6d, 0x44, 0xed, 0x6c, 0x9c, 0xa3, 0xd1, 0x0b, 0xb0, 0x16, 0xb9, 0x97, 0xed,
|
||||||
0xfb, 0xb1, 0xf0, 0x69, 0x1d, 0x36, 0xdc, 0xd7, 0x21, 0x40, 0x33, 0x09, 0x79, 0xd0, 0x3b, 0xbd,
|
0xa6, 0xa4, 0xde, 0x70, 0x31, 0x85, 0xe5, 0x71, 0xc9, 0x10, 0xee, 0x2f, 0xee, 0x7a, 0x46, 0x33,
|
||||||
0x9c, 0x5e, 0x4c, 0xce, 0xb0, 0xff, 0x1f, 0x72, 0xc1, 0x19, 0x1d, 0x4f, 0x47, 0x67, 0xbe, 0x25,
|
0xbb, 0xd1, 0x33, 0x76, 0x6a, 0xb8, 0x5d, 0xd4, 0x46, 0x99, 0xf3, 0xc3, 0x80, 0x75, 0xf5, 0x07,
|
||||||
0xf1, 0xf1, 0x34, 0x0c, 0x8f, 0xf1, 0xb5, 0xbf, 0x26, 0x17, 0xd3, 0x8b, 0xc9, 0xf5, 0xd5, 0xd9,
|
0x5e, 0x79, 0x34, 0x8c, 0x56, 0x95, 0xcf, 0x19, 0x02, 0x73, 0x41, 0xa2, 0x44, 0xbf, 0x66, 0x72,
|
||||||
0x47, 0xbf, 0x83, 0x36, 0xc1, 0x3d, 0xff, 0x3c, 0x9e, 0x5c, 0x8e, 0xf0, 0x71, 0xe8, 0xdb, 0x27,
|
0x8d, 0xf6, 0xc0, 0x14, 0x1a, 0xe5, 0x15, 0xfe, 0xbf, 0xdb, 0xab, 0x56, 0xa5, 0x26, 0x4f, 0x56,
|
||||||
0x18, 0x5a, 0x5f, 0xb2, 0x6f, 0x47, 0xf3, 0x84, 0x2f, 0xc4, 0x6c, 0x18, 0xe7, 0x6c, 0xaf, 0xe9,
|
0x09, 0xc1, 0x12, 0x2d, 0xd2, 0xa4, 0x5e, 0x60, 0xdb, 0xbc, 0x2d, 0x4d, 0x8a, 0x87, 0x35, 0xf6,
|
||||||
0xee, 0xe9, 0x6e, 0xc4, 0xf2, 0x1b, 0x9a, 0xee, 0xcd, 0xf3, 0x77, 0x49, 0x1e, 0x35, 0xdd, 0x48,
|
0xd1, 0x08, 0xa0, 0x9c, 0x84, 0xda, 0xd0, 0x3c, 0x3e, 0x9b, 0x9e, 0x4e, 0x06, 0xb8, 0xf3, 0x1f,
|
||||||
0x77, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x45, 0x21, 0x7f, 0x64, 0x2b, 0x05, 0x00, 0x00,
|
0xb2, 0xa0, 0x3e, 0x3c, 0x9c, 0x0e, 0x07, 0x1d, 0x43, 0xd4, 0xc7, 0xd3, 0xd1, 0xe8, 0x10, 0x5f,
|
||||||
|
0x74, 0xd6, 0xc4, 0x66, 0x7a, 0x3a, 0xb9, 0x38, 0x1f, 0xbc, 0xec, 0xd4, 0xd0, 0x06, 0x58, 0x27,
|
||||||
|
0xaf, 0xc7, 0x93, 0xb3, 0x21, 0x3e, 0x1c, 0x75, 0xcc, 0x23, 0x0c, 0x95, 0xef, 0xfe, 0xbb, 0x83,
|
||||||
|
0x20, 0x64, 0x0b, 0x3e, 0x77, 0xfd, 0x98, 0xf6, 0xcb, 0x6e, 0x5f, 0x75, 0x67, 0x34, 0xbe, 0x24,
|
||||||
|
0x51, 0x3f, 0x88, 0x9f, 0x85, 0xf1, 0xac, 0xec, 0xce, 0x54, 0xf7, 0x57, 0x00, 0x00, 0x00, 0xff,
|
||||||
|
0xff, 0xd0, 0x84, 0x91, 0x73, 0x59, 0x06, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
4
vendor/github.com/prometheus/common/expfmt/decode.go
generated
vendored
4
vendor/github.com/prometheus/common/expfmt/decode.go
generated
vendored
@ -164,9 +164,9 @@ func (sd *SampleDecoder) Decode(s *model.Vector) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ExtractSamples builds a slice of samples from the provided metric
|
// ExtractSamples builds a slice of samples from the provided metric
|
||||||
// families. If an error occurs during sample extraction, it continues to
|
// families. If an error occurrs during sample extraction, it continues to
|
||||||
// extract from the remaining metric families. The returned error is the last
|
// extract from the remaining metric families. The returned error is the last
|
||||||
// error that has occured.
|
// error that has occurred.
|
||||||
func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) (model.Vector, error) {
|
func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) (model.Vector, error) {
|
||||||
var (
|
var (
|
||||||
all model.Vector
|
all model.Vector
|
||||||
|
2
vendor/github.com/prometheus/common/expfmt/expfmt.go
generated
vendored
2
vendor/github.com/prometheus/common/expfmt/expfmt.go
generated
vendored
@ -26,7 +26,7 @@ const (
|
|||||||
|
|
||||||
// The Content-Type values for the different wire protocols.
|
// The Content-Type values for the different wire protocols.
|
||||||
FmtUnknown Format = `<unknown>`
|
FmtUnknown Format = `<unknown>`
|
||||||
FmtText Format = `text/plain; version=` + TextVersion
|
FmtText Format = `text/plain; version=` + TextVersion + `; charset=utf-8`
|
||||||
FmtProtoDelim Format = ProtoFmt + ` encoding=delimited`
|
FmtProtoDelim Format = ProtoFmt + ` encoding=delimited`
|
||||||
FmtProtoText Format = ProtoFmt + ` encoding=text`
|
FmtProtoText Format = ProtoFmt + ` encoding=text`
|
||||||
FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text`
|
FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text`
|
||||||
|
365
vendor/github.com/prometheus/common/expfmt/text_create.go
generated
vendored
365
vendor/github.com/prometheus/common/expfmt/text_create.go
generated
vendored
@ -14,13 +14,45 @@
|
|||||||
package expfmt
|
package expfmt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/prometheus/common/model"
|
||||||
|
|
||||||
dto "github.com/prometheus/client_model/go"
|
dto "github.com/prometheus/client_model/go"
|
||||||
"github.com/prometheus/common/model"
|
)
|
||||||
|
|
||||||
|
// enhancedWriter has all the enhanced write functions needed here. bytes.Buffer
|
||||||
|
// implements it.
|
||||||
|
type enhancedWriter interface {
|
||||||
|
io.Writer
|
||||||
|
WriteRune(r rune) (n int, err error)
|
||||||
|
WriteString(s string) (n int, err error)
|
||||||
|
WriteByte(c byte) error
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
initialBufSize = 512
|
||||||
|
initialNumBufSize = 24
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
bufPool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return bytes.NewBuffer(make([]byte, 0, initialBufSize))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
numBufPool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
b := make([]byte, 0, initialNumBufSize)
|
||||||
|
return &b
|
||||||
|
},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// MetricFamilyToText converts a MetricFamily proto message into text format and
|
// MetricFamilyToText converts a MetricFamily proto message into text format and
|
||||||
@ -32,37 +64,92 @@ import (
|
|||||||
// will result in invalid text format output.
|
// will result in invalid text format output.
|
||||||
//
|
//
|
||||||
// This method fulfills the type 'prometheus.encoder'.
|
// This method fulfills the type 'prometheus.encoder'.
|
||||||
func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
|
func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err error) {
|
||||||
var written int
|
|
||||||
|
|
||||||
// Fail-fast checks.
|
// Fail-fast checks.
|
||||||
if len(in.Metric) == 0 {
|
if len(in.Metric) == 0 {
|
||||||
return written, fmt.Errorf("MetricFamily has no metrics: %s", in)
|
return 0, fmt.Errorf("MetricFamily has no metrics: %s", in)
|
||||||
}
|
}
|
||||||
name := in.GetName()
|
name := in.GetName()
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return written, fmt.Errorf("MetricFamily has no name: %s", in)
|
return 0, fmt.Errorf("MetricFamily has no name: %s", in)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try the interface upgrade. If it doesn't work, we'll use a
|
||||||
|
// bytes.Buffer from the sync.Pool and write out its content to out in a
|
||||||
|
// single go in the end.
|
||||||
|
w, ok := out.(enhancedWriter)
|
||||||
|
if !ok {
|
||||||
|
b := bufPool.Get().(*bytes.Buffer)
|
||||||
|
b.Reset()
|
||||||
|
w = b
|
||||||
|
defer func() {
|
||||||
|
bWritten, bErr := out.Write(b.Bytes())
|
||||||
|
written = bWritten
|
||||||
|
if err == nil {
|
||||||
|
err = bErr
|
||||||
|
}
|
||||||
|
bufPool.Put(b)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
var n int
|
||||||
|
|
||||||
// Comments, first HELP, then TYPE.
|
// Comments, first HELP, then TYPE.
|
||||||
if in.Help != nil {
|
if in.Help != nil {
|
||||||
n, err := fmt.Fprintf(
|
n, err = w.WriteString("# HELP ")
|
||||||
out, "# HELP %s %s\n",
|
|
||||||
name, escapeString(*in.Help, false),
|
|
||||||
)
|
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return
|
||||||
}
|
}
|
||||||
|
n, err = w.WriteString(name)
|
||||||
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = w.WriteByte(' ')
|
||||||
|
written++
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n, err = writeEscapedString(w, *in.Help, false)
|
||||||
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = w.WriteByte('\n')
|
||||||
|
written++
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n, err = w.WriteString("# TYPE ")
|
||||||
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n, err = w.WriteString(name)
|
||||||
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
metricType := in.GetType()
|
metricType := in.GetType()
|
||||||
n, err := fmt.Fprintf(
|
switch metricType {
|
||||||
out, "# TYPE %s %s\n",
|
case dto.MetricType_COUNTER:
|
||||||
name, strings.ToLower(metricType.String()),
|
n, err = w.WriteString(" counter\n")
|
||||||
)
|
case dto.MetricType_GAUGE:
|
||||||
|
n, err = w.WriteString(" gauge\n")
|
||||||
|
case dto.MetricType_SUMMARY:
|
||||||
|
n, err = w.WriteString(" summary\n")
|
||||||
|
case dto.MetricType_UNTYPED:
|
||||||
|
n, err = w.WriteString(" untyped\n")
|
||||||
|
case dto.MetricType_HISTOGRAM:
|
||||||
|
n, err = w.WriteString(" histogram\n")
|
||||||
|
default:
|
||||||
|
return written, fmt.Errorf("unknown metric type %s", metricType.String())
|
||||||
|
}
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally the samples, one line for each.
|
// Finally the samples, one line for each.
|
||||||
@ -75,9 +162,8 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
n, err = writeSample(
|
n, err = writeSample(
|
||||||
name, metric, "", "",
|
w, name, "", metric, "", 0,
|
||||||
metric.Counter.GetValue(),
|
metric.Counter.GetValue(),
|
||||||
out,
|
|
||||||
)
|
)
|
||||||
case dto.MetricType_GAUGE:
|
case dto.MetricType_GAUGE:
|
||||||
if metric.Gauge == nil {
|
if metric.Gauge == nil {
|
||||||
@ -86,9 +172,8 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
n, err = writeSample(
|
n, err = writeSample(
|
||||||
name, metric, "", "",
|
w, name, "", metric, "", 0,
|
||||||
metric.Gauge.GetValue(),
|
metric.Gauge.GetValue(),
|
||||||
out,
|
|
||||||
)
|
)
|
||||||
case dto.MetricType_UNTYPED:
|
case dto.MetricType_UNTYPED:
|
||||||
if metric.Untyped == nil {
|
if metric.Untyped == nil {
|
||||||
@ -97,9 +182,8 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
n, err = writeSample(
|
n, err = writeSample(
|
||||||
name, metric, "", "",
|
w, name, "", metric, "", 0,
|
||||||
metric.Untyped.GetValue(),
|
metric.Untyped.GetValue(),
|
||||||
out,
|
|
||||||
)
|
)
|
||||||
case dto.MetricType_SUMMARY:
|
case dto.MetricType_SUMMARY:
|
||||||
if metric.Summary == nil {
|
if metric.Summary == nil {
|
||||||
@ -109,29 +193,26 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
|
|||||||
}
|
}
|
||||||
for _, q := range metric.Summary.Quantile {
|
for _, q := range metric.Summary.Quantile {
|
||||||
n, err = writeSample(
|
n, err = writeSample(
|
||||||
name, metric,
|
w, name, "", metric,
|
||||||
model.QuantileLabel, fmt.Sprint(q.GetQuantile()),
|
model.QuantileLabel, q.GetQuantile(),
|
||||||
q.GetValue(),
|
q.GetValue(),
|
||||||
out,
|
|
||||||
)
|
)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n, err = writeSample(
|
n, err = writeSample(
|
||||||
name+"_sum", metric, "", "",
|
w, name, "_sum", metric, "", 0,
|
||||||
metric.Summary.GetSampleSum(),
|
metric.Summary.GetSampleSum(),
|
||||||
out,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
written += n
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
n, err = writeSample(
|
n, err = writeSample(
|
||||||
name+"_count", metric, "", "",
|
w, name, "_count", metric, "", 0,
|
||||||
float64(metric.Summary.GetSampleCount()),
|
float64(metric.Summary.GetSampleCount()),
|
||||||
out,
|
|
||||||
)
|
)
|
||||||
case dto.MetricType_HISTOGRAM:
|
case dto.MetricType_HISTOGRAM:
|
||||||
if metric.Histogram == nil {
|
if metric.Histogram == nil {
|
||||||
@ -140,46 +221,42 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
infSeen := false
|
infSeen := false
|
||||||
for _, q := range metric.Histogram.Bucket {
|
for _, b := range metric.Histogram.Bucket {
|
||||||
n, err = writeSample(
|
n, err = writeSample(
|
||||||
name+"_bucket", metric,
|
w, name, "_bucket", metric,
|
||||||
model.BucketLabel, fmt.Sprint(q.GetUpperBound()),
|
model.BucketLabel, b.GetUpperBound(),
|
||||||
float64(q.GetCumulativeCount()),
|
float64(b.GetCumulativeCount()),
|
||||||
out,
|
|
||||||
)
|
)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return
|
||||||
}
|
}
|
||||||
if math.IsInf(q.GetUpperBound(), +1) {
|
if math.IsInf(b.GetUpperBound(), +1) {
|
||||||
infSeen = true
|
infSeen = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !infSeen {
|
if !infSeen {
|
||||||
n, err = writeSample(
|
n, err = writeSample(
|
||||||
name+"_bucket", metric,
|
w, name, "_bucket", metric,
|
||||||
model.BucketLabel, "+Inf",
|
model.BucketLabel, math.Inf(+1),
|
||||||
float64(metric.Histogram.GetSampleCount()),
|
float64(metric.Histogram.GetSampleCount()),
|
||||||
out,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
written += n
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
n, err = writeSample(
|
n, err = writeSample(
|
||||||
name+"_sum", metric, "", "",
|
w, name, "_sum", metric, "", 0,
|
||||||
metric.Histogram.GetSampleSum(),
|
metric.Histogram.GetSampleSum(),
|
||||||
out,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
return written, err
|
|
||||||
}
|
|
||||||
written += n
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
n, err = writeSample(
|
n, err = writeSample(
|
||||||
name+"_count", metric, "", "",
|
w, name, "_count", metric, "", 0,
|
||||||
float64(metric.Histogram.GetSampleCount()),
|
float64(metric.Histogram.GetSampleCount()),
|
||||||
out,
|
|
||||||
)
|
)
|
||||||
default:
|
default:
|
||||||
return written, fmt.Errorf(
|
return written, fmt.Errorf(
|
||||||
@ -188,116 +265,204 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
|
|||||||
}
|
}
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return written, nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeSample writes a single sample in text format to out, given the metric
|
// writeSample writes a single sample in text format to w, given the metric
|
||||||
// name, the metric proto message itself, optionally an additional label name
|
// name, the metric proto message itself, optionally an additional label name
|
||||||
// and value (use empty strings if not required), and the value. The function
|
// with a float64 value (use empty string as label name if not required), and
|
||||||
// returns the number of bytes written and any error encountered.
|
// the value. The function returns the number of bytes written and any error
|
||||||
|
// encountered.
|
||||||
func writeSample(
|
func writeSample(
|
||||||
name string,
|
w enhancedWriter,
|
||||||
|
name, suffix string,
|
||||||
metric *dto.Metric,
|
metric *dto.Metric,
|
||||||
additionalLabelName, additionalLabelValue string,
|
additionalLabelName string, additionalLabelValue float64,
|
||||||
value float64,
|
value float64,
|
||||||
out io.Writer,
|
|
||||||
) (int, error) {
|
) (int, error) {
|
||||||
var written int
|
var written int
|
||||||
n, err := fmt.Fprint(out, name)
|
n, err := w.WriteString(name)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
n, err = labelPairsToText(
|
if suffix != "" {
|
||||||
metric.Label,
|
n, err = w.WriteString(suffix)
|
||||||
additionalLabelName, additionalLabelValue,
|
written += n
|
||||||
out,
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n, err = writeLabelPairs(
|
||||||
|
w, metric.Label, additionalLabelName, additionalLabelValue,
|
||||||
)
|
)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
n, err = fmt.Fprintf(out, " %v", value)
|
err = w.WriteByte(' ')
|
||||||
|
written++
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
n, err = writeFloat(w, value)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
if metric.TimestampMs != nil {
|
if metric.TimestampMs != nil {
|
||||||
n, err = fmt.Fprintf(out, " %v", *metric.TimestampMs)
|
err = w.WriteByte(' ')
|
||||||
|
written++
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
n, err = writeInt(w, *metric.TimestampMs)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n, err = out.Write([]byte{'\n'})
|
err = w.WriteByte('\n')
|
||||||
written += n
|
written++
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
return written, nil
|
return written, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// labelPairsToText converts a slice of LabelPair proto messages plus the
|
// writeLabelPairs converts a slice of LabelPair proto messages plus the
|
||||||
// explicitly given additional label pair into text formatted as required by the
|
// explicitly given additional label pair into text formatted as required by the
|
||||||
// text format and writes it to 'out'. An empty slice in combination with an
|
// text format and writes it to 'w'. An empty slice in combination with an empty
|
||||||
// empty string 'additionalLabelName' results in nothing being
|
// string 'additionalLabelName' results in nothing being written. Otherwise, the
|
||||||
// written. Otherwise, the label pairs are written, escaped as required by the
|
// label pairs are written, escaped as required by the text format, and enclosed
|
||||||
// text format, and enclosed in '{...}'. The function returns the number of
|
// in '{...}'. The function returns the number of bytes written and any error
|
||||||
// bytes written and any error encountered.
|
// encountered.
|
||||||
func labelPairsToText(
|
func writeLabelPairs(
|
||||||
|
w enhancedWriter,
|
||||||
in []*dto.LabelPair,
|
in []*dto.LabelPair,
|
||||||
additionalLabelName, additionalLabelValue string,
|
additionalLabelName string, additionalLabelValue float64,
|
||||||
out io.Writer,
|
|
||||||
) (int, error) {
|
) (int, error) {
|
||||||
if len(in) == 0 && additionalLabelName == "" {
|
if len(in) == 0 && additionalLabelName == "" {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
var written int
|
var (
|
||||||
separator := '{'
|
written int
|
||||||
for _, lp := range in {
|
separator byte = '{'
|
||||||
n, err := fmt.Fprintf(
|
|
||||||
out, `%c%s="%s"`,
|
|
||||||
separator, lp.GetName(), escapeString(lp.GetValue(), true),
|
|
||||||
)
|
)
|
||||||
|
for _, lp := range in {
|
||||||
|
err := w.WriteByte(separator)
|
||||||
|
written++
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
n, err := w.WriteString(lp.GetName())
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
|
n, err = w.WriteString(`="`)
|
||||||
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
n, err = writeEscapedString(w, lp.GetValue(), true)
|
||||||
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
err = w.WriteByte('"')
|
||||||
|
written++
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
separator = ','
|
separator = ','
|
||||||
}
|
}
|
||||||
if additionalLabelName != "" {
|
if additionalLabelName != "" {
|
||||||
n, err := fmt.Fprintf(
|
err := w.WriteByte(separator)
|
||||||
out, `%c%s="%s"`,
|
written++
|
||||||
separator, additionalLabelName,
|
if err != nil {
|
||||||
escapeString(additionalLabelValue, true),
|
return written, err
|
||||||
)
|
}
|
||||||
|
n, err := w.WriteString(additionalLabelName)
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
}
|
n, err = w.WriteString(`="`)
|
||||||
n, err := out.Write([]byte{'}'})
|
|
||||||
written += n
|
written += n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return written, err
|
return written, err
|
||||||
}
|
}
|
||||||
|
n, err = writeFloat(w, additionalLabelValue)
|
||||||
|
written += n
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
err = w.WriteByte('"')
|
||||||
|
written++
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err := w.WriteByte('}')
|
||||||
|
written++
|
||||||
|
if err != nil {
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
return written, nil
|
return written, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeEscapedString replaces '\' by '\\', new line character by '\n', and - if
|
||||||
|
// includeDoubleQuote is true - '"' by '\"'.
|
||||||
var (
|
var (
|
||||||
escape = strings.NewReplacer("\\", `\\`, "\n", `\n`)
|
escaper = strings.NewReplacer("\\", `\\`, "\n", `\n`)
|
||||||
escapeWithDoubleQuote = strings.NewReplacer("\\", `\\`, "\n", `\n`, "\"", `\"`)
|
quotedEscaper = strings.NewReplacer("\\", `\\`, "\n", `\n`, "\"", `\"`)
|
||||||
)
|
)
|
||||||
|
|
||||||
// escapeString replaces '\' by '\\', new line character by '\n', and - if
|
func writeEscapedString(w enhancedWriter, v string, includeDoubleQuote bool) (int, error) {
|
||||||
// includeDoubleQuote is true - '"' by '\"'.
|
|
||||||
func escapeString(v string, includeDoubleQuote bool) string {
|
|
||||||
if includeDoubleQuote {
|
if includeDoubleQuote {
|
||||||
return escapeWithDoubleQuote.Replace(v)
|
return quotedEscaper.WriteString(w, v)
|
||||||
|
} else {
|
||||||
|
return escaper.WriteString(w, v)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return escape.Replace(v)
|
|
||||||
|
// writeFloat is equivalent to fmt.Fprint with a float64 argument but hardcodes
|
||||||
|
// a few common cases for increased efficiency. For non-hardcoded cases, it uses
|
||||||
|
// strconv.AppendFloat to avoid allocations, similar to writeInt.
|
||||||
|
func writeFloat(w enhancedWriter, f float64) (int, error) {
|
||||||
|
switch {
|
||||||
|
case f == 1:
|
||||||
|
return 1, w.WriteByte('1')
|
||||||
|
case f == 0:
|
||||||
|
return 1, w.WriteByte('0')
|
||||||
|
case f == -1:
|
||||||
|
return w.WriteString("-1")
|
||||||
|
case math.IsNaN(f):
|
||||||
|
return w.WriteString("NaN")
|
||||||
|
case math.IsInf(f, +1):
|
||||||
|
return w.WriteString("+Inf")
|
||||||
|
case math.IsInf(f, -1):
|
||||||
|
return w.WriteString("-Inf")
|
||||||
|
default:
|
||||||
|
bp := numBufPool.Get().(*[]byte)
|
||||||
|
*bp = strconv.AppendFloat((*bp)[:0], f, 'g', -1, 64)
|
||||||
|
written, err := w.Write(*bp)
|
||||||
|
numBufPool.Put(bp)
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeInt is equivalent to fmt.Fprint with an int64 argument but uses
|
||||||
|
// strconv.AppendInt with a byte slice taken from a sync.Pool to avoid
|
||||||
|
// allocations.
|
||||||
|
func writeInt(w enhancedWriter, i int64) (int, error) {
|
||||||
|
bp := numBufPool.Get().(*[]byte)
|
||||||
|
*bp = strconv.AppendInt((*bp)[:0], i, 10)
|
||||||
|
written, err := w.Write(*bp)
|
||||||
|
numBufPool.Put(bp)
|
||||||
|
return written, err
|
||||||
}
|
}
|
||||||
|
10
vendor/github.com/prometheus/common/expfmt/text_parse.go
generated
vendored
10
vendor/github.com/prometheus/common/expfmt/text_parse.go
generated
vendored
@ -315,6 +315,10 @@ func (p *TextParser) startLabelValue() stateFn {
|
|||||||
if p.readTokenAsLabelValue(); p.err != nil {
|
if p.readTokenAsLabelValue(); p.err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if !model.LabelValue(p.currentToken.String()).IsValid() {
|
||||||
|
p.parseError(fmt.Sprintf("invalid label value %q", p.currentToken.String()))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
p.currentLabelPair.Value = proto.String(p.currentToken.String())
|
p.currentLabelPair.Value = proto.String(p.currentToken.String())
|
||||||
// Special treatment of summaries:
|
// Special treatment of summaries:
|
||||||
// - Quantile labels are special, will result in dto.Quantile later.
|
// - Quantile labels are special, will result in dto.Quantile later.
|
||||||
@ -355,7 +359,7 @@ func (p *TextParser) startLabelValue() stateFn {
|
|||||||
}
|
}
|
||||||
return p.readingValue
|
return p.readingValue
|
||||||
default:
|
default:
|
||||||
p.parseError(fmt.Sprintf("unexpected end of label value %q", p.currentLabelPair.Value))
|
p.parseError(fmt.Sprintf("unexpected end of label value %q", p.currentLabelPair.GetValue()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -552,8 +556,8 @@ func (p *TextParser) readTokenUntilWhitespace() {
|
|||||||
// byte considered is the byte already read (now in p.currentByte). The first
|
// byte considered is the byte already read (now in p.currentByte). The first
|
||||||
// newline byte encountered is still copied into p.currentByte, but not into
|
// newline byte encountered is still copied into p.currentByte, but not into
|
||||||
// p.currentToken. If recognizeEscapeSequence is true, two escape sequences are
|
// p.currentToken. If recognizeEscapeSequence is true, two escape sequences are
|
||||||
// recognized: '\\' tranlates into '\', and '\n' into a line-feed character. All
|
// recognized: '\\' translates into '\', and '\n' into a line-feed character.
|
||||||
// other escape sequences are invalid and cause an error.
|
// All other escape sequences are invalid and cause an error.
|
||||||
func (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) {
|
func (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) {
|
||||||
p.currentToken.Reset()
|
p.currentToken.Reset()
|
||||||
escaped := false
|
escaped := false
|
||||||
|
6
vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go
generated
vendored
6
vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go
generated
vendored
@ -1,12 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
|
Copyright (c) 2011, Open Knowledge Foundation Ltd.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
HTTP Content-Type Autonegotiation.
|
HTTP Content-Type Autonegotiation.
|
||||||
|
|
||||||
The functions in this package implement the behaviour specified in
|
The functions in this package implement the behaviour specified in
|
||||||
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||||
|
|
||||||
Copyright (c) 2011, Open Knowledge Foundation Ltd.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
met:
|
met:
|
||||||
|
1
vendor/github.com/prometheus/common/model/metric.go
generated
vendored
1
vendor/github.com/prometheus/common/model/metric.go
generated
vendored
@ -21,7 +21,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
separator = []byte{0}
|
|
||||||
// MetricNameRE is a regular expression matching valid metric
|
// MetricNameRE is a regular expression matching valid metric
|
||||||
// names. Note that the IsValidMetricName function performs the same
|
// names. Note that the IsValidMetricName function performs the same
|
||||||
// check but faster than a match with this regular expression.
|
// check but faster than a match with this regular expression.
|
||||||
|
4
vendor/github.com/prometheus/common/model/silence.go
generated
vendored
4
vendor/github.com/prometheus/common/model/silence.go
generated
vendored
@ -59,8 +59,8 @@ func (m *Matcher) Validate() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Silence defines the representation of a silence definiton
|
// Silence defines the representation of a silence definition in the Prometheus
|
||||||
// in the Prometheus eco-system.
|
// eco-system.
|
||||||
type Silence struct {
|
type Silence struct {
|
||||||
ID uint64 `json:"id,omitempty"`
|
ID uint64 `json:"id,omitempty"`
|
||||||
|
|
||||||
|
25
vendor/github.com/prometheus/common/model/time.go
generated
vendored
25
vendor/github.com/prometheus/common/model/time.go
generated
vendored
@ -43,7 +43,7 @@ const (
|
|||||||
// (1970-01-01 00:00 UTC) excluding leap seconds.
|
// (1970-01-01 00:00 UTC) excluding leap seconds.
|
||||||
type Time int64
|
type Time int64
|
||||||
|
|
||||||
// Interval describes and interval between two timestamps.
|
// Interval describes an interval between two timestamps.
|
||||||
type Interval struct {
|
type Interval struct {
|
||||||
Start, End Time
|
Start, End Time
|
||||||
}
|
}
|
||||||
@ -150,7 +150,13 @@ func (t *Time) UnmarshalJSON(b []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the value was something like -0.1 the negative is lost in the
|
||||||
|
// parsing because of the leading zero, this ensures that we capture it.
|
||||||
|
if len(p[0]) > 0 && p[0][0] == '-' && v+va > 0 {
|
||||||
|
*t = Time(v+va) * -1
|
||||||
|
} else {
|
||||||
*t = Time(v + va)
|
*t = Time(v + va)
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid time %q", string(b))
|
return fmt.Errorf("invalid time %q", string(b))
|
||||||
@ -163,9 +169,21 @@ func (t *Time) UnmarshalJSON(b []byte) error {
|
|||||||
// This type should not propagate beyond the scope of input/output processing.
|
// This type should not propagate beyond the scope of input/output processing.
|
||||||
type Duration time.Duration
|
type Duration time.Duration
|
||||||
|
|
||||||
|
// Set implements pflag/flag.Value
|
||||||
|
func (d *Duration) Set(s string) error {
|
||||||
|
var err error
|
||||||
|
*d, err = ParseDuration(s)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type implements pflag.Value
|
||||||
|
func (d *Duration) Type() string {
|
||||||
|
return "duration"
|
||||||
|
}
|
||||||
|
|
||||||
var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$")
|
var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$")
|
||||||
|
|
||||||
// StringToDuration parses a string into a time.Duration, assuming that a year
|
// ParseDuration parses a string into a time.Duration, assuming that a year
|
||||||
// always has 365d, a week always has 7d, and a day always has 24h.
|
// always has 365d, a week always has 7d, and a day always has 24h.
|
||||||
func ParseDuration(durationStr string) (Duration, error) {
|
func ParseDuration(durationStr string) (Duration, error) {
|
||||||
matches := durationRE.FindStringSubmatch(durationStr)
|
matches := durationRE.FindStringSubmatch(durationStr)
|
||||||
@ -202,6 +220,9 @@ func (d Duration) String() string {
|
|||||||
ms = int64(time.Duration(d) / time.Millisecond)
|
ms = int64(time.Duration(d) / time.Millisecond)
|
||||||
unit = "ms"
|
unit = "ms"
|
||||||
)
|
)
|
||||||
|
if ms == 0 {
|
||||||
|
return "0s"
|
||||||
|
}
|
||||||
factors := map[string]int64{
|
factors := map[string]int64{
|
||||||
"y": 1000 * 60 * 60 * 24 * 365,
|
"y": 1000 * 60 * 60 * 24 * 365,
|
||||||
"w": 1000 * 60 * 60 * 24 * 7,
|
"w": 1000 * 60 * 60 * 24 * 7,
|
||||||
|
4
vendor/github.com/prometheus/common/model/value.go
generated
vendored
4
vendor/github.com/prometheus/common/model/value.go
generated
vendored
@ -100,7 +100,7 @@ func (s *SamplePair) UnmarshalJSON(b []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Equal returns true if this SamplePair and o have equal Values and equal
|
// Equal returns true if this SamplePair and o have equal Values and equal
|
||||||
// Timestamps. The sematics of Value equality is defined by SampleValue.Equal.
|
// Timestamps. The semantics of Value equality is defined by SampleValue.Equal.
|
||||||
func (s *SamplePair) Equal(o *SamplePair) bool {
|
func (s *SamplePair) Equal(o *SamplePair) bool {
|
||||||
return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp))
|
return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp))
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ type Sample struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Equal compares first the metrics, then the timestamp, then the value. The
|
// Equal compares first the metrics, then the timestamp, then the value. The
|
||||||
// sematics of value equality is defined by SampleValue.Equal.
|
// semantics of value equality is defined by SampleValue.Equal.
|
||||||
func (s *Sample) Equal(o *Sample) bool {
|
func (s *Sample) Equal(o *Sample) bool {
|
||||||
if s == o {
|
if s == o {
|
||||||
return true
|
return true
|
||||||
|
14
vendor/modules.txt
vendored
14
vendor/modules.txt
vendored
@ -37,7 +37,7 @@ github.com/aws/aws-sdk-go/private/protocol/query/queryutil
|
|||||||
github.com/aws/aws-sdk-go/private/protocol/rest
|
github.com/aws/aws-sdk-go/private/protocol/rest
|
||||||
github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil
|
github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil
|
||||||
github.com/aws/aws-sdk-go/service/sts
|
github.com/aws/aws-sdk-go/service/sts
|
||||||
# github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f
|
# github.com/beorn7/perks v1.0.0
|
||||||
github.com/beorn7/perks/quantile
|
github.com/beorn7/perks/quantile
|
||||||
# github.com/blang/semver v3.1.0+incompatible
|
# github.com/blang/semver v3.1.0+incompatible
|
||||||
github.com/blang/semver
|
github.com/blang/semver
|
||||||
@ -126,6 +126,12 @@ github.com/golang/protobuf/ptypes/duration
|
|||||||
github.com/golang/protobuf/ptypes/timestamp
|
github.com/golang/protobuf/ptypes/timestamp
|
||||||
# github.com/golang/snappy v0.0.0-20150730031844-723cc1e459b8
|
# github.com/golang/snappy v0.0.0-20150730031844-723cc1e459b8
|
||||||
github.com/golang/snappy
|
github.com/golang/snappy
|
||||||
|
# github.com/google/go-cmp v0.3.1
|
||||||
|
github.com/google/go-cmp/cmp
|
||||||
|
github.com/google/go-cmp/cmp/internal/diff
|
||||||
|
github.com/google/go-cmp/cmp/internal/flags
|
||||||
|
github.com/google/go-cmp/cmp/internal/function
|
||||||
|
github.com/google/go-cmp/cmp/internal/value
|
||||||
# github.com/google/uuid v1.1.1
|
# github.com/google/uuid v1.1.1
|
||||||
github.com/google/uuid
|
github.com/google/uuid
|
||||||
# github.com/influxdb/influxdb v0.9.6-0.20151125225445-9eab56311373
|
# github.com/influxdb/influxdb v0.9.6-0.20151125225445-9eab56311373
|
||||||
@ -206,13 +212,13 @@ github.com/pmezard/go-difflib/difflib
|
|||||||
# github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13
|
# github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13
|
||||||
github.com/pquerna/ffjson/fflib/v1
|
github.com/pquerna/ffjson/fflib/v1
|
||||||
github.com/pquerna/ffjson/fflib/v1/internal
|
github.com/pquerna/ffjson/fflib/v1/internal
|
||||||
# github.com/prometheus/client_golang v0.9.1
|
# github.com/prometheus/client_golang v1.0.0
|
||||||
github.com/prometheus/client_golang/prometheus
|
github.com/prometheus/client_golang/prometheus
|
||||||
github.com/prometheus/client_golang/prometheus/internal
|
github.com/prometheus/client_golang/prometheus/internal
|
||||||
github.com/prometheus/client_golang/prometheus/promhttp
|
github.com/prometheus/client_golang/prometheus/promhttp
|
||||||
# github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4
|
# github.com/prometheus/client_model v0.2.0
|
||||||
github.com/prometheus/client_model/go
|
github.com/prometheus/client_model/go
|
||||||
# github.com/prometheus/common v0.0.0-20170220103846-49fee292b27b
|
# github.com/prometheus/common v0.4.1
|
||||||
github.com/prometheus/common/expfmt
|
github.com/prometheus/common/expfmt
|
||||||
github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg
|
github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg
|
||||||
github.com/prometheus/common/model
|
github.com/prometheus/common/model
|
||||||
|
Loading…
Reference in New Issue
Block a user