Coder Social home page Coder Social logo

census-instrumentation / opencensus-go Goto Github PK

View Code? Open in Web Editor NEW
2.0K 68.0 328.0 1.98 MB

A stats collection and distributed tracing framework

Home Page: http://opencensus.io

License: Apache License 2.0

Go 98.84% Shell 0.03% HTML 0.74% Makefile 0.39%
go stats trace monitoring cloud golang opencensus distributed-tracing prometheus jaegertracing

opencensus-go's Issues

Rename aggregations and windows

Aggregation implementations are using "Aggregation" as a prefix, Window implementations are using "Window" as a prefix. In Go, we prefer the natural language order.

Some example type names with the new order:

type CountAggregation struct{}
type DistributionAggregation struct{}

type SlidingTimeWindow struct {}
type SlidingCountWindow struct {}

exporter/stackdriver: distribution range is not allowed

Consider the following view:

        // Create view to see the processed video size cumulatively.
	view := stats.NewView(
		"my.org/views/video_size_cum",
		"processed video size over time",
		nil,
		videoSize,
		stats.DistributionAggregation([]float64{0, 1 << 16, 1 << 32}),
		stats.Cumulative{},
	)

While exporting, it errors with:

Wait longer than the reporting duration...
2017/11/21 13:45:34 Failed to export to Stackdriver Monitoring: rpc error: code = InvalidArgument desc = Field timeSeries[0].points[0].distributionValue.range is not allowed: Distribution range is not yet supported.

Support Go 1.6?

gRPC and AppEngine requires 1.6 support to be around for a little while. Support 1.6 by removing the sort.Slice and context package dependencies.

See also grpc/grpc-go#1603.

NewMap should take a context

We would like to avoid users accidentally dropping the tags in the current context. Make NewMap working against a context.Context rather than an initial tag.Map.

func NewMap(ctx context.Context, m ...Mutator)

Remove unnecessary constructors

There are lightweight types such as WindowSlidingTime, WindowSlidingCount, and WindowCumulative that are not complicated enough to require a constructor. Remove NewWindowCumulative and make the zero value useful, remove NewWindowSlidingCount and export fields on WindowSlidingCount, and remove NewWindowSlidingTime and export the fields of WindowSlidingTime.

/cc @hyangah @bogdandrutu

Provide composite gRPC stats handler

Provide a stats handler that does enables both stats and tracing. Users who prefer not to have both can depend on grpcstats and grpctrace packages individually.

Complicated sequence is required to collect data from views

Currently, in the stats package:

  • Views are required to be initialized, registered and subscribed to in order to collect data via exporters.
  • Views are also automatically registered if they are subscribed to after initialization.
  • Views are required to be initialized, registered and force collected in order to collect data via force collection.

This is a complicated sequence of actions required from the user and it is easy to get it wrong. It seems like registration can be handled as a part of subscription and force collection.

I am suggesting the following sequence instead:

  • Views are required to be initialized and subscribed to in order to collect data. If a view with the same name exists, subscription returns an error. Unsubscribe to free the name.
  • Views are required to be initialized and force collected from in order to collect data. If a view with the same name exists, force collection API returns an error. Stop force collection to free the name.

Thoughts?

/cc @dinooliva @bogdandrutu

Remove force collection

Force collection became identical to the subscription after subscription via channels is removed. Remove force collection related APIs.

stats: define Measurement as a struct

stats.Measurement is a value with a defined set of types, so it should be defined as a struct that can only be constructed inside the stats package, not as an interface with an unexported method.

Sketch:

type Measurement struct {
  m interface{} // one of *Float64Measure or *Int64Measure
  v interface{} // one of int64 or float64
}

Rename utility encoder/decoder

ToOrderedTagsSlice can be redesigned into:

func DecodeOrderedTags(buf []byte, keys []Key) []Tag

ToValuesString can be redesigned into:

func EncodeOrderedTags(set *Set, keys []Key) []byte

We should also consider whether we need to provide these utilities from the tags package.

Hide non-user facing testing utilities

ContainsRow and EqualRows are both utilities to support the stats package tests. Hide them from the user, given they will never be required by the end user.

Remove ValueAsString?

func (k *KeyString) ValueAsString(b []byte) string

is not accessing any of the Key fields and is doing a redundant job of casting a []byte into string.

/cc @acetechnologist

Provide View related APIs as View methods

Currently the stats API contains quite a few package-level APIs works primarily with a View instance.

func RegisterView(v View) error
func RetrieveData(v View) ([]*Row, error)
func StopForcedCollection(v View) error
func SubscribeToView(v View, c chan *ViewData) error
func UnregisterView(v View) error
func UnsubscribeFromView(v View, c chan *ViewData) error

They could instead accept a View as a receiver. There are two advantages: (a) some function names will be shorter because we will be able to drop the "View" suffix from their names, (b) godoc will render them under the View type and it is easy for their discoverability.

func (v View) Register() error
func (v View) RetrieveData() ([]*Row, error)
func (v View) StopForcedCollection() error
func (v View) Subscribe(c chan *ViewData) error
func (v View) Unregister() error
func (v View) Unsubscribe(c chan *ViewData) error

Happy to send a PR.

/cc @acetechnologist @bogdandrutu

Measures should return unit

All measure types need to be able to report their unit. Enforce measures to return a unit as string.

type Measure interface {
     Name() string
     Unit() string
}

tag: add pprof.Do equivalent to record profiler samples with a tag map

