aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/go.opencensus.io
diff options
context:
space:
mode:
authorNathan Dench <ndenc2@gmail.com>2019-05-24 15:16:44 +1000
committerNathan Dench <ndenc2@gmail.com>2019-05-24 15:16:44 +1000
commit107c1cdb09c575aa2f61d97f48d8587eb6bada4c (patch)
treeca7d008643efc555c388baeaf1d986e0b6b3e28c /vendor/go.opencensus.io
parent844b5a68d8af4791755b8f0ad293cc99f5959183 (diff)
downloadterraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.gz
terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.zst
terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.zip
Upgrade to 0.12
Diffstat (limited to 'vendor/go.opencensus.io')
-rw-r--r--vendor/go.opencensus.io/.gitignore9
-rw-r--r--vendor/go.opencensus.io/.travis.yml27
-rw-r--r--vendor/go.opencensus.io/AUTHORS1
-rw-r--r--vendor/go.opencensus.io/CONTRIBUTING.md56
-rw-r--r--vendor/go.opencensus.io/Gopkg.lock231
-rw-r--r--vendor/go.opencensus.io/Gopkg.toml36
-rw-r--r--vendor/go.opencensus.io/LICENSE202
-rw-r--r--vendor/go.opencensus.io/README.md263
-rw-r--r--vendor/go.opencensus.io/appveyor.yml24
-rw-r--r--vendor/go.opencensus.io/exemplar/exemplar.go78
-rw-r--r--vendor/go.opencensus.io/go.mod25
-rw-r--r--vendor/go.opencensus.io/go.sum48
-rw-r--r--vendor/go.opencensus.io/internal/internal.go37
-rw-r--r--vendor/go.opencensus.io/internal/sanitize.go50
-rw-r--r--vendor/go.opencensus.io/internal/tagencoding/tagencoding.go72
-rw-r--r--vendor/go.opencensus.io/internal/traceinternals.go52
-rw-r--r--vendor/go.opencensus.io/opencensus.go21
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/client.go117
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/client_stats.go135
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/doc.go19
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go123
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/route.go51
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/server.go440
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/span_annotating_client_trace.go169
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/stats.go265
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/trace.go228
-rw-r--r--vendor/go.opencensus.io/stats/doc.go69
-rw-r--r--vendor/go.opencensus.io/stats/internal/record.go25
-rw-r--r--vendor/go.opencensus.io/stats/internal/validation.go28
-rw-r--r--vendor/go.opencensus.io/stats/measure.go123
-rw-r--r--vendor/go.opencensus.io/stats/measure_float64.go36
-rw-r--r--vendor/go.opencensus.io/stats/measure_int64.go36
-rw-r--r--vendor/go.opencensus.io/stats/record.go69
-rw-r--r--vendor/go.opencensus.io/stats/units.go25
-rw-r--r--vendor/go.opencensus.io/stats/view/aggregation.go120
-rw-r--r--vendor/go.opencensus.io/stats/view/aggregation_data.go235
-rw-r--r--vendor/go.opencensus.io/stats/view/collector.go87
-rw-r--r--vendor/go.opencensus.io/stats/view/doc.go47
-rw-r--r--vendor/go.opencensus.io/stats/view/export.go58
-rw-r--r--vendor/go.opencensus.io/stats/view/view.go185
-rw-r--r--vendor/go.opencensus.io/stats/view/worker.go229
-rw-r--r--vendor/go.opencensus.io/stats/view/worker_commands.go183
-rw-r--r--vendor/go.opencensus.io/tag/context.go67
-rw-r--r--vendor/go.opencensus.io/tag/doc.go26
-rw-r--r--vendor/go.opencensus.io/tag/key.go35
-rw-r--r--vendor/go.opencensus.io/tag/map.go197
-rw-r--r--vendor/go.opencensus.io/tag/map_codec.go234
-rw-r--r--vendor/go.opencensus.io/tag/profile_19.go31
-rw-r--r--vendor/go.opencensus.io/tag/profile_not19.go23
-rw-r--r--vendor/go.opencensus.io/tag/validate.go56
-rw-r--r--vendor/go.opencensus.io/trace/basetypes.go114
-rw-r--r--vendor/go.opencensus.io/trace/config.go48
-rw-r--r--vendor/go.opencensus.io/trace/doc.go53
-rw-r--r--vendor/go.opencensus.io/trace/exemplar.go43
-rw-r--r--vendor/go.opencensus.io/trace/export.go90
-rw-r--r--vendor/go.opencensus.io/trace/internal/internal.go21
-rw-r--r--vendor/go.opencensus.io/trace/propagation/propagation.go108
-rw-r--r--vendor/go.opencensus.io/trace/sampling.go75
-rw-r--r--vendor/go.opencensus.io/trace/spanbucket.go130
-rw-r--r--vendor/go.opencensus.io/trace/spanstore.go306
-rw-r--r--vendor/go.opencensus.io/trace/status_codes.go37
-rw-r--r--vendor/go.opencensus.io/trace/trace.go516
-rw-r--r--vendor/go.opencensus.io/trace/trace_go11.go32
-rw-r--r--vendor/go.opencensus.io/trace/trace_nongo11.go25
-rw-r--r--vendor/go.opencensus.io/trace/tracestate/tracestate.go147
65 files changed, 6748 insertions, 0 deletions
diff --git a/vendor/go.opencensus.io/.gitignore b/vendor/go.opencensus.io/.gitignore
new file mode 100644
index 0000000..74a6db4
--- /dev/null
+++ b/vendor/go.opencensus.io/.gitignore
@@ -0,0 +1,9 @@
1/.idea/
2
3# go.opencensus.io/exporter/aws
4/exporter/aws/
5
6# Exclude vendor, use dep ensure after checkout:
7/vendor/github.com/
8/vendor/golang.org/
9/vendor/google.golang.org/
diff --git a/vendor/go.opencensus.io/.travis.yml b/vendor/go.opencensus.io/.travis.yml
new file mode 100644
index 0000000..73c8571
--- /dev/null
+++ b/vendor/go.opencensus.io/.travis.yml
@@ -0,0 +1,27 @@
1language: go
2
3go:
4 # 1.8 is tested by AppVeyor
5 - 1.11.x
6
7go_import_path: go.opencensus.io
8
9# Don't email me the results of the test runs.
10notifications:
11 email: false
12
13before_script:
14 - GO_FILES=$(find . -iname '*.go' | grep -v /vendor/) # All the .go files, excluding vendor/ if any
15 - PKGS=$(go list ./... | grep -v /vendor/) # All the import paths, excluding vendor/ if any
16 - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh # Install latest dep release
17 - go get github.com/rakyll/embedmd
18
19script:
20 - embedmd -d README.md # Ensure embedded code is up-to-date
21 - go build ./... # Ensure dependency updates don't break build
22 - if [ -n "$(gofmt -s -l $GO_FILES)" ]; then echo "gofmt the following files:"; gofmt -s -l $GO_FILES; exit 1; fi
23 - go vet ./...
24 - go test -v -race $PKGS # Run all the tests with the race detector enabled
25 - GOARCH=386 go test -v $PKGS # Run all tests against a 386 architecture
26 - 'if [[ $TRAVIS_GO_VERSION = 1.8* ]]; then ! golint ./... | grep -vE "(_mock|_string|\.pb)\.go:"; fi'
27 - go run internal/check/version.go
diff --git a/vendor/go.opencensus.io/AUTHORS b/vendor/go.opencensus.io/AUTHORS
new file mode 100644
index 0000000..e491a9e
--- /dev/null
+++ b/vendor/go.opencensus.io/AUTHORS
@@ -0,0 +1 @@
Google Inc.
diff --git a/vendor/go.opencensus.io/CONTRIBUTING.md b/vendor/go.opencensus.io/CONTRIBUTING.md
new file mode 100644
index 0000000..3f3aed3
--- /dev/null
+++ b/vendor/go.opencensus.io/CONTRIBUTING.md
@@ -0,0 +1,56 @@
1# How to contribute
2
3We'd love to accept your patches and contributions to this project. There are
4just a few small guidelines you need to follow.
5
6## Contributor License Agreement
7
8Contributions to this project must be accompanied by a Contributor License
9Agreement. You (or your employer) retain the copyright to your contribution,
10this simply gives us permission to use and redistribute your contributions as
11part of the project. Head over to <https://cla.developers.google.com/> to see
12your current agreements on file or to sign a new one.
13
14You generally only need to submit a CLA once, so if you've already submitted one
15(even if it was for a different project), you probably don't need to do it
16again.
17
18## Code reviews
19
20All submissions, including submissions by project members, require review. We
21use GitHub pull requests for this purpose. Consult [GitHub Help] for more
22information on using pull requests.
23
24[GitHub Help]: https://help.github.com/articles/about-pull-requests/
25
26## Instructions
27
28Fork the repo, checkout the upstream repo to your GOPATH by:
29
30```
31$ go get -d go.opencensus.io
32```
33
34Add your fork as an origin:
35
36```
37cd $(go env GOPATH)/src/go.opencensus.io
38git remote add fork git@github.com:YOUR_GITHUB_USERNAME/opencensus-go.git
39```
40
41Run tests:
42
43```
44$ go test ./...
45```
46
47Checkout a new branch, make modifications and push the branch to your fork:
48
49```
50$ git checkout -b feature
51# edit files
52$ git commit
53$ git push fork feature
54```
55
56Open a pull request against the main opencensus-go repo.
diff --git a/vendor/go.opencensus.io/Gopkg.lock b/vendor/go.opencensus.io/Gopkg.lock
new file mode 100644
index 0000000..3be12ac
--- /dev/null
+++ b/vendor/go.opencensus.io/Gopkg.lock
@@ -0,0 +1,231 @@
1# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
2
3
4[[projects]]
5 branch = "master"
6 digest = "1:eee9386329f4fcdf8d6c0def0c9771b634bdd5ba460d888aa98c17d59b37a76c"
7 name = "git.apache.org/thrift.git"
8 packages = ["lib/go/thrift"]
9 pruneopts = "UT"
10 revision = "6e67faa92827ece022380b211c2caaadd6145bf5"
11 source = "github.com/apache/thrift"
12
13[[projects]]
14 branch = "master"
15 digest = "1:d6afaeed1502aa28e80a4ed0981d570ad91b2579193404256ce672ed0a609e0d"
16 name = "github.com/beorn7/perks"
17 packages = ["quantile"]
18 pruneopts = "UT"
19 revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
20
21[[projects]]
22 digest = "1:4c0989ca0bcd10799064318923b9bc2db6b4d6338dd75f3f2d86c3511aaaf5cf"
23 name = "github.com/golang/protobuf"
24 packages = [
25 "proto",
26 "ptypes",
27 "ptypes/any",
28 "ptypes/duration",
29 "ptypes/timestamp",
30 ]
31 pruneopts = "UT"
32 revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5"
33 version = "v1.2.0"
34
35[[projects]]
36 digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc"
37 name = "github.com/matttproud/golang_protobuf_extensions"
38 packages = ["pbutil"]
39 pruneopts = "UT"
40 revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c"
41 version = "v1.0.1"
42
43[[projects]]
44 digest = "1:824c8f3aa4c5f23928fa84ebbd5ed2e9443b3f0cb958a40c1f2fbed5cf5e64b1"
45 name = "github.com/openzipkin/zipkin-go"
46 packages = [
47 ".",
48 "idgenerator",
49 "model",
50 "propagation",
51 "reporter",
52 "reporter/http",
53 ]
54 pruneopts = "UT"
55 revision = "d455a5674050831c1e187644faa4046d653433c2"
56 version = "v0.1.1"
57
58[[projects]]
59 digest = "1:d14a5f4bfecf017cb780bdde1b6483e5deb87e12c332544d2c430eda58734bcb"
60 name = "github.com/prometheus/client_golang"
61 packages = [
62 "prometheus",
63 "prometheus/promhttp",
64 ]
65 pruneopts = "UT"
66 revision = "c5b7fccd204277076155f10851dad72b76a49317"
67 version = "v0.8.0"
68
69[[projects]]
70 branch = "master"
71 digest = "1:2d5cd61daa5565187e1d96bae64dbbc6080dacf741448e9629c64fd93203b0d4"
72 name = "github.com/prometheus/client_model"
73 packages = ["go"]
74 pruneopts = "UT"
75 revision = "5c3871d89910bfb32f5fcab2aa4b9ec68e65a99f"
76
77[[projects]]
78 branch = "master"
79 digest = "1:63b68062b8968092eb86bedc4e68894bd096ea6b24920faca8b9dcf451f54bb5"
80 name = "github.com/prometheus/common"
81 packages = [
82 "expfmt",
83 "internal/bitbucket.org/ww/goautoneg",
84 "model",
85 ]
86 pruneopts = "UT"
87 revision = "c7de2306084e37d54b8be01f3541a8464345e9a5"
88
89[[projects]]
90 branch = "master"
91 digest = "1:8c49953a1414305f2ff5465147ee576dd705487c35b15918fcd4efdc0cb7a290"
92 name = "github.com/prometheus/procfs"
93 packages = [
94 ".",
95 "internal/util",
96 "nfs",
97 "xfs",
98 ]
99 pruneopts = "UT"
100 revision = "05ee40e3a273f7245e8777337fc7b46e533a9a92"
101
102[[projects]]
103 branch = "master"
104 digest = "1:deafe4ab271911fec7de5b693d7faae3f38796d9eb8622e2b9e7df42bb3dfea9"
105 name = "golang.org/x/net"
106 packages = [
107 "context",
108 "http/httpguts",
109 "http2",
110 "http2/hpack",
111 "idna",
112 "internal/timeseries",
113 "trace",
114 ]
115 pruneopts = "UT"
116 revision = "922f4815f713f213882e8ef45e0d315b164d705c"
117
118[[projects]]
119 branch = "master"
120 digest = "1:e0140c0c868c6e0f01c0380865194592c011fe521d6e12d78bfd33e756fe018a"
121 name = "golang.org/x/sync"
122 packages = ["semaphore"]
123 pruneopts = "UT"
124 revision = "1d60e4601c6fd243af51cc01ddf169918a5407ca"
125
126[[projects]]
127 branch = "master"
128 digest = "1:a3f00ac457c955fe86a41e1495e8f4c54cb5399d609374c5cc26aa7d72e542c8"
129 name = "golang.org/x/sys"
130 packages = ["unix"]
131 pruneopts = "UT"
132 revision = "3b58ed4ad3395d483fc92d5d14123ce2c3581fec"
133
134[[projects]]
135 digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18"
136 name = "golang.org/x/text"
137 packages = [
138 "collate",
139 "collate/build",
140 "internal/colltab",
141 "internal/gen",
142 "internal/tag",
143 "internal/triegen",
144 "internal/ucd",
145 "language",
146 "secure/bidirule",
147 "transform",
148 "unicode/bidi",
149 "unicode/cldr",
150 "unicode/norm",
151 "unicode/rangetable",
152 ]
153 pruneopts = "UT"
154 revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
155 version = "v0.3.0"
156
157[[projects]]
158 branch = "master"
159 digest = "1:c0c17c94fe8bc1ab34e7f586a4a8b788c5e1f4f9f750ff23395b8b2f5a523530"
160 name = "google.golang.org/api"
161 packages = ["support/bundler"]
162 pruneopts = "UT"
163 revision = "e21acd801f91da814261b938941d193bb036441a"
164
165[[projects]]
166 branch = "master"
167 digest = "1:077c1c599507b3b3e9156d17d36e1e61928ee9b53a5b420f10f28ebd4a0b275c"
168 name = "google.golang.org/genproto"
169 packages = ["googleapis/rpc/status"]
170 pruneopts = "UT"
171 revision = "c66870c02cf823ceb633bcd05be3c7cda29976f4"
172
173[[projects]]
174 digest = "1:3dd7996ce6bf52dec6a2f69fa43e7c4cefea1d4dfa3c8ab7a5f8a9f7434e239d"
175 name = "google.golang.org/grpc"
176 packages = [
177 ".",
178 "balancer",
179 "balancer/base",
180 "balancer/roundrobin",
181 "codes",
182 "connectivity",
183 "credentials",
184 "encoding",
185 "encoding/proto",
186 "grpclog",
187 "internal",
188 "internal/backoff",
189 "internal/channelz",
190 "internal/envconfig",
191 "internal/grpcrand",
192 "internal/transport",
193 "keepalive",
194 "metadata",
195 "naming",
196 "peer",
197 "resolver",
198 "resolver/dns",
199 "resolver/passthrough",
200 "stats",
201 "status",
202 "tap",
203 ]
204 pruneopts = "UT"
205 revision = "32fb0ac620c32ba40a4626ddf94d90d12cce3455"
206 version = "v1.14.0"
207
208[solve-meta]
209 analyzer-name = "dep"
210 analyzer-version = 1
211 input-imports = [
212 "git.apache.org/thrift.git/lib/go/thrift",
213 "github.com/golang/protobuf/proto",
214 "github.com/openzipkin/zipkin-go",
215 "github.com/openzipkin/zipkin-go/model",
216 "github.com/openzipkin/zipkin-go/reporter",
217 "github.com/openzipkin/zipkin-go/reporter/http",
218 "github.com/prometheus/client_golang/prometheus",
219 "github.com/prometheus/client_golang/prometheus/promhttp",
220 "golang.org/x/net/context",
221 "golang.org/x/net/http2",
222 "google.golang.org/api/support/bundler",
223 "google.golang.org/grpc",
224 "google.golang.org/grpc/codes",
225 "google.golang.org/grpc/grpclog",
226 "google.golang.org/grpc/metadata",
227 "google.golang.org/grpc/stats",
228 "google.golang.org/grpc/status",
229 ]
230 solver-name = "gps-cdcl"
231 solver-version = 1
diff --git a/vendor/go.opencensus.io/Gopkg.toml b/vendor/go.opencensus.io/Gopkg.toml
new file mode 100644
index 0000000..a9f3cd6
--- /dev/null
+++ b/vendor/go.opencensus.io/Gopkg.toml
@@ -0,0 +1,36 @@
1# For v0.x.y dependencies, prefer adding a constraints of the form: version=">= 0.x.y"
2# to avoid locking to a particular minor version which can cause dep to not be
3# able to find a satisfying dependency graph.
4
5[[constraint]]
6 branch = "master"
7 name = "git.apache.org/thrift.git"
8 source = "github.com/apache/thrift"
9
10[[constraint]]
11 name = "github.com/golang/protobuf"
12 version = "1.0.0"
13
14[[constraint]]
15 name = "github.com/openzipkin/zipkin-go"
16 version = ">=0.1.0"
17
18[[constraint]]
19 name = "github.com/prometheus/client_golang"
20 version = ">=0.8.0"
21
22[[constraint]]
23 branch = "master"
24 name = "golang.org/x/net"
25
26[[constraint]]
27 branch = "master"
28 name = "google.golang.org/api"
29
30[[constraint]]
31 name = "google.golang.org/grpc"
32 version = "1.11.3"
33
34[prune]
35 go-tests = true
36 unused-packages = true
diff --git a/vendor/go.opencensus.io/LICENSE b/vendor/go.opencensus.io/LICENSE
new file mode 100644
index 0000000..7a4a3ea
--- /dev/null
+++ b/vendor/go.opencensus.io/LICENSE
@@ -0,0 +1,202 @@
1
2 Apache License
3 Version 2.0, January 2004
4 http://www.apache.org/licenses/
5
6 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
8 1. Definitions.
9
10 "License" shall mean the terms and conditions for use, reproduction,
11 and distribution as defined by Sections 1 through 9 of this document.
12
13 "Licensor" shall mean the copyright owner or entity authorized by
14 the copyright owner that is granting the License.
15
16 "Legal Entity" shall mean the union of the acting entity and all
17 other entities that control, are controlled by, or are under common
18 control with that entity. For the purposes of this definition,
19 "control" means (i) the power, direct or indirect, to cause the
20 direction or management of such entity, whether by contract or
21 otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 outstanding shares, or (iii) beneficial ownership of such entity.
23
24 "You" (or "Your") shall mean an individual or Legal Entity
25 exercising permissions granted by this License.
26
27 "Source" form shall mean the preferred form for making modifications,
28 including but not limited to software source code, documentation
29 source, and configuration files.
30
31 "Object" form shall mean any form resulting from mechanical
32 transformation or translation of a Source form, including but
33 not limited to compiled object code, generated documentation,
34 and conversions to other media types.
35
36 "Work" shall mean the work of authorship, whether in Source or
37 Object form, made available under the License, as indicated by a
38 copyright notice that is included in or attached to the work
39 (an example is provided in the Appendix below).
40
41 "Derivative Works" shall mean any work, whether in Source or Object
42 form, that is based on (or derived from) the Work and for which the
43 editorial revisions, annotations, elaborations, or other modifications
44 represent, as a whole, an original work of authorship. For the purposes
45 of this License, Derivative Works shall not include works that remain
46 separable from, or merely link (or bind by name) to the interfaces of,
47 the Work and Derivative Works thereof.
48
49 "Contribution" shall mean any work of authorship, including
50 the original version of the Work and any modifications or additions
51 to that Work or Derivative Works thereof, that is intentionally
52 submitted to Licensor for inclusion in the Work by the copyright owner
53 or by an individual or Legal Entity authorized to submit on behalf of
54 the copyright owner. For the purposes of this definition, "submitted"
55 means any form of electronic, verbal, or written communication sent
56 to the Licensor or its representatives, including but not limited to
57 communication on electronic mailing lists, source code control systems,
58 and issue tracking systems that are managed by, or on behalf of, the
59 Licensor for the purpose of discussing and improving the Work, but
60 excluding communication that is conspicuously marked or otherwise
61 designated in writing by the copyright owner as "Not a Contribution."
62
63 "Contributor" shall mean Licensor and any individual or Legal Entity
64 on behalf of whom a Contribution has been received by Licensor and
65 subsequently incorporated within the Work.
66
67 2. Grant of Copyright License. Subject to the terms and conditions of
68 this License, each Contributor hereby grants to You a perpetual,
69 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 copyright license to reproduce, prepare Derivative Works of,
71 publicly display, publicly perform, sublicense, and distribute the
72 Work and such Derivative Works in Source or Object form.
73
74 3. Grant of Patent License. Subject to the terms and conditions of
75 this License, each Contributor hereby grants to You a perpetual,
76 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 (except as stated in this section) patent license to make, have made,
78 use, offer to sell, sell, import, and otherwise transfer the Work,
79 where such license applies only to those patent claims licensable
80 by such Contributor that are necessarily infringed by their
81 Contribution(s) alone or by combination of their Contribution(s)
82 with the Work to which such Contribution(s) was submitted. If You
83 institute patent litigation against any entity (including a
84 cross-claim or counterclaim in a lawsuit) alleging that the Work
85 or a Contribution incorporated within the Work constitutes direct
86 or contributory patent infringement, then any patent licenses
87 granted to You under this License for that Work shall terminate
88 as of the date such litigation is filed.
89
90 4. Redistribution. You may reproduce and distribute copies of the
91 Work or Derivative Works thereof in any medium, with or without
92 modifications, and in Source or Object form, provided that You
93 meet the following conditions:
94
95 (a) You must give any other recipients of the Work or
96 Derivative Works a copy of this License; and
97
98 (b) You must cause any modified files to carry prominent notices
99 stating that You changed the files; and
100
101 (c) You must retain, in the Source form of any Derivative Works
102 that You distribute, all copyright, patent, trademark, and
103 attribution notices from the Source form of the Work,
104 excluding those notices that do not pertain to any part of
105 the Derivative Works; and
106
107 (d) If the Work includes a "NOTICE" text file as part of its
108 distribution, then any Derivative Works that You distribute must
109 include a readable copy of the attribution notices contained
110 within such NOTICE file, excluding those notices that do not
111 pertain to any part of the Derivative Works, in at least one
112 of the following places: within a NOTICE text file distributed
113 as part of the Derivative Works; within the Source form or
114 documentation, if provided along with the Derivative Works; or,
115 within a display generated by the Derivative Works, if and
116 wherever such third-party notices normally appear. The contents
117 of the NOTICE file are for informational purposes only and
118 do not modify the License. You may add Your own attribution
119 notices within Derivative Works that You distribute, alongside
120 or as an addendum to the NOTICE text from the Work, provided
121 that such additional attribution notices cannot be construed
122 as modifying the License.
123
124 You may add Your own copyright statement to Your modifications and
125 may provide additional or different license terms and conditions
126 for use, reproduction, or distribution of Your modifications, or
127 for any such Derivative Works as a whole, provided Your use,
128 reproduction, and distribution of the Work otherwise complies with
129 the conditions stated in this License.
130
131 5. Submission of Contributions. Unless You explicitly state otherwise,
132 any Contribution intentionally submitted for inclusion in the Work
133 by You to the Licensor shall be under the terms and conditions of
134 this License, without any additional terms or conditions.
135 Notwithstanding the above, nothing herein shall supersede or modify
136 the terms of any separate license agreement you may have executed
137 with Licensor regarding such Contributions.
138
139 6. Trademarks. This License does not grant permission to use the trade
140 names, trademarks, service marks, or product names of the Licensor,
141 except as required for reasonable and customary use in describing the
142 origin of the Work and reproducing the content of the NOTICE file.
143
144 7. Disclaimer of Warranty. Unless required by applicable law or
145 agreed to in writing, Licensor provides the Work (and each
146 Contributor provides its Contributions) on an "AS IS" BASIS,
147 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 implied, including, without limitation, any warranties or conditions
149 of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 PARTICULAR PURPOSE. You are solely responsible for determining the
151 appropriateness of using or redistributing the Work and assume any
152 risks associated with Your exercise of permissions under this License.
153
154 8. Limitation of Liability. In no event and under no legal theory,
155 whether in tort (including negligence), contract, or otherwise,
156 unless required by applicable law (such as deliberate and grossly
157 negligent acts) or agreed to in writing, shall any Contributor be
158 liable to You for damages, including any direct, indirect, special,
159 incidental, or consequential damages of any character arising as a
160 result of this License or out of the use or inability to use the
161 Work (including but not limited to damages for loss of goodwill,
162 work stoppage, computer failure or malfunction, or any and all
163 other commercial damages or losses), even if such Contributor
164 has been advised of the possibility of such damages.
165
166 9. Accepting Warranty or Additional Liability. While redistributing
167 the Work or Derivative Works thereof, You may choose to offer,
168 and charge a fee for, acceptance of support, warranty, indemnity,
169 or other liability obligations and/or rights consistent with this
170 License. However, in accepting such obligations, You may act only
171 on Your own behalf and on Your sole responsibility, not on behalf
172 of any other Contributor, and only if You agree to indemnify,
173 defend, and hold each Contributor harmless for any liability
174 incurred by, or claims asserted against, such Contributor by reason
175 of your accepting any such warranty or additional liability.
176
177 END OF TERMS AND CONDITIONS
178
179 APPENDIX: How to apply the Apache License to your work.
180
181 To apply the Apache License to your work, attach the following
182 boilerplate notice, with the fields enclosed by brackets "[]"
183 replaced with your own identifying information. (Don't include
184 the brackets!) The text should be enclosed in the appropriate
185 comment syntax for the file format. We also recommend that a
186 file or class name and description of purpose be included on the
187 same "printed page" as the copyright notice for easier
188 identification within third-party archives.
189
190 Copyright [yyyy] [name of copyright owner]
191
192 Licensed under the Apache License, Version 2.0 (the "License");
193 you may not use this file except in compliance with the License.
194 You may obtain a copy of the License at
195
196 http://www.apache.org/licenses/LICENSE-2.0
197
198 Unless required by applicable law or agreed to in writing, software
199 distributed under the License is distributed on an "AS IS" BASIS,
200 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 See the License for the specific language governing permissions and
202 limitations under the License. \ No newline at end of file
diff --git a/vendor/go.opencensus.io/README.md b/vendor/go.opencensus.io/README.md
new file mode 100644
index 0000000..97d6698
--- /dev/null
+++ b/vendor/go.opencensus.io/README.md
@@ -0,0 +1,263 @@
1# OpenCensus Libraries for Go
2
3[![Build Status][travis-image]][travis-url]
4[![Windows Build Status][appveyor-image]][appveyor-url]
5[![GoDoc][godoc-image]][godoc-url]
6[![Gitter chat][gitter-image]][gitter-url]
7
8OpenCensus Go is a Go implementation of OpenCensus, a toolkit for
9collecting application performance and behavior monitoring data.
10Currently it consists of three major components: tags, stats and tracing.
11
12## Installation
13
14```
15$ go get -u go.opencensus.io
16```
17
18The API of this project is still evolving, see: [Deprecation Policy](#deprecation-policy).
19The use of vendoring or a dependency management tool is recommended.
20
21## Prerequisites
22
23OpenCensus Go libraries require Go 1.8 or later.
24
25## Getting Started
26
27The easiest way to get started using OpenCensus in your application is to use an existing
28integration with your RPC framework:
29
30* [net/http](https://godoc.org/go.opencensus.io/plugin/ochttp)
31* [gRPC](https://godoc.org/go.opencensus.io/plugin/ocgrpc)
32* [database/sql](https://godoc.org/github.com/basvanbeek/ocsql)
33* [Go kit](https://godoc.org/github.com/go-kit/kit/tracing/opencensus)
34* [Groupcache](https://godoc.org/github.com/orijtech/groupcache)
35* [Caddy webserver](https://godoc.org/github.com/orijtech/caddy)
36* [MongoDB](https://godoc.org/github.com/orijtech/mongo-go-driver)
37* [Redis gomodule/redigo](https://godoc.org/github.com/orijtech/redigo)
38* [Redis goredis/redis](https://godoc.org/github.com/orijtech/redis)
39* [Memcache](https://godoc.org/github.com/orijtech/gomemcache)
40
41If you're using a framework not listed here, you could either implement your own middleware for your
42framework or use [custom stats](#stats) and [spans](#spans) directly in your application.
43
44## Exporters
45
46OpenCensus can export instrumentation data to various backends.
47OpenCensus has exporter implementations for the following, users
48can implement their own exporters by implementing the exporter interfaces
49([stats](https://godoc.org/go.opencensus.io/stats/view#Exporter),
50[trace](https://godoc.org/go.opencensus.io/trace#Exporter)):
51
52* [Prometheus][exporter-prom] for stats
53* [OpenZipkin][exporter-zipkin] for traces
54* [Stackdriver][exporter-stackdriver] Monitoring for stats and Trace for traces
55* [Jaeger][exporter-jaeger] for traces
56* [AWS X-Ray][exporter-xray] for traces
57* [Datadog][exporter-datadog] for stats and traces
58* [Graphite][exporter-graphite] for stats
59* [Honeycomb][exporter-honeycomb] for traces
60
61## Overview
62
63![OpenCensus Overview](https://i.imgur.com/cf4ElHE.jpg)
64
65In a microservices environment, a user request may go through
66multiple services until there is a response. OpenCensus allows
67you to instrument your services and collect diagnostics data all
68through your services end-to-end.
69
70## Tags
71
72Tags represent propagated key-value pairs. They are propagated using `context.Context`
73in the same process or can be encoded to be transmitted on the wire. Usually, this will
74be handled by an integration plugin, e.g. `ocgrpc.ServerHandler` and `ocgrpc.ClientHandler`
75for gRPC.
76
77Package `tag` allows adding or modifying tags in the current context.
78
79[embedmd]:# (internal/readme/tags.go new)
80```go
81ctx, err = tag.New(ctx,
82 tag.Insert(osKey, "macOS-10.12.5"),
83 tag.Upsert(userIDKey, "cde36753ed"),
84)
85if err != nil {
86 log.Fatal(err)
87}
88```
89
90## Stats
91
92OpenCensus is a low-overhead framework even if instrumentation is always enabled.
93In order to be so, it is optimized to make recording of data points fast
94and separate from the data aggregation.
95
96OpenCensus stats collection happens in two stages:
97
98* Definition of measures and recording of data points
99* Definition of views and aggregation of the recorded data
100
101### Recording
102
103Measurements are data points associated with a measure.
104Recording implicitly tags the set of Measurements with the tags from the
105provided context:
106
107[embedmd]:# (internal/readme/stats.go record)
108```go
109stats.Record(ctx, videoSize.M(102478))
110```
111
112### Views
113
114Views are how Measures are aggregated. You can think of them as queries over the
115set of recorded data points (measurements).
116
117Views have two parts: the tags to group by and the aggregation type used.
118
119Currently three types of aggregations are supported:
120* CountAggregation is used to count the number of times a sample was recorded.
121* DistributionAggregation is used to provide a histogram of the values of the samples.
122* SumAggregation is used to sum up all sample values.
123
124[embedmd]:# (internal/readme/stats.go aggs)
125```go
126distAgg := view.Distribution(0, 1<<32, 2<<32, 3<<32)
127countAgg := view.Count()
128sumAgg := view.Sum()
129```
130
131Here we create a view with the DistributionAggregation over our measure.
132
133[embedmd]:# (internal/readme/stats.go view)
134```go
135if err := view.Register(&view.View{
136 Name: "example.com/video_size_distribution",
137 Description: "distribution of processed video size over time",
138 Measure: videoSize,
139 Aggregation: view.Distribution(0, 1<<32, 2<<32, 3<<32),
140}); err != nil {
141 log.Fatalf("Failed to register view: %v", err)
142}
143```
144
145Register begins collecting data for the view. Registered views' data will be
146exported via the registered exporters.
147
148## Traces
149
150A distributed trace tracks the progression of a single user request as
151it is handled by the services and processes that make up an application.
152Each step is called a span in the trace. Spans include metadata about the step,
153including especially the time spent in the step, called the span’s latency.
154
155Below you see a trace and several spans underneath it.
156
157![Traces and spans](https://i.imgur.com/7hZwRVj.png)
158
159### Spans
160
161Span is the unit step in a trace. Each span has a name, latency, status and
162additional metadata.
163
164Below we are starting a span for a cache read and ending it
165when we are done:
166
167[embedmd]:# (internal/readme/trace.go startend)
168```go
169ctx, span := trace.StartSpan(ctx, "cache.Get")
170defer span.End()
171
172// Do work to get from cache.
173```
174
175### Propagation
176
177Spans can have parents or can be root spans if they don't have any parents.
178The current span is propagated in-process and across the network to allow associating
179new child spans with the parent.
180
181In the same process, `context.Context` is used to propagate spans.
182`trace.StartSpan` creates a new span as a root if the current context
183doesn't contain a span. Or, it creates a child of the span that is
184already in current context. The returned context can be used to keep
185propagating the newly created span in the current context.
186
187[embedmd]:# (internal/readme/trace.go startend)
188```go
189ctx, span := trace.StartSpan(ctx, "cache.Get")
190defer span.End()
191
192// Do work to get from cache.
193```
194
195Across the network, OpenCensus provides different propagation
196methods for different protocols.
197
198* gRPC integrations use the OpenCensus' [binary propagation format](https://godoc.org/go.opencensus.io/trace/propagation).
199* HTTP integrations use Zipkin's [B3](https://github.com/openzipkin/b3-propagation)
200 by default but can be configured to use a custom propagation method by setting another
201 [propagation.HTTPFormat](https://godoc.org/go.opencensus.io/trace/propagation#HTTPFormat).
202
203## Execution Tracer
204
205With Go 1.11, OpenCensus Go will support integration with the Go execution tracer.
206See [Debugging Latency in Go](https://medium.com/observability/debugging-latency-in-go-1-11-9f97a7910d68)
207for an example of their mutual use.
208
209## Profiles
210
211OpenCensus tags can be applied as profiler labels
212for users who are on Go 1.9 and above.
213
214[embedmd]:# (internal/readme/tags.go profiler)
215```go
216ctx, err = tag.New(ctx,
217 tag.Insert(osKey, "macOS-10.12.5"),
218 tag.Insert(userIDKey, "fff0989878"),
219)
220if err != nil {
221 log.Fatal(err)
222}
223tag.Do(ctx, func(ctx context.Context) {
224 // Do work.
225 // When profiling is on, samples will be
226 // recorded with the key/values from the tag map.
227})
228```
229
230A screenshot of the CPU profile from the program above:
231
232![CPU profile](https://i.imgur.com/jBKjlkw.png)
233
234## Deprecation Policy
235
236Before version 1.0.0, the following deprecation policy will be observed:
237
238No backwards-incompatible changes will be made except for the removal of symbols that have
239been marked as *Deprecated* for at least one minor release (e.g. 0.9.0 to 0.10.0). A release
240removing the *Deprecated* functionality will be made no sooner than 28 days after the first
241release in which the functionality was marked *Deprecated*.
242
243[travis-image]: https://travis-ci.org/census-instrumentation/opencensus-go.svg?branch=master
244[travis-url]: https://travis-ci.org/census-instrumentation/opencensus-go
245[appveyor-image]: https://ci.appveyor.com/api/projects/status/vgtt29ps1783ig38?svg=true
246[appveyor-url]: https://ci.appveyor.com/project/opencensusgoteam/opencensus-go/branch/master
247[godoc-image]: https://godoc.org/go.opencensus.io?status.svg
248[godoc-url]: https://godoc.org/go.opencensus.io
249[gitter-image]: https://badges.gitter.im/census-instrumentation/lobby.svg
250[gitter-url]: https://gitter.im/census-instrumentation/lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
251
252
253[new-ex]: https://godoc.org/go.opencensus.io/tag#example-NewMap
254[new-replace-ex]: https://godoc.org/go.opencensus.io/tag#example-NewMap--Replace
255
256[exporter-prom]: https://godoc.org/go.opencensus.io/exporter/prometheus
257[exporter-stackdriver]: https://godoc.org/contrib.go.opencensus.io/exporter/stackdriver
258[exporter-zipkin]: https://godoc.org/go.opencensus.io/exporter/zipkin
259[exporter-jaeger]: https://godoc.org/go.opencensus.io/exporter/jaeger
260[exporter-xray]: https://github.com/census-ecosystem/opencensus-go-exporter-aws
261[exporter-datadog]: https://github.com/DataDog/opencensus-go-exporter-datadog
262[exporter-graphite]: https://github.com/census-ecosystem/opencensus-go-exporter-graphite
263[exporter-honeycomb]: https://github.com/honeycombio/opencensus-exporter
diff --git a/vendor/go.opencensus.io/appveyor.yml b/vendor/go.opencensus.io/appveyor.yml
new file mode 100644
index 0000000..9805788
--- /dev/null
+++ b/vendor/go.opencensus.io/appveyor.yml
@@ -0,0 +1,24 @@
1version: "{build}"
2
3platform: x64
4
5clone_folder: c:\gopath\src\go.opencensus.io
6
7environment:
8 GOPATH: 'c:\gopath'
9 GOVERSION: '1.11'
10 GO111MODULE: 'on'
11 CGO_ENABLED: '0' # See: https://github.com/appveyor/ci/issues/2613
12
13install:
14 - set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
15 - go version
16 - go env
17
18build: false
19deploy: false
20
21test_script:
22 - cd %APPVEYOR_BUILD_FOLDER%
23 - go build -v .\...
24 - go test -v .\... # No -race because cgo is disabled
diff --git a/vendor/go.opencensus.io/exemplar/exemplar.go b/vendor/go.opencensus.io/exemplar/exemplar.go
new file mode 100644
index 0000000..e676df8
--- /dev/null
+++ b/vendor/go.opencensus.io/exemplar/exemplar.go
@@ -0,0 +1,78 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package exemplar implements support for exemplars. Exemplars are additional
16// data associated with each measurement.
17//
18// Their purpose it to provide an example of the kind of thing
19// (request, RPC, trace span, etc.) that resulted in that measurement.
20package exemplar
21
22import (
23 "context"
24 "time"
25)
26
27const (
28 KeyTraceID = "trace_id"
29 KeySpanID = "span_id"
30 KeyPrefixTag = "tag:"
31)
32
33// Exemplar is an example data point associated with each bucket of a
34// distribution type aggregation.
35type Exemplar struct {
36 Value float64 // the value that was recorded
37 Timestamp time.Time // the time the value was recorded
38 Attachments Attachments // attachments (if any)
39}
40
41// Attachments is a map of extra values associated with a recorded data point.
42// The map should only be mutated from AttachmentExtractor functions.
43type Attachments map[string]string
44
45// AttachmentExtractor is a function capable of extracting exemplar attachments
46// from the context used to record measurements.
47// The map passed to the function should be mutated and returned. It will
48// initially be nil: the first AttachmentExtractor that would like to add keys to the
49// map is responsible for initializing it.
50type AttachmentExtractor func(ctx context.Context, a Attachments) Attachments
51
52var extractors []AttachmentExtractor
53
54// RegisterAttachmentExtractor registers the given extractor associated with the exemplar
55// type name.
56//
57// Extractors will be used to attempt to extract exemplars from the context
58// associated with each recorded measurement.
59//
60// Packages that support exemplars should register their extractor functions on
61// initialization.
62//
63// RegisterAttachmentExtractor should not be called after any measurements have
64// been recorded.
65func RegisterAttachmentExtractor(e AttachmentExtractor) {
66 extractors = append(extractors, e)
67}
68
69// NewFromContext extracts exemplars from the given context.
70// Each registered AttachmentExtractor (see RegisterAttachmentExtractor) is called in an
71// unspecified order to add attachments to the exemplar.
72func AttachmentsFromContext(ctx context.Context) Attachments {
73 var a Attachments
74 for _, extractor := range extractors {
75 a = extractor(ctx, a)
76 }
77 return a
78}
diff --git a/vendor/go.opencensus.io/go.mod b/vendor/go.opencensus.io/go.mod
new file mode 100644
index 0000000..1236f4c
--- /dev/null
+++ b/vendor/go.opencensus.io/go.mod
@@ -0,0 +1,25 @@
1module go.opencensus.io
2
3require (
4 git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999
5 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973
6 github.com/ghodss/yaml v1.0.0 // indirect
7 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
8 github.com/golang/protobuf v1.2.0
9 github.com/google/go-cmp v0.2.0
10 github.com/grpc-ecosystem/grpc-gateway v1.5.0 // indirect
11 github.com/matttproud/golang_protobuf_extensions v1.0.1
12 github.com/openzipkin/zipkin-go v0.1.1
13 github.com/prometheus/client_golang v0.8.0
14 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910
15 github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e
16 github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273
17 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd
18 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f
19 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e
20 golang.org/x/text v0.3.0
21 google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf
22 google.golang.org/genproto v0.0.0-20180831171423-11092d34479b
23 google.golang.org/grpc v1.14.0
24 gopkg.in/yaml.v2 v2.2.1 // indirect
25)
diff --git a/vendor/go.opencensus.io/go.sum b/vendor/go.opencensus.io/go.sum
new file mode 100644
index 0000000..3e0bab8
--- /dev/null
+++ b/vendor/go.opencensus.io/go.sum
@@ -0,0 +1,48 @@
1git.apache.org/thrift.git v0.0.0-20180807212849-6e67faa92827/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
2git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999 h1:sihTnRgTOUSCQz0iS0pjZuFQy/z7GXCJgSBg3+rZKHw=
3git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
4github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
5github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
6github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
7github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
8github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
9github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
10github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
11github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
12github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
13github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
14github.com/grpc-ecosystem/grpc-gateway v1.5.0 h1:WcmKMm43DR7RdtlkEXQJyo5ws8iTp98CyhCCbOHMvNI=
15github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
16github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
17github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
18github.com/openzipkin/zipkin-go v0.1.1 h1:A/ADD6HaPnAKj3yS7HjGHRK77qi41Hi0DirOOIQAeIw=
19github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
20github.com/prometheus/client_golang v0.8.0 h1:1921Yw9Gc3iSc4VQh3PIoOqgPCZS7G/4xQNVUp8Mda8=
21github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
22github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
23github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
24github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e h1:n/3MEhJQjQxrOUCzh1Y3Re6aJUUWRp2M9+Oc3eVn/54=
25github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
26github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273 h1:agujYaXJSxSo18YNX3jzl+4G6Bstwt+kqv47GS12uL0=
27github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
28golang.org/x/net v0.0.0-20180821023952-922f4815f713/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
29golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
30golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
31golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
32golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
33golang.org/x/sys v0.0.0-20180821140842-3b58ed4ad339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
34golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
35golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
36golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
37golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
38google.golang.org/api v0.0.0-20180818000503-e21acd801f91/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
39google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf h1:rjxqQmxjyqerRKEj+tZW+MCm4LgpFXu18bsEoCMgDsk=
40google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
41google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
42google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw=
43google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
44google.golang.org/grpc v1.14.0 h1:ArxJuB1NWfPY6r9Gp9gqwplT0Ge7nqv9msgu03lHLmo=
45google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
46gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
47gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
48gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/go.opencensus.io/internal/internal.go b/vendor/go.opencensus.io/internal/internal.go
new file mode 100644
index 0000000..e1d1238
--- /dev/null
+++ b/vendor/go.opencensus.io/internal/internal.go
@@ -0,0 +1,37 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package internal // import "go.opencensus.io/internal"
16
17import (
18 "fmt"
19 "time"
20
21 "go.opencensus.io"
22)
23
24// UserAgent is the user agent to be added to the outgoing
25// requests from the exporters.
26var UserAgent = fmt.Sprintf("opencensus-go [%s]", opencensus.Version())
27
28// MonotonicEndTime returns the end time at present
29// but offset from start, monotonically.
30//
31// The monotonic clock is used in subtractions hence
32// the duration since start added back to start gives
33// end as a monotonic time.
34// See https://golang.org/pkg/time/#hdr-Monotonic_Clocks
35func MonotonicEndTime(start time.Time) time.Time {
36 return start.Add(time.Now().Sub(start))
37}
diff --git a/vendor/go.opencensus.io/internal/sanitize.go b/vendor/go.opencensus.io/internal/sanitize.go
new file mode 100644
index 0000000..de8ccf2
--- /dev/null
+++ b/vendor/go.opencensus.io/internal/sanitize.go
@@ -0,0 +1,50 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package internal
16
17import (
18 "strings"
19 "unicode"
20)
21
22const labelKeySizeLimit = 100
23
24// Sanitize returns a string that is trunacated to 100 characters if it's too
25// long, and replaces non-alphanumeric characters to underscores.
26func Sanitize(s string) string {
27 if len(s) == 0 {
28 return s
29 }
30 if len(s) > labelKeySizeLimit {
31 s = s[:labelKeySizeLimit]
32 }
33 s = strings.Map(sanitizeRune, s)
34 if unicode.IsDigit(rune(s[0])) {
35 s = "key_" + s
36 }
37 if s[0] == '_' {
38 s = "key" + s
39 }
40 return s
41}
42
43// converts anything that is not a letter or digit to an underscore
44func sanitizeRune(r rune) rune {
45 if unicode.IsLetter(r) || unicode.IsDigit(r) {
46 return r
47 }
48 // Everything else turns into an underscore
49 return '_'
50}
diff --git a/vendor/go.opencensus.io/internal/tagencoding/tagencoding.go b/vendor/go.opencensus.io/internal/tagencoding/tagencoding.go
new file mode 100644
index 0000000..3b1af8b
--- /dev/null
+++ b/vendor/go.opencensus.io/internal/tagencoding/tagencoding.go
@@ -0,0 +1,72 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16// Package tagencoding contains the tag encoding
17// used interally by the stats collector.
18package tagencoding // import "go.opencensus.io/internal/tagencoding"
19
20type Values struct {
21 Buffer []byte
22 WriteIndex int
23 ReadIndex int
24}
25
26func (vb *Values) growIfRequired(expected int) {
27 if len(vb.Buffer)-vb.WriteIndex < expected {
28 tmp := make([]byte, 2*(len(vb.Buffer)+1)+expected)
29 copy(tmp, vb.Buffer)
30 vb.Buffer = tmp
31 }
32}
33
34func (vb *Values) WriteValue(v []byte) {
35 length := len(v) & 0xff
36 vb.growIfRequired(1 + length)
37
38 // writing length of v
39 vb.Buffer[vb.WriteIndex] = byte(length)
40 vb.WriteIndex++
41
42 if length == 0 {
43 // No value was encoded for this key
44 return
45 }
46
47 // writing v
48 copy(vb.Buffer[vb.WriteIndex:], v[:length])
49 vb.WriteIndex += length
50}
51
52// ReadValue is the helper method to read the values when decoding valuesBytes to a map[Key][]byte.
53func (vb *Values) ReadValue() []byte {
54 // read length of v
55 length := int(vb.Buffer[vb.ReadIndex])
56 vb.ReadIndex++
57 if length == 0 {
58 // No value was encoded for this key
59 return nil
60 }
61
62 // read value of v
63 v := make([]byte, length)
64 endIdx := vb.ReadIndex + length
65 copy(v, vb.Buffer[vb.ReadIndex:endIdx])
66 vb.ReadIndex = endIdx
67 return v
68}
69
70func (vb *Values) Bytes() []byte {
71 return vb.Buffer[:vb.WriteIndex]
72}
diff --git a/vendor/go.opencensus.io/internal/traceinternals.go b/vendor/go.opencensus.io/internal/traceinternals.go
new file mode 100644
index 0000000..553ca68
--- /dev/null
+++ b/vendor/go.opencensus.io/internal/traceinternals.go
@@ -0,0 +1,52 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package internal
16
17import (
18 "time"
19)
20
21// Trace allows internal access to some trace functionality.
22// TODO(#412): remove this
23var Trace interface{}
24
25var LocalSpanStoreEnabled bool
26
27// BucketConfiguration stores the number of samples to store for span buckets
28// for successful and failed spans for a particular span name.
29type BucketConfiguration struct {
30 Name string
31 MaxRequestsSucceeded int
32 MaxRequestsErrors int
33}
34
35// PerMethodSummary is a summary of the spans stored for a single span name.
36type PerMethodSummary struct {
37 Active int
38 LatencyBuckets []LatencyBucketSummary
39 ErrorBuckets []ErrorBucketSummary
40}
41
42// LatencyBucketSummary is a summary of a latency bucket.
43type LatencyBucketSummary struct {
44 MinLatency, MaxLatency time.Duration
45 Size int
46}
47
48// ErrorBucketSummary is a summary of an error bucket.
49type ErrorBucketSummary struct {
50 ErrorCode int32
51 Size int
52}
diff --git a/vendor/go.opencensus.io/opencensus.go b/vendor/go.opencensus.io/opencensus.go
new file mode 100644
index 0000000..62f0348
--- /dev/null
+++ b/vendor/go.opencensus.io/opencensus.go
@@ -0,0 +1,21 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package opencensus contains Go support for OpenCensus.
16package opencensus // import "go.opencensus.io"
17
18// Version is the current release version of OpenCensus in use.
19func Version() string {
20 return "0.18.0"
21}
diff --git a/vendor/go.opencensus.io/plugin/ochttp/client.go b/vendor/go.opencensus.io/plugin/ochttp/client.go
new file mode 100644
index 0000000..da815b2
--- /dev/null
+++ b/vendor/go.opencensus.io/plugin/ochttp/client.go
@@ -0,0 +1,117 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package ochttp
16
17import (
18 "net/http"
19 "net/http/httptrace"
20
21 "go.opencensus.io/trace"
22 "go.opencensus.io/trace/propagation"
23)
24
25// Transport is an http.RoundTripper that instruments all outgoing requests with
26// OpenCensus stats and tracing.
27//
28// The zero value is intended to be a useful default, but for
29// now it's recommended that you explicitly set Propagation, since the default
30// for this may change.
31type Transport struct {
32 // Base may be set to wrap another http.RoundTripper that does the actual
33 // requests. By default http.DefaultTransport is used.
34 //
35 // If base HTTP roundtripper implements CancelRequest,
36 // the returned round tripper will be cancelable.
37 Base http.RoundTripper
38
39 // Propagation defines how traces are propagated. If unspecified, a default
40 // (currently B3 format) will be used.
41 Propagation propagation.HTTPFormat
42
43 // StartOptions are applied to the span started by this Transport around each
44 // request.
45 //
46 // StartOptions.SpanKind will always be set to trace.SpanKindClient
47 // for spans started by this transport.
48 StartOptions trace.StartOptions
49
50 // GetStartOptions allows to set start options per request. If set,
51 // StartOptions is going to be ignored.
52 GetStartOptions func(*http.Request) trace.StartOptions
53
54 // NameFromRequest holds the function to use for generating the span name
55 // from the information found in the outgoing HTTP Request. By default the
56 // name equals the URL Path.
57 FormatSpanName func(*http.Request) string
58
59 // NewClientTrace may be set to a function allowing the current *trace.Span
60 // to be annotated with HTTP request event information emitted by the
61 // httptrace package.
62 NewClientTrace func(*http.Request, *trace.Span) *httptrace.ClientTrace
63
64 // TODO: Implement tag propagation for HTTP.
65}
66
67// RoundTrip implements http.RoundTripper, delegating to Base and recording stats and traces for the request.
68func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
69 rt := t.base()
70 if isHealthEndpoint(req.URL.Path) {
71 return rt.RoundTrip(req)
72 }
73 // TODO: remove excessive nesting of http.RoundTrippers here.
74 format := t.Propagation
75 if format == nil {
76 format = defaultFormat
77 }
78 spanNameFormatter := t.FormatSpanName
79 if spanNameFormatter == nil {
80 spanNameFormatter = spanNameFromURL
81 }
82
83 startOpts := t.StartOptions
84 if t.GetStartOptions != nil {
85 startOpts = t.GetStartOptions(req)
86 }
87
88 rt = &traceTransport{
89 base: rt,
90 format: format,
91 startOptions: trace.StartOptions{
92 Sampler: startOpts.Sampler,
93 SpanKind: trace.SpanKindClient,
94 },
95 formatSpanName: spanNameFormatter,
96 newClientTrace: t.NewClientTrace,
97 }
98 rt = statsTransport{base: rt}
99 return rt.RoundTrip(req)
100}
101
102func (t *Transport) base() http.RoundTripper {
103 if t.Base != nil {
104 return t.Base
105 }
106 return http.DefaultTransport
107}
108
109// CancelRequest cancels an in-flight request by closing its connection.
110func (t *Transport) CancelRequest(req *http.Request) {
111 type canceler interface {
112 CancelRequest(*http.Request)
113 }
114 if cr, ok := t.base().(canceler); ok {
115 cr.CancelRequest(req)
116 }
117}
diff --git a/vendor/go.opencensus.io/plugin/ochttp/client_stats.go b/vendor/go.opencensus.io/plugin/ochttp/client_stats.go
new file mode 100644
index 0000000..066ebb8
--- /dev/null
+++ b/vendor/go.opencensus.io/plugin/ochttp/client_stats.go
@@ -0,0 +1,135 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package ochttp
16
17import (
18 "context"
19 "io"
20 "net/http"
21 "strconv"
22 "sync"
23 "time"
24
25 "go.opencensus.io/stats"
26 "go.opencensus.io/tag"
27)
28
29// statsTransport is an http.RoundTripper that collects stats for the outgoing requests.
30type statsTransport struct {
31 base http.RoundTripper
32}
33
34// RoundTrip implements http.RoundTripper, delegating to Base and recording stats for the request.
35func (t statsTransport) RoundTrip(req *http.Request) (*http.Response, error) {
36 ctx, _ := tag.New(req.Context(),
37 tag.Upsert(KeyClientHost, req.URL.Host),
38 tag.Upsert(Host, req.URL.Host),
39 tag.Upsert(KeyClientPath, req.URL.Path),
40 tag.Upsert(Path, req.URL.Path),
41 tag.Upsert(KeyClientMethod, req.Method),
42 tag.Upsert(Method, req.Method))
43 req = req.WithContext(ctx)
44 track := &tracker{
45 start: time.Now(),
46 ctx: ctx,
47 }
48 if req.Body == nil {
49 // TODO: Handle cases where ContentLength is not set.
50 track.reqSize = -1
51 } else if req.ContentLength > 0 {
52 track.reqSize = req.ContentLength
53 }
54 stats.Record(ctx, ClientRequestCount.M(1))
55
56 // Perform request.
57 resp, err := t.base.RoundTrip(req)
58
59 if err != nil {
60 track.statusCode = http.StatusInternalServerError
61 track.end()
62 } else {
63 track.statusCode = resp.StatusCode
64 if resp.Body == nil {
65 track.end()
66 } else {
67 track.body = resp.Body
68 resp.Body = track
69 }
70 }
71 return resp, err
72}
73
74// CancelRequest cancels an in-flight request by closing its connection.
75func (t statsTransport) CancelRequest(req *http.Request) {
76 type canceler interface {
77 CancelRequest(*http.Request)
78 }
79 if cr, ok := t.base.(canceler); ok {
80 cr.CancelRequest(req)
81 }
82}
83
84type tracker struct {
85 ctx context.Context
86 respSize int64
87 reqSize int64
88 start time.Time
89 body io.ReadCloser
90 statusCode int
91 endOnce sync.Once
92}
93
94var _ io.ReadCloser = (*tracker)(nil)
95
96func (t *tracker) end() {
97 t.endOnce.Do(func() {
98 latencyMs := float64(time.Since(t.start)) / float64(time.Millisecond)
99 m := []stats.Measurement{
100 ClientSentBytes.M(t.reqSize),
101 ClientReceivedBytes.M(t.respSize),
102 ClientRoundtripLatency.M(latencyMs),
103 ClientLatency.M(latencyMs),
104 ClientResponseBytes.M(t.respSize),
105 }
106 if t.reqSize >= 0 {
107 m = append(m, ClientRequestBytes.M(t.reqSize))
108 }
109
110 stats.RecordWithTags(t.ctx, []tag.Mutator{
111 tag.Upsert(StatusCode, strconv.Itoa(t.statusCode)),
112 tag.Upsert(KeyClientStatus, strconv.Itoa(t.statusCode)),
113 }, m...)
114 })
115}
116
117func (t *tracker) Read(b []byte) (int, error) {
118 n, err := t.body.Read(b)
119 switch err {
120 case nil:
121 t.respSize += int64(n)
122 return n, nil
123 case io.EOF:
124 t.end()
125 }
126 return n, err
127}
128
129func (t *tracker) Close() error {
130 // Invoking endSpan on Close will help catch the cases
131 // in which a read returned a non-nil error, we set the
132 // span status but didn't end the span.
133 t.end()
134 return t.body.Close()
135}
diff --git a/vendor/go.opencensus.io/plugin/ochttp/doc.go b/vendor/go.opencensus.io/plugin/ochttp/doc.go
new file mode 100644
index 0000000..10e626b
--- /dev/null
+++ b/vendor/go.opencensus.io/plugin/ochttp/doc.go
@@ -0,0 +1,19 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package ochttp provides OpenCensus instrumentation for net/http package.
16//
17// For server instrumentation, see Handler. For client-side instrumentation,
18// see Transport.
19package ochttp // import "go.opencensus.io/plugin/ochttp"
diff --git a/vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go b/vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go
new file mode 100644
index 0000000..f777772
--- /dev/null
+++ b/vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go
@@ -0,0 +1,123 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package b3 contains a propagation.HTTPFormat implementation
16// for B3 propagation. See https://github.com/openzipkin/b3-propagation
17// for more details.
18package b3 // import "go.opencensus.io/plugin/ochttp/propagation/b3"
19
20import (
21 "encoding/hex"
22 "net/http"
23
24 "go.opencensus.io/trace"
25 "go.opencensus.io/trace/propagation"
26)
27
28// B3 headers that OpenCensus understands.
29const (
30 TraceIDHeader = "X-B3-TraceId"
31 SpanIDHeader = "X-B3-SpanId"
32 SampledHeader = "X-B3-Sampled"
33)
34
35// HTTPFormat implements propagation.HTTPFormat to propagate
36// traces in HTTP headers in B3 propagation format.
37// HTTPFormat skips the X-B3-ParentId and X-B3-Flags headers
38// because there are additional fields not represented in the
39// OpenCensus span context. Spans created from the incoming
40// header will be the direct children of the client-side span.
41// Similarly, reciever of the outgoing spans should use client-side
42// span created by OpenCensus as the parent.
43type HTTPFormat struct{}
44
45var _ propagation.HTTPFormat = (*HTTPFormat)(nil)
46
47// SpanContextFromRequest extracts a B3 span context from incoming requests.
48func (f *HTTPFormat) SpanContextFromRequest(req *http.Request) (sc trace.SpanContext, ok bool) {
49 tid, ok := ParseTraceID(req.Header.Get(TraceIDHeader))
50 if !ok {
51 return trace.SpanContext{}, false
52 }
53 sid, ok := ParseSpanID(req.Header.Get(SpanIDHeader))
54 if !ok {
55 return trace.SpanContext{}, false
56 }
57 sampled, _ := ParseSampled(req.Header.Get(SampledHeader))
58 return trace.SpanContext{
59 TraceID: tid,
60 SpanID: sid,
61 TraceOptions: sampled,
62 }, true
63}
64
65// ParseTraceID parses the value of the X-B3-TraceId header.
66func ParseTraceID(tid string) (trace.TraceID, bool) {
67 if tid == "" {
68 return trace.TraceID{}, false
69 }
70 b, err := hex.DecodeString(tid)
71 if err != nil {
72 return trace.TraceID{}, false
73 }
74 var traceID trace.TraceID
75 if len(b) <= 8 {
76 // The lower 64-bits.
77 start := 8 + (8 - len(b))
78 copy(traceID[start:], b)
79 } else {
80 start := 16 - len(b)
81 copy(traceID[start:], b)
82 }
83
84 return traceID, true
85}
86
87// ParseSpanID parses the value of the X-B3-SpanId or X-B3-ParentSpanId headers.
88func ParseSpanID(sid string) (spanID trace.SpanID, ok bool) {
89 if sid == "" {
90 return trace.SpanID{}, false
91 }
92 b, err := hex.DecodeString(sid)
93 if err != nil {
94 return trace.SpanID{}, false
95 }
96 start := 8 - len(b)
97 copy(spanID[start:], b)
98 return spanID, true
99}
100
101// ParseSampled parses the value of the X-B3-Sampled header.
102func ParseSampled(sampled string) (trace.TraceOptions, bool) {
103 switch sampled {
104 case "true", "1":
105 return trace.TraceOptions(1), true
106 default:
107 return trace.TraceOptions(0), false
108 }
109}
110
111// SpanContextToRequest modifies the given request to include B3 headers.
112func (f *HTTPFormat) SpanContextToRequest(sc trace.SpanContext, req *http.Request) {
113 req.Header.Set(TraceIDHeader, hex.EncodeToString(sc.TraceID[:]))
114 req.Header.Set(SpanIDHeader, hex.EncodeToString(sc.SpanID[:]))
115
116 var sampled string
117 if sc.IsSampled() {
118 sampled = "1"
119 } else {
120 sampled = "0"
121 }
122 req.Header.Set(SampledHeader, sampled)
123}
diff --git a/vendor/go.opencensus.io/plugin/ochttp/route.go b/vendor/go.opencensus.io/plugin/ochttp/route.go
new file mode 100644
index 0000000..dbe22d5
--- /dev/null
+++ b/vendor/go.opencensus.io/plugin/ochttp/route.go
@@ -0,0 +1,51 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package ochttp
16
17import (
18 "net/http"
19
20 "go.opencensus.io/tag"
21)
22
23// WithRouteTag returns an http.Handler that records stats with the
24// http_server_route tag set to the given value.
25func WithRouteTag(handler http.Handler, route string) http.Handler {
26 return taggedHandlerFunc(func(w http.ResponseWriter, r *http.Request) []tag.Mutator {
27 addRoute := []tag.Mutator{tag.Upsert(KeyServerRoute, route)}
28 ctx, _ := tag.New(r.Context(), addRoute...)
29 r = r.WithContext(ctx)
30 handler.ServeHTTP(w, r)
31 return addRoute
32 })
33}
34
35// taggedHandlerFunc is a http.Handler that returns tags describing the
36// processing of the request. These tags will be recorded along with the
37// measures in this package at the end of the request.
38type taggedHandlerFunc func(w http.ResponseWriter, r *http.Request) []tag.Mutator
39
40func (h taggedHandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) {
41 tags := h(w, r)
42 if a, ok := r.Context().Value(addedTagsKey{}).(*addedTags); ok {
43 a.t = append(a.t, tags...)
44 }
45}
46
47type addedTagsKey struct{}
48
49type addedTags struct {
50 t []tag.Mutator
51}
diff --git a/vendor/go.opencensus.io/plugin/ochttp/server.go b/vendor/go.opencensus.io/plugin/ochttp/server.go
new file mode 100644
index 0000000..ff72de9
--- /dev/null
+++ b/vendor/go.opencensus.io/plugin/ochttp/server.go
@@ -0,0 +1,440 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package ochttp
16
17import (
18 "context"
19 "io"
20 "net/http"
21 "strconv"
22 "sync"
23 "time"
24
25 "go.opencensus.io/stats"
26 "go.opencensus.io/tag"
27 "go.opencensus.io/trace"
28 "go.opencensus.io/trace/propagation"
29)
30
31// Handler is an http.Handler wrapper to instrument your HTTP server with
32// OpenCensus. It supports both stats and tracing.
33//
34// Tracing
35//
36// This handler is aware of the incoming request's span, reading it from request
37// headers as configured using the Propagation field.
38// The extracted span can be accessed from the incoming request's
39// context.
40//
41// span := trace.FromContext(r.Context())
42//
43// The server span will be automatically ended at the end of ServeHTTP.
44type Handler struct {
45 // Propagation defines how traces are propagated. If unspecified,
46 // B3 propagation will be used.
47 Propagation propagation.HTTPFormat
48
49 // Handler is the handler used to handle the incoming request.
50 Handler http.Handler
51
52 // StartOptions are applied to the span started by this Handler around each
53 // request.
54 //
55 // StartOptions.SpanKind will always be set to trace.SpanKindServer
56 // for spans started by this transport.
57 StartOptions trace.StartOptions
58
59 // GetStartOptions allows to set start options per request. If set,
60 // StartOptions is going to be ignored.
61 GetStartOptions func(*http.Request) trace.StartOptions
62
63 // IsPublicEndpoint should be set to true for publicly accessible HTTP(S)
64 // servers. If true, any trace metadata set on the incoming request will
65 // be added as a linked trace instead of being added as a parent of the
66 // current trace.
67 IsPublicEndpoint bool
68
69 // FormatSpanName holds the function to use for generating the span name
70 // from the information found in the incoming HTTP Request. By default the
71 // name equals the URL Path.
72 FormatSpanName func(*http.Request) string
73}
74
75func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
76 var tags addedTags
77 r, traceEnd := h.startTrace(w, r)
78 defer traceEnd()
79 w, statsEnd := h.startStats(w, r)
80 defer statsEnd(&tags)
81 handler := h.Handler
82 if handler == nil {
83 handler = http.DefaultServeMux
84 }
85 r = r.WithContext(context.WithValue(r.Context(), addedTagsKey{}, &tags))
86 handler.ServeHTTP(w, r)
87}
88
89func (h *Handler) startTrace(w http.ResponseWriter, r *http.Request) (*http.Request, func()) {
90 if isHealthEndpoint(r.URL.Path) {
91 return r, func() {}
92 }
93 var name string
94 if h.FormatSpanName == nil {
95 name = spanNameFromURL(r)
96 } else {
97 name = h.FormatSpanName(r)
98 }
99 ctx := r.Context()
100
101 startOpts := h.StartOptions
102 if h.GetStartOptions != nil {
103 startOpts = h.GetStartOptions(r)
104 }
105
106 var span *trace.Span
107 sc, ok := h.extractSpanContext(r)
108 if ok && !h.IsPublicEndpoint {
109 ctx, span = trace.StartSpanWithRemoteParent(ctx, name, sc,
110 trace.WithSampler(startOpts.Sampler),
111 trace.WithSpanKind(trace.SpanKindServer))
112 } else {
113 ctx, span = trace.StartSpan(ctx, name,
114 trace.WithSampler(startOpts.Sampler),
115 trace.WithSpanKind(trace.SpanKindServer),
116 )
117 if ok {
118 span.AddLink(trace.Link{
119 TraceID: sc.TraceID,
120 SpanID: sc.SpanID,
121 Type: trace.LinkTypeChild,
122 Attributes: nil,
123 })
124 }
125 }
126 span.AddAttributes(requestAttrs(r)...)
127 return r.WithContext(ctx), span.End
128}
129
130func (h *Handler) extractSpanContext(r *http.Request) (trace.SpanContext, bool) {
131 if h.Propagation == nil {
132 return defaultFormat.SpanContextFromRequest(r)
133 }
134 return h.Propagation.SpanContextFromRequest(r)
135}
136
137func (h *Handler) startStats(w http.ResponseWriter, r *http.Request) (http.ResponseWriter, func(tags *addedTags)) {
138 ctx, _ := tag.New(r.Context(),
139 tag.Upsert(Host, r.URL.Host),
140 tag.Upsert(Path, r.URL.Path),
141 tag.Upsert(Method, r.Method))
142 track := &trackingResponseWriter{
143 start: time.Now(),
144 ctx: ctx,
145 writer: w,
146 }
147 if r.Body == nil {
148 // TODO: Handle cases where ContentLength is not set.
149 track.reqSize = -1
150 } else if r.ContentLength > 0 {
151 track.reqSize = r.ContentLength
152 }
153 stats.Record(ctx, ServerRequestCount.M(1))
154 return track.wrappedResponseWriter(), track.end
155}
156
157type trackingResponseWriter struct {
158 ctx context.Context
159 reqSize int64
160 respSize int64
161 start time.Time
162 statusCode int
163 statusLine string
164 endOnce sync.Once
165 writer http.ResponseWriter
166}
167
168// Compile time assertion for ResponseWriter interface
169var _ http.ResponseWriter = (*trackingResponseWriter)(nil)
170
171var logTagsErrorOnce sync.Once
172
173func (t *trackingResponseWriter) end(tags *addedTags) {
174 t.endOnce.Do(func() {
175 if t.statusCode == 0 {
176 t.statusCode = 200
177 }
178
179 span := trace.FromContext(t.ctx)
180 span.SetStatus(TraceStatus(t.statusCode, t.statusLine))
181 span.AddAttributes(trace.Int64Attribute(StatusCodeAttribute, int64(t.statusCode)))
182
183 m := []stats.Measurement{
184 ServerLatency.M(float64(time.Since(t.start)) / float64(time.Millisecond)),
185 ServerResponseBytes.M(t.respSize),
186 }
187 if t.reqSize >= 0 {
188 m = append(m, ServerRequestBytes.M(t.reqSize))
189 }
190 allTags := make([]tag.Mutator, len(tags.t)+1)
191 allTags[0] = tag.Upsert(StatusCode, strconv.Itoa(t.statusCode))
192 copy(allTags[1:], tags.t)
193 stats.RecordWithTags(t.ctx, allTags, m...)
194 })
195}
196
197func (t *trackingResponseWriter) Header() http.Header {
198 return t.writer.Header()
199}
200
201func (t *trackingResponseWriter) Write(data []byte) (int, error) {
202 n, err := t.writer.Write(data)
203 t.respSize += int64(n)
204 return n, err
205}
206
207func (t *trackingResponseWriter) WriteHeader(statusCode int) {
208 t.writer.WriteHeader(statusCode)
209 t.statusCode = statusCode
210 t.statusLine = http.StatusText(t.statusCode)
211}
212
213// wrappedResponseWriter returns a wrapped version of the original
214// ResponseWriter and only implements the same combination of additional
215// interfaces as the original.
216// This implementation is based on https://github.com/felixge/httpsnoop.
217func (t *trackingResponseWriter) wrappedResponseWriter() http.ResponseWriter {
218 var (
219 hj, i0 = t.writer.(http.Hijacker)
220 cn, i1 = t.writer.(http.CloseNotifier)
221 pu, i2 = t.writer.(http.Pusher)
222 fl, i3 = t.writer.(http.Flusher)
223 rf, i4 = t.writer.(io.ReaderFrom)
224 )
225
226 switch {
227 case !i0 && !i1 && !i2 && !i3 && !i4:
228 return struct {
229 http.ResponseWriter
230 }{t}
231 case !i0 && !i1 && !i2 && !i3 && i4:
232 return struct {
233 http.ResponseWriter
234 io.ReaderFrom
235 }{t, rf}
236 case !i0 && !i1 && !i2 && i3 && !i4:
237 return struct {
238 http.ResponseWriter
239 http.Flusher
240 }{t, fl}
241 case !i0 && !i1 && !i2 && i3 && i4:
242 return struct {
243 http.ResponseWriter
244 http.Flusher
245 io.ReaderFrom
246 }{t, fl, rf}
247 case !i0 && !i1 && i2 && !i3 && !i4:
248 return struct {
249 http.ResponseWriter
250 http.Pusher
251 }{t, pu}
252 case !i0 && !i1 && i2 && !i3 && i4:
253 return struct {
254 http.ResponseWriter
255 http.Pusher
256 io.ReaderFrom
257 }{t, pu, rf}
258 case !i0 && !i1 && i2 && i3 && !i4:
259 return struct {
260 http.ResponseWriter
261 http.Pusher
262 http.Flusher
263 }{t, pu, fl}
264 case !i0 && !i1 && i2 && i3 && i4:
265 return struct {
266 http.ResponseWriter
267 http.Pusher
268 http.Flusher
269 io.ReaderFrom
270 }{t, pu, fl, rf}
271 case !i0 && i1 && !i2 && !i3 && !i4:
272 return struct {
273 http.ResponseWriter
274 http.CloseNotifier
275 }{t, cn}
276 case !i0 && i1 && !i2 && !i3 && i4:
277 return struct {
278 http.ResponseWriter
279 http.CloseNotifier
280 io.ReaderFrom
281 }{t, cn, rf}
282 case !i0 && i1 && !i2 && i3 && !i4:
283 return struct {
284 http.ResponseWriter
285 http.CloseNotifier
286 http.Flusher
287 }{t, cn, fl}
288 case !i0 && i1 && !i2 && i3 && i4:
289 return struct {
290 http.ResponseWriter
291 http.CloseNotifier
292 http.Flusher
293 io.ReaderFrom
294 }{t, cn, fl, rf}
295 case !i0 && i1 && i2 && !i3 && !i4:
296 return struct {
297 http.ResponseWriter
298 http.CloseNotifier
299 http.Pusher
300 }{t, cn, pu}
301 case !i0 && i1 && i2 && !i3 && i4:
302 return struct {
303 http.ResponseWriter
304 http.CloseNotifier
305 http.Pusher
306 io.ReaderFrom
307 }{t, cn, pu, rf}
308 case !i0 && i1 && i2 && i3 && !i4:
309 return struct {
310 http.ResponseWriter
311 http.CloseNotifier
312 http.Pusher
313 http.Flusher
314 }{t, cn, pu, fl}
315 case !i0 && i1 && i2 && i3 && i4:
316 return struct {
317 http.ResponseWriter
318 http.CloseNotifier
319 http.Pusher
320 http.Flusher
321 io.ReaderFrom
322 }{t, cn, pu, fl, rf}
323 case i0 && !i1 && !i2 && !i3 && !i4:
324 return struct {
325 http.ResponseWriter
326 http.Hijacker
327 }{t, hj}
328 case i0 && !i1 && !i2 && !i3 && i4:
329 return struct {
330 http.ResponseWriter
331 http.Hijacker
332 io.ReaderFrom
333 }{t, hj, rf}
334 case i0 && !i1 && !i2 && i3 && !i4:
335 return struct {
336 http.ResponseWriter
337 http.Hijacker
338 http.Flusher
339 }{t, hj, fl}
340 case i0 && !i1 && !i2 && i3 && i4:
341 return struct {
342 http.ResponseWriter
343 http.Hijacker
344 http.Flusher
345 io.ReaderFrom
346 }{t, hj, fl, rf}
347 case i0 && !i1 && i2 && !i3 && !i4:
348 return struct {
349 http.ResponseWriter
350 http.Hijacker
351 http.Pusher
352 }{t, hj, pu}
353 case i0 && !i1 && i2 && !i3 && i4:
354 return struct {
355 http.ResponseWriter
356 http.Hijacker
357 http.Pusher
358 io.ReaderFrom
359 }{t, hj, pu, rf}
360 case i0 && !i1 && i2 && i3 && !i4:
361 return struct {
362 http.ResponseWriter
363 http.Hijacker
364 http.Pusher
365 http.Flusher
366 }{t, hj, pu, fl}
367 case i0 && !i1 && i2 && i3 && i4:
368 return struct {
369 http.ResponseWriter
370 http.Hijacker
371 http.Pusher
372 http.Flusher
373 io.ReaderFrom
374 }{t, hj, pu, fl, rf}
375 case i0 && i1 && !i2 && !i3 && !i4:
376 return struct {
377 http.ResponseWriter
378 http.Hijacker
379 http.CloseNotifier
380 }{t, hj, cn}
381 case i0 && i1 && !i2 && !i3 && i4:
382 return struct {
383 http.ResponseWriter
384 http.Hijacker
385 http.CloseNotifier
386 io.ReaderFrom
387 }{t, hj, cn, rf}
388 case i0 && i1 && !i2 && i3 && !i4:
389 return struct {
390 http.ResponseWriter
391 http.Hijacker
392 http.CloseNotifier
393 http.Flusher
394 }{t, hj, cn, fl}
395 case i0 && i1 && !i2 && i3 && i4:
396 return struct {
397 http.ResponseWriter
398 http.Hijacker
399 http.CloseNotifier
400 http.Flusher
401 io.ReaderFrom
402 }{t, hj, cn, fl, rf}
403 case i0 && i1 && i2 && !i3 && !i4:
404 return struct {
405 http.ResponseWriter
406 http.Hijacker
407 http.CloseNotifier
408 http.Pusher
409 }{t, hj, cn, pu}
410 case i0 && i1 && i2 && !i3 && i4:
411 return struct {
412 http.ResponseWriter
413 http.Hijacker
414 http.CloseNotifier
415 http.Pusher
416 io.ReaderFrom
417 }{t, hj, cn, pu, rf}
418 case i0 && i1 && i2 && i3 && !i4:
419 return struct {
420 http.ResponseWriter
421 http.Hijacker
422 http.CloseNotifier
423 http.Pusher
424 http.Flusher
425 }{t, hj, cn, pu, fl}
426 case i0 && i1 && i2 && i3 && i4:
427 return struct {
428 http.ResponseWriter
429 http.Hijacker
430 http.CloseNotifier
431 http.Pusher
432 http.Flusher
433 io.ReaderFrom
434 }{t, hj, cn, pu, fl, rf}
435 default:
436 return struct {
437 http.ResponseWriter
438 }{t}
439 }
440}
diff --git a/vendor/go.opencensus.io/plugin/ochttp/span_annotating_client_trace.go b/vendor/go.opencensus.io/plugin/ochttp/span_annotating_client_trace.go
new file mode 100644
index 0000000..05c6c56
--- /dev/null
+++ b/vendor/go.opencensus.io/plugin/ochttp/span_annotating_client_trace.go
@@ -0,0 +1,169 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package ochttp
16
17import (
18 "crypto/tls"
19 "net/http"
20 "net/http/httptrace"
21 "strings"
22
23 "go.opencensus.io/trace"
24)
25
26type spanAnnotator struct {
27 sp *trace.Span
28}
29
30// TODO: Remove NewSpanAnnotator at the next release.
31
32// NewSpanAnnotator returns a httptrace.ClientTrace which annotates
33// all emitted httptrace events on the provided Span.
34// Deprecated: Use NewSpanAnnotatingClientTrace instead
35func NewSpanAnnotator(r *http.Request, s *trace.Span) *httptrace.ClientTrace {
36 return NewSpanAnnotatingClientTrace(r, s)
37}
38
39// NewSpanAnnotatingClientTrace returns a httptrace.ClientTrace which annotates
40// all emitted httptrace events on the provided Span.
41func NewSpanAnnotatingClientTrace(_ *http.Request, s *trace.Span) *httptrace.ClientTrace {
42 sa := spanAnnotator{sp: s}
43
44 return &httptrace.ClientTrace{
45 GetConn: sa.getConn,
46 GotConn: sa.gotConn,
47 PutIdleConn: sa.putIdleConn,
48 GotFirstResponseByte: sa.gotFirstResponseByte,
49 Got100Continue: sa.got100Continue,
50 DNSStart: sa.dnsStart,
51 DNSDone: sa.dnsDone,
52 ConnectStart: sa.connectStart,
53 ConnectDone: sa.connectDone,
54 TLSHandshakeStart: sa.tlsHandshakeStart,
55 TLSHandshakeDone: sa.tlsHandshakeDone,
56 WroteHeaders: sa.wroteHeaders,
57 Wait100Continue: sa.wait100Continue,
58 WroteRequest: sa.wroteRequest,
59 }
60}
61
62func (s spanAnnotator) getConn(hostPort string) {
63 attrs := []trace.Attribute{
64 trace.StringAttribute("httptrace.get_connection.host_port", hostPort),
65 }
66 s.sp.Annotate(attrs, "GetConn")
67}
68
69func (s spanAnnotator) gotConn(info httptrace.GotConnInfo) {
70 attrs := []trace.Attribute{
71 trace.BoolAttribute("httptrace.got_connection.reused", info.Reused),
72 trace.BoolAttribute("httptrace.got_connection.was_idle", info.WasIdle),
73 }
74 if info.WasIdle {
75 attrs = append(attrs,
76 trace.StringAttribute("httptrace.got_connection.idle_time", info.IdleTime.String()))
77 }
78 s.sp.Annotate(attrs, "GotConn")
79}
80
81// PutIdleConn implements a httptrace.ClientTrace hook
82func (s spanAnnotator) putIdleConn(err error) {
83 var attrs []trace.Attribute
84 if err != nil {
85 attrs = append(attrs,
86 trace.StringAttribute("httptrace.put_idle_connection.error", err.Error()))
87 }
88 s.sp.Annotate(attrs, "PutIdleConn")
89}
90
91func (s spanAnnotator) gotFirstResponseByte() {
92 s.sp.Annotate(nil, "GotFirstResponseByte")
93}
94
95func (s spanAnnotator) got100Continue() {
96 s.sp.Annotate(nil, "Got100Continue")
97}
98
99func (s spanAnnotator) dnsStart(info httptrace.DNSStartInfo) {
100 attrs := []trace.Attribute{
101 trace.StringAttribute("httptrace.dns_start.host", info.Host),
102 }
103 s.sp.Annotate(attrs, "DNSStart")
104}
105
106func (s spanAnnotator) dnsDone(info httptrace.DNSDoneInfo) {
107 var addrs []string
108 for _, addr := range info.Addrs {
109 addrs = append(addrs, addr.String())
110 }
111 attrs := []trace.Attribute{
112 trace.StringAttribute("httptrace.dns_done.addrs", strings.Join(addrs, " , ")),
113 }
114 if info.Err != nil {
115 attrs = append(attrs,
116 trace.StringAttribute("httptrace.dns_done.error", info.Err.Error()))
117 }
118 s.sp.Annotate(attrs, "DNSDone")
119}
120
121func (s spanAnnotator) connectStart(network, addr string) {
122 attrs := []trace.Attribute{
123 trace.StringAttribute("httptrace.connect_start.network", network),
124 trace.StringAttribute("httptrace.connect_start.addr", addr),
125 }
126 s.sp.Annotate(attrs, "ConnectStart")
127}
128
129func (s spanAnnotator) connectDone(network, addr string, err error) {
130 attrs := []trace.Attribute{
131 trace.StringAttribute("httptrace.connect_done.network", network),
132 trace.StringAttribute("httptrace.connect_done.addr", addr),
133 }
134 if err != nil {
135 attrs = append(attrs,
136 trace.StringAttribute("httptrace.connect_done.error", err.Error()))
137 }
138 s.sp.Annotate(attrs, "ConnectDone")
139}
140
141func (s spanAnnotator) tlsHandshakeStart() {
142 s.sp.Annotate(nil, "TLSHandshakeStart")
143}
144
145func (s spanAnnotator) tlsHandshakeDone(_ tls.ConnectionState, err error) {
146 var attrs []trace.Attribute
147 if err != nil {
148 attrs = append(attrs,
149 trace.StringAttribute("httptrace.tls_handshake_done.error", err.Error()))
150 }
151 s.sp.Annotate(attrs, "TLSHandshakeDone")
152}
153
154func (s spanAnnotator) wroteHeaders() {
155 s.sp.Annotate(nil, "WroteHeaders")
156}
157
158func (s spanAnnotator) wait100Continue() {
159 s.sp.Annotate(nil, "Wait100Continue")
160}
161
162func (s spanAnnotator) wroteRequest(info httptrace.WroteRequestInfo) {
163 var attrs []trace.Attribute
164 if info.Err != nil {
165 attrs = append(attrs,
166 trace.StringAttribute("httptrace.wrote_request.error", info.Err.Error()))
167 }
168 s.sp.Annotate(attrs, "WroteRequest")
169}
diff --git a/vendor/go.opencensus.io/plugin/ochttp/stats.go b/vendor/go.opencensus.io/plugin/ochttp/stats.go
new file mode 100644
index 0000000..46dcc8e
--- /dev/null
+++ b/vendor/go.opencensus.io/plugin/ochttp/stats.go
@@ -0,0 +1,265 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package ochttp
16
17import (
18 "go.opencensus.io/stats"
19 "go.opencensus.io/stats/view"
20 "go.opencensus.io/tag"
21)
22
23// The following client HTTP measures are supported for use in custom views.
24var (
25 // Deprecated: Use a Count aggregation over one of the other client measures to achieve the same effect.
26 ClientRequestCount = stats.Int64("opencensus.io/http/client/request_count", "Number of HTTP requests started", stats.UnitDimensionless)
27 // Deprecated: Use ClientSentBytes.
28 ClientRequestBytes = stats.Int64("opencensus.io/http/client/request_bytes", "HTTP request body size if set as ContentLength (uncompressed)", stats.UnitBytes)
29 // Deprecated: Use ClientReceivedBytes.
30 ClientResponseBytes = stats.Int64("opencensus.io/http/client/response_bytes", "HTTP response body size (uncompressed)", stats.UnitBytes)
31 // Deprecated: Use ClientRoundtripLatency.
32 ClientLatency = stats.Float64("opencensus.io/http/client/latency", "End-to-end latency", stats.UnitMilliseconds)
33)
34
35// Client measures supported for use in custom views.
36var (
37 ClientSentBytes = stats.Int64(
38 "opencensus.io/http/client/sent_bytes",
39 "Total bytes sent in request body (not including headers)",
40 stats.UnitBytes,
41 )
42 ClientReceivedBytes = stats.Int64(
43 "opencensus.io/http/client/received_bytes",
44 "Total bytes received in response bodies (not including headers but including error responses with bodies)",
45 stats.UnitBytes,
46 )
47 ClientRoundtripLatency = stats.Float64(
48 "opencensus.io/http/client/roundtrip_latency",
49 "Time between first byte of request headers sent to last byte of response received, or terminal error",
50 stats.UnitMilliseconds,
51 )
52)
53
54// The following server HTTP measures are supported for use in custom views:
55var (
56 ServerRequestCount = stats.Int64("opencensus.io/http/server/request_count", "Number of HTTP requests started", stats.UnitDimensionless)
57 ServerRequestBytes = stats.Int64("opencensus.io/http/server/request_bytes", "HTTP request body size if set as ContentLength (uncompressed)", stats.UnitBytes)
58 ServerResponseBytes = stats.Int64("opencensus.io/http/server/response_bytes", "HTTP response body size (uncompressed)", stats.UnitBytes)
59 ServerLatency = stats.Float64("opencensus.io/http/server/latency", "End-to-end latency", stats.UnitMilliseconds)
60)
61
62// The following tags are applied to stats recorded by this package. Host, Path
63// and Method are applied to all measures. StatusCode is not applied to
64// ClientRequestCount or ServerRequestCount, since it is recorded before the status is known.
65var (
66 // Host is the value of the HTTP Host header.
67 //
68 // The value of this tag can be controlled by the HTTP client, so you need
69 // to watch out for potentially generating high-cardinality labels in your
70 // metrics backend if you use this tag in views.
71 Host, _ = tag.NewKey("http.host")
72
73 // StatusCode is the numeric HTTP response status code,
74 // or "error" if a transport error occurred and no status code was read.
75 StatusCode, _ = tag.NewKey("http.status")
76
77 // Path is the URL path (not including query string) in the request.
78 //
79 // The value of this tag can be controlled by the HTTP client, so you need
80 // to watch out for potentially generating high-cardinality labels in your
81 // metrics backend if you use this tag in views.
82 Path, _ = tag.NewKey("http.path")
83
84 // Method is the HTTP method of the request, capitalized (GET, POST, etc.).
85 Method, _ = tag.NewKey("http.method")
86
87 // KeyServerRoute is a low cardinality string representing the logical
88 // handler of the request. This is usually the pattern registered on the a
89 // ServeMux (or similar string).
90 KeyServerRoute, _ = tag.NewKey("http_server_route")
91)
92
93// Client tag keys.
94var (
95 // KeyClientMethod is the HTTP method, capitalized (i.e. GET, POST, PUT, DELETE, etc.).
96 KeyClientMethod, _ = tag.NewKey("http_client_method")
97 // KeyClientPath is the URL path (not including query string).
98 KeyClientPath, _ = tag.NewKey("http_client_path")
99 // KeyClientStatus is the HTTP status code as an integer (e.g. 200, 404, 500.), or "error" if no response status line was received.
100 KeyClientStatus, _ = tag.NewKey("http_client_status")
101 // KeyClientHost is the value of the request Host header.
102 KeyClientHost, _ = tag.NewKey("http_client_host")
103)
104
105// Default distributions used by views in this package.
106var (
107 DefaultSizeDistribution = view.Distribution(0, 1024, 2048, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864, 268435456, 1073741824, 4294967296)
108 DefaultLatencyDistribution = view.Distribution(0, 1, 2, 3, 4, 5, 6, 8, 10, 13, 16, 20, 25, 30, 40, 50, 65, 80, 100, 130, 160, 200, 250, 300, 400, 500, 650, 800, 1000, 2000, 5000, 10000, 20000, 50000, 100000)
109)
110
111// Package ochttp provides some convenience views.
112// You still need to register these views for data to actually be collected.
113var (
114 ClientSentBytesDistribution = &view.View{
115 Name: "opencensus.io/http/client/sent_bytes",
116 Measure: ClientSentBytes,
117 Aggregation: DefaultSizeDistribution,
118 Description: "Total bytes sent in request body (not including headers), by HTTP method and response status",
119 TagKeys: []tag.Key{KeyClientMethod, KeyClientStatus},
120 }
121
122 ClientReceivedBytesDistribution = &view.View{
123 Name: "opencensus.io/http/client/received_bytes",
124 Measure: ClientReceivedBytes,
125 Aggregation: DefaultSizeDistribution,
126 Description: "Total bytes received in response bodies (not including headers but including error responses with bodies), by HTTP method and response status",
127 TagKeys: []tag.Key{KeyClientMethod, KeyClientStatus},
128 }
129
130 ClientRoundtripLatencyDistribution = &view.View{
131 Name: "opencensus.io/http/client/roundtrip_latency",
132 Measure: ClientRoundtripLatency,
133 Aggregation: DefaultLatencyDistribution,
134 Description: "End-to-end latency, by HTTP method and response status",
135 TagKeys: []tag.Key{KeyClientMethod, KeyClientStatus},
136 }
137
138 ClientCompletedCount = &view.View{
139 Name: "opencensus.io/http/client/completed_count",
140 Measure: ClientRoundtripLatency,
141 Aggregation: view.Count(),
142 Description: "Count of completed requests, by HTTP method and response status",
143 TagKeys: []tag.Key{KeyClientMethod, KeyClientStatus},
144 }
145)
146
147var (
148 // Deprecated: No direct replacement, but see ClientCompletedCount.
149 ClientRequestCountView = &view.View{
150 Name: "opencensus.io/http/client/request_count",
151 Description: "Count of HTTP requests started",
152 Measure: ClientRequestCount,
153 Aggregation: view.Count(),
154 }
155
156 // Deprecated: Use ClientSentBytesDistribution.
157 ClientRequestBytesView = &view.View{
158 Name: "opencensus.io/http/client/request_bytes",
159 Description: "Size distribution of HTTP request body",
160 Measure: ClientSentBytes,
161 Aggregation: DefaultSizeDistribution,
162 }
163
164 // Deprecated: Use ClientReceivedBytesDistribution.
165 ClientResponseBytesView = &view.View{
166 Name: "opencensus.io/http/client/response_bytes",
167 Description: "Size distribution of HTTP response body",
168 Measure: ClientReceivedBytes,
169 Aggregation: DefaultSizeDistribution,
170 }
171
172 // Deprecated: Use ClientRoundtripLatencyDistribution.
173 ClientLatencyView = &view.View{
174 Name: "opencensus.io/http/client/latency",
175 Description: "Latency distribution of HTTP requests",
176 Measure: ClientRoundtripLatency,
177 Aggregation: DefaultLatencyDistribution,
178 }
179
180 // Deprecated: Use ClientCompletedCount.
181 ClientRequestCountByMethod = &view.View{
182 Name: "opencensus.io/http/client/request_count_by_method",
183 Description: "Client request count by HTTP method",
184 TagKeys: []tag.Key{Method},
185 Measure: ClientSentBytes,
186 Aggregation: view.Count(),
187 }
188
189 // Deprecated: Use ClientCompletedCount.
190 ClientResponseCountByStatusCode = &view.View{
191 Name: "opencensus.io/http/client/response_count_by_status_code",
192 Description: "Client response count by status code",
193 TagKeys: []tag.Key{StatusCode},
194 Measure: ClientRoundtripLatency,
195 Aggregation: view.Count(),
196 }
197)
198
199var (
200 ServerRequestCountView = &view.View{
201 Name: "opencensus.io/http/server/request_count",
202 Description: "Count of HTTP requests started",
203 Measure: ServerRequestCount,
204 Aggregation: view.Count(),
205 }
206
207 ServerRequestBytesView = &view.View{
208 Name: "opencensus.io/http/server/request_bytes",
209 Description: "Size distribution of HTTP request body",
210 Measure: ServerRequestBytes,
211 Aggregation: DefaultSizeDistribution,
212 }
213
214 ServerResponseBytesView = &view.View{
215 Name: "opencensus.io/http/server/response_bytes",
216 Description: "Size distribution of HTTP response body",
217 Measure: ServerResponseBytes,
218 Aggregation: DefaultSizeDistribution,
219 }
220
221 ServerLatencyView = &view.View{
222 Name: "opencensus.io/http/server/latency",
223 Description: "Latency distribution of HTTP requests",
224 Measure: ServerLatency,
225 Aggregation: DefaultLatencyDistribution,
226 }
227
228 ServerRequestCountByMethod = &view.View{
229 Name: "opencensus.io/http/server/request_count_by_method",
230 Description: "Server request count by HTTP method",
231 TagKeys: []tag.Key{Method},
232 Measure: ServerRequestCount,
233 Aggregation: view.Count(),
234 }
235
236 ServerResponseCountByStatusCode = &view.View{
237 Name: "opencensus.io/http/server/response_count_by_status_code",
238 Description: "Server response count by status code",
239 TagKeys: []tag.Key{StatusCode},
240 Measure: ServerLatency,
241 Aggregation: view.Count(),
242 }
243)
244
245// DefaultClientViews are the default client views provided by this package.
246// Deprecated: No replacement. Register the views you would like individually.
247var DefaultClientViews = []*view.View{
248 ClientRequestCountView,
249 ClientRequestBytesView,
250 ClientResponseBytesView,
251 ClientLatencyView,
252 ClientRequestCountByMethod,
253 ClientResponseCountByStatusCode,
254}
255
256// DefaultServerViews are the default server views provided by this package.
257// Deprecated: No replacement. Register the views you would like individually.
258var DefaultServerViews = []*view.View{
259 ServerRequestCountView,
260 ServerRequestBytesView,
261 ServerResponseBytesView,
262 ServerLatencyView,
263 ServerRequestCountByMethod,
264 ServerResponseCountByStatusCode,
265}
diff --git a/vendor/go.opencensus.io/plugin/ochttp/trace.go b/vendor/go.opencensus.io/plugin/ochttp/trace.go
new file mode 100644
index 0000000..819a2d5
--- /dev/null
+++ b/vendor/go.opencensus.io/plugin/ochttp/trace.go
@@ -0,0 +1,228 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package ochttp
16
17import (
18 "io"
19 "net/http"
20 "net/http/httptrace"
21
22 "go.opencensus.io/plugin/ochttp/propagation/b3"
23 "go.opencensus.io/trace"
24 "go.opencensus.io/trace/propagation"
25)
26
27// TODO(jbd): Add godoc examples.
28
29var defaultFormat propagation.HTTPFormat = &b3.HTTPFormat{}
30
31// Attributes recorded on the span for the requests.
32// Only trace exporters will need them.
33const (
34 HostAttribute = "http.host"
35 MethodAttribute = "http.method"
36 PathAttribute = "http.path"
37 UserAgentAttribute = "http.user_agent"
38 StatusCodeAttribute = "http.status_code"
39)
40
41type traceTransport struct {
42 base http.RoundTripper
43 startOptions trace.StartOptions
44 format propagation.HTTPFormat
45 formatSpanName func(*http.Request) string
46 newClientTrace func(*http.Request, *trace.Span) *httptrace.ClientTrace
47}
48
49// TODO(jbd): Add message events for request and response size.
50
51// RoundTrip creates a trace.Span and inserts it into the outgoing request's headers.
52// The created span can follow a parent span, if a parent is presented in
53// the request's context.
54func (t *traceTransport) RoundTrip(req *http.Request) (*http.Response, error) {
55 name := t.formatSpanName(req)
56 // TODO(jbd): Discuss whether we want to prefix
57 // outgoing requests with Sent.
58 ctx, span := trace.StartSpan(req.Context(), name,
59 trace.WithSampler(t.startOptions.Sampler),
60 trace.WithSpanKind(trace.SpanKindClient))
61
62 if t.newClientTrace != nil {
63 req = req.WithContext(httptrace.WithClientTrace(ctx, t.newClientTrace(req, span)))
64 } else {
65 req = req.WithContext(ctx)
66 }
67
68 if t.format != nil {
69 // SpanContextToRequest will modify its Request argument, which is
70 // contrary to the contract for http.RoundTripper, so we need to
71 // pass it a copy of the Request.
72 // However, the Request struct itself was already copied by
73 // the WithContext calls above and so we just need to copy the header.
74 header := make(http.Header)
75 for k, v := range req.Header {
76 header[k] = v
77 }
78 req.Header = header
79 t.format.SpanContextToRequest(span.SpanContext(), req)
80 }
81
82 span.AddAttributes(requestAttrs(req)...)
83 resp, err := t.base.RoundTrip(req)
84 if err != nil {
85 span.SetStatus(trace.Status{Code: trace.StatusCodeUnknown, Message: err.Error()})
86 span.End()
87 return resp, err
88 }
89
90 span.AddAttributes(responseAttrs(resp)...)
91 span.SetStatus(TraceStatus(resp.StatusCode, resp.Status))
92
93 // span.End() will be invoked after
94 // a read from resp.Body returns io.EOF or when
95 // resp.Body.Close() is invoked.
96 resp.Body = &bodyTracker{rc: resp.Body, span: span}
97 return resp, err
98}
99
100// bodyTracker wraps a response.Body and invokes
101// trace.EndSpan on encountering io.EOF on reading
102// the body of the original response.
103type bodyTracker struct {
104 rc io.ReadCloser
105 span *trace.Span
106}
107
108var _ io.ReadCloser = (*bodyTracker)(nil)
109
110func (bt *bodyTracker) Read(b []byte) (int, error) {
111 n, err := bt.rc.Read(b)
112
113 switch err {
114 case nil:
115 return n, nil
116 case io.EOF:
117 bt.span.End()
118 default:
119 // For all other errors, set the span status
120 bt.span.SetStatus(trace.Status{
121 // Code 2 is the error code for Internal server error.
122 Code: 2,
123 Message: err.Error(),
124 })
125 }
126 return n, err
127}
128
129func (bt *bodyTracker) Close() error {
130 // Invoking endSpan on Close will help catch the cases
131 // in which a read returned a non-nil error, we set the
132 // span status but didn't end the span.
133 bt.span.End()
134 return bt.rc.Close()
135}
136
137// CancelRequest cancels an in-flight request by closing its connection.
138func (t *traceTransport) CancelRequest(req *http.Request) {
139 type canceler interface {
140 CancelRequest(*http.Request)
141 }
142 if cr, ok := t.base.(canceler); ok {
143 cr.CancelRequest(req)
144 }
145}
146
147func spanNameFromURL(req *http.Request) string {
148 return req.URL.Path
149}
150
151func requestAttrs(r *http.Request) []trace.Attribute {
152 return []trace.Attribute{
153 trace.StringAttribute(PathAttribute, r.URL.Path),
154 trace.StringAttribute(HostAttribute, r.URL.Host),
155 trace.StringAttribute(MethodAttribute, r.Method),
156 trace.StringAttribute(UserAgentAttribute, r.UserAgent()),
157 }
158}
159
160func responseAttrs(resp *http.Response) []trace.Attribute {
161 return []trace.Attribute{
162 trace.Int64Attribute(StatusCodeAttribute, int64(resp.StatusCode)),
163 }
164}
165
166// TraceStatus is a utility to convert the HTTP status code to a trace.Status that
167// represents the outcome as closely as possible.
168func TraceStatus(httpStatusCode int, statusLine string) trace.Status {
169 var code int32
170 if httpStatusCode < 200 || httpStatusCode >= 400 {
171 code = trace.StatusCodeUnknown
172 }
173 switch httpStatusCode {
174 case 499:
175 code = trace.StatusCodeCancelled
176 case http.StatusBadRequest:
177 code = trace.StatusCodeInvalidArgument
178 case http.StatusGatewayTimeout:
179 code = trace.StatusCodeDeadlineExceeded
180 case http.StatusNotFound:
181 code = trace.StatusCodeNotFound
182 case http.StatusForbidden:
183 code = trace.StatusCodePermissionDenied
184 case http.StatusUnauthorized: // 401 is actually unauthenticated.
185 code = trace.StatusCodeUnauthenticated
186 case http.StatusTooManyRequests:
187 code = trace.StatusCodeResourceExhausted
188 case http.StatusNotImplemented:
189 code = trace.StatusCodeUnimplemented
190 case http.StatusServiceUnavailable:
191 code = trace.StatusCodeUnavailable
192 case http.StatusOK:
193 code = trace.StatusCodeOK
194 }
195 return trace.Status{Code: code, Message: codeToStr[code]}
196}
197
198var codeToStr = map[int32]string{
199 trace.StatusCodeOK: `OK`,
200 trace.StatusCodeCancelled: `CANCELLED`,
201 trace.StatusCodeUnknown: `UNKNOWN`,
202 trace.StatusCodeInvalidArgument: `INVALID_ARGUMENT`,
203 trace.StatusCodeDeadlineExceeded: `DEADLINE_EXCEEDED`,
204 trace.StatusCodeNotFound: `NOT_FOUND`,
205 trace.StatusCodeAlreadyExists: `ALREADY_EXISTS`,
206 trace.StatusCodePermissionDenied: `PERMISSION_DENIED`,
207 trace.StatusCodeResourceExhausted: `RESOURCE_EXHAUSTED`,
208 trace.StatusCodeFailedPrecondition: `FAILED_PRECONDITION`,
209 trace.StatusCodeAborted: `ABORTED`,
210 trace.StatusCodeOutOfRange: `OUT_OF_RANGE`,
211 trace.StatusCodeUnimplemented: `UNIMPLEMENTED`,
212 trace.StatusCodeInternal: `INTERNAL`,
213 trace.StatusCodeUnavailable: `UNAVAILABLE`,
214 trace.StatusCodeDataLoss: `DATA_LOSS`,
215 trace.StatusCodeUnauthenticated: `UNAUTHENTICATED`,
216}
217
218func isHealthEndpoint(path string) bool {
219 // Health checking is pretty frequent and
220 // traces collected for health endpoints
221 // can be extremely noisy and expensive.
222 // Disable canonical health checking endpoints
223 // like /healthz and /_ah/health for now.
224 if path == "/healthz" || path == "/_ah/health" {
225 return true
226 }
227 return false
228}
diff --git a/vendor/go.opencensus.io/stats/doc.go b/vendor/go.opencensus.io/stats/doc.go
new file mode 100644
index 0000000..00d473e
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/doc.go
@@ -0,0 +1,69 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16/*
17Package stats contains support for OpenCensus stats recording.
18
19OpenCensus allows users to create typed measures, record measurements,
20aggregate the collected data, and export the aggregated data.
21
22Measures
23
24A measure represents a type of data point to be tracked and recorded.
25For example, latency, request Mb/s, and response Mb/s are measures
26to collect from a server.
27
28Measure constructors such as Int64 and Float64 automatically
29register the measure by the given name. Each registered measure needs
30to be unique by name. Measures also have a description and a unit.
31
32Libraries can define and export measures. Application authors can then
33create views and collect and break down measures by the tags they are
34interested in.
35
36Recording measurements
37
38Measurement is a data point to be collected for a measure. For example,
39for a latency (ms) measure, 100 is a measurement that represents a 100ms
40latency event. Measurements are created from measures with
41the current context. Tags from the current context are recorded with the
42measurements if they are any.
43
44Recorded measurements are dropped immediately if no views are registered for them.
45There is usually no need to conditionally enable and disable
46recording to reduce cost. Recording of measurements is cheap.
47
48Libraries can always record measurements, and applications can later decide
49on which measurements they want to collect by registering views. This allows
50libraries to turn on the instrumentation by default.
51
52Exemplars
53
54For a given recorded measurement, the associated exemplar is a diagnostic map
55that gives more information about the measurement.
56
57When aggregated using a Distribution aggregation, an exemplar is kept for each
58bucket in the Distribution. This allows you to easily find an example of a
59measurement that fell into each bucket.
60
61For example, if you also use the OpenCensus trace package and you
62record a measurement with a context that contains a sampled trace span,
63then the trace span will be added to the exemplar associated with the measurement.
64
65When exported to a supporting back end, you should be able to easily navigate
66to example traces that fell into each bucket in the Distribution.
67
68*/
69package stats // import "go.opencensus.io/stats"
diff --git a/vendor/go.opencensus.io/stats/internal/record.go b/vendor/go.opencensus.io/stats/internal/record.go
new file mode 100644
index 0000000..ed54552
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/internal/record.go
@@ -0,0 +1,25 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package internal
16
17import (
18 "go.opencensus.io/tag"
19)
20
21// DefaultRecorder will be called for each Record call.
22var DefaultRecorder func(tags *tag.Map, measurement interface{}, attachments map[string]string)
23
24// SubscriptionReporter reports when a view subscribed with a measure.
25var SubscriptionReporter func(measure string)
diff --git a/vendor/go.opencensus.io/stats/internal/validation.go b/vendor/go.opencensus.io/stats/internal/validation.go
new file mode 100644
index 0000000..b946667
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/internal/validation.go
@@ -0,0 +1,28 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package internal // import "go.opencensus.io/stats/internal"
16
17const (
18 MaxNameLength = 255
19)
20
21func IsPrintable(str string) bool {
22 for _, r := range str {
23 if !(r >= ' ' && r <= '~') {
24 return false
25 }
26 }
27 return true
28}
diff --git a/vendor/go.opencensus.io/stats/measure.go b/vendor/go.opencensus.io/stats/measure.go
new file mode 100644
index 0000000..64d02b1
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/measure.go
@@ -0,0 +1,123 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package stats
17
18import (
19 "sync"
20 "sync/atomic"
21)
22
23// Measure represents a single numeric value to be tracked and recorded.
24// For example, latency, request bytes, and response bytes could be measures
25// to collect from a server.
26//
27// Measures by themselves have no outside effects. In order to be exported,
28// the measure needs to be used in a View. If no Views are defined over a
29// measure, there is very little cost in recording it.
30type Measure interface {
31 // Name returns the name of this measure.
32 //
33 // Measure names are globally unique (among all libraries linked into your program).
34 // We recommend prefixing the measure name with a domain name relevant to your
35 // project or application.
36 //
37 // Measure names are never sent over the wire or exported to backends.
38 // They are only used to create Views.
39 Name() string
40
41 // Description returns the human-readable description of this measure.
42 Description() string
43
44 // Unit returns the units for the values this measure takes on.
45 //
46 // Units are encoded according to the case-sensitive abbreviations from the
47 // Unified Code for Units of Measure: http://unitsofmeasure.org/ucum.html
48 Unit() string
49}
50
51// measureDescriptor is the untyped descriptor associated with each measure.
52// Int64Measure and Float64Measure wrap measureDescriptor to provide typed
53// recording APIs.
54// Two Measures with the same name will have the same measureDescriptor.
55type measureDescriptor struct {
56 subs int32 // access atomically
57
58 name string
59 description string
60 unit string
61}
62
63func (m *measureDescriptor) subscribe() {
64 atomic.StoreInt32(&m.subs, 1)
65}
66
67func (m *measureDescriptor) subscribed() bool {
68 return atomic.LoadInt32(&m.subs) == 1
69}
70
71// Name returns the name of the measure.
72func (m *measureDescriptor) Name() string {
73 return m.name
74}
75
76// Description returns the description of the measure.
77func (m *measureDescriptor) Description() string {
78 return m.description
79}
80
81// Unit returns the unit of the measure.
82func (m *measureDescriptor) Unit() string {
83 return m.unit
84}
85
86var (
87 mu sync.RWMutex
88 measures = make(map[string]*measureDescriptor)
89)
90
91func registerMeasureHandle(name, desc, unit string) *measureDescriptor {
92 mu.Lock()
93 defer mu.Unlock()
94
95 if stored, ok := measures[name]; ok {
96 return stored
97 }
98 m := &measureDescriptor{
99 name: name,
100 description: desc,
101 unit: unit,
102 }
103 measures[name] = m
104 return m
105}
106
107// Measurement is the numeric value measured when recording stats. Each measure
108// provides methods to create measurements of their kind. For example, Int64Measure
109// provides M to convert an int64 into a measurement.
110type Measurement struct {
111 v float64
112 m *measureDescriptor
113}
114
115// Value returns the value of the Measurement as a float64.
116func (m Measurement) Value() float64 {
117 return m.v
118}
119
120// Measure returns the Measure from which this Measurement was created.
121func (m Measurement) Measure() Measure {
122 return m.m
123}
diff --git a/vendor/go.opencensus.io/stats/measure_float64.go b/vendor/go.opencensus.io/stats/measure_float64.go
new file mode 100644
index 0000000..acedb21
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/measure_float64.go
@@ -0,0 +1,36 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package stats
17
18// Float64Measure is a measure for float64 values.
19type Float64Measure struct {
20 *measureDescriptor
21}
22
23// M creates a new float64 measurement.
24// Use Record to record measurements.
25func (m *Float64Measure) M(v float64) Measurement {
26 return Measurement{m: m.measureDescriptor, v: v}
27}
28
29// Float64 creates a new measure for float64 values.
30//
31// See the documentation for interface Measure for more guidance on the
32// parameters of this function.
33func Float64(name, description, unit string) *Float64Measure {
34 mi := registerMeasureHandle(name, description, unit)
35 return &Float64Measure{mi}
36}
diff --git a/vendor/go.opencensus.io/stats/measure_int64.go b/vendor/go.opencensus.io/stats/measure_int64.go
new file mode 100644
index 0000000..c4243ba
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/measure_int64.go
@@ -0,0 +1,36 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package stats
17
18// Int64Measure is a measure for int64 values.
19type Int64Measure struct {
20 *measureDescriptor
21}
22
23// M creates a new int64 measurement.
24// Use Record to record measurements.
25func (m *Int64Measure) M(v int64) Measurement {
26 return Measurement{m: m.measureDescriptor, v: float64(v)}
27}
28
29// Int64 creates a new measure for int64 values.
30//
31// See the documentation for interface Measure for more guidance on the
32// parameters of this function.
33func Int64(name, description, unit string) *Int64Measure {
34 mi := registerMeasureHandle(name, description, unit)
35 return &Int64Measure{mi}
36}
diff --git a/vendor/go.opencensus.io/stats/record.go b/vendor/go.opencensus.io/stats/record.go
new file mode 100644
index 0000000..0aced02
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/record.go
@@ -0,0 +1,69 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package stats
17
18import (
19 "context"
20
21 "go.opencensus.io/exemplar"
22 "go.opencensus.io/stats/internal"
23 "go.opencensus.io/tag"
24)
25
26func init() {
27 internal.SubscriptionReporter = func(measure string) {
28 mu.Lock()
29 measures[measure].subscribe()
30 mu.Unlock()
31 }
32}
33
34// Record records one or multiple measurements with the same context at once.
35// If there are any tags in the context, measurements will be tagged with them.
36func Record(ctx context.Context, ms ...Measurement) {
37 recorder := internal.DefaultRecorder
38 if recorder == nil {
39 return
40 }
41 if len(ms) == 0 {
42 return
43 }
44 record := false
45 for _, m := range ms {
46 if m.m.subscribed() {
47 record = true
48 break
49 }
50 }
51 if !record {
52 return
53 }
54 recorder(tag.FromContext(ctx), ms, exemplar.AttachmentsFromContext(ctx))
55}
56
57// RecordWithTags records one or multiple measurements at once.
58//
59// Measurements will be tagged with the tags in the context mutated by the mutators.
60// RecordWithTags is useful if you want to record with tag mutations but don't want
61// to propagate the mutations in the context.
62func RecordWithTags(ctx context.Context, mutators []tag.Mutator, ms ...Measurement) error {
63 ctx, err := tag.New(ctx, mutators...)
64 if err != nil {
65 return err
66 }
67 Record(ctx, ms...)
68 return nil
69}
diff --git a/vendor/go.opencensus.io/stats/units.go b/vendor/go.opencensus.io/stats/units.go
new file mode 100644
index 0000000..6931a5f
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/units.go
@@ -0,0 +1,25 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package stats
17
18// Units are encoded according to the case-sensitive abbreviations from the
19// Unified Code for Units of Measure: http://unitsofmeasure.org/ucum.html
20const (
21 UnitNone = "1" // Deprecated: Use UnitDimensionless.
22 UnitDimensionless = "1"
23 UnitBytes = "By"
24 UnitMilliseconds = "ms"
25)
diff --git a/vendor/go.opencensus.io/stats/view/aggregation.go b/vendor/go.opencensus.io/stats/view/aggregation.go
new file mode 100644
index 0000000..b7f169b
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/view/aggregation.go
@@ -0,0 +1,120 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package view
17
18// AggType represents the type of aggregation function used on a View.
19type AggType int
20
21// All available aggregation types.
22const (
23 AggTypeNone AggType = iota // no aggregation; reserved for future use.
24 AggTypeCount // the count aggregation, see Count.
25 AggTypeSum // the sum aggregation, see Sum.
26 AggTypeDistribution // the distribution aggregation, see Distribution.
27 AggTypeLastValue // the last value aggregation, see LastValue.
28)
29
30func (t AggType) String() string {
31 return aggTypeName[t]
32}
33
34var aggTypeName = map[AggType]string{
35 AggTypeNone: "None",
36 AggTypeCount: "Count",
37 AggTypeSum: "Sum",
38 AggTypeDistribution: "Distribution",
39 AggTypeLastValue: "LastValue",
40}
41
42// Aggregation represents a data aggregation method. Use one of the functions:
43// Count, Sum, or Distribution to construct an Aggregation.
44type Aggregation struct {
45 Type AggType // Type is the AggType of this Aggregation.
46 Buckets []float64 // Buckets are the bucket endpoints if this Aggregation represents a distribution, see Distribution.
47
48 newData func() AggregationData
49}
50
51var (
52 aggCount = &Aggregation{
53 Type: AggTypeCount,
54 newData: func() AggregationData {
55 return &CountData{}
56 },
57 }
58 aggSum = &Aggregation{
59 Type: AggTypeSum,
60 newData: func() AggregationData {
61 return &SumData{}
62 },
63 }
64)
65
66// Count indicates that data collected and aggregated
67// with this method will be turned into a count value.
68// For example, total number of accepted requests can be
69// aggregated by using Count.
70func Count() *Aggregation {
71 return aggCount
72}
73
74// Sum indicates that data collected and aggregated
75// with this method will be summed up.
76// For example, accumulated request bytes can be aggregated by using
77// Sum.
78func Sum() *Aggregation {
79 return aggSum
80}
81
82// Distribution indicates that the desired aggregation is
83// a histogram distribution.
84//
85// An distribution aggregation may contain a histogram of the values in the
86// population. The bucket boundaries for that histogram are described
87// by the bounds. This defines len(bounds)+1 buckets.
88//
89// If len(bounds) >= 2 then the boundaries for bucket index i are:
90//
91// [-infinity, bounds[i]) for i = 0
92// [bounds[i-1], bounds[i]) for 0 < i < length
93// [bounds[i-1], +infinity) for i = length
94//
95// If len(bounds) is 0 then there is no histogram associated with the
96// distribution. There will be a single bucket with boundaries
97// (-infinity, +infinity).
98//
99// If len(bounds) is 1 then there is no finite buckets, and that single
100// element is the common boundary of the overflow and underflow buckets.
101func Distribution(bounds ...float64) *Aggregation {
102 return &Aggregation{
103 Type: AggTypeDistribution,
104 Buckets: bounds,
105 newData: func() AggregationData {
106 return newDistributionData(bounds)
107 },
108 }
109}
110
111// LastValue only reports the last value recorded using this
112// aggregation. All other measurements will be dropped.
113func LastValue() *Aggregation {
114 return &Aggregation{
115 Type: AggTypeLastValue,
116 newData: func() AggregationData {
117 return &LastValueData{}
118 },
119 }
120}
diff --git a/vendor/go.opencensus.io/stats/view/aggregation_data.go b/vendor/go.opencensus.io/stats/view/aggregation_data.go
new file mode 100644
index 0000000..960b946
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/view/aggregation_data.go
@@ -0,0 +1,235 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package view
17
18import (
19 "math"
20
21 "go.opencensus.io/exemplar"
22)
23
24// AggregationData represents an aggregated value from a collection.
25// They are reported on the view data during exporting.
26// Mosts users won't directly access aggregration data.
27type AggregationData interface {
28 isAggregationData() bool
29 addSample(e *exemplar.Exemplar)
30 clone() AggregationData
31 equal(other AggregationData) bool
32}
33
34const epsilon = 1e-9
35
36// CountData is the aggregated data for the Count aggregation.
37// A count aggregation processes data and counts the recordings.
38//
39// Most users won't directly access count data.
40type CountData struct {
41 Value int64
42}
43
44func (a *CountData) isAggregationData() bool { return true }
45
46func (a *CountData) addSample(_ *exemplar.Exemplar) {
47 a.Value = a.Value + 1
48}
49
50func (a *CountData) clone() AggregationData {
51 return &CountData{Value: a.Value}
52}
53
54func (a *CountData) equal(other AggregationData) bool {
55 a2, ok := other.(*CountData)
56 if !ok {
57 return false
58 }
59
60 return a.Value == a2.Value
61}
62
63// SumData is the aggregated data for the Sum aggregation.
64// A sum aggregation processes data and sums up the recordings.
65//
66// Most users won't directly access sum data.
67type SumData struct {
68 Value float64
69}
70
71func (a *SumData) isAggregationData() bool { return true }
72
73func (a *SumData) addSample(e *exemplar.Exemplar) {
74 a.Value += e.Value
75}
76
77func (a *SumData) clone() AggregationData {
78 return &SumData{Value: a.Value}
79}
80
81func (a *SumData) equal(other AggregationData) bool {
82 a2, ok := other.(*SumData)
83 if !ok {
84 return false
85 }
86 return math.Pow(a.Value-a2.Value, 2) < epsilon
87}
88
89// DistributionData is the aggregated data for the
90// Distribution aggregation.
91//
92// Most users won't directly access distribution data.
93//
94// For a distribution with N bounds, the associated DistributionData will have
95// N+1 buckets.
96type DistributionData struct {
97 Count int64 // number of data points aggregated
98 Min float64 // minimum value in the distribution
99 Max float64 // max value in the distribution
100 Mean float64 // mean of the distribution
101 SumOfSquaredDev float64 // sum of the squared deviation from the mean
102 CountPerBucket []int64 // number of occurrences per bucket
103 // ExemplarsPerBucket is slice the same length as CountPerBucket containing
104 // an exemplar for the associated bucket, or nil.
105 ExemplarsPerBucket []*exemplar.Exemplar
106 bounds []float64 // histogram distribution of the values
107}
108
109func newDistributionData(bounds []float64) *DistributionData {
110 bucketCount := len(bounds) + 1
111 return &DistributionData{
112 CountPerBucket: make([]int64, bucketCount),
113 ExemplarsPerBucket: make([]*exemplar.Exemplar, bucketCount),
114 bounds: bounds,
115 Min: math.MaxFloat64,
116 Max: math.SmallestNonzeroFloat64,
117 }
118}
119
120// Sum returns the sum of all samples collected.
121func (a *DistributionData) Sum() float64 { return a.Mean * float64(a.Count) }
122
123func (a *DistributionData) variance() float64 {
124 if a.Count <= 1 {
125 return 0
126 }
127 return a.SumOfSquaredDev / float64(a.Count-1)
128}
129
130func (a *DistributionData) isAggregationData() bool { return true }
131
132func (a *DistributionData) addSample(e *exemplar.Exemplar) {
133 f := e.Value
134 if f < a.Min {
135 a.Min = f
136 }
137 if f > a.Max {
138 a.Max = f
139 }
140 a.Count++
141 a.addToBucket(e)
142
143 if a.Count == 1 {
144 a.Mean = f
145 return
146 }
147
148 oldMean := a.Mean
149 a.Mean = a.Mean + (f-a.Mean)/float64(a.Count)
150 a.SumOfSquaredDev = a.SumOfSquaredDev + (f-oldMean)*(f-a.Mean)
151}
152
153func (a *DistributionData) addToBucket(e *exemplar.Exemplar) {
154 var count *int64
155 var ex **exemplar.Exemplar
156 for i, b := range a.bounds {
157 if e.Value < b {
158 count = &a.CountPerBucket[i]
159 ex = &a.ExemplarsPerBucket[i]
160 break
161 }
162 }
163 if count == nil {
164 count = &a.CountPerBucket[len(a.bounds)]
165 ex = &a.ExemplarsPerBucket[len(a.bounds)]
166 }
167 *count++
168 *ex = maybeRetainExemplar(*ex, e)
169}
170
171func maybeRetainExemplar(old, cur *exemplar.Exemplar) *exemplar.Exemplar {
172 if old == nil {
173 return cur
174 }
175
176 // Heuristic to pick the "better" exemplar: first keep the one with a
177 // sampled trace attachment, if neither have a trace attachment, pick the
178 // one with more attachments.
179 _, haveTraceID := cur.Attachments[exemplar.KeyTraceID]
180 if haveTraceID || len(cur.Attachments) >= len(old.Attachments) {
181 return cur
182 }
183 return old
184}
185
186func (a *DistributionData) clone() AggregationData {
187 c := *a
188 c.CountPerBucket = append([]int64(nil), a.CountPerBucket...)
189 c.ExemplarsPerBucket = append([]*exemplar.Exemplar(nil), a.ExemplarsPerBucket...)
190 return &c
191}
192
193func (a *DistributionData) equal(other AggregationData) bool {
194 a2, ok := other.(*DistributionData)
195 if !ok {
196 return false
197 }
198 if a2 == nil {
199 return false
200 }
201 if len(a.CountPerBucket) != len(a2.CountPerBucket) {
202 return false
203 }
204 for i := range a.CountPerBucket {
205 if a.CountPerBucket[i] != a2.CountPerBucket[i] {
206 return false
207 }
208 }
209 return a.Count == a2.Count && a.Min == a2.Min && a.Max == a2.Max && math.Pow(a.Mean-a2.Mean, 2) < epsilon && math.Pow(a.variance()-a2.variance(), 2) < epsilon
210}
211
212// LastValueData returns the last value recorded for LastValue aggregation.
213type LastValueData struct {
214 Value float64
215}
216
217func (l *LastValueData) isAggregationData() bool {
218 return true
219}
220
221func (l *LastValueData) addSample(e *exemplar.Exemplar) {
222 l.Value = e.Value
223}
224
225func (l *LastValueData) clone() AggregationData {
226 return &LastValueData{l.Value}
227}
228
229func (l *LastValueData) equal(other AggregationData) bool {
230 a2, ok := other.(*LastValueData)
231 if !ok {
232 return false
233 }
234 return l.Value == a2.Value
235}
diff --git a/vendor/go.opencensus.io/stats/view/collector.go b/vendor/go.opencensus.io/stats/view/collector.go
new file mode 100644
index 0000000..32415d4
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/view/collector.go
@@ -0,0 +1,87 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package view
17
18import (
19 "sort"
20
21 "go.opencensus.io/exemplar"
22
23 "go.opencensus.io/internal/tagencoding"
24 "go.opencensus.io/tag"
25)
26
27type collector struct {
28 // signatures holds the aggregations values for each unique tag signature
29 // (values for all keys) to its aggregator.
30 signatures map[string]AggregationData
31 // Aggregation is the description of the aggregation to perform for this
32 // view.
33 a *Aggregation
34}
35
36func (c *collector) addSample(s string, e *exemplar.Exemplar) {
37 aggregator, ok := c.signatures[s]
38 if !ok {
39 aggregator = c.a.newData()
40 c.signatures[s] = aggregator
41 }
42 aggregator.addSample(e)
43}
44
45// collectRows returns a snapshot of the collected Row values.
46func (c *collector) collectedRows(keys []tag.Key) []*Row {
47 rows := make([]*Row, 0, len(c.signatures))
48 for sig, aggregator := range c.signatures {
49 tags := decodeTags([]byte(sig), keys)
50 row := &Row{Tags: tags, Data: aggregator.clone()}
51 rows = append(rows, row)
52 }
53 return rows
54}
55
56func (c *collector) clearRows() {
57 c.signatures = make(map[string]AggregationData)
58}
59
60// encodeWithKeys encodes the map by using values
61// only associated with the keys provided.
62func encodeWithKeys(m *tag.Map, keys []tag.Key) []byte {
63 vb := &tagencoding.Values{
64 Buffer: make([]byte, len(keys)),
65 }
66 for _, k := range keys {
67 v, _ := m.Value(k)
68 vb.WriteValue([]byte(v))
69 }
70 return vb.Bytes()
71}
72
73// decodeTags decodes tags from the buffer and
74// orders them by the keys.
75func decodeTags(buf []byte, keys []tag.Key) []tag.Tag {
76 vb := &tagencoding.Values{Buffer: buf}
77 var tags []tag.Tag
78 for _, k := range keys {
79 v := vb.ReadValue()
80 if v != nil {
81 tags = append(tags, tag.Tag{Key: k, Value: string(v)})
82 }
83 }
84 vb.ReadIndex = 0
85 sort.Slice(tags, func(i, j int) bool { return tags[i].Key.Name() < tags[j].Key.Name() })
86 return tags
87}
diff --git a/vendor/go.opencensus.io/stats/view/doc.go b/vendor/go.opencensus.io/stats/view/doc.go
new file mode 100644
index 0000000..dced225
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/view/doc.go
@@ -0,0 +1,47 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16// Package view contains support for collecting and exposing aggregates over stats.
17//
18// In order to collect measurements, views need to be defined and registered.
19// A view allows recorded measurements to be filtered and aggregated.
20//
21// All recorded measurements can be grouped by a list of tags.
22//
23// OpenCensus provides several aggregation methods: Count, Distribution and Sum.
24//
25// Count only counts the number of measurement points recorded.
26// Distribution provides statistical summary of the aggregated data by counting
27// how many recorded measurements fall into each bucket.
28// Sum adds up the measurement values.
29// LastValue just keeps track of the most recently recorded measurement value.
30// All aggregations are cumulative.
31//
32// Views can be registerd and unregistered at any time during program execution.
33//
34// Libraries can define views but it is recommended that in most cases registering
35// views be left up to applications.
36//
37// Exporting
38//
39// Collected and aggregated data can be exported to a metric collection
40// backend by registering its exporter.
41//
42// Multiple exporters can be registered to upload the data to various
43// different back ends.
44package view // import "go.opencensus.io/stats/view"
45
46// TODO(acetechnologist): Add a link to the language independent OpenCensus
47// spec when it is available.
diff --git a/vendor/go.opencensus.io/stats/view/export.go b/vendor/go.opencensus.io/stats/view/export.go
new file mode 100644
index 0000000..7cb5971
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/view/export.go
@@ -0,0 +1,58 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package view
16
17import "sync"
18
19var (
20 exportersMu sync.RWMutex // guards exporters
21 exporters = make(map[Exporter]struct{})
22)
23
24// Exporter exports the collected records as view data.
25//
26// The ExportView method should return quickly; if an
27// Exporter takes a significant amount of time to
28// process a Data, that work should be done on another goroutine.
29//
30// It is safe to assume that ExportView will not be called concurrently from
31// multiple goroutines.
32//
33// The Data should not be modified.
34type Exporter interface {
35 ExportView(viewData *Data)
36}
37
38// RegisterExporter registers an exporter.
39// Collected data will be reported via all the
40// registered exporters. Once you no longer
41// want data to be exported, invoke UnregisterExporter
42// with the previously registered exporter.
43//
44// Binaries can register exporters, libraries shouldn't register exporters.
45func RegisterExporter(e Exporter) {
46 exportersMu.Lock()
47 defer exportersMu.Unlock()
48
49 exporters[e] = struct{}{}
50}
51
52// UnregisterExporter unregisters an exporter.
53func UnregisterExporter(e Exporter) {
54 exportersMu.Lock()
55 defer exportersMu.Unlock()
56
57 delete(exporters, e)
58}
diff --git a/vendor/go.opencensus.io/stats/view/view.go b/vendor/go.opencensus.io/stats/view/view.go
new file mode 100644
index 0000000..c2a08af
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/view/view.go
@@ -0,0 +1,185 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package view
17
18import (
19 "bytes"
20 "fmt"
21 "reflect"
22 "sort"
23 "sync/atomic"
24 "time"
25
26 "go.opencensus.io/exemplar"
27
28 "go.opencensus.io/stats"
29 "go.opencensus.io/stats/internal"
30 "go.opencensus.io/tag"
31)
32
33// View allows users to aggregate the recorded stats.Measurements.
34// Views need to be passed to the Register function to be before data will be
35// collected and sent to Exporters.
36type View struct {
37 Name string // Name of View. Must be unique. If unset, will default to the name of the Measure.
38 Description string // Description is a human-readable description for this view.
39
40 // TagKeys are the tag keys describing the grouping of this view.
41 // A single Row will be produced for each combination of associated tag values.
42 TagKeys []tag.Key
43
44 // Measure is a stats.Measure to aggregate in this view.
45 Measure stats.Measure
46
47 // Aggregation is the aggregation function tp apply to the set of Measurements.
48 Aggregation *Aggregation
49}
50
51// WithName returns a copy of the View with a new name. This is useful for
52// renaming views to cope with limitations placed on metric names by various
53// backends.
54func (v *View) WithName(name string) *View {
55 vNew := *v
56 vNew.Name = name
57 return &vNew
58}
59
60// same compares two views and returns true if they represent the same aggregation.
61func (v *View) same(other *View) bool {
62 if v == other {
63 return true
64 }
65 if v == nil {
66 return false
67 }
68 return reflect.DeepEqual(v.Aggregation, other.Aggregation) &&
69 v.Measure.Name() == other.Measure.Name()
70}
71
72// canonicalize canonicalizes v by setting explicit
73// defaults for Name and Description and sorting the TagKeys
74func (v *View) canonicalize() error {
75 if v.Measure == nil {
76 return fmt.Errorf("cannot register view %q: measure not set", v.Name)
77 }
78 if v.Aggregation == nil {
79 return fmt.Errorf("cannot register view %q: aggregation not set", v.Name)
80 }
81 if v.Name == "" {
82 v.Name = v.Measure.Name()
83 }
84 if v.Description == "" {
85 v.Description = v.Measure.Description()
86 }
87 if err := checkViewName(v.Name); err != nil {
88 return err
89 }
90 sort.Slice(v.TagKeys, func(i, j int) bool {
91 return v.TagKeys[i].Name() < v.TagKeys[j].Name()
92 })
93 return nil
94}
95
96// viewInternal is the internal representation of a View.
97type viewInternal struct {
98 view *View // view is the canonicalized View definition associated with this view.
99 subscribed uint32 // 1 if someone is subscribed and data need to be exported, use atomic to access
100 collector *collector
101}
102
103func newViewInternal(v *View) (*viewInternal, error) {
104 return &viewInternal{
105 view: v,
106 collector: &collector{make(map[string]AggregationData), v.Aggregation},
107 }, nil
108}
109
110func (v *viewInternal) subscribe() {
111 atomic.StoreUint32(&v.subscribed, 1)
112}
113
114func (v *viewInternal) unsubscribe() {
115 atomic.StoreUint32(&v.subscribed, 0)
116}
117
118// isSubscribed returns true if the view is exporting
119// data by subscription.
120func (v *viewInternal) isSubscribed() bool {
121 return atomic.LoadUint32(&v.subscribed) == 1
122}
123
124func (v *viewInternal) clearRows() {
125 v.collector.clearRows()
126}
127
128func (v *viewInternal) collectedRows() []*Row {
129 return v.collector.collectedRows(v.view.TagKeys)
130}
131
132func (v *viewInternal) addSample(m *tag.Map, e *exemplar.Exemplar) {
133 if !v.isSubscribed() {
134 return
135 }
136 sig := string(encodeWithKeys(m, v.view.TagKeys))
137 v.collector.addSample(sig, e)
138}
139
140// A Data is a set of rows about usage of the single measure associated
141// with the given view. Each row is specific to a unique set of tags.
142type Data struct {
143 View *View
144 Start, End time.Time
145 Rows []*Row
146}
147
148// Row is the collected value for a specific set of key value pairs a.k.a tags.
149type Row struct {
150 Tags []tag.Tag
151 Data AggregationData
152}
153
154func (r *Row) String() string {
155 var buffer bytes.Buffer
156 buffer.WriteString("{ ")
157 buffer.WriteString("{ ")
158 for _, t := range r.Tags {
159 buffer.WriteString(fmt.Sprintf("{%v %v}", t.Key.Name(), t.Value))
160 }
161 buffer.WriteString(" }")
162 buffer.WriteString(fmt.Sprintf("%v", r.Data))
163 buffer.WriteString(" }")
164 return buffer.String()
165}
166
167// Equal returns true if both rows are equal. Tags are expected to be ordered
168// by the key name. Even both rows have the same tags but the tags appear in
169// different orders it will return false.
170func (r *Row) Equal(other *Row) bool {
171 if r == other {
172 return true
173 }
174 return reflect.DeepEqual(r.Tags, other.Tags) && r.Data.equal(other.Data)
175}
176
177func checkViewName(name string) error {
178 if len(name) > internal.MaxNameLength {
179 return fmt.Errorf("view name cannot be larger than %v", internal.MaxNameLength)
180 }
181 if !internal.IsPrintable(name) {
182 return fmt.Errorf("view name needs to be an ASCII string")
183 }
184 return nil
185}
diff --git a/vendor/go.opencensus.io/stats/view/worker.go b/vendor/go.opencensus.io/stats/view/worker.go
new file mode 100644
index 0000000..63b0ee3
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/view/worker.go
@@ -0,0 +1,229 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package view
17
18import (
19 "fmt"
20 "time"
21
22 "go.opencensus.io/stats"
23 "go.opencensus.io/stats/internal"
24 "go.opencensus.io/tag"
25)
26
27func init() {
28 defaultWorker = newWorker()
29 go defaultWorker.start()
30 internal.DefaultRecorder = record
31}
32
33type measureRef struct {
34 measure string
35 views map[*viewInternal]struct{}
36}
37
38type worker struct {
39 measures map[string]*measureRef
40 views map[string]*viewInternal
41 startTimes map[*viewInternal]time.Time
42
43 timer *time.Ticker
44 c chan command
45 quit, done chan bool
46}
47
48var defaultWorker *worker
49
50var defaultReportingDuration = 10 * time.Second
51
52// Find returns a registered view associated with this name.
53// If no registered view is found, nil is returned.
54func Find(name string) (v *View) {
55 req := &getViewByNameReq{
56 name: name,
57 c: make(chan *getViewByNameResp),
58 }
59 defaultWorker.c <- req
60 resp := <-req.c
61 return resp.v
62}
63
64// Register begins collecting data for the given views.
65// Once a view is registered, it reports data to the registered exporters.
66func Register(views ...*View) error {
67 for _, v := range views {
68 if err := v.canonicalize(); err != nil {
69 return err
70 }
71 }
72 req := &registerViewReq{
73 views: views,
74 err: make(chan error),
75 }
76 defaultWorker.c <- req
77 return <-req.err
78}
79
80// Unregister the given views. Data will not longer be exported for these views
81// after Unregister returns.
82// It is not necessary to unregister from views you expect to collect for the
83// duration of your program execution.
84func Unregister(views ...*View) {
85 names := make([]string, len(views))
86 for i := range views {
87 names[i] = views[i].Name
88 }
89 req := &unregisterFromViewReq{
90 views: names,
91 done: make(chan struct{}),
92 }
93 defaultWorker.c <- req
94 <-req.done
95}
96
97// RetrieveData gets a snapshot of the data collected for the the view registered
98// with the given name. It is intended for testing only.
99func RetrieveData(viewName string) ([]*Row, error) {
100 req := &retrieveDataReq{
101 now: time.Now(),
102 v: viewName,
103 c: make(chan *retrieveDataResp),
104 }
105 defaultWorker.c <- req
106 resp := <-req.c
107 return resp.rows, resp.err
108}
109
110func record(tags *tag.Map, ms interface{}, attachments map[string]string) {
111 req := &recordReq{
112 tm: tags,
113 ms: ms.([]stats.Measurement),
114 attachments: attachments,
115 t: time.Now(),
116 }
117 defaultWorker.c <- req
118}
119
120// SetReportingPeriod sets the interval between reporting aggregated views in
121// the program. If duration is less than or equal to zero, it enables the
122// default behavior.
123//
124// Note: each exporter makes different promises about what the lowest supported
125// duration is. For example, the Stackdriver exporter recommends a value no
126// lower than 1 minute. Consult each exporter per your needs.
127func SetReportingPeriod(d time.Duration) {
128 // TODO(acetechnologist): ensure that the duration d is more than a certain
129 // value. e.g. 1s
130 req := &setReportingPeriodReq{
131 d: d,
132 c: make(chan bool),
133 }
134 defaultWorker.c <- req
135 <-req.c // don't return until the timer is set to the new duration.
136}
137
138func newWorker() *worker {
139 return &worker{
140 measures: make(map[string]*measureRef),
141 views: make(map[string]*viewInternal),
142 startTimes: make(map[*viewInternal]time.Time),
143 timer: time.NewTicker(defaultReportingDuration),
144 c: make(chan command, 1024),
145 quit: make(chan bool),
146 done: make(chan bool),
147 }
148}
149
150func (w *worker) start() {
151 for {
152 select {
153 case cmd := <-w.c:
154 cmd.handleCommand(w)
155 case <-w.timer.C:
156 w.reportUsage(time.Now())
157 case <-w.quit:
158 w.timer.Stop()
159 close(w.c)
160 w.done <- true
161 return
162 }
163 }
164}
165
166func (w *worker) stop() {
167 w.quit <- true
168 <-w.done
169}
170
171func (w *worker) getMeasureRef(name string) *measureRef {
172 if mr, ok := w.measures[name]; ok {
173 return mr
174 }
175 mr := &measureRef{
176 measure: name,
177 views: make(map[*viewInternal]struct{}),
178 }
179 w.measures[name] = mr
180 return mr
181}
182
183func (w *worker) tryRegisterView(v *View) (*viewInternal, error) {
184 vi, err := newViewInternal(v)
185 if err != nil {
186 return nil, err
187 }
188 if x, ok := w.views[vi.view.Name]; ok {
189 if !x.view.same(vi.view) {
190 return nil, fmt.Errorf("cannot register view %q; a different view with the same name is already registered", v.Name)
191 }
192
193 // the view is already registered so there is nothing to do and the
194 // command is considered successful.
195 return x, nil
196 }
197 w.views[vi.view.Name] = vi
198 ref := w.getMeasureRef(vi.view.Measure.Name())
199 ref.views[vi] = struct{}{}
200 return vi, nil
201}
202
203func (w *worker) reportView(v *viewInternal, now time.Time) {
204 if !v.isSubscribed() {
205 return
206 }
207 rows := v.collectedRows()
208 _, ok := w.startTimes[v]
209 if !ok {
210 w.startTimes[v] = now
211 }
212 viewData := &Data{
213 View: v.view,
214 Start: w.startTimes[v],
215 End: time.Now(),
216 Rows: rows,
217 }
218 exportersMu.Lock()
219 for e := range exporters {
220 e.ExportView(viewData)
221 }
222 exportersMu.Unlock()
223}
224
225func (w *worker) reportUsage(now time.Time) {
226 for _, v := range w.views {
227 w.reportView(v, now)
228 }
229}
diff --git a/vendor/go.opencensus.io/stats/view/worker_commands.go b/vendor/go.opencensus.io/stats/view/worker_commands.go
new file mode 100644
index 0000000..b38f26f
--- /dev/null
+++ b/vendor/go.opencensus.io/stats/view/worker_commands.go
@@ -0,0 +1,183 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package view
17
18import (
19 "errors"
20 "fmt"
21 "strings"
22 "time"
23
24 "go.opencensus.io/exemplar"
25
26 "go.opencensus.io/stats"
27 "go.opencensus.io/stats/internal"
28 "go.opencensus.io/tag"
29)
30
31type command interface {
32 handleCommand(w *worker)
33}
34
35// getViewByNameReq is the command to get a view given its name.
36type getViewByNameReq struct {
37 name string
38 c chan *getViewByNameResp
39}
40
41type getViewByNameResp struct {
42 v *View
43}
44
45func (cmd *getViewByNameReq) handleCommand(w *worker) {
46 v := w.views[cmd.name]
47 if v == nil {
48 cmd.c <- &getViewByNameResp{nil}
49 return
50 }
51 cmd.c <- &getViewByNameResp{v.view}
52}
53
54// registerViewReq is the command to register a view.
55type registerViewReq struct {
56 views []*View
57 err chan error
58}
59
60func (cmd *registerViewReq) handleCommand(w *worker) {
61 var errstr []string
62 for _, view := range cmd.views {
63 vi, err := w.tryRegisterView(view)
64 if err != nil {
65 errstr = append(errstr, fmt.Sprintf("%s: %v", view.Name, err))
66 continue
67 }
68 internal.SubscriptionReporter(view.Measure.Name())
69 vi.subscribe()
70 }
71 if len(errstr) > 0 {
72 cmd.err <- errors.New(strings.Join(errstr, "\n"))
73 } else {
74 cmd.err <- nil
75 }
76}
77
78// unregisterFromViewReq is the command to unregister to a view. Has no
79// impact on the data collection for client that are pulling data from the
80// library.
81type unregisterFromViewReq struct {
82 views []string
83 done chan struct{}
84}
85
86func (cmd *unregisterFromViewReq) handleCommand(w *worker) {
87 for _, name := range cmd.views {
88 vi, ok := w.views[name]
89 if !ok {
90 continue
91 }
92
93 // Report pending data for this view before removing it.
94 w.reportView(vi, time.Now())
95
96 vi.unsubscribe()
97 if !vi.isSubscribed() {
98 // this was the last subscription and view is not collecting anymore.
99 // The collected data can be cleared.
100 vi.clearRows()
101 }
102 delete(w.views, name)
103 }
104 cmd.done <- struct{}{}
105}
106
107// retrieveDataReq is the command to retrieve data for a view.
108type retrieveDataReq struct {
109 now time.Time
110 v string
111 c chan *retrieveDataResp
112}
113
114type retrieveDataResp struct {
115 rows []*Row
116 err error
117}
118
119func (cmd *retrieveDataReq) handleCommand(w *worker) {
120 vi, ok := w.views[cmd.v]
121 if !ok {
122 cmd.c <- &retrieveDataResp{
123 nil,
124 fmt.Errorf("cannot retrieve data; view %q is not registered", cmd.v),
125 }
126 return
127 }
128
129 if !vi.isSubscribed() {
130 cmd.c <- &retrieveDataResp{
131 nil,
132 fmt.Errorf("cannot retrieve data; view %q has no subscriptions or collection is not forcibly started", cmd.v),
133 }
134 return
135 }
136 cmd.c <- &retrieveDataResp{
137 vi.collectedRows(),
138 nil,
139 }
140}
141
142// recordReq is the command to record data related to multiple measures
143// at once.
144type recordReq struct {
145 tm *tag.Map
146 ms []stats.Measurement
147 attachments map[string]string
148 t time.Time
149}
150
151func (cmd *recordReq) handleCommand(w *worker) {
152 for _, m := range cmd.ms {
153 if (m == stats.Measurement{}) { // not registered
154 continue
155 }
156 ref := w.getMeasureRef(m.Measure().Name())
157 for v := range ref.views {
158 e := &exemplar.Exemplar{
159 Value: m.Value(),
160 Timestamp: cmd.t,
161 Attachments: cmd.attachments,
162 }
163 v.addSample(cmd.tm, e)
164 }
165 }
166}
167
168// setReportingPeriodReq is the command to modify the duration between
169// reporting the collected data to the registered clients.
170type setReportingPeriodReq struct {
171 d time.Duration
172 c chan bool
173}
174
175func (cmd *setReportingPeriodReq) handleCommand(w *worker) {
176 w.timer.Stop()
177 if cmd.d <= 0 {
178 w.timer = time.NewTicker(defaultReportingDuration)
179 } else {
180 w.timer = time.NewTicker(cmd.d)
181 }
182 cmd.c <- true
183}
diff --git a/vendor/go.opencensus.io/tag/context.go b/vendor/go.opencensus.io/tag/context.go
new file mode 100644
index 0000000..dcc13f4
--- /dev/null
+++ b/vendor/go.opencensus.io/tag/context.go
@@ -0,0 +1,67 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package tag
17
18import (
19 "context"
20
21 "go.opencensus.io/exemplar"
22)
23
24// FromContext returns the tag map stored in the context.
25func FromContext(ctx context.Context) *Map {
26 // The returned tag map shouldn't be mutated.
27 ts := ctx.Value(mapCtxKey)
28 if ts == nil {
29 return nil
30 }
31 return ts.(*Map)
32}
33
34// NewContext creates a new context with the given tag map.
35// To propagate a tag map to downstream methods and downstream RPCs, add a tag map
36// to the current context. NewContext will return a copy of the current context,
37// and put the tag map into the returned one.
38// If there is already a tag map in the current context, it will be replaced with m.
39func NewContext(ctx context.Context, m *Map) context.Context {
40 return context.WithValue(ctx, mapCtxKey, m)
41}
42
43type ctxKey struct{}
44
45var mapCtxKey = ctxKey{}
46
47func init() {
48 exemplar.RegisterAttachmentExtractor(extractTagsAttachments)
49}
50
51func extractTagsAttachments(ctx context.Context, a exemplar.Attachments) exemplar.Attachments {
52 m := FromContext(ctx)
53 if m == nil {
54 return a
55 }
56 if len(m.m) == 0 {
57 return a
58 }
59 if a == nil {
60 a = make(map[string]string)
61 }
62
63 for k, v := range m.m {
64 a[exemplar.KeyPrefixTag+k.Name()] = v
65 }
66 return a
67}
diff --git a/vendor/go.opencensus.io/tag/doc.go b/vendor/go.opencensus.io/tag/doc.go
new file mode 100644
index 0000000..da16b74
--- /dev/null
+++ b/vendor/go.opencensus.io/tag/doc.go
@@ -0,0 +1,26 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16/*
17Package tag contains OpenCensus tags.
18
19Tags are key-value pairs. Tags provide additional cardinality to
20the OpenCensus instrumentation data.
21
22Tags can be propagated on the wire and in the same
23process via context.Context. Encode and Decode should be
24used to represent tags into their binary propagation form.
25*/
26package tag // import "go.opencensus.io/tag"
diff --git a/vendor/go.opencensus.io/tag/key.go b/vendor/go.opencensus.io/tag/key.go
new file mode 100644
index 0000000..ebbed95
--- /dev/null
+++ b/vendor/go.opencensus.io/tag/key.go
@@ -0,0 +1,35 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package tag
17
18// Key represents a tag key.
19type Key struct {
20 name string
21}
22
23// NewKey creates or retrieves a string key identified by name.
24// Calling NewKey consequently with the same name returns the same key.
25func NewKey(name string) (Key, error) {
26 if !checkKeyName(name) {
27 return Key{}, errInvalidKeyName
28 }
29 return Key{name: name}, nil
30}
31
32// Name returns the name of the key.
33func (k Key) Name() string {
34 return k.name
35}
diff --git a/vendor/go.opencensus.io/tag/map.go b/vendor/go.opencensus.io/tag/map.go
new file mode 100644
index 0000000..5b72ba6
--- /dev/null
+++ b/vendor/go.opencensus.io/tag/map.go
@@ -0,0 +1,197 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package tag
17
18import (
19 "bytes"
20 "context"
21 "fmt"
22 "sort"
23)
24
25// Tag is a key value pair that can be propagated on wire.
26type Tag struct {
27 Key Key
28 Value string
29}
30
31// Map is a map of tags. Use New to create a context containing
32// a new Map.
33type Map struct {
34 m map[Key]string
35}
36
37// Value returns the value for the key if a value for the key exists.
38func (m *Map) Value(k Key) (string, bool) {
39 if m == nil {
40 return "", false
41 }
42 v, ok := m.m[k]
43 return v, ok
44}
45
46func (m *Map) String() string {
47 if m == nil {
48 return "nil"
49 }
50 keys := make([]Key, 0, len(m.m))
51 for k := range m.m {
52 keys = append(keys, k)
53 }
54 sort.Slice(keys, func(i, j int) bool { return keys[i].Name() < keys[j].Name() })
55
56 var buffer bytes.Buffer
57 buffer.WriteString("{ ")
58 for _, k := range keys {
59 buffer.WriteString(fmt.Sprintf("{%v %v}", k.name, m.m[k]))
60 }
61 buffer.WriteString(" }")
62 return buffer.String()
63}
64
65func (m *Map) insert(k Key, v string) {
66 if _, ok := m.m[k]; ok {
67 return
68 }
69 m.m[k] = v
70}
71
72func (m *Map) update(k Key, v string) {
73 if _, ok := m.m[k]; ok {
74 m.m[k] = v
75 }
76}
77
78func (m *Map) upsert(k Key, v string) {
79 m.m[k] = v
80}
81
82func (m *Map) delete(k Key) {
83 delete(m.m, k)
84}
85
86func newMap() *Map {
87 return &Map{m: make(map[Key]string)}
88}
89
90// Mutator modifies a tag map.
91type Mutator interface {
92 Mutate(t *Map) (*Map, error)
93}
94
95// Insert returns a mutator that inserts a
96// value associated with k. If k already exists in the tag map,
97// mutator doesn't update the value.
98func Insert(k Key, v string) Mutator {
99 return &mutator{
100 fn: func(m *Map) (*Map, error) {
101 if !checkValue(v) {
102 return nil, errInvalidValue
103 }
104 m.insert(k, v)
105 return m, nil
106 },
107 }
108}
109
110// Update returns a mutator that updates the
111// value of the tag associated with k with v. If k doesn't
112// exists in the tag map, the mutator doesn't insert the value.
113func Update(k Key, v string) Mutator {
114 return &mutator{
115 fn: func(m *Map) (*Map, error) {
116 if !checkValue(v) {
117 return nil, errInvalidValue
118 }
119 m.update(k, v)
120 return m, nil
121 },
122 }
123}
124
125// Upsert returns a mutator that upserts the
126// value of the tag associated with k with v. It inserts the
127// value if k doesn't exist already. It mutates the value
128// if k already exists.
129func Upsert(k Key, v string) Mutator {
130 return &mutator{
131 fn: func(m *Map) (*Map, error) {
132 if !checkValue(v) {
133 return nil, errInvalidValue
134 }
135 m.upsert(k, v)
136 return m, nil
137 },
138 }
139}
140
141// Delete returns a mutator that deletes
142// the value associated with k.
143func Delete(k Key) Mutator {
144 return &mutator{
145 fn: func(m *Map) (*Map, error) {
146 m.delete(k)
147 return m, nil
148 },
149 }
150}
151
152// New returns a new context that contains a tag map
153// originated from the incoming context and modified
154// with the provided mutators.
155func New(ctx context.Context, mutator ...Mutator) (context.Context, error) {
156 m := newMap()
157 orig := FromContext(ctx)
158 if orig != nil {
159 for k, v := range orig.m {
160 if !checkKeyName(k.Name()) {
161 return ctx, fmt.Errorf("key:%q: %v", k, errInvalidKeyName)
162 }
163 if !checkValue(v) {
164 return ctx, fmt.Errorf("key:%q value:%q: %v", k.Name(), v, errInvalidValue)
165 }
166 m.insert(k, v)
167 }
168 }
169 var err error
170 for _, mod := range mutator {
171 m, err = mod.Mutate(m)
172 if err != nil {
173 return ctx, err
174 }
175 }
176 return NewContext(ctx, m), nil
177}
178
179// Do is similar to pprof.Do: a convenience for installing the tags
180// from the context as Go profiler labels. This allows you to
181// correlated runtime profiling with stats.
182//
183// It converts the key/values from the given map to Go profiler labels
184// and calls pprof.Do.
185//
186// Do is going to do nothing if your Go version is below 1.9.
187func Do(ctx context.Context, f func(ctx context.Context)) {
188 do(ctx, f)
189}
190
191type mutator struct {
192 fn func(t *Map) (*Map, error)
193}
194
195func (m *mutator) Mutate(t *Map) (*Map, error) {
196 return m.fn(t)
197}
diff --git a/vendor/go.opencensus.io/tag/map_codec.go b/vendor/go.opencensus.io/tag/map_codec.go
new file mode 100644
index 0000000..3e99895
--- /dev/null
+++ b/vendor/go.opencensus.io/tag/map_codec.go
@@ -0,0 +1,234 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16package tag
17
18import (
19 "encoding/binary"
20 "fmt"
21)
22
23// KeyType defines the types of keys allowed. Currently only keyTypeString is
24// supported.
25type keyType byte
26
27const (
28 keyTypeString keyType = iota
29 keyTypeInt64
30 keyTypeTrue
31 keyTypeFalse
32
33 tagsVersionID = byte(0)
34)
35
36type encoderGRPC struct {
37 buf []byte
38 writeIdx, readIdx int
39}
40
41// writeKeyString writes the fieldID '0' followed by the key string and value
42// string.
43func (eg *encoderGRPC) writeTagString(k, v string) {
44 eg.writeByte(byte(keyTypeString))
45 eg.writeStringWithVarintLen(k)
46 eg.writeStringWithVarintLen(v)
47}
48
49func (eg *encoderGRPC) writeTagUint64(k string, i uint64) {
50 eg.writeByte(byte(keyTypeInt64))
51 eg.writeStringWithVarintLen(k)
52 eg.writeUint64(i)
53}
54
55func (eg *encoderGRPC) writeTagTrue(k string) {
56 eg.writeByte(byte(keyTypeTrue))
57 eg.writeStringWithVarintLen(k)
58}
59
60func (eg *encoderGRPC) writeTagFalse(k string) {
61 eg.writeByte(byte(keyTypeFalse))
62 eg.writeStringWithVarintLen(k)
63}
64
65func (eg *encoderGRPC) writeBytesWithVarintLen(bytes []byte) {
66 length := len(bytes)
67
68 eg.growIfRequired(binary.MaxVarintLen64 + length)
69 eg.writeIdx += binary.PutUvarint(eg.buf[eg.writeIdx:], uint64(length))
70 copy(eg.buf[eg.writeIdx:], bytes)
71 eg.writeIdx += length
72}
73
74func (eg *encoderGRPC) writeStringWithVarintLen(s string) {
75 length := len(s)
76
77 eg.growIfRequired(binary.MaxVarintLen64 + length)
78 eg.writeIdx += binary.PutUvarint(eg.buf[eg.writeIdx:], uint64(length))
79 copy(eg.buf[eg.writeIdx:], s)
80 eg.writeIdx += length
81}
82
83func (eg *encoderGRPC) writeByte(v byte) {
84 eg.growIfRequired(1)
85 eg.buf[eg.writeIdx] = v
86 eg.writeIdx++
87}
88
89func (eg *encoderGRPC) writeUint32(i uint32) {
90 eg.growIfRequired(4)
91 binary.LittleEndian.PutUint32(eg.buf[eg.writeIdx:], i)
92 eg.writeIdx += 4
93}
94
95func (eg *encoderGRPC) writeUint64(i uint64) {
96 eg.growIfRequired(8)
97 binary.LittleEndian.PutUint64(eg.buf[eg.writeIdx:], i)
98 eg.writeIdx += 8
99}
100
101func (eg *encoderGRPC) readByte() byte {
102 b := eg.buf[eg.readIdx]
103 eg.readIdx++
104 return b
105}
106
107func (eg *encoderGRPC) readUint32() uint32 {
108 i := binary.LittleEndian.Uint32(eg.buf[eg.readIdx:])
109 eg.readIdx += 4
110 return i
111}
112
113func (eg *encoderGRPC) readUint64() uint64 {
114 i := binary.LittleEndian.Uint64(eg.buf[eg.readIdx:])
115 eg.readIdx += 8
116 return i
117}
118
119func (eg *encoderGRPC) readBytesWithVarintLen() ([]byte, error) {
120 if eg.readEnded() {
121 return nil, fmt.Errorf("unexpected end while readBytesWithVarintLen '%x' starting at idx '%v'", eg.buf, eg.readIdx)
122 }
123 length, valueStart := binary.Uvarint(eg.buf[eg.readIdx:])
124 if valueStart <= 0 {
125 return nil, fmt.Errorf("unexpected end while readBytesWithVarintLen '%x' starting at idx '%v'", eg.buf, eg.readIdx)
126 }
127
128 valueStart += eg.readIdx
129 valueEnd := valueStart + int(length)
130 if valueEnd > len(eg.buf) {
131 return nil, fmt.Errorf("malformed encoding: length:%v, upper:%v, maxLength:%v", length, valueEnd, len(eg.buf))
132 }
133
134 eg.readIdx = valueEnd
135 return eg.buf[valueStart:valueEnd], nil
136}
137
138func (eg *encoderGRPC) readStringWithVarintLen() (string, error) {
139 bytes, err := eg.readBytesWithVarintLen()
140 if err != nil {
141 return "", err
142 }
143 return string(bytes), nil
144}
145
146func (eg *encoderGRPC) growIfRequired(expected int) {
147 if len(eg.buf)-eg.writeIdx < expected {
148 tmp := make([]byte, 2*(len(eg.buf)+1)+expected)
149 copy(tmp, eg.buf)
150 eg.buf = tmp
151 }
152}
153
154func (eg *encoderGRPC) readEnded() bool {
155 return eg.readIdx >= len(eg.buf)
156}
157
158func (eg *encoderGRPC) bytes() []byte {
159 return eg.buf[:eg.writeIdx]
160}
161
162// Encode encodes the tag map into a []byte. It is useful to propagate
163// the tag maps on wire in binary format.
164func Encode(m *Map) []byte {
165 eg := &encoderGRPC{
166 buf: make([]byte, len(m.m)),
167 }
168 eg.writeByte(byte(tagsVersionID))
169 for k, v := range m.m {
170 eg.writeByte(byte(keyTypeString))
171 eg.writeStringWithVarintLen(k.name)
172 eg.writeBytesWithVarintLen([]byte(v))
173 }
174 return eg.bytes()
175}
176
177// Decode decodes the given []byte into a tag map.
178func Decode(bytes []byte) (*Map, error) {
179 ts := newMap()
180 err := DecodeEach(bytes, ts.upsert)
181 if err != nil {
182 // no partial failures
183 return nil, err
184 }
185 return ts, nil
186}
187
188// DecodeEach decodes the given serialized tag map, calling handler for each
189// tag key and value decoded.
190func DecodeEach(bytes []byte, fn func(key Key, val string)) error {
191 eg := &encoderGRPC{
192 buf: bytes,
193 }
194 if len(eg.buf) == 0 {
195 return nil
196 }
197
198 version := eg.readByte()
199 if version > tagsVersionID {
200 return fmt.Errorf("cannot decode: unsupported version: %q; supports only up to: %q", version, tagsVersionID)
201 }
202
203 for !eg.readEnded() {
204 typ := keyType(eg.readByte())
205
206 if typ != keyTypeString {
207 return fmt.Errorf("cannot decode: invalid key type: %q", typ)
208 }
209
210 k, err := eg.readBytesWithVarintLen()
211 if err != nil {
212 return err
213 }
214
215 v, err := eg.readBytesWithVarintLen()
216 if err != nil {
217 return err
218 }
219
220 key, err := NewKey(string(k))
221 if err != nil {
222 return err
223 }
224 val := string(v)
225 if !checkValue(val) {
226 return errInvalidValue
227 }
228 fn(key, val)
229 if err != nil {
230 return err
231 }
232 }
233 return nil
234}
diff --git a/vendor/go.opencensus.io/tag/profile_19.go b/vendor/go.opencensus.io/tag/profile_19.go
new file mode 100644
index 0000000..f81cd0b
--- /dev/null
+++ b/vendor/go.opencensus.io/tag/profile_19.go
@@ -0,0 +1,31 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// +build go1.9
16
17package tag
18
19import (
20 "context"
21 "runtime/pprof"
22)
23
24func do(ctx context.Context, f func(ctx context.Context)) {
25 m := FromContext(ctx)
26 keyvals := make([]string, 0, 2*len(m.m))
27 for k, v := range m.m {
28 keyvals = append(keyvals, k.Name(), v)
29 }
30 pprof.Do(ctx, pprof.Labels(keyvals...), f)
31}
diff --git a/vendor/go.opencensus.io/tag/profile_not19.go b/vendor/go.opencensus.io/tag/profile_not19.go
new file mode 100644
index 0000000..83adbce
--- /dev/null
+++ b/vendor/go.opencensus.io/tag/profile_not19.go
@@ -0,0 +1,23 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// +build !go1.9
16
17package tag
18
19import "context"
20
21func do(ctx context.Context, f func(ctx context.Context)) {
22 f(ctx)
23}
diff --git a/vendor/go.opencensus.io/tag/validate.go b/vendor/go.opencensus.io/tag/validate.go
new file mode 100644
index 0000000..0939fc6
--- /dev/null
+++ b/vendor/go.opencensus.io/tag/validate.go
@@ -0,0 +1,56 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package tag
16
17import "errors"
18
19const (
20 maxKeyLength = 255
21
22 // valid are restricted to US-ASCII subset (range 0x20 (' ') to 0x7e ('~')).
23 validKeyValueMin = 32
24 validKeyValueMax = 126
25)
26
27var (
28 errInvalidKeyName = errors.New("invalid key name: only ASCII characters accepted; max length must be 255 characters")
29 errInvalidValue = errors.New("invalid value: only ASCII characters accepted; max length must be 255 characters")
30)
31
32func checkKeyName(name string) bool {
33 if len(name) == 0 {
34 return false
35 }
36 if len(name) > maxKeyLength {
37 return false
38 }
39 return isASCII(name)
40}
41
42func isASCII(s string) bool {
43 for _, c := range s {
44 if (c < validKeyValueMin) || (c > validKeyValueMax) {
45 return false
46 }
47 }
48 return true
49}
50
51func checkValue(v string) bool {
52 if len(v) > maxKeyLength {
53 return false
54 }
55 return isASCII(v)
56}
diff --git a/vendor/go.opencensus.io/trace/basetypes.go b/vendor/go.opencensus.io/trace/basetypes.go
new file mode 100644
index 0000000..01f0f90
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/basetypes.go
@@ -0,0 +1,114 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package trace
16
17import (
18 "fmt"
19 "time"
20)
21
22type (
23 // TraceID is a 16-byte identifier for a set of spans.
24 TraceID [16]byte
25
26 // SpanID is an 8-byte identifier for a single span.
27 SpanID [8]byte
28)
29
30func (t TraceID) String() string {
31 return fmt.Sprintf("%02x", t[:])
32}
33
34func (s SpanID) String() string {
35 return fmt.Sprintf("%02x", s[:])
36}
37
38// Annotation represents a text annotation with a set of attributes and a timestamp.
39type Annotation struct {
40 Time time.Time
41 Message string
42 Attributes map[string]interface{}
43}
44
45// Attribute represents a key-value pair on a span, link or annotation.
46// Construct with one of: BoolAttribute, Int64Attribute, or StringAttribute.
47type Attribute struct {
48 key string
49 value interface{}
50}
51
52// BoolAttribute returns a bool-valued attribute.
53func BoolAttribute(key string, value bool) Attribute {
54 return Attribute{key: key, value: value}
55}
56
57// Int64Attribute returns an int64-valued attribute.
58func Int64Attribute(key string, value int64) Attribute {
59 return Attribute{key: key, value: value}
60}
61
62// StringAttribute returns a string-valued attribute.
63func StringAttribute(key string, value string) Attribute {
64 return Attribute{key: key, value: value}
65}
66
67// LinkType specifies the relationship between the span that had the link
68// added, and the linked span.
69type LinkType int32
70
71// LinkType values.
72const (
73 LinkTypeUnspecified LinkType = iota // The relationship of the two spans is unknown.
74 LinkTypeChild // The current span is a child of the linked span.
75 LinkTypeParent // The current span is the parent of the linked span.
76)
77
78// Link represents a reference from one span to another span.
79type Link struct {
80 TraceID TraceID
81 SpanID SpanID
82 Type LinkType
83 // Attributes is a set of attributes on the link.
84 Attributes map[string]interface{}
85}
86
87// MessageEventType specifies the type of message event.
88type MessageEventType int32
89
90// MessageEventType values.
91const (
92 MessageEventTypeUnspecified MessageEventType = iota // Unknown event type.
93 MessageEventTypeSent // Indicates a sent RPC message.
94 MessageEventTypeRecv // Indicates a received RPC message.
95)
96
97// MessageEvent represents an event describing a message sent or received on the network.
98type MessageEvent struct {
99 Time time.Time
100 EventType MessageEventType
101 MessageID int64
102 UncompressedByteSize int64
103 CompressedByteSize int64
104}
105
106// Status is the status of a Span.
107type Status struct {
108 // Code is a status code. Zero indicates success.
109 //
110 // If Code will be propagated to Google APIs, it ideally should be a value from
111 // https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto .
112 Code int32
113 Message string
114}
diff --git a/vendor/go.opencensus.io/trace/config.go b/vendor/go.opencensus.io/trace/config.go
new file mode 100644
index 0000000..0816892
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/config.go
@@ -0,0 +1,48 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package trace
16
17import (
18 "sync"
19
20 "go.opencensus.io/trace/internal"
21)
22
23// Config represents the global tracing configuration.
24type Config struct {
25 // DefaultSampler is the default sampler used when creating new spans.
26 DefaultSampler Sampler
27
28 // IDGenerator is for internal use only.
29 IDGenerator internal.IDGenerator
30}
31
32var configWriteMu sync.Mutex
33
34// ApplyConfig applies changes to the global tracing configuration.
35//
36// Fields not provided in the given config are going to be preserved.
37func ApplyConfig(cfg Config) {
38 configWriteMu.Lock()
39 defer configWriteMu.Unlock()
40 c := *config.Load().(*Config)
41 if cfg.DefaultSampler != nil {
42 c.DefaultSampler = cfg.DefaultSampler
43 }
44 if cfg.IDGenerator != nil {
45 c.IDGenerator = cfg.IDGenerator
46 }
47 config.Store(&c)
48}
diff --git a/vendor/go.opencensus.io/trace/doc.go b/vendor/go.opencensus.io/trace/doc.go
new file mode 100644
index 0000000..04b1ee4
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/doc.go
@@ -0,0 +1,53 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/*
16Package trace contains support for OpenCensus distributed tracing.
17
18The following assumes a basic familiarity with OpenCensus concepts.
19See http://opencensus.io
20
21
22Exporting Traces
23
24To export collected tracing data, register at least one exporter. You can use
25one of the provided exporters or write your own.
26
27 trace.RegisterExporter(exporter)
28
29By default, traces will be sampled relatively rarely. To change the sampling
30frequency for your entire program, call ApplyConfig. Use a ProbabilitySampler
31to sample a subset of traces, or use AlwaysSample to collect a trace on every run:
32
33 trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
34
35Be careful about using trace.AlwaysSample in a production application with
36significant traffic: a new trace will be started and exported for every request.
37
38Adding Spans to a Trace
39
40A trace consists of a tree of spans. In Go, the current span is carried in a
41context.Context.
42
43It is common to want to capture all the activity of a function call in a span. For
44this to work, the function must take a context.Context as a parameter. Add these two
45lines to the top of the function:
46
47 ctx, span := trace.StartSpan(ctx, "example.com/Run")
48 defer span.End()
49
50StartSpan will create a new top-level span if the context
51doesn't contain another span, otherwise it will create a child span.
52*/
53package trace // import "go.opencensus.io/trace"
diff --git a/vendor/go.opencensus.io/trace/exemplar.go b/vendor/go.opencensus.io/trace/exemplar.go
new file mode 100644
index 0000000..416d805
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/exemplar.go
@@ -0,0 +1,43 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package trace
16
17import (
18 "context"
19 "encoding/hex"
20
21 "go.opencensus.io/exemplar"
22)
23
24func init() {
25 exemplar.RegisterAttachmentExtractor(attachSpanContext)
26}
27
28func attachSpanContext(ctx context.Context, a exemplar.Attachments) exemplar.Attachments {
29 span := FromContext(ctx)
30 if span == nil {
31 return a
32 }
33 sc := span.SpanContext()
34 if !sc.IsSampled() {
35 return a
36 }
37 if a == nil {
38 a = make(exemplar.Attachments)
39 }
40 a[exemplar.KeyTraceID] = hex.EncodeToString(sc.TraceID[:])
41 a[exemplar.KeySpanID] = hex.EncodeToString(sc.SpanID[:])
42 return a
43}
diff --git a/vendor/go.opencensus.io/trace/export.go b/vendor/go.opencensus.io/trace/export.go
new file mode 100644
index 0000000..77a8c73
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/export.go
@@ -0,0 +1,90 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package trace
16
17import (
18 "sync"
19 "sync/atomic"
20 "time"
21)
22
23// Exporter is a type for functions that receive sampled trace spans.
24//
25// The ExportSpan method should be safe for concurrent use and should return
26// quickly; if an Exporter takes a significant amount of time to process a
27// SpanData, that work should be done on another goroutine.
28//
29// The SpanData should not be modified, but a pointer to it can be kept.
30type Exporter interface {
31 ExportSpan(s *SpanData)
32}
33
34type exportersMap map[Exporter]struct{}
35
36var (
37 exporterMu sync.Mutex
38 exporters atomic.Value
39)
40
41// RegisterExporter adds to the list of Exporters that will receive sampled
42// trace spans.
43//
44// Binaries can register exporters, libraries shouldn't register exporters.
45func RegisterExporter(e Exporter) {
46 exporterMu.Lock()
47 new := make(exportersMap)
48 if old, ok := exporters.Load().(exportersMap); ok {
49 for k, v := range old {
50 new[k] = v
51 }
52 }
53 new[e] = struct{}{}
54 exporters.Store(new)
55 exporterMu.Unlock()
56}
57
58// UnregisterExporter removes from the list of Exporters the Exporter that was
59// registered with the given name.
60func UnregisterExporter(e Exporter) {
61 exporterMu.Lock()
62 new := make(exportersMap)
63 if old, ok := exporters.Load().(exportersMap); ok {
64 for k, v := range old {
65 new[k] = v
66 }
67 }
68 delete(new, e)
69 exporters.Store(new)
70 exporterMu.Unlock()
71}
72
73// SpanData contains all the information collected by a Span.
74type SpanData struct {
75 SpanContext
76 ParentSpanID SpanID
77 SpanKind int
78 Name string
79 StartTime time.Time
80 // The wall clock time of EndTime will be adjusted to always be offset
81 // from StartTime by the duration of the span.
82 EndTime time.Time
83 // The values of Attributes each have type string, bool, or int64.
84 Attributes map[string]interface{}
85 Annotations []Annotation
86 MessageEvents []MessageEvent
87 Status
88 Links []Link
89 HasRemoteParent bool
90}
diff --git a/vendor/go.opencensus.io/trace/internal/internal.go b/vendor/go.opencensus.io/trace/internal/internal.go
new file mode 100644
index 0000000..1c8b9b3
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/internal/internal.go
@@ -0,0 +1,21 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package internal provides trace internals.
16package internal
17
18type IDGenerator interface {
19 NewTraceID() [16]byte
20 NewSpanID() [8]byte
21}
diff --git a/vendor/go.opencensus.io/trace/propagation/propagation.go b/vendor/go.opencensus.io/trace/propagation/propagation.go
new file mode 100644
index 0000000..1eb190a
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/propagation/propagation.go
@@ -0,0 +1,108 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package propagation implements the binary trace context format.
16package propagation // import "go.opencensus.io/trace/propagation"
17
18// TODO: link to external spec document.
19
20// BinaryFormat format:
21//
22// Binary value: <version_id><version_format>
23// version_id: 1 byte representing the version id.
24//
25// For version_id = 0:
26//
27// version_format: <field><field>
28// field_format: <field_id><field_format>
29//
30// Fields:
31//
32// TraceId: (field_id = 0, len = 16, default = "0000000000000000") - 16-byte array representing the trace_id.
33// SpanId: (field_id = 1, len = 8, default = "00000000") - 8-byte array representing the span_id.
34// TraceOptions: (field_id = 2, len = 1, default = "0") - 1-byte array representing the trace_options.
35//
36// Fields MUST be encoded using the field id order (smaller to higher).
37//
38// Valid value example:
39//
40// {0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1, 97,
41// 98, 99, 100, 101, 102, 103, 104, 2, 1}
42//
43// version_id = 0;
44// trace_id = {64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79}
45// span_id = {97, 98, 99, 100, 101, 102, 103, 104};
46// trace_options = {1};
47
48import (
49 "net/http"
50
51 "go.opencensus.io/trace"
52)
53
54// Binary returns the binary format representation of a SpanContext.
55//
56// If sc is the zero value, Binary returns nil.
57func Binary(sc trace.SpanContext) []byte {
58 if sc == (trace.SpanContext{}) {
59 return nil
60 }
61 var b [29]byte
62 copy(b[2:18], sc.TraceID[:])
63 b[18] = 1
64 copy(b[19:27], sc.SpanID[:])
65 b[27] = 2
66 b[28] = uint8(sc.TraceOptions)
67 return b[:]
68}
69
70// FromBinary returns the SpanContext represented by b.
71//
72// If b has an unsupported version ID or contains no TraceID, FromBinary
73// returns with ok==false.
74func FromBinary(b []byte) (sc trace.SpanContext, ok bool) {
75 if len(b) == 0 || b[0] != 0 {
76 return trace.SpanContext{}, false
77 }
78 b = b[1:]
79 if len(b) >= 17 && b[0] == 0 {
80 copy(sc.TraceID[:], b[1:17])
81 b = b[17:]
82 } else {
83 return trace.SpanContext{}, false
84 }
85 if len(b) >= 9 && b[0] == 1 {
86 copy(sc.SpanID[:], b[1:9])
87 b = b[9:]
88 }
89 if len(b) >= 2 && b[0] == 2 {
90 sc.TraceOptions = trace.TraceOptions(b[1])
91 }
92 return sc, true
93}
94
95// HTTPFormat implementations propagate span contexts
96// in HTTP requests.
97//
98// SpanContextFromRequest extracts a span context from incoming
99// requests.
100//
101// SpanContextToRequest modifies the given request to include the given
102// span context.
103type HTTPFormat interface {
104 SpanContextFromRequest(req *http.Request) (sc trace.SpanContext, ok bool)
105 SpanContextToRequest(sc trace.SpanContext, req *http.Request)
106}
107
108// TODO(jbd): Find a more representative but short name for HTTPFormat.
diff --git a/vendor/go.opencensus.io/trace/sampling.go b/vendor/go.opencensus.io/trace/sampling.go
new file mode 100644
index 0000000..71c10f9
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/sampling.go
@@ -0,0 +1,75 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package trace
16
17import (
18 "encoding/binary"
19)
20
21const defaultSamplingProbability = 1e-4
22
23// Sampler decides whether a trace should be sampled and exported.
24type Sampler func(SamplingParameters) SamplingDecision
25
26// SamplingParameters contains the values passed to a Sampler.
27type SamplingParameters struct {
28 ParentContext SpanContext
29 TraceID TraceID
30 SpanID SpanID
31 Name string
32 HasRemoteParent bool
33}
34
35// SamplingDecision is the value returned by a Sampler.
36type SamplingDecision struct {
37 Sample bool
38}
39
40// ProbabilitySampler returns a Sampler that samples a given fraction of traces.
41//
42// It also samples spans whose parents are sampled.
43func ProbabilitySampler(fraction float64) Sampler {
44 if !(fraction >= 0) {
45 fraction = 0
46 } else if fraction >= 1 {
47 return AlwaysSample()
48 }
49
50 traceIDUpperBound := uint64(fraction * (1 << 63))
51 return Sampler(func(p SamplingParameters) SamplingDecision {
52 if p.ParentContext.IsSampled() {
53 return SamplingDecision{Sample: true}
54 }
55 x := binary.BigEndian.Uint64(p.TraceID[0:8]) >> 1
56 return SamplingDecision{Sample: x < traceIDUpperBound}
57 })
58}
59
60// AlwaysSample returns a Sampler that samples every trace.
61// Be careful about using this sampler in a production application with
62// significant traffic: a new trace will be started and exported for every
63// request.
64func AlwaysSample() Sampler {
65 return func(p SamplingParameters) SamplingDecision {
66 return SamplingDecision{Sample: true}
67 }
68}
69
70// NeverSample returns a Sampler that samples no traces.
71func NeverSample() Sampler {
72 return func(p SamplingParameters) SamplingDecision {
73 return SamplingDecision{Sample: false}
74 }
75}
diff --git a/vendor/go.opencensus.io/trace/spanbucket.go b/vendor/go.opencensus.io/trace/spanbucket.go
new file mode 100644
index 0000000..fbabad3
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/spanbucket.go
@@ -0,0 +1,130 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package trace
16
17import (
18 "time"
19)
20
21// samplePeriod is the minimum time between accepting spans in a single bucket.
22const samplePeriod = time.Second
23
24// defaultLatencies contains the default latency bucket bounds.
25// TODO: consider defaults, make configurable
26var defaultLatencies = [...]time.Duration{
27 10 * time.Microsecond,
28 100 * time.Microsecond,
29 time.Millisecond,
30 10 * time.Millisecond,
31 100 * time.Millisecond,
32 time.Second,
33 10 * time.Second,
34 time.Minute,
35}
36
37// bucket is a container for a set of spans for a particular error code or latency range.
38type bucket struct {
39 nextTime time.Time // next time we can accept a span
40 buffer []*SpanData // circular buffer of spans
41 nextIndex int // location next SpanData should be placed in buffer
42 overflow bool // whether the circular buffer has wrapped around
43}
44
45func makeBucket(bufferSize int) bucket {
46 return bucket{
47 buffer: make([]*SpanData, bufferSize),
48 }
49}
50
51// add adds a span to the bucket, if nextTime has been reached.
52func (b *bucket) add(s *SpanData) {
53 if s.EndTime.Before(b.nextTime) {
54 return
55 }
56 if len(b.buffer) == 0 {
57 return
58 }
59 b.nextTime = s.EndTime.Add(samplePeriod)
60 b.buffer[b.nextIndex] = s
61 b.nextIndex++
62 if b.nextIndex == len(b.buffer) {
63 b.nextIndex = 0
64 b.overflow = true
65 }
66}
67
68// size returns the number of spans in the bucket.
69func (b *bucket) size() int {
70 if b.overflow {
71 return len(b.buffer)
72 }
73 return b.nextIndex
74}
75
76// span returns the ith span in the bucket.
77func (b *bucket) span(i int) *SpanData {
78 if !b.overflow {
79 return b.buffer[i]
80 }
81 if i < len(b.buffer)-b.nextIndex {
82 return b.buffer[b.nextIndex+i]
83 }
84 return b.buffer[b.nextIndex+i-len(b.buffer)]
85}
86
87// resize changes the size of the bucket to n, keeping up to n existing spans.
88func (b *bucket) resize(n int) {
89 cur := b.size()
90 newBuffer := make([]*SpanData, n)
91 if cur < n {
92 for i := 0; i < cur; i++ {
93 newBuffer[i] = b.span(i)
94 }
95 b.buffer = newBuffer
96 b.nextIndex = cur
97 b.overflow = false
98 return
99 }
100 for i := 0; i < n; i++ {
101 newBuffer[i] = b.span(i + cur - n)
102 }
103 b.buffer = newBuffer
104 b.nextIndex = 0
105 b.overflow = true
106}
107
108// latencyBucket returns the appropriate bucket number for a given latency.
109func latencyBucket(latency time.Duration) int {
110 i := 0
111 for i < len(defaultLatencies) && latency >= defaultLatencies[i] {
112 i++
113 }
114 return i
115}
116
117// latencyBucketBounds returns the lower and upper bounds for a latency bucket
118// number.
119//
120// The lower bound is inclusive, the upper bound is exclusive (except for the
121// last bucket.)
122func latencyBucketBounds(index int) (lower time.Duration, upper time.Duration) {
123 if index == 0 {
124 return 0, defaultLatencies[index]
125 }
126 if index == len(defaultLatencies) {
127 return defaultLatencies[index-1], 1<<63 - 1
128 }
129 return defaultLatencies[index-1], defaultLatencies[index]
130}
diff --git a/vendor/go.opencensus.io/trace/spanstore.go b/vendor/go.opencensus.io/trace/spanstore.go
new file mode 100644
index 0000000..c442d99
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/spanstore.go
@@ -0,0 +1,306 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package trace
16
17import (
18 "sync"
19 "time"
20
21 "go.opencensus.io/internal"
22)
23
24const (
25 maxBucketSize = 100000
26 defaultBucketSize = 10
27)
28
29var (
30 ssmu sync.RWMutex // protects spanStores
31 spanStores = make(map[string]*spanStore)
32)
33
34// This exists purely to avoid exposing internal methods used by z-Pages externally.
35type internalOnly struct{}
36
37func init() {
38 //TODO(#412): remove
39 internal.Trace = &internalOnly{}
40}
41
42// ReportActiveSpans returns the active spans for the given name.
43func (i internalOnly) ReportActiveSpans(name string) []*SpanData {
44 s := spanStoreForName(name)
45 if s == nil {
46 return nil
47 }
48 var out []*SpanData
49 s.mu.Lock()
50 defer s.mu.Unlock()
51 for span := range s.active {
52 out = append(out, span.makeSpanData())
53 }
54 return out
55}
56
57// ReportSpansByError returns a sample of error spans.
58//
59// If code is nonzero, only spans with that status code are returned.
60func (i internalOnly) ReportSpansByError(name string, code int32) []*SpanData {
61 s := spanStoreForName(name)
62 if s == nil {
63 return nil
64 }
65 var out []*SpanData
66 s.mu.Lock()
67 defer s.mu.Unlock()
68 if code != 0 {
69 if b, ok := s.errors[code]; ok {
70 for _, sd := range b.buffer {
71 if sd == nil {
72 break
73 }
74 out = append(out, sd)
75 }
76 }
77 } else {
78 for _, b := range s.errors {
79 for _, sd := range b.buffer {
80 if sd == nil {
81 break
82 }
83 out = append(out, sd)
84 }
85 }
86 }
87 return out
88}
89
90// ConfigureBucketSizes sets the number of spans to keep per latency and error
91// bucket for different span names.
92func (i internalOnly) ConfigureBucketSizes(bcs []internal.BucketConfiguration) {
93 for _, bc := range bcs {
94 latencyBucketSize := bc.MaxRequestsSucceeded
95 if latencyBucketSize < 0 {
96 latencyBucketSize = 0
97 }
98 if latencyBucketSize > maxBucketSize {
99 latencyBucketSize = maxBucketSize
100 }
101 errorBucketSize := bc.MaxRequestsErrors
102 if errorBucketSize < 0 {
103 errorBucketSize = 0
104 }
105 if errorBucketSize > maxBucketSize {
106 errorBucketSize = maxBucketSize
107 }
108 spanStoreSetSize(bc.Name, latencyBucketSize, errorBucketSize)
109 }
110}
111
112// ReportSpansPerMethod returns a summary of what spans are being stored for each span name.
113func (i internalOnly) ReportSpansPerMethod() map[string]internal.PerMethodSummary {
114 out := make(map[string]internal.PerMethodSummary)
115 ssmu.RLock()
116 defer ssmu.RUnlock()
117 for name, s := range spanStores {
118 s.mu.Lock()
119 p := internal.PerMethodSummary{
120 Active: len(s.active),
121 }
122 for code, b := range s.errors {
123 p.ErrorBuckets = append(p.ErrorBuckets, internal.ErrorBucketSummary{
124 ErrorCode: code,
125 Size: b.size(),
126 })
127 }
128 for i, b := range s.latency {
129 min, max := latencyBucketBounds(i)
130 p.LatencyBuckets = append(p.LatencyBuckets, internal.LatencyBucketSummary{
131 MinLatency: min,
132 MaxLatency: max,
133 Size: b.size(),
134 })
135 }
136 s.mu.Unlock()
137 out[name] = p
138 }
139 return out
140}
141
142// ReportSpansByLatency returns a sample of successful spans.
143//
144// minLatency is the minimum latency of spans to be returned.
145// maxLatency, if nonzero, is the maximum latency of spans to be returned.
146func (i internalOnly) ReportSpansByLatency(name string, minLatency, maxLatency time.Duration) []*SpanData {
147 s := spanStoreForName(name)
148 if s == nil {
149 return nil
150 }
151 var out []*SpanData
152 s.mu.Lock()
153 defer s.mu.Unlock()
154 for i, b := range s.latency {
155 min, max := latencyBucketBounds(i)
156 if i+1 != len(s.latency) && max <= minLatency {
157 continue
158 }
159 if maxLatency != 0 && maxLatency < min {
160 continue
161 }
162 for _, sd := range b.buffer {
163 if sd == nil {
164 break
165 }
166 if minLatency != 0 || maxLatency != 0 {
167 d := sd.EndTime.Sub(sd.StartTime)
168 if d < minLatency {
169 continue
170 }
171 if maxLatency != 0 && d > maxLatency {
172 continue
173 }
174 }
175 out = append(out, sd)
176 }
177 }
178 return out
179}
180
181// spanStore keeps track of spans stored for a particular span name.
182//
183// It contains all active spans; a sample of spans for failed requests,
184// categorized by error code; and a sample of spans for successful requests,
185// bucketed by latency.
186type spanStore struct {
187 mu sync.Mutex // protects everything below.
188 active map[*Span]struct{}
189 errors map[int32]*bucket
190 latency []bucket
191 maxSpansPerErrorBucket int
192}
193
194// newSpanStore creates a span store.
195func newSpanStore(name string, latencyBucketSize int, errorBucketSize int) *spanStore {
196 s := &spanStore{
197 active: make(map[*Span]struct{}),
198 latency: make([]bucket, len(defaultLatencies)+1),
199 maxSpansPerErrorBucket: errorBucketSize,
200 }
201 for i := range s.latency {
202 s.latency[i] = makeBucket(latencyBucketSize)
203 }
204 return s
205}
206
207// spanStoreForName returns the spanStore for the given name.
208//
209// It returns nil if it doesn't exist.
210func spanStoreForName(name string) *spanStore {
211 var s *spanStore
212 ssmu.RLock()
213 s, _ = spanStores[name]
214 ssmu.RUnlock()
215 return s
216}
217
218// spanStoreForNameCreateIfNew returns the spanStore for the given name.
219//
220// It creates it if it didn't exist.
221func spanStoreForNameCreateIfNew(name string) *spanStore {
222 ssmu.RLock()
223 s, ok := spanStores[name]
224 ssmu.RUnlock()
225 if ok {
226 return s
227 }
228 ssmu.Lock()
229 defer ssmu.Unlock()
230 s, ok = spanStores[name]
231 if ok {
232 return s
233 }
234 s = newSpanStore(name, defaultBucketSize, defaultBucketSize)
235 spanStores[name] = s
236 return s
237}
238
239// spanStoreSetSize resizes the spanStore for the given name.
240//
241// It creates it if it didn't exist.
242func spanStoreSetSize(name string, latencyBucketSize int, errorBucketSize int) {
243 ssmu.RLock()
244 s, ok := spanStores[name]
245 ssmu.RUnlock()
246 if ok {
247 s.resize(latencyBucketSize, errorBucketSize)
248 return
249 }
250 ssmu.Lock()
251 defer ssmu.Unlock()
252 s, ok = spanStores[name]
253 if ok {
254 s.resize(latencyBucketSize, errorBucketSize)
255 return
256 }
257 s = newSpanStore(name, latencyBucketSize, errorBucketSize)
258 spanStores[name] = s
259}
260
261func (s *spanStore) resize(latencyBucketSize int, errorBucketSize int) {
262 s.mu.Lock()
263 for i := range s.latency {
264 s.latency[i].resize(latencyBucketSize)
265 }
266 for _, b := range s.errors {
267 b.resize(errorBucketSize)
268 }
269 s.maxSpansPerErrorBucket = errorBucketSize
270 s.mu.Unlock()
271}
272
273// add adds a span to the active bucket of the spanStore.
274func (s *spanStore) add(span *Span) {
275 s.mu.Lock()
276 s.active[span] = struct{}{}
277 s.mu.Unlock()
278}
279
280// finished removes a span from the active set, and adds a corresponding
281// SpanData to a latency or error bucket.
282func (s *spanStore) finished(span *Span, sd *SpanData) {
283 latency := sd.EndTime.Sub(sd.StartTime)
284 if latency < 0 {
285 latency = 0
286 }
287 code := sd.Status.Code
288
289 s.mu.Lock()
290 delete(s.active, span)
291 if code == 0 {
292 s.latency[latencyBucket(latency)].add(sd)
293 } else {
294 if s.errors == nil {
295 s.errors = make(map[int32]*bucket)
296 }
297 if b := s.errors[code]; b != nil {
298 b.add(sd)
299 } else {
300 b := makeBucket(s.maxSpansPerErrorBucket)
301 s.errors[code] = &b
302 b.add(sd)
303 }
304 }
305 s.mu.Unlock()
306}
diff --git a/vendor/go.opencensus.io/trace/status_codes.go b/vendor/go.opencensus.io/trace/status_codes.go
new file mode 100644
index 0000000..ec60eff
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/status_codes.go
@@ -0,0 +1,37 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package trace
16
17// Status codes for use with Span.SetStatus. These correspond to the status
18// codes used by gRPC defined here: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
19const (
20 StatusCodeOK = 0
21 StatusCodeCancelled = 1
22 StatusCodeUnknown = 2
23 StatusCodeInvalidArgument = 3
24 StatusCodeDeadlineExceeded = 4
25 StatusCodeNotFound = 5
26 StatusCodeAlreadyExists = 6
27 StatusCodePermissionDenied = 7
28 StatusCodeResourceExhausted = 8
29 StatusCodeFailedPrecondition = 9
30 StatusCodeAborted = 10
31 StatusCodeOutOfRange = 11
32 StatusCodeUnimplemented = 12
33 StatusCodeInternal = 13
34 StatusCodeUnavailable = 14
35 StatusCodeDataLoss = 15
36 StatusCodeUnauthenticated = 16
37)
diff --git a/vendor/go.opencensus.io/trace/trace.go b/vendor/go.opencensus.io/trace/trace.go
new file mode 100644
index 0000000..9e5e5f0
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/trace.go
@@ -0,0 +1,516 @@
1// Copyright 2017, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package trace
16
17import (
18 "context"
19 crand "crypto/rand"
20 "encoding/binary"
21 "fmt"
22 "math/rand"
23 "sync"
24 "sync/atomic"
25 "time"
26
27 "go.opencensus.io/internal"
28 "go.opencensus.io/trace/tracestate"
29)
30
31// Span represents a span of a trace. It has an associated SpanContext, and
32// stores data accumulated while the span is active.
33//
34// Ideally users should interact with Spans by calling the functions in this
35// package that take a Context parameter.
36type Span struct {
37 // data contains information recorded about the span.
38 //
39 // It will be non-nil if we are exporting the span or recording events for it.
40 // Otherwise, data is nil, and the Span is simply a carrier for the
41 // SpanContext, so that the trace ID is propagated.
42 data *SpanData
43 mu sync.Mutex // protects the contents of *data (but not the pointer value.)
44 spanContext SpanContext
45 // spanStore is the spanStore this span belongs to, if any, otherwise it is nil.
46 *spanStore
47 endOnce sync.Once
48
49 executionTracerTaskEnd func() // ends the execution tracer span
50}
51
52// IsRecordingEvents returns true if events are being recorded for this span.
53// Use this check to avoid computing expensive annotations when they will never
54// be used.
55func (s *Span) IsRecordingEvents() bool {
56 if s == nil {
57 return false
58 }
59 return s.data != nil
60}
61
62// TraceOptions contains options associated with a trace span.
63type TraceOptions uint32
64
65// IsSampled returns true if the span will be exported.
66func (sc SpanContext) IsSampled() bool {
67 return sc.TraceOptions.IsSampled()
68}
69
70// setIsSampled sets the TraceOptions bit that determines whether the span will be exported.
71func (sc *SpanContext) setIsSampled(sampled bool) {
72 if sampled {
73 sc.TraceOptions |= 1
74 } else {
75 sc.TraceOptions &= ^TraceOptions(1)
76 }
77}
78
79// IsSampled returns true if the span will be exported.
80func (t TraceOptions) IsSampled() bool {
81 return t&1 == 1
82}
83
84// SpanContext contains the state that must propagate across process boundaries.
85//
86// SpanContext is not an implementation of context.Context.
87// TODO: add reference to external Census docs for SpanContext.
88type SpanContext struct {
89 TraceID TraceID
90 SpanID SpanID
91 TraceOptions TraceOptions
92 Tracestate *tracestate.Tracestate
93}
94
95type contextKey struct{}
96
97// FromContext returns the Span stored in a context, or nil if there isn't one.
98func FromContext(ctx context.Context) *Span {
99 s, _ := ctx.Value(contextKey{}).(*Span)
100 return s
101}
102
103// NewContext returns a new context with the given Span attached.
104func NewContext(parent context.Context, s *Span) context.Context {
105 return context.WithValue(parent, contextKey{}, s)
106}
107
108// All available span kinds. Span kind must be either one of these values.
109const (
110 SpanKindUnspecified = iota
111 SpanKindServer
112 SpanKindClient
113)
114
115// StartOptions contains options concerning how a span is started.
116type StartOptions struct {
117 // Sampler to consult for this Span. If provided, it is always consulted.
118 //
119 // If not provided, then the behavior differs based on whether
120 // the parent of this Span is remote, local, or there is no parent.
121 // In the case of a remote parent or no parent, the
122 // default sampler (see Config) will be consulted. Otherwise,
123 // when there is a non-remote parent, no new sampling decision will be made:
124 // we will preserve the sampling of the parent.
125 Sampler Sampler
126
127 // SpanKind represents the kind of a span. If none is set,
128 // SpanKindUnspecified is used.
129 SpanKind int
130}
131
132// StartOption apply changes to StartOptions.
133type StartOption func(*StartOptions)
134
135// WithSpanKind makes new spans to be created with the given kind.
136func WithSpanKind(spanKind int) StartOption {
137 return func(o *StartOptions) {
138 o.SpanKind = spanKind
139 }
140}
141
142// WithSampler makes new spans to be be created with a custom sampler.
143// Otherwise, the global sampler is used.
144func WithSampler(sampler Sampler) StartOption {
145 return func(o *StartOptions) {
146 o.Sampler = sampler
147 }
148}
149
150// StartSpan starts a new child span of the current span in the context. If
151// there is no span in the context, creates a new trace and span.
152//
153// Returned context contains the newly created span. You can use it to
154// propagate the returned span in process.
155func StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span) {
156 var opts StartOptions
157 var parent SpanContext
158 if p := FromContext(ctx); p != nil {
159 parent = p.spanContext
160 }
161 for _, op := range o {
162 op(&opts)
163 }
164 span := startSpanInternal(name, parent != SpanContext{}, parent, false, opts)
165
166 ctx, end := startExecutionTracerTask(ctx, name)
167 span.executionTracerTaskEnd = end
168 return NewContext(ctx, span), span
169}
170
171// StartSpanWithRemoteParent starts a new child span of the span from the given parent.
172//
173// If the incoming context contains a parent, it ignores. StartSpanWithRemoteParent is
174// preferred for cases where the parent is propagated via an incoming request.
175//
176// Returned context contains the newly created span. You can use it to
177// propagate the returned span in process.
178func StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) {
179 var opts StartOptions
180 for _, op := range o {
181 op(&opts)
182 }
183 span := startSpanInternal(name, parent != SpanContext{}, parent, true, opts)
184 ctx, end := startExecutionTracerTask(ctx, name)
185 span.executionTracerTaskEnd = end
186 return NewContext(ctx, span), span
187}
188
189func startSpanInternal(name string, hasParent bool, parent SpanContext, remoteParent bool, o StartOptions) *Span {
190 span := &Span{}
191 span.spanContext = parent
192
193 cfg := config.Load().(*Config)
194
195 if !hasParent {
196 span.spanContext.TraceID = cfg.IDGenerator.NewTraceID()
197 }
198 span.spanContext.SpanID = cfg.IDGenerator.NewSpanID()
199 sampler := cfg.DefaultSampler
200
201 if !hasParent || remoteParent || o.Sampler != nil {
202 // If this span is the child of a local span and no Sampler is set in the
203 // options, keep the parent's TraceOptions.
204 //
205 // Otherwise, consult the Sampler in the options if it is non-nil, otherwise
206 // the default sampler.
207 if o.Sampler != nil {
208 sampler = o.Sampler
209 }
210 span.spanContext.setIsSampled(sampler(SamplingParameters{
211 ParentContext: parent,
212 TraceID: span.spanContext.TraceID,
213 SpanID: span.spanContext.SpanID,
214 Name: name,
215 HasRemoteParent: remoteParent}).Sample)
216 }
217
218 if !internal.LocalSpanStoreEnabled && !span.spanContext.IsSampled() {
219 return span
220 }
221
222 span.data = &SpanData{
223 SpanContext: span.spanContext,
224 StartTime: time.Now(),
225 SpanKind: o.SpanKind,
226 Name: name,
227 HasRemoteParent: remoteParent,
228 }
229 if hasParent {
230 span.data.ParentSpanID = parent.SpanID
231 }
232 if internal.LocalSpanStoreEnabled {
233 var ss *spanStore
234 ss = spanStoreForNameCreateIfNew(name)
235 if ss != nil {
236 span.spanStore = ss
237 ss.add(span)
238 }
239 }
240
241 return span
242}
243
244// End ends the span.
245func (s *Span) End() {
246 if s == nil {
247 return
248 }
249 if s.executionTracerTaskEnd != nil {
250 s.executionTracerTaskEnd()
251 }
252 if !s.IsRecordingEvents() {
253 return
254 }
255 s.endOnce.Do(func() {
256 exp, _ := exporters.Load().(exportersMap)
257 mustExport := s.spanContext.IsSampled() && len(exp) > 0
258 if s.spanStore != nil || mustExport {
259 sd := s.makeSpanData()
260 sd.EndTime = internal.MonotonicEndTime(sd.StartTime)
261 if s.spanStore != nil {
262 s.spanStore.finished(s, sd)
263 }
264 if mustExport {
265 for e := range exp {
266 e.ExportSpan(sd)
267 }
268 }
269 }
270 })
271}
272
273// makeSpanData produces a SpanData representing the current state of the Span.
274// It requires that s.data is non-nil.
275func (s *Span) makeSpanData() *SpanData {
276 var sd SpanData
277 s.mu.Lock()
278 sd = *s.data
279 if s.data.Attributes != nil {
280 sd.Attributes = make(map[string]interface{})
281 for k, v := range s.data.Attributes {
282 sd.Attributes[k] = v
283 }
284 }
285 s.mu.Unlock()
286 return &sd
287}
288
289// SpanContext returns the SpanContext of the span.
290func (s *Span) SpanContext() SpanContext {
291 if s == nil {
292 return SpanContext{}
293 }
294 return s.spanContext
295}
296
297// SetName sets the name of the span, if it is recording events.
298func (s *Span) SetName(name string) {
299 if !s.IsRecordingEvents() {
300 return
301 }
302 s.mu.Lock()
303 s.data.Name = name
304 s.mu.Unlock()
305}
306
307// SetStatus sets the status of the span, if it is recording events.
308func (s *Span) SetStatus(status Status) {
309 if !s.IsRecordingEvents() {
310 return
311 }
312 s.mu.Lock()
313 s.data.Status = status
314 s.mu.Unlock()
315}
316
317// AddAttributes sets attributes in the span.
318//
319// Existing attributes whose keys appear in the attributes parameter are overwritten.
320func (s *Span) AddAttributes(attributes ...Attribute) {
321 if !s.IsRecordingEvents() {
322 return
323 }
324 s.mu.Lock()
325 if s.data.Attributes == nil {
326 s.data.Attributes = make(map[string]interface{})
327 }
328 copyAttributes(s.data.Attributes, attributes)
329 s.mu.Unlock()
330}
331
332// copyAttributes copies a slice of Attributes into a map.
333func copyAttributes(m map[string]interface{}, attributes []Attribute) {
334 for _, a := range attributes {
335 m[a.key] = a.value
336 }
337}
338
339func (s *Span) lazyPrintfInternal(attributes []Attribute, format string, a ...interface{}) {
340 now := time.Now()
341 msg := fmt.Sprintf(format, a...)
342 var m map[string]interface{}
343 s.mu.Lock()
344 if len(attributes) != 0 {
345 m = make(map[string]interface{})
346 copyAttributes(m, attributes)
347 }
348 s.data.Annotations = append(s.data.Annotations, Annotation{
349 Time: now,
350 Message: msg,
351 Attributes: m,
352 })
353 s.mu.Unlock()
354}
355
356func (s *Span) printStringInternal(attributes []Attribute, str string) {
357 now := time.Now()
358 var a map[string]interface{}
359 s.mu.Lock()
360 if len(attributes) != 0 {
361 a = make(map[string]interface{})
362 copyAttributes(a, attributes)
363 }
364 s.data.Annotations = append(s.data.Annotations, Annotation{
365 Time: now,
366 Message: str,
367 Attributes: a,
368 })
369 s.mu.Unlock()
370}
371
372// Annotate adds an annotation with attributes.
373// Attributes can be nil.
374func (s *Span) Annotate(attributes []Attribute, str string) {
375 if !s.IsRecordingEvents() {
376 return
377 }
378 s.printStringInternal(attributes, str)
379}
380
381// Annotatef adds an annotation with attributes.
382func (s *Span) Annotatef(attributes []Attribute, format string, a ...interface{}) {
383 if !s.IsRecordingEvents() {
384 return
385 }
386 s.lazyPrintfInternal(attributes, format, a...)
387}
388
389// AddMessageSendEvent adds a message send event to the span.
390//
391// messageID is an identifier for the message, which is recommended to be
392// unique in this span and the same between the send event and the receive
393// event (this allows to identify a message between the sender and receiver).
394// For example, this could be a sequence id.
395func (s *Span) AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) {
396 if !s.IsRecordingEvents() {
397 return
398 }
399 now := time.Now()
400 s.mu.Lock()
401 s.data.MessageEvents = append(s.data.MessageEvents, MessageEvent{
402 Time: now,
403 EventType: MessageEventTypeSent,
404 MessageID: messageID,
405 UncompressedByteSize: uncompressedByteSize,
406 CompressedByteSize: compressedByteSize,
407 })
408 s.mu.Unlock()
409}
410
411// AddMessageReceiveEvent adds a message receive event to the span.
412//
413// messageID is an identifier for the message, which is recommended to be
414// unique in this span and the same between the send event and the receive
415// event (this allows to identify a message between the sender and receiver).
416// For example, this could be a sequence id.
417func (s *Span) AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) {
418 if !s.IsRecordingEvents() {
419 return
420 }
421 now := time.Now()
422 s.mu.Lock()
423 s.data.MessageEvents = append(s.data.MessageEvents, MessageEvent{
424 Time: now,
425 EventType: MessageEventTypeRecv,
426 MessageID: messageID,
427 UncompressedByteSize: uncompressedByteSize,
428 CompressedByteSize: compressedByteSize,
429 })
430 s.mu.Unlock()
431}
432
433// AddLink adds a link to the span.
434func (s *Span) AddLink(l Link) {
435 if !s.IsRecordingEvents() {
436 return
437 }
438 s.mu.Lock()
439 s.data.Links = append(s.data.Links, l)
440 s.mu.Unlock()
441}
442
443func (s *Span) String() string {
444 if s == nil {
445 return "<nil>"
446 }
447 if s.data == nil {
448 return fmt.Sprintf("span %s", s.spanContext.SpanID)
449 }
450 s.mu.Lock()
451 str := fmt.Sprintf("span %s %q", s.spanContext.SpanID, s.data.Name)
452 s.mu.Unlock()
453 return str
454}
455
456var config atomic.Value // access atomically
457
458func init() {
459 gen := &defaultIDGenerator{}
460 // initialize traceID and spanID generators.
461 var rngSeed int64
462 for _, p := range []interface{}{
463 &rngSeed, &gen.traceIDAdd, &gen.nextSpanID, &gen.spanIDInc,
464 } {
465 binary.Read(crand.Reader, binary.LittleEndian, p)
466 }
467 gen.traceIDRand = rand.New(rand.NewSource(rngSeed))
468 gen.spanIDInc |= 1
469
470 config.Store(&Config{
471 DefaultSampler: ProbabilitySampler(defaultSamplingProbability),
472 IDGenerator: gen,
473 })
474}
475
476type defaultIDGenerator struct {
477 sync.Mutex
478
479 // Please keep these as the first fields
480 // so that these 8 byte fields will be aligned on addresses
481 // divisible by 8, on both 32-bit and 64-bit machines when
482 // performing atomic increments and accesses.
483 // See:
484 // * https://github.com/census-instrumentation/opencensus-go/issues/587
485 // * https://github.com/census-instrumentation/opencensus-go/issues/865
486 // * https://golang.org/pkg/sync/atomic/#pkg-note-BUG
487 nextSpanID uint64
488 spanIDInc uint64
489
490 traceIDAdd [2]uint64
491 traceIDRand *rand.Rand
492}
493
494// NewSpanID returns a non-zero span ID from a randomly-chosen sequence.
495func (gen *defaultIDGenerator) NewSpanID() [8]byte {
496 var id uint64
497 for id == 0 {
498 id = atomic.AddUint64(&gen.nextSpanID, gen.spanIDInc)
499 }
500 var sid [8]byte
501 binary.LittleEndian.PutUint64(sid[:], id)
502 return sid
503}
504
505// NewTraceID returns a non-zero trace ID from a randomly-chosen sequence.
506// mu should be held while this function is called.
507func (gen *defaultIDGenerator) NewTraceID() [16]byte {
508 var tid [16]byte
509 // Construct the trace ID from two outputs of traceIDRand, with a constant
510 // added to each half for additional entropy.
511 gen.Lock()
512 binary.LittleEndian.PutUint64(tid[0:8], gen.traceIDRand.Uint64()+gen.traceIDAdd[0])
513 binary.LittleEndian.PutUint64(tid[8:16], gen.traceIDRand.Uint64()+gen.traceIDAdd[1])
514 gen.Unlock()
515 return tid
516}
diff --git a/vendor/go.opencensus.io/trace/trace_go11.go b/vendor/go.opencensus.io/trace/trace_go11.go
new file mode 100644
index 0000000..b7d8aaf
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/trace_go11.go
@@ -0,0 +1,32 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// +build go1.11
16
17package trace
18
19import (
20 "context"
21 t "runtime/trace"
22)
23
24func startExecutionTracerTask(ctx context.Context, name string) (context.Context, func()) {
25 if !t.IsEnabled() {
26 // Avoid additional overhead if
27 // runtime/trace is not enabled.
28 return ctx, func() {}
29 }
30 nctx, task := t.NewTask(ctx, name)
31 return nctx, task.End
32}
diff --git a/vendor/go.opencensus.io/trace/trace_nongo11.go b/vendor/go.opencensus.io/trace/trace_nongo11.go
new file mode 100644
index 0000000..e254198
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/trace_nongo11.go
@@ -0,0 +1,25 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// +build !go1.11
16
17package trace
18
19import (
20 "context"
21)
22
23func startExecutionTracerTask(ctx context.Context, name string) (context.Context, func()) {
24 return ctx, func() {}
25}
diff --git a/vendor/go.opencensus.io/trace/tracestate/tracestate.go b/vendor/go.opencensus.io/trace/tracestate/tracestate.go
new file mode 100644
index 0000000..2d6c713
--- /dev/null
+++ b/vendor/go.opencensus.io/trace/tracestate/tracestate.go
@@ -0,0 +1,147 @@
1// Copyright 2018, OpenCensus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package tracestate implements support for the Tracestate header of the
16// W3C TraceContext propagation format.
17package tracestate
18
19import (
20 "fmt"
21 "regexp"
22)
23
24const (
25 keyMaxSize = 256
26 valueMaxSize = 256
27 maxKeyValuePairs = 32
28)
29
30const (
31 keyWithoutVendorFormat = `[a-z][_0-9a-z\-\*\/]{0,255}`
32 keyWithVendorFormat = `[a-z][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}`
33 keyFormat = `(` + keyWithoutVendorFormat + `)|(` + keyWithVendorFormat + `)`
34 valueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]`
35)
36
37var keyValidationRegExp = regexp.MustCompile(`^(` + keyFormat + `)$`)
38var valueValidationRegExp = regexp.MustCompile(`^(` + valueFormat + `)$`)
39
40// Tracestate represents tracing-system specific context in a list of key-value pairs. Tracestate allows different
41// vendors propagate additional information and inter-operate with their legacy Id formats.
42type Tracestate struct {
43 entries []Entry
44}
45
46// Entry represents one key-value pair in a list of key-value pair of Tracestate.
47type Entry struct {
48 // Key is an opaque string up to 256 characters printable. It MUST begin with a lowercase letter,
49 // and can only contain lowercase letters a-z, digits 0-9, underscores _, dashes -, asterisks *, and
50 // forward slashes /.
51 Key string
52
53 // Value is an opaque string up to 256 characters printable ASCII RFC0020 characters (i.e., the
54 // range 0x20 to 0x7E) except comma , and =.
55 Value string
56}
57
58// Entries returns a slice of Entry.
59func (ts *Tracestate) Entries() []Entry {
60 if ts == nil {
61 return nil
62 }
63 return ts.entries
64}
65
66func (ts *Tracestate) remove(key string) *Entry {
67 for index, entry := range ts.entries {
68 if entry.Key == key {
69 ts.entries = append(ts.entries[:index], ts.entries[index+1:]...)
70 return &entry
71 }
72 }
73 return nil
74}
75
76func (ts *Tracestate) add(entries []Entry) error {
77 for _, entry := range entries {
78 ts.remove(entry.Key)
79 }
80 if len(ts.entries)+len(entries) > maxKeyValuePairs {
81 return fmt.Errorf("adding %d key-value pairs to current %d pairs exceeds the limit of %d",
82 len(entries), len(ts.entries), maxKeyValuePairs)
83 }
84 ts.entries = append(entries, ts.entries...)
85 return nil
86}
87
88func isValid(entry Entry) bool {
89 return keyValidationRegExp.MatchString(entry.Key) &&
90 valueValidationRegExp.MatchString(entry.Value)
91}
92
93func containsDuplicateKey(entries ...Entry) (string, bool) {
94 keyMap := make(map[string]int)
95 for _, entry := range entries {
96 if _, ok := keyMap[entry.Key]; ok {
97 return entry.Key, true
98 }
99 keyMap[entry.Key] = 1
100 }
101 return "", false
102}
103
104func areEntriesValid(entries ...Entry) (*Entry, bool) {
105 for _, entry := range entries {
106 if !isValid(entry) {
107 return &entry, false
108 }
109 }
110 return nil, true
111}
112
113// New creates a Tracestate object from a parent and/or entries (key-value pair).
114// Entries from the parent are copied if present. The entries passed to this function
115// are inserted in front of those copied from the parent. If an entry copied from the
116// parent contains the same key as one of the entry in entries then the entry copied
117// from the parent is removed. See add func.
118//
119// An error is returned with nil Tracestate if
120// 1. one or more entry in entries is invalid.
121// 2. two or more entries in the input entries have the same key.
122// 3. the number of entries combined from the parent and the input entries exceeds maxKeyValuePairs.
123// (duplicate entry is counted only once).
124func New(parent *Tracestate, entries ...Entry) (*Tracestate, error) {
125 if parent == nil && len(entries) == 0 {
126 return nil, nil
127 }
128 if entry, ok := areEntriesValid(entries...); !ok {
129 return nil, fmt.Errorf("key-value pair {%s, %s} is invalid", entry.Key, entry.Value)
130 }
131
132 if key, duplicate := containsDuplicateKey(entries...); duplicate {
133 return nil, fmt.Errorf("contains duplicate keys (%s)", key)
134 }
135
136 tracestate := Tracestate{}
137
138 if parent != nil && len(parent.entries) > 0 {
139 tracestate.entries = append([]Entry{}, parent.entries...)
140 }
141
142 err := tracestate.add(entries)
143 if err != nil {
144 return nil, err
145 }
146 return &tracestate, nil
147}