Skip to content
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

Change resource.New() to use functional options; add builtin attributes for (host.*, telemetry.sdk.*) #1235

Merged
merged 16 commits into from
Oct 31, 2020
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased]

### Added

- Support for `resource.Configure()` to configure Resource with
automatic values for builtin semantic `telemetry.sdk.*` and
`host.name` conventions. (#1235)

### Changed

- Move the `go.opentelemetry.io/otel/api/trace` package into `go.opentelemetry.io/otel` with the following changes. (#1229)
Expand Down
2 changes: 1 addition & 1 deletion sdk/metric/benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func newFixture(b *testing.B) *benchFixture {
AggregatorSelector: processortest.AggregatorSelector(),
}

bf.accumulator = sdk.NewAccumulator(bf)
bf.accumulator = sdk.NewAccumulator(bf, nil)
bf.meter = metric.WrapMeterImpl(bf.accumulator, "benchmarks")
return bf
}
Expand Down
45 changes: 0 additions & 45 deletions sdk/metric/config.go

This file was deleted.

2 changes: 1 addition & 1 deletion sdk/metric/controller/pull/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func New(checkpointer export.Checkpointer, options ...Option) *Controller {
}
accum := sdk.NewAccumulator(
checkpointer,
sdk.WithResource(config.Resource),
config.Resource,
)
return &Controller{
accumulator: accum,
Expand Down
2 changes: 1 addition & 1 deletion sdk/metric/controller/push/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func New(checkpointer export.Checkpointer, exporter export.Exporter, opts ...Opt

impl := sdk.NewAccumulator(
checkpointer,
sdk.WithResource(c.Resource),
c.Resource,
)
return &Controller{
provider: registry.NewMeterProvider(impl),
Expand Down
2 changes: 1 addition & 1 deletion sdk/metric/correct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func newSDK(t *testing.T) (metric.Meter, *metricsdk.Accumulator, *correctnessPro
}
accum := metricsdk.NewAccumulator(
processor,
metricsdk.WithResource(testResource),
testResource,
)
meter := metric.WrapMeterImpl(accum, "test")
return meter, accum, processor
Expand Down
4 changes: 1 addition & 3 deletions sdk/metric/processor/processortest/test_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ func generateTestData(proc export.Processor) {
ctx := context.Background()
accum := metricsdk.NewAccumulator(
proc,
metricsdk.WithResource(
resource.New(label.String("R", "V")),
),
resource.New(label.String("R", "V")),
)
meter := metric.WrapMeterImpl(accum, "testing")

Expand Down
8 changes: 2 additions & 6 deletions sdk/metric/processor/reducer/reducer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,7 @@ func TestFilterProcessor(t *testing.T) {
)
accum := metricsdk.NewAccumulator(
reducer.New(testFilter{}, processorTest.Checkpointer(testProc)),
metricsdk.WithResource(
resource.New(label.String("R", "V")),
),
resource.New(label.String("R", "V")),
)
generateData(accum)

Expand All @@ -94,9 +92,7 @@ func TestFilterBasicProcessor(t *testing.T) {
basicProc := basic.New(processorTest.AggregatorSelector(), export.CumulativeExporter)
accum := metricsdk.NewAccumulator(
reducer.New(testFilter{}, basicProc),
metricsdk.WithResource(
resource.New(label.String("R", "V")),
),
resource.New(label.String("R", "V")),
)
exporter := processorTest.NewExporter(basicProc, label.DefaultEncoder())

Expand Down
9 changes: 2 additions & 7 deletions sdk/metric/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,16 +305,11 @@ func (s *syncInstrument) RecordOne(ctx context.Context, number api.Number, kvs [
// processor will call Collect() when it receives a request to scrape
// current metric values. A push-based processor should configure its
// own periodic collection.
func NewAccumulator(processor export.Processor, opts ...Option) *Accumulator {
c := &Config{}
for _, opt := range opts {
opt.Apply(c)
}

func NewAccumulator(processor export.Processor, resource *resource.Resource) *Accumulator {
jmacd marked this conversation as resolved.
Show resolved Hide resolved
return &Accumulator{
processor: processor,
asyncInstruments: internal.NewAsyncInstrumentState(),
resource: c.Resource,
resource: resource,
}
}

Expand Down
2 changes: 1 addition & 1 deletion sdk/metric/stress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ func stressTest(t *testing.T, impl testImpl) {
AggregatorSelector: processortest.AggregatorSelector(),
}
cc := concurrency()
sdk := NewAccumulator(fixture)
sdk := NewAccumulator(fixture, nil)
meter := metric.WrapMeterImpl(sdk, "stress_test")
fixture.wg.Add(cc + 1)

Expand Down
3 changes: 3 additions & 0 deletions sdk/resource/auto.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ func Detect(ctx context.Context, detectors ...Detector) (*Resource, error) {
var autoDetectedRes *Resource
var errInfo []string
for _, detector := range detectors {
if detector == nil {
continue
}
res, err := detector.Detect(ctx)
if err != nil {
errInfo = append(errInfo, err.Error())
Expand Down
49 changes: 49 additions & 0 deletions sdk/resource/builtin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright The 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 resource

import (
"context"
"os"

opentelemetry "go.opentelemetry.io/otel/sdk"
"go.opentelemetry.io/otel/semconv"
)

type (
TelemetrySDK struct{}
Host struct{}
jmacd marked this conversation as resolved.
Show resolved Hide resolved
)

var (
_ Detector = TelemetrySDK{}
_ Detector = Host{}
)

func (TelemetrySDK) Detect(context.Context) (*Resource, error) {
jmacd marked this conversation as resolved.
Show resolved Hide resolved
return New(
semconv.TelemetrySDKNameKey.String("opentelemetry-go"),
semconv.TelemetrySDKLanguageKey.String("go"),
semconv.TelemetrySDKVersionKey.String(opentelemetry.Version()),
), nil
}

func (Host) Detect(context.Context) (*Resource, error) {
hostname, err := os.Hostname()
if err != nil {
return nil, err
jmacd marked this conversation as resolved.
Show resolved Hide resolved
}
return New(semconv.HostNameKey.String(hostname)), nil
}
145 changes: 145 additions & 0 deletions sdk/resource/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Copyright The 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 resource

import (
"context"

"go.opentelemetry.io/otel/label"
)

// config contains configuration for an SDK.
jmacd marked this conversation as resolved.
Show resolved Hide resolved
type config struct {
// detectors that will be evaluated.
detectors []Detector

// telemetrySDK is used to specify non-default
// `telemetry.sdk.*` attributes.
telemetrySDK Detector

// HostResource is used to specify non-default `host.*`
// attributes.
host Detector

// FromEnv is used to specify non-default OTEL_RESOURCE_ATTRIBUTES
// attributes.
fromEnv Detector
}

// Option is the interface that applies a configuration option.
type Option interface {
// Apply sets the Option value of a config.
Apply(*config)
}

// WithAttributes adds attributes to the configured Resource.
func WithAttributes(attributes ...label.KeyValue) Option {
return WithDetectors(detectAttributes{attributes})
}

type detectAttributes struct {
attributes []label.KeyValue
}

func (d detectAttributes) Detect(context.Context) (*Resource, error) {
return New(d.attributes...), nil
}

// WithDetectors adds detectors to be evaluated for the configured resource.
func WithDetectors(detectors ...Detector) Option {
return detectorsOption{detectors}
}

type detectorsOption struct {
detectors []Detector
}

func (o detectorsOption) Apply(cfg *config) {
cfg.detectors = append(cfg.detectors, o.detectors...)
}

// WithTelemetrySDK overrides the builtin `telemetry.sdk.*`
// attributes. Use nil to disable these attributes entirely.
func WithTelemetrySDK(d Detector) Option {
return telemetrySDKOption{d}
}

type telemetrySDKOption struct {
Detector
}

func (o telemetrySDKOption) Apply(cfg *config) {
cfg.telemetrySDK = o.Detector
}

// WithHost overrides the builtin `host.*` attributes. Use nil to
// disable these attributes entirely.
func WithHost(d Detector) Option {
return hostOption{d}
}

type hostOption struct {
Detector
}

func (o hostOption) Apply(cfg *config) {
cfg.host = o.Detector
}

// WithFromEnv overrides the builtin detector for
// OTEL_RESOURCE_ATTRIBUTES. Use nil to disable environment checking.
func WithFromEnv(d Detector) Option {
return fromEnvOption{d}
}

type fromEnvOption struct {
Detector
}

func (o fromEnvOption) Apply(cfg *config) {
cfg.fromEnv = o.Detector
}

// WithNoBuiltin disables all the builtin detectors, including the
// telemetry.sdk.*, host.*, and the environment detector.
func WithNoBuiltin() Option {
jmacd marked this conversation as resolved.
Show resolved Hide resolved
return noBuiltinOption{}
}

type noBuiltinOption struct{}

func (o noBuiltinOption) Apply(cfg *config) {
cfg.host = nil
cfg.telemetrySDK = nil
cfg.fromEnv = nil
}

// Configure returns a Resource combined from the provided attributes,
// user-provided detectors and builtin detectors.
func Configure(ctx context.Context, opts ...Option) (*Resource, error) {
jmacd marked this conversation as resolved.
Show resolved Hide resolved
cfg := config{
telemetrySDK: TelemetrySDK{},
host: Host{},
fromEnv: FromEnv{},
}
for _, opt := range opts {
opt.Apply(&cfg)
}
detectors := append(
[]Detector{cfg.telemetrySDK, cfg.host, cfg.fromEnv},
cfg.detectors...,
)
return Detect(ctx, detectors...)
}
Loading