Skip to content
This repository has been archived by the owner on Jul 31, 2023. It is now read-only.

Add metric API #975

Merged
merged 2 commits into from
Nov 20, 2018
Merged

Conversation

semistrict
Copy link
Contributor

No description provided.

@semistrict
Copy link
Contributor Author

The follow-ups are here: https://github.com/ramonza/opencensus-go/pulls

@semistrict
Copy link
Contributor Author

@rakyll split up the PR, PTAL

func NewRegistry() *Registry {
m := &Registry{
sources: make(map[*uintptr]Producer),
ind: 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused remainder from before the uintptr trick :)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup!

Copy link
Contributor

@rakyll rakyll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few high level comments.

metric/doc.go Outdated

// Package metric contains a data model and exporter support for metrics.
// The data model is derived from the metric protocol buffers:
// https://github.com/census-instrumentation/opencensus-proto/blob/master/src/opencensus/proto/metrics/v1/metrics.proto
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User doesn't have to know about the proto, please remove this.


// LabelValue represents the value of a label. A missing value (nil) is distinct
// from an empty string value.
type LabelValue *string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a unlikely type. Why not simply type LabelValue { Value string }?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention here is to be able to represent no value (nil) and empty string value distinctly. The protobuf does this, so we need to as well to be compatible. Using a type like you suggest would not allow us to represent these two distinctly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Protobuf types are not an idiomatic due to the limitations and code-generation nature of the problem. In handcrafted libraries, we are doing better than proto.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We proposed to replace with this with struct { Value string, HasValue bool } to differentiate between "missing" and an empty string value.

// from an empty string value.
type LabelValue *string

// NewLabelValue creates a new non-nil LabelValue that represents the given string.
Copy link
Contributor

@rakyll rakyll Nov 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This becomes if the type changes.

LabelValue{ Value: "val" } would just work.

metric/point.go Outdated
// [0, bucket_bounds[i]) for i == 0
// [bucket_bounds[i-1], bucket_bounds[i]) for 0 < i < N-1
// [bucket_bounds[i-1], +infinity) for i == N-1
ExplicitBoundaries []float64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just Boundaries?

metric/point.go Outdated
)

// NewDoublePoint creates a new Point holding a float64 value.
func NewDoublePoint(t time.Time, val float64) Point {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NewFloat64Point

m.mu.Lock()
defer m.mu.Unlock()
if source == m {
panic("attempt to add registry to itself")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this statically possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*Registry implements Producer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The question is it might be broken to make Registry implementing Read() []*Metric.

Can't we make it implement ReadAll() []*Metric to differentiate it from the producers? Otherwise, we should introduce a MultiProducer a la io.MultiReader instead of this type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will rename

metric/metric.go Outdated
// Metric represents a quantity measured against a resource with different
// label value combinations.
type Metric struct {
Descriptor *Descriptor // metric descriptor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Descriptor Descriptor

No need for a pointer.

// value of this point.
// Consumers of Point should use this in preference to switching on the type
// of the value directly, since new value types may be added.
func (p Point) ReadValue(vv ValueVisitor) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something that exporters would use? If yes, maybe we shouldn't have it in this package.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is. This whole package is mostly for use by exporters.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any end to end example usage for the new APIs here? It is not clear what the package is for. If it is mainly for the exporters, we shouldn't use a top-level package like "metric" where we would like to put the developer-facing APIs to.

@@ -0,0 +1,11 @@
package metric
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing license.

@@ -0,0 +1,29 @@
package metric
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing license.

@semistrict
Copy link
Contributor Author

Updated @rakyll @rghetia PTAL

@rghetia
Copy link
Contributor

rghetia commented Nov 20, 2018

LGTM

@semistrict semistrict merged commit a91cf18 into census-instrumentation:master Nov 20, 2018
rakyll added a commit to rakyll/opencensus-go that referenced this pull request Nov 21, 2018
This reverts commit a91cf18.

The API was merged without an API review.
rakyll added a commit that referenced this pull request Nov 21, 2018
This reverts commit a91cf18.

The API was merged without an API review.
Copy link
Contributor

@rakyll rakyll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted this change because they are open issues, and left some more comments. 296c89c

Please provide a few end to end examples so we can see the call sites. We can discuss the APIs on a design doc if it works better.


// LabelValue represents the value of a label. A missing value (nil) is distinct
// from an empty string value.
type LabelValue *string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Protobuf types are not an idiomatic due to the limitations and code-generation nature of the problem. In handcrafted libraries, we are doing better than proto.

m.mu.Lock()
defer m.mu.Unlock()
if source == m {
panic("attempt to add registry to itself")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The question is it might be broken to make Registry implementing Read() []*Metric.

Can't we make it implement ReadAll() []*Metric to differentiate it from the producers? Otherwise, we should introduce a MultiProducer a la io.MultiReader instead of this type.

// rely on the DefaultRegistry.
type Registry struct {
mu sync.RWMutex
sources map[*uintptr]Producer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In what case? Also why a pointer to uintptr?

// value of this point.
// Consumers of Point should use this in preference to switching on the type
// of the value directly, since new value types may be added.
func (p Point) ReadValue(vv ValueVisitor) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any end to end example usage for the new APIs here? It is not clear what the package is for. If it is mainly for the exporters, we shouldn't use a top-level package like "metric" where we would like to put the developer-facing APIs to.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants