diff --git a/exporter/stackdriver/stats.go b/exporter/stackdriver/stats.go index c34eeff9774..cead12f4ffe 100644 --- a/exporter/stackdriver/stats.go +++ b/exporter/stackdriver/stats.go @@ -241,7 +241,7 @@ func (e *statsExporter) createMeasure(ctx context.Context, vd *view.Data) error viewName := vd.View.Name if md, ok := e.createdViews[viewName]; ok { - return equalAggTagKeys(md, agg, tagKeys) + return equalMeasureAggTagKeys(md, m, agg, tagKeys) } metricType := namespacedViewName(viewName) @@ -264,7 +264,12 @@ func (e *statsExporter) createMeasure(ctx context.Context, vd *view.Data) error case view.AggTypeDistribution: valueType = metricpb.MetricDescriptor_DISTRIBUTION case view.AggTypeLastValue: - valueType = metricpb.MetricDescriptor_DOUBLE + switch m.(type) { + case *stats.Int64Measure: + valueType = metricpb.MetricDescriptor_INT64 + case *stats.Float64Measure: + valueType = metricpb.MetricDescriptor_DOUBLE + } default: return fmt.Errorf("unsupported aggregation type: %s", agg.Type.String()) } @@ -351,9 +356,16 @@ func newTypedValue(vd *view.View, r *view.Row) *monitoringpb.TypedValue { }, }} case *view.LastValueData: - return &monitoringpb.TypedValue{Value: &monitoringpb.TypedValue_DoubleValue{ - DoubleValue: v.Value, - }} + switch vd.Measure.(type) { + case *stats.Int64Measure: + return &monitoringpb.TypedValue{Value: &monitoringpb.TypedValue_Int64Value{ + Int64Value: int64(v.Value), + }} + case *stats.Float64Measure: + return &monitoringpb.TypedValue{Value: &monitoringpb.TypedValue_DoubleValue{ + DoubleValue: v.Value, + }} + } } return nil } @@ -388,12 +400,18 @@ func newLabelDescriptors(keys []tag.Key) []*labelpb.LabelDescriptor { return labelDescriptors } -func equalAggTagKeys(md *metricpb.MetricDescriptor, agg *view.Aggregation, keys []tag.Key) error { +func equalMeasureAggTagKeys(md *metricpb.MetricDescriptor, m stats.Measure, agg *view.Aggregation, keys []tag.Key) error { var aggTypeMatch bool switch md.ValueType { case metricpb.MetricDescriptor_INT64: - aggTypeMatch = agg.Type == view.AggTypeCount || agg.Type == view.AggTypeSum + if _, ok := m.(*stats.Int64Measure); !ok { + return fmt.Errorf("stackdriver metric descriptor was not created as int64") + } + aggTypeMatch = agg.Type == view.AggTypeCount || agg.Type == view.AggTypeSum || agg.Type == view.AggTypeLastValue case metricpb.MetricDescriptor_DOUBLE: + if _, ok := m.(*stats.Float64Measure); !ok { + return fmt.Errorf("stackdriver metric descriptor was not created as double") + } aggTypeMatch = agg.Type == view.AggTypeSum || agg.Type == view.AggTypeLastValue case metricpb.MetricDescriptor_DISTRIBUTION: aggTypeMatch = agg.Type == view.AggTypeDistribution diff --git a/exporter/stackdriver/stats_test.go b/exporter/stackdriver/stats_test.go index 0e5bc2f546c..e4708476fcd 100644 --- a/exporter/stackdriver/stats_test.go +++ b/exporter/stackdriver/stats_test.go @@ -418,6 +418,7 @@ func TestEqualAggWindowTagKeys(t *testing.T) { tests := []struct { name string md *metricpb.MetricDescriptor + m stats.Measure agg *view.Aggregation keys []tag.Key wantErr bool @@ -429,6 +430,7 @@ func TestEqualAggWindowTagKeys(t *testing.T) { ValueType: metricpb.MetricDescriptor_INT64, Labels: []*label.LabelDescriptor{{Key: opencensusTaskKey}}, }, + m: stats.Int64("name", "", ""), agg: view.Count(), wantErr: false, }, @@ -439,6 +441,7 @@ func TestEqualAggWindowTagKeys(t *testing.T) { ValueType: metricpb.MetricDescriptor_DOUBLE, Labels: []*label.LabelDescriptor{{Key: opencensusTaskKey}}, }, + m: stats.Float64("name", "", ""), agg: view.Sum(), wantErr: false, }, @@ -449,6 +452,7 @@ func TestEqualAggWindowTagKeys(t *testing.T) { ValueType: metricpb.MetricDescriptor_INT64, Labels: []*label.LabelDescriptor{{Key: opencensusTaskKey}}, }, + m: stats.Int64("name", "", ""), agg: view.Sum(), wantErr: false, }, @@ -459,19 +463,43 @@ func TestEqualAggWindowTagKeys(t *testing.T) { ValueType: metricpb.MetricDescriptor_DOUBLE, Labels: []*label.LabelDescriptor{{Key: opencensusTaskKey}}, }, + m: stats.Float64("name", "", ""), agg: view.LastValue(), wantErr: false, }, { - name: "distribution agg - mismatch", + name: "last value agg int64", + md: &metricpb.MetricDescriptor{ + MetricKind: metricpb.MetricDescriptor_CUMULATIVE, + ValueType: metricpb.MetricDescriptor_INT64, + Labels: []*label.LabelDescriptor{{Key: opencensusTaskKey}}, + }, + m: stats.Int64("name", "", ""), + agg: view.LastValue(), + wantErr: false, + }, + { + name: "distribution - mismatch", md: &metricpb.MetricDescriptor{ MetricKind: metricpb.MetricDescriptor_CUMULATIVE, ValueType: metricpb.MetricDescriptor_DISTRIBUTION, Labels: []*label.LabelDescriptor{{Key: opencensusTaskKey}}, }, + m: stats.Int64("name", "", ""), agg: view.Count(), wantErr: true, }, + { + name: "last value - measure mismatch", + md: &metricpb.MetricDescriptor{ + MetricKind: metricpb.MetricDescriptor_CUMULATIVE, + ValueType: metricpb.MetricDescriptor_INT64, + Labels: []*label.LabelDescriptor{{Key: opencensusTaskKey}}, + }, + m: stats.Float64("name", "", ""), + agg: view.LastValue(), + wantErr: true, + }, { name: "distribution agg with keys", md: &metricpb.MetricDescriptor{ @@ -483,6 +511,7 @@ func TestEqualAggWindowTagKeys(t *testing.T) { {Key: opencensusTaskKey}, }, }, + m: stats.Int64("name", "", ""), agg: view.Distribution(), keys: []tag.Key{key1, key2}, wantErr: false, @@ -493,6 +522,7 @@ func TestEqualAggWindowTagKeys(t *testing.T) { MetricKind: metricpb.MetricDescriptor_CUMULATIVE, ValueType: metricpb.MetricDescriptor_DISTRIBUTION, }, + m: stats.Int64("name", "", ""), agg: view.Distribution(), keys: []tag.Key{key1, key2}, wantErr: true, @@ -504,13 +534,14 @@ func TestEqualAggWindowTagKeys(t *testing.T) { ValueType: metricpb.MetricDescriptor_INT64, Labels: []*label.LabelDescriptor{{Key: opencensusTaskKey}}, }, + m: stats.Int64("name", "", ""), agg: view.Count(), wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := equalAggTagKeys(tt.md, tt.agg, tt.keys) + err := equalMeasureAggTagKeys(tt.md, tt.m, tt.agg, tt.keys) if err != nil && !tt.wantErr { t.Errorf("equalAggTagKeys() = %q; want no error", err) }