* update vendor directory, add go.opencensus.io * update imports * oops * s/opentracing/opencensus/ & remove prometheus / zipkin stuff & remove old stats * the dep train rides again * fix gin build * deps from last guy * start in on the agent metrics * she builds * remove tags for now, cardinality error is fussing. subscribe instead of register * update to patched version of opencensus to proceed for now TODO switch to a release * meh fix imports * println debug the bad boys * lace it with the tags * update deps again * fix all inconsistent cardinality errors * add our own logger * fix init * fix oom measure * remove bugged removal code * fix s3 measures * fix prom handler nil
OpenCensus Libraries for Go
OpenCensus Go is a Go implementation of OpenCensus, a toolkit for collecting application performance and behavior monitoring data. Currently it consists of three major components: tags, stats, and tracing.
This project is still at a very early stage of development. The API is changing rapidly, vendoring is recommended.
Installation
$ go get -u go.opencensus.io/...
Prerequisites
OpenCensus Go libraries require Go 1.8 or later.
Exporters
OpenCensus can export instrumentation data to various backends. Currently, OpenCensus supports:
- Prometheus for stats
- OpenZipkin for traces
- Stackdriver Monitoring and Trace
- Jaeger for traces
Tags
Tags represent propagated key-value pairs. They are propagated using context.Context in the same process or can be encoded to be transmitted on the wire and decoded back to a tag.Map at the destination.
Getting a key by a name
A key is defined by its name. To use a key, a user needs to know its name and type.
// Get a key to represent user OS.
key, err := tag.NewKey("my.org/keys/user-os")
if err != nil {
log.Fatal(err)
}
Creating tags and propagating them
Package tag provides a builder to create tag maps and put it into the current context. To propagate a tag map to downstream methods and RPCs, New will add the produced tag map to the current context. If there is already a tag map in the current context, it will be replaced.
osKey, err := tag.NewKey("my.org/keys/user-os")
if err != nil {
log.Fatal(err)
}
userIDKey, err := tag.NewKey("my.org/keys/user-id")
if err != nil {
log.Fatal(err)
}
ctx, err = tag.New(ctx,
tag.Insert(osKey, "macOS-10.12.5"),
tag.Upsert(userIDKey, "cde36753ed"),
)
if err != nil {
log.Fatal(err)
}
Propagating a tag map in a context
If you have access to a tag.Map, you can also propagate it in the current context:
m := tag.FromContext(ctx)
In order to update existing tags from the current context, use New and pass the returned context.
ctx, err = tag.New(ctx,
tag.Insert(osKey, "macOS-10.12.5"),
tag.Upsert(userIDKey, "fff0989878"),
)
if err != nil {
log.Fatal(err)
}
Stats
Creating, retrieving and deleting a measure
Create and load measures with units:
videoSize, err := stats.Int64("my.org/video_size", "processed video size", "MB")
if err != nil {
log.Fatal(err)
}
Retrieve measure by name:
m := stats.FindMeasure("my.org/video_size")
if m == nil {
log.Fatalln("measure not found")
}
Creating an aggregation
Currently 4 types of aggregations are supported. The CountAggregation is used to count the number of times a sample was recorded. The DistributionAggregation is used to provide a histogram of the values of the samples. The SumAggregation is used to sum up all sample values. The MeanAggregation is used to calculate the mean of sample values.
distAgg := view.DistributionAggregation([]float64{0, 1 << 32, 2 << 32, 3 << 32})
countAgg := view.CountAggregation{}
sumAgg := view.SumAggregation{}
meanAgg := view.MeanAggregation{}
Creating, registering and unregistering a view
Create and register a view:
v, err := view.New(
"my.org/video_size_distribution",
"distribution of processed video size over time",
nil,
videoSize,
distAgg,
)
if err != nil {
log.Fatalf("cannot create view: %v", err)
}
if err := view.Register(v); err != nil {
log.Fatal(err)
}
Find view by name:
v = view.Find("my.org/video_size_distribution")
if v == nil {
log.Fatalln("view not found")
}
Unregister view:
if err = view.Unregister(v); err != nil {
log.Fatal(err)
}
Configure the default interval between reports of collected data. This is a system wide interval and impacts all views. The default interval duration is 10 seconds. Trying to set an interval with a duration less than a certain minimum (maybe 1s) should have no effect.
view.SetReportingPeriod(5 * time.Second)
Recording measurements
Recording usage can only be performed against already registered measure and their registered views. Measurements are implicitly tagged with the tags in the context:
stats.Record(ctx, videoSize.M(102478))
Retrieving collected data for a view
Users need to subscribe to a view in order to retrieve collected data.
if err := v.Subscribe(); err != nil {
log.Fatal(err)
}
Subscribed views' data will be exported via the registered exporters.
// Register an exporter to be able to retrieve
// the data from the subscribed views.
view.RegisterExporter(&exporter{})
An example logger exporter is below:
type exporter struct{}
func (e *exporter) ExportView(vd *view.Data) {
log.Println(vd)
}
Traces
Starting and ending a span
ctx, span := trace.StartSpan(ctx, "your choice of name")
defer span.End()
More tracing examples are coming soon...
Profiles
OpenCensus tags can be applied as profiler labels for users who are on Go 1.9 and above.
ctx, err = tag.New(ctx,
tag.Insert(osKey, "macOS-10.12.5"),
tag.Insert(userIDKey, "fff0989878"),
)
if err != nil {
log.Fatal(err)
}
tag.Do(ctx, func(ctx context.Context) {
// Do work.
// When profiling is on, samples will be
// recorded with the key/values from the tag map.
})
A screenshot of the CPU profile from the program above:
