// Copyright 2019, OpenCensus 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 view import ( "time" "go.opencensus.io/resource" "go.opencensus.io/metric/metricdata" "go.opencensus.io/stats" ) func getUnit(unit string) metricdata.Unit { switch unit { case "1": return metricdata.UnitDimensionless case "ms": return metricdata.UnitMilliseconds case "By": return metricdata.UnitBytes } return metricdata.UnitDimensionless } func getType(v *View) metricdata.Type { m := v.Measure agg := v.Aggregation switch agg.Type { case AggTypeSum: switch m.(type) { case *stats.Int64Measure: return metricdata.TypeCumulativeInt64 case *stats.Float64Measure: return metricdata.TypeCumulativeFloat64 default: panic("unexpected measure type") } case AggTypeDistribution: return metricdata.TypeCumulativeDistribution case AggTypeLastValue: switch m.(type) { case *stats.Int64Measure: return metricdata.TypeGaugeInt64 case *stats.Float64Measure: return metricdata.TypeGaugeFloat64 default: panic("unexpected measure type") } case AggTypeCount: switch m.(type) { case *stats.Int64Measure: return metricdata.TypeCumulativeInt64 case *stats.Float64Measure: return metricdata.TypeCumulativeInt64 default: panic("unexpected measure type") } default: panic("unexpected aggregation type") } } func getLabelKeys(v *View) []metricdata.LabelKey { labelKeys := []metricdata.LabelKey{} for _, k := range v.TagKeys { labelKeys = append(labelKeys, metricdata.LabelKey{Key: k.Name()}) } return labelKeys } func viewToMetricDescriptor(v *View) *metricdata.Descriptor { return &metricdata.Descriptor{ Name: v.Name, Description: v.Description, Unit: convertUnit(v), Type: getType(v), LabelKeys: getLabelKeys(v), } } func convertUnit(v *View) metricdata.Unit { switch v.Aggregation.Type { case AggTypeCount: return metricdata.UnitDimensionless default: return getUnit(v.Measure.Unit()) } } func toLabelValues(row *Row, expectedKeys []metricdata.LabelKey) []metricdata.LabelValue { labelValues := []metricdata.LabelValue{} tagMap := make(map[string]string) for _, tag := range row.Tags { tagMap[tag.Key.Name()] = tag.Value } for _, key := range expectedKeys { if val, ok := tagMap[key.Key]; ok { labelValues = append(labelValues, metricdata.NewLabelValue(val)) } else { labelValues = append(labelValues, metricdata.LabelValue{}) } } return labelValues } func rowToTimeseries(v *viewInternal, row *Row, now time.Time) *metricdata.TimeSeries { return &metricdata.TimeSeries{ Points: []metricdata.Point{row.Data.toPoint(v.metricDescriptor.Type, now)}, LabelValues: toLabelValues(row, v.metricDescriptor.LabelKeys), StartTime: row.Data.StartTime(), } } func viewToMetric(v *viewInternal, r *resource.Resource, now time.Time) *metricdata.Metric { rows := v.collectedRows() if len(rows) == 0 { return nil } ts := []*metricdata.TimeSeries{} for _, row := range rows { ts = append(ts, rowToTimeseries(v, row, now)) } m := &metricdata.Metric{ Descriptor: *v.metricDescriptor, TimeSeries: ts, Resource: r, } return m }