]>
Commit | Line | Data |
---|---|---|
107c1cdb ND |
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 | ||
8 | OpenCensus Go is a Go implementation of OpenCensus, a toolkit for | |
9 | collecting application performance and behavior monitoring data. | |
10 | Currently it consists of three major components: tags, stats and tracing. | |
11 | ||
12 | ## Installation | |
13 | ||
14 | ``` | |
15 | $ go get -u go.opencensus.io | |
16 | ``` | |
17 | ||
18 | The API of this project is still evolving, see: [Deprecation Policy](#deprecation-policy). | |
19 | The use of vendoring or a dependency management tool is recommended. | |
20 | ||
21 | ## Prerequisites | |
22 | ||
23 | OpenCensus Go libraries require Go 1.8 or later. | |
24 | ||
25 | ## Getting Started | |
26 | ||
27 | The easiest way to get started using OpenCensus in your application is to use an existing | |
28 | integration 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 | ||
41 | If you're using a framework not listed here, you could either implement your own middleware for your | |
42 | framework or use [custom stats](#stats) and [spans](#spans) directly in your application. | |
43 | ||
44 | ## Exporters | |
45 | ||
46 | OpenCensus can export instrumentation data to various backends. | |
47 | OpenCensus has exporter implementations for the following, users | |
48 | can 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 | ||
65 | In a microservices environment, a user request may go through | |
66 | multiple services until there is a response. OpenCensus allows | |
67 | you to instrument your services and collect diagnostics data all | |
68 | through your services end-to-end. | |
69 | ||
70 | ## Tags | |
71 | ||
72 | Tags represent propagated key-value pairs. They are propagated using `context.Context` | |
73 | in the same process or can be encoded to be transmitted on the wire. Usually, this will | |
74 | be handled by an integration plugin, e.g. `ocgrpc.ServerHandler` and `ocgrpc.ClientHandler` | |
75 | for gRPC. | |
76 | ||
77 | Package `tag` allows adding or modifying tags in the current context. | |
78 | ||
79 | [embedmd]:# (internal/readme/tags.go new) | |
80 | ```go | |
81 | ctx, err = tag.New(ctx, | |
82 | tag.Insert(osKey, "macOS-10.12.5"), | |
83 | tag.Upsert(userIDKey, "cde36753ed"), | |
84 | ) | |
85 | if err != nil { | |
86 | log.Fatal(err) | |
87 | } | |
88 | ``` | |
89 | ||
90 | ## Stats | |
91 | ||
92 | OpenCensus is a low-overhead framework even if instrumentation is always enabled. | |
93 | In order to be so, it is optimized to make recording of data points fast | |
94 | and separate from the data aggregation. | |
95 | ||
96 | OpenCensus 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 | ||
103 | Measurements are data points associated with a measure. | |
104 | Recording implicitly tags the set of Measurements with the tags from the | |
105 | provided context: | |
106 | ||
107 | [embedmd]:# (internal/readme/stats.go record) | |
108 | ```go | |
109 | stats.Record(ctx, videoSize.M(102478)) | |
110 | ``` | |
111 | ||
112 | ### Views | |
113 | ||
114 | Views are how Measures are aggregated. You can think of them as queries over the | |
115 | set of recorded data points (measurements). | |
116 | ||
117 | Views have two parts: the tags to group by and the aggregation type used. | |
118 | ||
119 | Currently 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 | |
126 | distAgg := view.Distribution(0, 1<<32, 2<<32, 3<<32) | |
127 | countAgg := view.Count() | |
128 | sumAgg := view.Sum() | |
129 | ``` | |
130 | ||
131 | Here we create a view with the DistributionAggregation over our measure. | |
132 | ||
133 | [embedmd]:# (internal/readme/stats.go view) | |
134 | ```go | |
135 | if 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 | ||
145 | Register begins collecting data for the view. Registered views' data will be | |
146 | exported via the registered exporters. | |
147 | ||
148 | ## Traces | |
149 | ||
150 | A distributed trace tracks the progression of a single user request as | |
151 | it is handled by the services and processes that make up an application. | |
152 | Each step is called a span in the trace. Spans include metadata about the step, | |
153 | including especially the time spent in the step, called the span’s latency. | |
154 | ||
155 | Below you see a trace and several spans underneath it. | |
156 | ||
157 | ![Traces and spans](https://i.imgur.com/7hZwRVj.png) | |
158 | ||
159 | ### Spans | |
160 | ||
161 | Span is the unit step in a trace. Each span has a name, latency, status and | |
162 | additional metadata. | |
163 | ||
164 | Below we are starting a span for a cache read and ending it | |
165 | when we are done: | |
166 | ||
167 | [embedmd]:# (internal/readme/trace.go startend) | |
168 | ```go | |
169 | ctx, span := trace.StartSpan(ctx, "cache.Get") | |
170 | defer span.End() | |
171 | ||
172 | // Do work to get from cache. | |
173 | ``` | |
174 | ||
175 | ### Propagation | |
176 | ||
177 | Spans can have parents or can be root spans if they don't have any parents. | |
178 | The current span is propagated in-process and across the network to allow associating | |
179 | new child spans with the parent. | |
180 | ||
181 | In the same process, `context.Context` is used to propagate spans. | |
182 | `trace.StartSpan` creates a new span as a root if the current context | |
183 | doesn't contain a span. Or, it creates a child of the span that is | |
184 | already in current context. The returned context can be used to keep | |
185 | propagating the newly created span in the current context. | |
186 | ||
187 | [embedmd]:# (internal/readme/trace.go startend) | |
188 | ```go | |
189 | ctx, span := trace.StartSpan(ctx, "cache.Get") | |
190 | defer span.End() | |
191 | ||
192 | // Do work to get from cache. | |
193 | ``` | |
194 | ||
195 | Across the network, OpenCensus provides different propagation | |
196 | methods 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 | ||
205 | With Go 1.11, OpenCensus Go will support integration with the Go execution tracer. | |
206 | See [Debugging Latency in Go](https://medium.com/observability/debugging-latency-in-go-1-11-9f97a7910d68) | |
207 | for an example of their mutual use. | |
208 | ||
209 | ## Profiles | |
210 | ||
211 | OpenCensus tags can be applied as profiler labels | |
212 | for users who are on Go 1.9 and above. | |
213 | ||
214 | [embedmd]:# (internal/readme/tags.go profiler) | |
215 | ```go | |
216 | ctx, err = tag.New(ctx, | |
217 | tag.Insert(osKey, "macOS-10.12.5"), | |
218 | tag.Insert(userIDKey, "fff0989878"), | |
219 | ) | |
220 | if err != nil { | |
221 | log.Fatal(err) | |
222 | } | |
223 | tag.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 | ||
230 | A screenshot of the CPU profile from the program above: | |
231 | ||
232 | ![CPU profile](https://i.imgur.com/jBKjlkw.png) | |
233 | ||
234 | ## Deprecation Policy | |
235 | ||
236 | Before version 1.0.0, the following deprecation policy will be observed: | |
237 | ||
238 | No backwards-incompatible changes will be made except for the removal of symbols that have | |
239 | been marked as *Deprecated* for at least one minor release (e.g. 0.9.0 to 0.10.0). A release | |
240 | removing the *Deprecated* functionality will be made no sooner than 28 days after the first | |
241 | release 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 |