-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Metrics proposal for Go #2
Changes from 7 commits
528d9c8
ecb6860
d17e9ae
1db27c8
d88ee56
8ef1a27
48032d7
4df8dd1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Copyright 2019, OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package metric | ||
|
||
type Float64AdditiveHandle struct { | ||
Handle | ||
} | ||
|
||
func NewFloat64Additive(name string, mos ...Option) *Float64AdditiveHandle { | ||
g := &Float64AdditiveHandle{} | ||
registerMetric(name, Additive, mos, &g.Handle) | ||
return g | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Copyright 2019, OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package aggregation | ||
|
||
//go:generate stringer -type=Operator | ||
type Operator int | ||
|
||
const ( | ||
NONE Operator = iota | ||
SUM | ||
COUNT | ||
MIN | ||
MAX | ||
LAST_VALUE | ||
DISTRIBUTION | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For a distribution if a histogram is used user requires to also configure the buckets. If a summary is used user requires to configure the percentiles. So I cannot see how this is used. |
||
) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,32 +18,51 @@ import ( | |
"context" | ||
|
||
"go.opentelemetry.io/api/core" | ||
"go.opentelemetry.io/api/metric/aggregation" | ||
"go.opentelemetry.io/api/registry" | ||
"go.opentelemetry.io/api/unit" | ||
) | ||
|
||
type MetricType int | ||
type Type int | ||
|
||
//go:generate stringer -type=Type | ||
const ( | ||
Invalid MetricType = iota | ||
Gauge // Supports Set() | ||
Cumulative // Supports Inc() | ||
Invalid Type = iota | ||
Gauge // Supports Set() | ||
Cumulative // Supports Inc(): only positive values | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cumulative also needs a set, because the classic example for this is CPU usage. If you want to report a CPU usage it is always going up (unless you do a CumulativeGauge that remembers the previous value and Inc delta). |
||
Additive // Supports Add(): positive or negative | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Additive and Gauge can be unified. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They could be. I was hoping to make there be a 1:1 mapping between measured value and the interpretation. If we decide to keep a Stats API (i.e., reject RFC 0003), then I feel strongly that the Metrics API should be layered on top of the Stats API, so there should be a 1:1 mapping from a metrics update into a lower-level stats measurement. If we combine Additive and Gauge, for example, then I need to know the kind of operation in order to interpret a statistic. By allowing the Additive and Gauge to be separate metric types, I can layer Metrics on top of Stats, because each Measure has only one kind. I.e., there's not a mixture of Set() and Add() calls in the same stream of measurements. |
||
Measure // Supports Record() | ||
) | ||
|
||
type Meter interface { | ||
// TODO more Metric types | ||
GetFloat64Gauge(ctx context.Context, gauge *Float64GaugeHandle, labels ...core.KeyValue) Float64Gauge | ||
GetFloat64Gauge(context.Context, *Float64GaugeHandle, ...core.KeyValue) Float64Gauge | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why a context in this case? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This allows context tags to be recorded, in case the SDK wants to do that. In addition, it allows us to associate the current active span with the measurement, which means we can reflect this metric update in the recorded span data, for example. |
||
GetFloat64Cumulative(context.Context, *Float64CumulativeHandle, ...core.KeyValue) Float64Cumulative | ||
GetFloat64Additive(context.Context, *Float64AdditiveHandle, ...core.KeyValue) Float64Additive | ||
GetFloat64Measure(context.Context, *Float64MeasureHandle, ...core.KeyValue) Float64Measure | ||
} | ||
|
||
type Float64Gauge interface { | ||
Set(ctx context.Context, value float64, labels ...core.KeyValue) | ||
} | ||
|
||
type Float64Cumulative interface { | ||
Inc(ctx context.Context, value float64, labels ...core.KeyValue) | ||
} | ||
|
||
type Float64Additive interface { | ||
Add(ctx context.Context, value float64, labels ...core.KeyValue) | ||
} | ||
|
||
type Float64Measure interface { | ||
Record(ctx context.Context, value float64, labels ...core.KeyValue) | ||
} | ||
|
||
type Handle struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is a Handle? why does this exist? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A handle is a common base type for any of the metrics. In this proposal, the only API difference between the metric types is the verb they use, the interpretation is left to the SDK. So the |
||
Variable registry.Variable | ||
|
||
Type MetricType | ||
Keys []core.Key | ||
Type Type | ||
Keys []core.Key | ||
Aggregation aggregation.Operator | ||
} | ||
|
||
type Option func(*Handle, *[]registry.Option) | ||
|
@@ -62,20 +81,25 @@ func WithUnit(unit unit.Unit) Option { | |
} | ||
} | ||
|
||
// WithKeys applies the provided dimension keys. | ||
// WithKeys applies recommended dimension keys. Multiple `WithKeys` | ||
// options accumulate. The keys specified in this way are taken as | ||
// the recommended aggregation keys for Gauge, Cumulative, and | ||
// Additive metrics. For Measure metrics, the keys recommended here | ||
// are taken as the default for aggregations. | ||
func WithKeys(keys ...core.Key) Option { | ||
return func(m *Handle, _ *[]registry.Option) { | ||
m.Keys = keys | ||
m.Keys = append(m.Keys, keys...) | ||
} | ||
} | ||
|
||
func (mtype MetricType) String() string { | ||
switch mtype { | ||
case Gauge: | ||
return "gauge" | ||
case Cumulative: | ||
return "cumulative" | ||
default: | ||
return "unknown" | ||
// WithAggregation applies a user-recommended aggregation to this | ||
// metric, useful particularly for Measure type metrics. | ||
func WithAggregation(aggr aggregation.Operator) Option { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not compatible with OpenCensus stats which is a primary requirement for this, because we need to not allow the instrumentation plugin to define the aggregation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not a definition. This is a recommendation. The SDK is not bound to follow this advice. If this value is not set, the default aggregation for MeasureMetrics is |
||
return func(m *Handle, _ *[]registry.Option) { | ||
m.Aggregation = aggr | ||
} | ||
} | ||
|
||
func (h Handle) Defined() bool { | ||
return h.Variable.Defined() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Copyright 2019, OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package metric | ||
|
||
type Float64CumulativeHandle struct { | ||
Handle | ||
} | ||
|
||
func NewFloat64Cumulative(name string, mos ...Option) *Float64CumulativeHandle { | ||
g := &Float64CumulativeHandle{} | ||
registerMetric(name, Cumulative, mos, &g.Handle) | ||
return g | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Copyright 2019, OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package metric | ||
|
||
type Float64MeasureHandle struct { | ||
Handle | ||
} | ||
|
||
func NewFloat64Measure(name string, mos ...Option) *Float64MeasureHandle { | ||
g := &Float64MeasureHandle{} | ||
registerMetric(name, Measure, mos, &g.Handle) | ||
return g | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why min/max? Where is this used?