mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2024-12-14 10:13:10 +02:00
144 lines
4.2 KiB
Go
144 lines
4.2 KiB
Go
|
// Copyright 2020, 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 transform provides translations for opentelemetry-go concepts and
|
||
|
// structures to otlp structures.
|
||
|
package transform
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
|
||
|
commonpb "github.com/open-telemetry/opentelemetry-proto/gen/go/common/v1"
|
||
|
metricpb "github.com/open-telemetry/opentelemetry-proto/gen/go/metrics/v1"
|
||
|
|
||
|
"go.opentelemetry.io/otel/api/core"
|
||
|
metricsdk "go.opentelemetry.io/otel/sdk/export/metric"
|
||
|
"go.opentelemetry.io/otel/sdk/export/metric/aggregator"
|
||
|
)
|
||
|
|
||
|
// ErrUnimplementedAgg is returned when a transformation of an unimplemented
|
||
|
// aggregator is attempted.
|
||
|
var ErrUnimplementedAgg = errors.New("unimplemented aggregator")
|
||
|
|
||
|
// Record transforms a Record into an OTLP Metric. An ErrUnimplementedAgg
|
||
|
// error is returned if the Record Aggregator is not supported.
|
||
|
func Record(r metricsdk.Record) (*metricpb.Metric, error) {
|
||
|
d := r.Descriptor()
|
||
|
l := r.Labels()
|
||
|
switch a := r.Aggregator().(type) {
|
||
|
case aggregator.MinMaxSumCount:
|
||
|
return minMaxSumCount(d, l, a)
|
||
|
case aggregator.Sum:
|
||
|
return sum(d, l, a)
|
||
|
}
|
||
|
return nil, ErrUnimplementedAgg
|
||
|
}
|
||
|
|
||
|
// sum transforms a Sum Aggregator into an OTLP Metric.
|
||
|
func sum(desc *metricsdk.Descriptor, labels metricsdk.Labels, a aggregator.Sum) (*metricpb.Metric, error) {
|
||
|
sum, err := a.Sum()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
m := &metricpb.Metric{
|
||
|
MetricDescriptor: &metricpb.MetricDescriptor{
|
||
|
Name: desc.Name(),
|
||
|
Description: desc.Description(),
|
||
|
Unit: string(desc.Unit()),
|
||
|
Labels: stringKeyValues(labels.Ordered()),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
switch n := desc.NumberKind(); n {
|
||
|
case core.Int64NumberKind, core.Uint64NumberKind:
|
||
|
m.MetricDescriptor.Type = metricpb.MetricDescriptor_COUNTER_INT64
|
||
|
m.Int64Datapoints = []*metricpb.Int64DataPoint{
|
||
|
{Value: sum.CoerceToInt64(n)},
|
||
|
}
|
||
|
case core.Float64NumberKind:
|
||
|
m.MetricDescriptor.Type = metricpb.MetricDescriptor_COUNTER_DOUBLE
|
||
|
m.DoubleDatapoints = []*metricpb.DoubleDataPoint{
|
||
|
{Value: sum.CoerceToFloat64(n)},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return m, nil
|
||
|
}
|
||
|
|
||
|
// minMaxSumCountValue returns the values of the MinMaxSumCount Aggregator
|
||
|
// as discret values.
|
||
|
func minMaxSumCountValues(a aggregator.MinMaxSumCount) (min, max, sum core.Number, count int64, err error) {
|
||
|
if min, err = a.Min(); err != nil {
|
||
|
return
|
||
|
}
|
||
|
if max, err = a.Max(); err != nil {
|
||
|
return
|
||
|
}
|
||
|
if sum, err = a.Sum(); err != nil {
|
||
|
return
|
||
|
}
|
||
|
if count, err = a.Count(); err != nil {
|
||
|
return
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// minMaxSumCount transforms a MinMaxSumCount Aggregator into an OTLP Metric.
|
||
|
func minMaxSumCount(desc *metricsdk.Descriptor, labels metricsdk.Labels, a aggregator.MinMaxSumCount) (*metricpb.Metric, error) {
|
||
|
min, max, sum, count, err := minMaxSumCountValues(a)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
numKind := desc.NumberKind()
|
||
|
return &metricpb.Metric{
|
||
|
MetricDescriptor: &metricpb.MetricDescriptor{
|
||
|
Name: desc.Name(),
|
||
|
Description: desc.Description(),
|
||
|
Unit: string(desc.Unit()),
|
||
|
Type: metricpb.MetricDescriptor_SUMMARY,
|
||
|
Labels: stringKeyValues(labels.Ordered()),
|
||
|
},
|
||
|
SummaryDatapoints: []*metricpb.SummaryDataPoint{
|
||
|
{
|
||
|
Count: uint64(count),
|
||
|
Sum: sum.CoerceToFloat64(numKind),
|
||
|
PercentileValues: []*metricpb.SummaryDataPoint_ValueAtPercentile{
|
||
|
{
|
||
|
Percentile: 0.0,
|
||
|
Value: min.CoerceToFloat64(numKind),
|
||
|
},
|
||
|
{
|
||
|
Percentile: 100.0,
|
||
|
Value: max.CoerceToFloat64(numKind),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
// stringKeyValues transforms a KeyValues into an OTLP StringKeyValues.
|
||
|
func stringKeyValues(kvs []core.KeyValue) []*commonpb.StringKeyValue {
|
||
|
result := make([]*commonpb.StringKeyValue, 0, len(kvs))
|
||
|
for _, kv := range kvs {
|
||
|
result = append(result, &commonpb.StringKeyValue{
|
||
|
Key: string(kv.Key),
|
||
|
Value: kv.Value.Emit(),
|
||
|
})
|
||
|
}
|
||
|
return result
|
||
|
}
|