Skip to content

Commit

Permalink
Add Aggregation/Temporality method to stdoutmetric
Browse files Browse the repository at this point in the history
  • Loading branch information
MrAlias committed Oct 4, 2022
1 parent 1a3c419 commit fc30414
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 2 deletions.
68 changes: 67 additions & 1 deletion exporters/stdout/stdoutmetric/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@ package stdoutmetric // import "go.opentelemetry.io/otel/exporters/stdout/stdout
import (
"encoding/json"
"os"

"go.opentelemetry.io/otel/internal/global"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/view"
)

// config contains options for the exporter.
type config struct {
encoder *encoderHolder
encoder *encoderHolder
temporalitySelector metric.TemporalitySelector
aggregationSelector metric.AggregationSelector
}

// newConfig creates a validated config configured with options.
Expand All @@ -36,6 +43,14 @@ func newConfig(options ...Option) config {
cfg.encoder = &encoderHolder{encoder: enc}
}

if cfg.temporalitySelector == nil {
cfg.temporalitySelector = metric.DefaultTemporalitySelector
}

if cfg.aggregationSelector == nil {
cfg.aggregationSelector = metric.DefaultAggregationSelector
}

return cfg
}

Expand All @@ -60,3 +75,54 @@ func WithEncoder(encoder Encoder) Option {
return c
})
}

// WithTemporalitySelector sets the TemporalitySelector the exporter will use
// to determine the Temporality of an instrument based on its kind. If this
// option is not used, the exporter will use the DefaultTemporalitySelector
// from the go.opentelemetry.io/otel/sdk/metric package.
func WithTemporalitySelector(selector metric.TemporalitySelector) Option {
return temporalitySelectorOption{selector: selector}
}

type temporalitySelectorOption struct {
selector metric.TemporalitySelector
}

func (t temporalitySelectorOption) apply(c config) config {
c.temporalitySelector = t.selector
return c
}

// WithAggregationSelector sets the AggregationSelector the exporter will use
// to determine the aggregation to use for an instrument based on its kind. If
// this option is not used, the exporter will use the
// DefaultAggregationSelector from the go.opentelemetry.io/otel/sdk/metric
// package or the aggregation explicitly passed for a view matching an
// instrument.
func WithAggregationSelector(selector metric.AggregationSelector) Option {
// Deep copy and validate before using.
wrapped := func(ik view.InstrumentKind) aggregation.Aggregation {
a := selector(ik)
cpA := a.Copy()
if err := cpA.Err(); err != nil {
cpA = metric.DefaultAggregationSelector(ik)
global.Error(
err, "using default aggregation instead",
"aggregation", a,
"replacement", cpA,
)
}
return cpA
}

return aggregationSelectorOption{selector: wrapped}
}

type aggregationSelectorOption struct {
selector metric.AggregationSelector
}

func (t aggregationSelectorOption) apply(c config) config {
c.aggregationSelector = t.selector
return c
}
18 changes: 17 additions & 1 deletion exporters/stdout/stdoutmetric/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,19 @@ import (
"sync/atomic"

"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
"go.opentelemetry.io/otel/sdk/metric/view"
)

// exporter is an OpenTelemetry metric exporter.
type exporter struct {
encVal atomic.Value // encoderHolder

shutdownOnce sync.Once

temporalitySelector metric.TemporalitySelector
aggregationSelector metric.AggregationSelector
}

// New returns a configured metric exporter.
Expand All @@ -36,11 +41,22 @@ type exporter struct {
// encoder with tab indentations that output to STDOUT.
func New(options ...Option) (metric.Exporter, error) {
cfg := newConfig(options...)
exp := &exporter{}
exp := &exporter{
temporalitySelector: cfg.temporalitySelector,
aggregationSelector: cfg.aggregationSelector,
}
exp.encVal.Store(*cfg.encoder)
return exp, nil
}

func (e *exporter) Temporality(k view.InstrumentKind) metricdata.Temporality {
return e.temporalitySelector(k)
}

func (e *exporter) Aggregation(k view.InstrumentKind) aggregation.Aggregation {
return e.aggregationSelector(k)
}

func (e *exporter) Export(ctx context.Context, data metricdata.ResourceMetrics) error {
select {
case <-ctx.Done():
Expand Down

0 comments on commit fc30414

Please sign in to comment.