153 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
// 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, startTime time.Time) *metricdata.TimeSeries {
 | 
						|
	return &metricdata.TimeSeries{
 | 
						|
		Points:      []metricdata.Point{row.Data.toPoint(v.metricDescriptor.Type, now)},
 | 
						|
		LabelValues: toLabelValues(row, v.metricDescriptor.LabelKeys),
 | 
						|
		StartTime:   startTime,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func viewToMetric(v *viewInternal, r *resource.Resource, now time.Time, startTime time.Time) *metricdata.Metric {
 | 
						|
	if v.metricDescriptor.Type == metricdata.TypeGaugeInt64 ||
 | 
						|
		v.metricDescriptor.Type == metricdata.TypeGaugeFloat64 {
 | 
						|
		startTime = time.Time{}
 | 
						|
	}
 | 
						|
 | 
						|
	rows := v.collectedRows()
 | 
						|
	if len(rows) == 0 {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	ts := []*metricdata.TimeSeries{}
 | 
						|
	for _, row := range rows {
 | 
						|
		ts = append(ts, rowToTimeseries(v, row, now, startTime))
 | 
						|
	}
 | 
						|
 | 
						|
	m := &metricdata.Metric{
 | 
						|
		Descriptor: *v.metricDescriptor,
 | 
						|
		TimeSeries: ts,
 | 
						|
		Resource:   r,
 | 
						|
	}
 | 
						|
	return m
 | 
						|
}
 |