Add a pprof.Do like utility to record profiler samples with a given tag map. Do looks for the tags inside the given context and sets them as pprof labels. Any goroutine started in f needs to propagate the tag map via c in order to be able to keep setting the labels in the new goroutines.

func Do(ctx context.Context, m *Map, f func(c context.Context))

exporter/stackdriver: MetricDescriptor name should be under domain "custom.googleapis.com/opencensus/"

Thanks @bogdandrutu for catching this.

For the Stackdriver Stats exporter, the name of MetricDescriptor needs to be under "custom.googleapis.com/opencensus/". The format of the whole name should be String.format("projects/%s/metricDescriptors/custom.googleapis.com%%2Fopencensus%%2F%s", projectId, viewName.replace("/", "%2F")). Stackdriver might return a permission denied error if we don't follow the name convention.

See https://github.com/census-instrumentation/opencensus-java/pull/827/files#diff-d2886f5b11a5e3be7a00a8f5fff5a1f0R84 for changes to Java exporter. Also refer to https://cloud.google.com/monitoring/custom-metrics/creating-metrics#custom_metric_names.

Rename TagSet to Set

tags.TagSet is repeating the "tag" twice and we don't like to stuttering in Go. Rename it to Set.

exporter/stackdriver: missing distribution value for CountAggregation

Consider the following view:

        view := stats.NewView(
		"my.org/views/video_size_cum",
		"processed video size over time",
		nil,
		videoSize,
		stats.CountAggregation{},
		stats.Cumulative{},
	)

It fails with:

2017/11/21 14:52:52 Failed to export to Stackdriver Monitoring: rpc error: code = InvalidArgument desc = Request was missing field timeSeries[0].points[0].distributionValue.

Think about tags.Set design

It's unclear whether tags.Set is intended to be mutable or immutable. @rakyll mentioned wanting to hide the encoding details from the user, so I recommended the following:

type Set map[Key]Value

func (set Set) Copy() Set

type Value struct {
  b []byte
}

func StringValue(s string) Value {
  return Value{[]byte(s)}
}

func Int64Value(i int64) Value {
  return Value{[]byte{/* encode the int */}}
}

Introduce exporters

Rather than allowing users access to the low-level buffer, introduce exporters and report the view data via the registered ones.

// Exporter exports the collected records as view data.
type Exporter interface {
	Export(viewData *ViewData)
}

// RegisterExporter registers an exporter.
func RegisterExporter(name string, e Exporter)

// UnregisterExporter unregisters an exporter.
func UnregisterExporter(name string)

As a follow up, we also need a rethinking of the current subscription model. In order to access to the view data of a view, you currently need to subscribe to a view after it is registered globally. Regardless of the registration status, view data can still be collected by force collection. Instead of having both methods available, we should either allow users to force collect or subscribe but not both.

Rename AggregationValue to AggregationData

To be more consistent with the Java library, rename AggregationValue to AggregationData.

All types named after AggregationValue will also be renamed:

  • CountAggregationValue -> CountData
  • DistributionAggregationValue -> DistributionData

trace: reduce the number of the printing APIs

The trace package currently allows users to print in a few different ways:

func LazyPrint(ctx context.Context, str fmt.Stringer)
func LazyPrintWithAttributes(ctx context.Context, attributes []Attribute, str fmt.Stringer)
func LazyPrintf(ctx context.Context, format string, a ...interface{})
func LazyPrintfWithAttributes(ctx context.Context, attributes []Attribute, format string, a ...interface{})
func Print(ctx context.Context, str string)
func PrintWithAttributes(ctx context.Context, attributes []Attribute, str string)

Instead of giving users different combinations of these options, we should provide a printing entry type and allow user to provide their options via the new type.

type Entry struct {
	Text       fmt.Stringer
	Attributes []Attribute
}

func LazyPrint(ctx context.Context, e Entry)

Then, we can provide maybe one other option for convience:

func LazyPrintf(ctx context.Context, format string, a ...interface{})

Users who doesn't want lazy formatting can always implement their own fmt.Stringer to format it at the point LazyPrint is called.

/cc @jcd2 @bogdandrutu

FindX should return boolean rather than error

All FindX functions are looking for an item in the map and return and error if not found. We should instead return a boolean for the convince of the user to handle nonexistence cases.

func FindMeasure(name string) (m Measure, ok bool)

func FindView(name string) (v *View, ok bool)

exporter/stackdriver: creation fails with AlreadyExists for new metrics

Metrics description creation is failing with "AlreadyExists" if the metric descriptor is being created for the first time:

Wait longer than the reporting duration...
2017/11/21 15:03:27 Failed to export to Stackdriver Monitoring: rpc error: code = AlreadyExists desc = Errors during metric descriptor creation: {(metric: custom.googleapis.com/opencensus%2Fmy.org%2Fviews%2Fvideoooosizeovertime, error: The metric already exists.)}.

Finalize the case for typed keys

Tags allow typed keys such (e.g. StringKey) but there is interest to drop typed keys and have StringKey as the only option. Determine the future for the tag package and remove the unnecessary abstractions before freezing the APIs.

/cc @dinooliva

exporter/stackdriver: add labels

Metrics are uploaded without the recorded tags being attached as Stackdriver Monitoring labels. Fix the exporter by adding the labels.

Setup vanity import paths

To reduce to dependencies to a specific git provider and to enhance the the current long and noisy import path, setup a vanity URL for the package and enforce the vanity URL everywhere. The vanity URL is either going to be "go.opencensus.io" or "opencensus.io/go".

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.