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

Support a single Resource per MeterProvider in the SDK #2120

Merged
merged 24 commits into from
Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

### Changed

- The Metrics SDK export record no longer contains a Resource pointer, the SDK `Export()` function for push-based exporters now takes a single Resource argument, pull-based exporters use `controller.Resource()`. (#2120)
jmacd marked this conversation as resolved.
Show resolved Hide resolved

### Deprecated

### Removed
Expand All @@ -20,6 +22,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

### Fixed

- The Metric SDK controller constructor does not automatically merge `resource.Environment()`. Multiple calls to `WithResource()` are handled correctly, and when no resources are provided `resource.Default()` is used. (#2120)

### Security

## [v1.0.0-RC2] - 2021-07-26
Expand Down
9 changes: 6 additions & 3 deletions bridge/opencensus/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ type exporter struct {

// ExportMetrics implements the OpenCensus metric Exporter interface
func (e *exporter) ExportMetrics(ctx context.Context, metrics []*metricdata.Metric) error {
return e.base.Export(ctx, &checkpointSet{metrics: metrics})
res := resource.Empty()
if len(metrics) != 0 {
res = convertResource(metrics[0].Resource)
}
return e.base.Export(ctx, res, &checkpointSet{metrics: metrics})
}

type checkpointSet struct {
Expand All @@ -68,7 +72,6 @@ func (d *checkpointSet) ForEach(exporter export.ExportKindSelector, f func(expor
otel.Handle(err)
continue
}
res := convertResource(m.Resource)
for _, ts := range m.TimeSeries {
if len(ts.Points) == 0 {
continue
Expand All @@ -86,7 +89,6 @@ func (d *checkpointSet) ForEach(exporter export.ExportKindSelector, f func(expor
if err := f(export.NewRecord(
&descriptor,
&ls,
res,
agg,
ts.StartTime,
agg.end(),
Expand Down Expand Up @@ -118,6 +120,7 @@ func convertLabels(keys []metricdata.LabelKey, values []metricdata.LabelValue) (
}

// convertResource converts an OpenCensus Resource to an OpenTelemetry Resource
// Note: the ocresource.Resource Type field is not used.
func convertResource(res *ocresource.Resource) *resource.Resource {
labels := []attribute.KeyValue{}
if res == nil {
Expand Down
28 changes: 19 additions & 9 deletions bridge/opencensus/exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ import (

type fakeExporter struct {
export.Exporter
records []export.Record
err error
records []export.Record
resource *resource.Resource
err error
}

func (f *fakeExporter) Export(ctx context.Context, cps exportmetric.CheckpointSet) error {
func (f *fakeExporter) Export(ctx context.Context, res *resource.Resource, cps exportmetric.CheckpointSet) error {
return cps.ForEach(f, func(record exportmetric.Record) error {
f.resource = res
f.records = append(f.records, record)
return f.err
})
Expand Down Expand Up @@ -81,6 +83,7 @@ func TestExportMetrics(t *testing.T) {
input []*metricdata.Metric
exportErr error
expected []export.Record
expectedResource *resource.Resource
expectedHandledError error
}{
{
Expand Down Expand Up @@ -141,6 +144,12 @@ func TestExportMetrics(t *testing.T) {
desc: "success",
input: []*metricdata.Metric{
{
Resource: &ocresource.Resource{
Labels: map[string]string{
"R1": "V1",
"R2": "V2",
},
},
TimeSeries: []*metricdata.TimeSeries{
{
StartTime: now,
Expand All @@ -151,11 +160,14 @@ func TestExportMetrics(t *testing.T) {
},
},
},
expectedResource: resource.NewSchemaless(
attribute.String("R1", "V1"),
attribute.String("R2", "V2"),
),
expected: []export.Record{
export.NewRecord(
&basicDesc,
attribute.EmptySet(),
resource.NewSchemaless(),
&ocExactAggregator{
points: []aggregation.Point{
{
Expand Down Expand Up @@ -187,7 +199,6 @@ func TestExportMetrics(t *testing.T) {
export.NewRecord(
&basicDesc,
attribute.EmptySet(),
resource.NewSchemaless(),
&ocExactAggregator{
points: []aggregation.Point{
{
Expand Down Expand Up @@ -222,7 +233,6 @@ func TestExportMetrics(t *testing.T) {
export.NewRecord(
&basicDesc,
attribute.EmptySet(),
resource.NewSchemaless(),
&ocExactAggregator{
points: []aggregation.Point{
{
Expand Down Expand Up @@ -254,16 +264,16 @@ func TestExportMetrics(t *testing.T) {
if len(tc.expected) != len(output) {
t.Fatalf("ExportMetrics(%+v) = %d records, want %d records", tc.input, len(output), len(tc.expected))
}
if fakeExporter.resource.String() != tc.expectedResource.String() {
t.Errorf("ExportMetrics(%+v)[i].Resource() = %+v, want %+v", tc.input, fakeExporter.resource.String(), tc.expectedResource.String())
}
for i, expected := range tc.expected {
if output[i].StartTime() != expected.StartTime() {
t.Errorf("ExportMetrics(%+v)[i].StartTime() = %+v, want %+v", tc.input, output[i].StartTime(), expected.StartTime())
}
if output[i].EndTime() != expected.EndTime() {
t.Errorf("ExportMetrics(%+v)[i].EndTime() = %+v, want %+v", tc.input, output[i].EndTime(), expected.EndTime())
}
if output[i].Resource().String() != expected.Resource().String() {
t.Errorf("ExportMetrics(%+v)[i].Resource() = %+v, want %+v", tc.input, output[i].Resource().String(), expected.Resource().String())
}
if output[i].Descriptor().Name() != expected.Descriptor().Name() {
t.Errorf("ExportMetrics(%+v)[i].Descriptor() = %+v, want %+v", tc.input, output[i].Descriptor().Name(), expected.Descriptor().Name())
}
Expand Down
5 changes: 3 additions & 2 deletions exporters/otlp/otlpmetric/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"go.opentelemetry.io/otel/metric"
metricsdk "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/resource"
)

var (
Expand All @@ -42,8 +43,8 @@ type Exporter struct {
}

// Export exports a batch of metrics.
func (e *Exporter) Export(ctx context.Context, checkpointSet metricsdk.CheckpointSet) error {
rms, err := metrictransform.CheckpointSet(ctx, e, checkpointSet, 1)
func (e *Exporter) Export(ctx context.Context, res *resource.Resource, checkpointSet metricsdk.CheckpointSet) error {
rms, err := metrictransform.CheckpointSet(ctx, e, res, checkpointSet, 1)
if err != nil {
return err
}
Expand Down
Loading