Skip to content

Commit

Permalink
Merge pull request #172 from lightstep/alt_metrics_sdk/provider_review
Browse files Browse the repository at this point in the history
Add the MeterProvider and related packages for review LS-29752
  • Loading branch information
jmacd authored Jun 2, 2022
2 parents 4f10770 + d1ff7b3 commit fdc9e85
Show file tree
Hide file tree
Showing 31 changed files with 2,673 additions and 36 deletions.
23 changes: 17 additions & 6 deletions examples/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,29 @@ func main() {
ctx := context.Background()
meter := metricglobal.Meter("testing")

// This example shows 1 instrument each for (UpDown)?(SumObserver|Counter)
// The two monotonic instruments of these have a fixed rate of +1.
// The two non-monotonic instruments of these have a fixed rate of -1.
// There are 2 example ValueObserver instruments (one a Gaussian, one a Sine wave).
//
// TODO: ValueRecorder examples.
// This example shows 1 instrument each for synchronous and
// asynchronous Counter and UpDownCounter. The two monotonic
// instruments of these have a fixed rate of +1. The two
// non-monotonic instruments of these have a fixed rate of -1.
// There are 2 example Gauge instruments (one a Gaussian, one
// a Sine wave), and one Histogram.

c1, _ := meter.SyncInt64().Counter(prefix + "counter")
c2, _ := meter.SyncInt64().UpDownCounter(prefix + "updowncounter")
hist, _ := meter.SyncFloat64().Histogram(prefix + "histogram")
go func() {
for {
c1.Add(ctx, 1)
c2.Add(ctx, -1)

secs := float64(time.Now().UnixNano()) / float64(time.Second)
mult := math.Sin(secs / (40 * math.Pi))
mult *= mult

for i := 0; i < 10000; i++ {
hist.Record(ctx, mult*(100+rand.NormFloat64()*100))
}

time.Sleep(time.Second)
}
}()
Expand Down Expand Up @@ -114,6 +124,7 @@ func main() {
func(ctx context.Context) {
secs := float64(time.Now().UnixNano()) / float64(time.Second)

sineWave.Observe(ctx, math.Sin(secs/(50*math.Pi)), attribute.String("period", "fastest"))
sineWave.Observe(ctx, math.Sin(secs/(200*math.Pi)), attribute.String("period", "fast"))
sineWave.Observe(ctx, math.Sin(secs/(1000*math.Pi)), attribute.String("period", "regular"))
sineWave.Observe(ctx, math.Sin(secs/(5000*math.Pi)), attribute.String("period", "slow"))
Expand Down
21 changes: 16 additions & 5 deletions launcher/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,15 @@ func WithMetricReportingPeriod(p time.Duration) Option {
}
}

// WithMetricTemporalityPreference controls the temporality preference
// used for Counter and Histogram (only not for UpDownCounter, which
// ignores this preference for specified reasons).
func WithMetricTemporalityPreference(prefName string) Option {
return func(c *Config) {
c.MetricTemporalityPreference = prefName
}
}

// WithMetricEnabled configures whether metrics should be enabled
func WithMetricsEnabled(enabled bool) Option {
return func(c *Config) {
Expand Down Expand Up @@ -199,6 +208,7 @@ type Config struct {
LogLevel string `env:"OTEL_LOG_LEVEL,default=info"`
Propagators []string `env:"OTEL_PROPAGATORS,default=b3"`
MetricReportingPeriod string `env:"OTEL_EXPORTER_OTLP_METRIC_PERIOD,default=30s"`
MetricTemporalityPreference string `env:"OTEL_EXPORTER_OTLP_METRIC_TEMPORALITY_PREFERENCE,default=cumulative"`
ResourceAttributes map[string]string
Resource *resource.Resource
logger Logger
Expand Down Expand Up @@ -361,11 +371,12 @@ func setupMetrics(c Config) (func() error, error) {
return nil, nil
}
return pipelines.NewMetricsPipeline(pipelines.PipelineConfig{
Endpoint: c.MetricExporterEndpoint,
Insecure: c.MetricExporterEndpointInsecure,
Headers: c.Headers,
Resource: c.Resource,
ReportingPeriod: c.MetricReportingPeriod,
Endpoint: c.MetricExporterEndpoint,
Insecure: c.MetricExporterEndpointInsecure,
Headers: c.Headers,
Resource: c.Resource,
ReportingPeriod: c.MetricReportingPeriod,
TemporalityPreference: c.MetricTemporalityPreference,
})
}

Expand Down
6 changes: 6 additions & 0 deletions launcher/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ func TestDefaultConfig(t *testing.T) {
MetricExporterEndpointInsecure: false,
MetricReportingPeriod: "30s",
MetricsEnabled: true,
MetricTemporalityPreference: "cumulative",
LogLevel: "info",
Propagators: []string{"b3"},
Resource: resource.NewWithAttributes(semconv.SchemaURL, attributes...),
Expand Down Expand Up @@ -349,6 +350,7 @@ func TestEnvironmentVariables(t *testing.T) {
MetricExporterEndpoint: "metrics-url",
MetricExporterEndpointInsecure: true,
MetricReportingPeriod: "30s",
MetricTemporalityPreference: "delta",
LogLevel: "debug",
Propagators: []string{"b3", "w3c"},
Resource: resource.NewWithAttributes(semconv.SchemaURL, attributes...),
Expand All @@ -372,6 +374,7 @@ func TestConfigurationOverrides(t *testing.T) {
WithSpanExporterInsecure(false),
WithMetricExporterEndpoint("override-metrics-url"),
WithMetricExporterInsecure(false),
WithMetricTemporalityPreference("stateless"),
WithLogLevel("info"),
WithLogger(logger),
WithErrorHandler(handler),
Expand All @@ -395,6 +398,7 @@ func TestConfigurationOverrides(t *testing.T) {
MetricExporterEndpoint: "override-metrics-url",
MetricExporterEndpointInsecure: false,
MetricReportingPeriod: "30s",
MetricTemporalityPreference: "stateless",
Headers: map[string]string{"lightstep-access-token": "override-access-token"},
LogLevel: "info",
Propagators: []string{"b3"},
Expand Down Expand Up @@ -600,6 +604,7 @@ func setEnvironment() {
os.Setenv("OTEL_LOG_LEVEL", "debug")
os.Setenv("OTEL_PROPAGATORS", "b3,w3c")
os.Setenv("OTEL_RESOURCE_ATTRIBUTES", "service.name=test-service-name-b")
os.Setenv("OTEL_EXPORTER_OTLP_METRIC_TEMPORALITY_PREFERENCE", "delta")
os.Setenv("LS_METRICS_ENABLED", "false")
}

Expand All @@ -616,6 +621,7 @@ func unsetEnvironment() {
"OTEL_PROPAGATORS",
"OTEL_RESOURCE_ATTRIBUTES",
"OTEL_EXPORTER_OTLP_METRIC_PERIOD",
"OTEL_EXPORTER_OTLP_METRIC_TEMPORALITY_PREFERENCE",
"LS_METRICS_ENABLED",
}
for _, envvar := range vars {
Expand Down
59 changes: 59 additions & 0 deletions lightstep/sdk/metric/asyncinst.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// 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 metric // import "github.com/lightstep/otel-launcher-go/lightstep/sdk/metric"

import (
"go.opentelemetry.io/otel/metric/instrument"
"go.opentelemetry.io/otel/metric/instrument/asyncfloat64"
"go.opentelemetry.io/otel/metric/instrument/asyncint64"
"github.com/lightstep/otel-launcher-go/lightstep/sdk/metric/internal/asyncstate"
"github.com/lightstep/otel-launcher-go/lightstep/sdk/metric/number"
"github.com/lightstep/otel-launcher-go/lightstep/sdk/metric/sdkinstrument"
)

type (
asyncint64Instruments struct{ *meter }
asyncfloat64Instruments struct{ *meter }
)

func (i asyncint64Instruments) Counter(name string, opts ...instrument.Option) (asyncint64.Counter, error) {
inst, err := i.asynchronousInstrument(name, opts, number.Int64Kind, sdkinstrument.CounterObserverKind)
return asyncstate.NewObserver[int64, number.Int64Traits](inst), err
}

func (i asyncint64Instruments) UpDownCounter(name string, opts ...instrument.Option) (asyncint64.UpDownCounter, error) {
inst, err := i.asynchronousInstrument(name, opts, number.Int64Kind, sdkinstrument.UpDownCounterObserverKind)
return asyncstate.NewObserver[int64, number.Int64Traits](inst), err
}

func (i asyncint64Instruments) Gauge(name string, opts ...instrument.Option) (asyncint64.Gauge, error) {
inst, err := i.asynchronousInstrument(name, opts, number.Int64Kind, sdkinstrument.GaugeObserverKind)
return asyncstate.NewObserver[int64, number.Int64Traits](inst), err
}

func (f asyncfloat64Instruments) Counter(name string, opts ...instrument.Option) (asyncfloat64.Counter, error) {
inst, err := f.asynchronousInstrument(name, opts, number.Float64Kind, sdkinstrument.CounterObserverKind)
return asyncstate.NewObserver[float64, number.Float64Traits](inst), err
}

func (f asyncfloat64Instruments) UpDownCounter(name string, opts ...instrument.Option) (asyncfloat64.UpDownCounter, error) {
inst, err := f.asynchronousInstrument(name, opts, number.Float64Kind, sdkinstrument.UpDownCounterObserverKind)
return asyncstate.NewObserver[float64, number.Float64Traits](inst), err
}

func (f asyncfloat64Instruments) Gauge(name string, opts ...instrument.Option) (asyncfloat64.Gauge, error) {
inst, err := f.asynchronousInstrument(name, opts, number.Float64Kind, sdkinstrument.GaugeObserverKind)
return asyncstate.NewObserver[float64, number.Float64Traits](inst), err
}
92 changes: 92 additions & 0 deletions lightstep/sdk/metric/asyncinst_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// 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 metric

import (
"context"
"testing"
"time"

"github.com/lightstep/otel-launcher-go/lightstep/sdk/metric/aggregator/aggregation"
"github.com/lightstep/otel-launcher-go/lightstep/sdk/metric/aggregator/gauge"
"github.com/lightstep/otel-launcher-go/lightstep/sdk/metric/aggregator/sum"
"github.com/lightstep/otel-launcher-go/lightstep/sdk/metric/internal/test"
"github.com/lightstep/otel-launcher-go/lightstep/sdk/metric/number"
"github.com/lightstep/otel-launcher-go/lightstep/sdk/metric/sdkinstrument"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/instrument"
"go.opentelemetry.io/otel/sdk/resource"
)

func TestAsyncInsts(t *testing.T) {
rdr := NewManualReader("test")
res := resource.Empty()
provider := NewMeterProvider(WithReader(rdr), WithResource(res))

ci := must(provider.Meter("test").AsyncInt64().Counter("icount"))
cf := must(provider.Meter("test").AsyncFloat64().Counter("fcount"))
ui := must(provider.Meter("test").AsyncInt64().UpDownCounter("iupcount"))
uf := must(provider.Meter("test").AsyncFloat64().UpDownCounter("fupcount"))
gi := must(provider.Meter("test").AsyncInt64().Gauge("igauge"))
gf := must(provider.Meter("test").AsyncFloat64().Gauge("fgauge"))

attr := attribute.String("a", "B")

_ = provider.Meter("test").RegisterCallback([]instrument.Asynchronous{
ci, cf, ui, uf, gi, gf,
}, func(ctx context.Context) {
ci.Observe(ctx, 2, attr)
cf.Observe(ctx, 3, attr)
ui.Observe(ctx, 4, attr)
uf.Observe(ctx, 5, attr)
gi.Observe(ctx, 6, attr)
gf.Observe(ctx, 7, attr)
})

data := rdr.Produce(nil)
notime := time.Time{}
cumulative := aggregation.CumulativeTemporality

test.RequireEqualResourceMetrics(
t, data, res,
test.Scope(
test.Library("test"),
test.Instrument(
test.Descriptor("icount", sdkinstrument.CounterObserverKind, number.Int64Kind),
test.Point(notime, notime, sum.NewMonotonicInt64(2), cumulative, attr),
),
test.Instrument(
test.Descriptor("fcount", sdkinstrument.CounterObserverKind, number.Float64Kind),
test.Point(notime, notime, sum.NewMonotonicFloat64(3), cumulative, attr),
),
test.Instrument(
test.Descriptor("iupcount", sdkinstrument.UpDownCounterObserverKind, number.Int64Kind),
test.Point(notime, notime, sum.NewNonMonotonicInt64(4), cumulative, attr),
),
test.Instrument(
test.Descriptor("fupcount", sdkinstrument.UpDownCounterObserverKind, number.Float64Kind),
test.Point(notime, notime, sum.NewNonMonotonicFloat64(5), cumulative, attr),
),
test.Instrument(
test.Descriptor("igauge", sdkinstrument.GaugeObserverKind, number.Int64Kind),
test.Point(notime, notime, gauge.NewInt64(6), cumulative, attr),
),
test.Instrument(
test.Descriptor("fgauge", sdkinstrument.GaugeObserverKind, number.Float64Kind),
test.Point(notime, notime, gauge.NewFloat64(7), cumulative, attr),
),
),
)
}
Loading

0 comments on commit fdc9e85

Please sign in to comment.