1// Copyright 2019, OpenCensus Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14// 15 16package view 17 18import ( 19 "time" 20 21 "go.opencensus.io/resource" 22 23 "go.opencensus.io/metric/metricdata" 24 "go.opencensus.io/stats" 25) 26 27func getUnit(unit string) metricdata.Unit { 28 switch unit { 29 case "1": 30 return metricdata.UnitDimensionless 31 case "ms": 32 return metricdata.UnitMilliseconds 33 case "By": 34 return metricdata.UnitBytes 35 } 36 return metricdata.UnitDimensionless 37} 38 39func getType(v *View) metricdata.Type { 40 m := v.Measure 41 agg := v.Aggregation 42 43 switch agg.Type { 44 case AggTypeSum: 45 switch m.(type) { 46 case *stats.Int64Measure: 47 return metricdata.TypeCumulativeInt64 48 case *stats.Float64Measure: 49 return metricdata.TypeCumulativeFloat64 50 default: 51 panic("unexpected measure type") 52 } 53 case AggTypeDistribution: 54 return metricdata.TypeCumulativeDistribution 55 case AggTypeLastValue: 56 switch m.(type) { 57 case *stats.Int64Measure: 58 return metricdata.TypeGaugeInt64 59 case *stats.Float64Measure: 60 return metricdata.TypeGaugeFloat64 61 default: 62 panic("unexpected measure type") 63 } 64 case AggTypeCount: 65 switch m.(type) { 66 case *stats.Int64Measure: 67 return metricdata.TypeCumulativeInt64 68 case *stats.Float64Measure: 69 return metricdata.TypeCumulativeInt64 70 default: 71 panic("unexpected measure type") 72 } 73 default: 74 panic("unexpected aggregation type") 75 } 76} 77 78func getLabelKeys(v *View) []metricdata.LabelKey { 79 labelKeys := []metricdata.LabelKey{} 80 for _, k := range v.TagKeys { 81 labelKeys = append(labelKeys, metricdata.LabelKey{Key: k.Name()}) 82 } 83 return labelKeys 84} 85 86func viewToMetricDescriptor(v *View) *metricdata.Descriptor { 87 return &metricdata.Descriptor{ 88 Name: v.Name, 89 Description: v.Description, 90 Unit: convertUnit(v), 91 Type: getType(v), 92 LabelKeys: getLabelKeys(v), 93 } 94} 95 96func convertUnit(v *View) metricdata.Unit { 97 switch v.Aggregation.Type { 98 case AggTypeCount: 99 return metricdata.UnitDimensionless 100 default: 101 return getUnit(v.Measure.Unit()) 102 } 103} 104 105func toLabelValues(row *Row, expectedKeys []metricdata.LabelKey) []metricdata.LabelValue { 106 labelValues := []metricdata.LabelValue{} 107 tagMap := make(map[string]string) 108 for _, tag := range row.Tags { 109 tagMap[tag.Key.Name()] = tag.Value 110 } 111 112 for _, key := range expectedKeys { 113 if val, ok := tagMap[key.Key]; ok { 114 labelValues = append(labelValues, metricdata.NewLabelValue(val)) 115 } else { 116 labelValues = append(labelValues, metricdata.LabelValue{}) 117 } 118 } 119 return labelValues 120} 121 122func rowToTimeseries(v *viewInternal, row *Row, now time.Time) *metricdata.TimeSeries { 123 return &metricdata.TimeSeries{ 124 Points: []metricdata.Point{row.Data.toPoint(v.metricDescriptor.Type, now)}, 125 LabelValues: toLabelValues(row, v.metricDescriptor.LabelKeys), 126 StartTime: row.Data.StartTime(), 127 } 128} 129 130func viewToMetric(v *viewInternal, r *resource.Resource, now time.Time) *metricdata.Metric { 131 rows := v.collectedRows() 132 if len(rows) == 0 { 133 return nil 134 } 135 136 ts := []*metricdata.TimeSeries{} 137 for _, row := range rows { 138 ts = append(ts, rowToTimeseries(v, row, now)) 139 } 140 141 m := &metricdata.Metric{ 142 Descriptor: *v.metricDescriptor, 143 TimeSeries: ts, 144 Resource: r, 145 } 146 return m 147} 148