@@ -20,16 +20,91 @@ directly to Stackdriver Metrics.
2020*/
2121
2222import (
23+ "errors"
2324 "fmt"
25+ "path"
2426
2527 "github.com/golang/protobuf/ptypes/timestamp"
2628
2729 distributionpb "google.golang.org/genproto/googleapis/api/distribution"
30+ labelpb "google.golang.org/genproto/googleapis/api/label"
31+ googlemetricpb "google.golang.org/genproto/googleapis/api/metric"
2832 monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
2933
3034 metricspb "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1"
3135)
3236
37+ var errNilMetric = errors .New ("expecting a non-nil metric" )
38+
39+ func (se * statsExporter ) protoToMonitoringMetricDescriptor (metric * metricspb.Metric ) (* googlemetricpb.MetricDescriptor , error ) {
40+ if metric == nil {
41+ return nil , errNilMetric
42+ }
43+
44+ metricName , description , unit , _ := metricProseFromProto (metric )
45+ metricType , _ := se .metricTypeFromProto (metricName )
46+ displayName := se .displayName (metricName )
47+ metricKind , valueType := protoMetricDescriptorTypeToMetricKind (metric )
48+
49+ sdm := & googlemetricpb.MetricDescriptor {
50+ Name : fmt .Sprintf ("projects/%s/metricDescriptors/%s" , se .o .ProjectID , metricType ),
51+ DisplayName : displayName ,
52+ Description : description ,
53+ Unit : unit ,
54+ Type : metricType ,
55+ MetricKind : metricKind ,
56+ ValueType : valueType ,
57+ Labels : labelDescriptorsFromProto (se .defaultLabels , metric .GetMetricDescriptor ().GetLabelKeys ()),
58+ }
59+
60+ return sdm , nil
61+ }
62+
63+ func labelDescriptorsFromProto (defaults map [string ]labelValue , protoLabelKeys []* metricspb.LabelKey ) []* labelpb.LabelDescriptor {
64+ labelDescriptors := make ([]* labelpb.LabelDescriptor , 0 , len (defaults )+ len (protoLabelKeys ))
65+
66+ // Fill in the defaults first.
67+ for key , lbl := range defaults {
68+ labelDescriptors = append (labelDescriptors , & labelpb.LabelDescriptor {
69+ Key : sanitize (key ),
70+ Description : lbl .desc ,
71+ ValueType : labelpb .LabelDescriptor_STRING ,
72+ })
73+ }
74+
75+ // Now fill in those from the metric.
76+ for _ , protoKey := range protoLabelKeys {
77+ labelDescriptors = append (labelDescriptors , & labelpb.LabelDescriptor {
78+ Key : sanitize (protoKey .GetKey ()),
79+ Description : protoKey .GetDescription (),
80+ ValueType : labelpb .LabelDescriptor_STRING , // We only use string tags
81+ })
82+ }
83+ return labelDescriptors
84+ }
85+
86+ func metricProseFromProto (metric * metricspb.Metric ) (name , description , unit string , ok bool ) {
87+ mname := metric .GetName ()
88+ if mname != "" {
89+ name = mname
90+ return
91+ }
92+
93+ md := metric .GetMetricDescriptor ()
94+
95+ name = md .GetName ()
96+ unit = md .GetUnit ()
97+ description = md .GetDescription ()
98+
99+ return
100+ }
101+
102+ func (se * statsExporter ) metricTypeFromProto (name string ) (string , bool ) {
103+ // TODO: (@odeke-em) support non-"custom.googleapis.com" metrics names.
104+ name = path .Join ("custom.googleapis.com" , "opencensus" , name )
105+ return name , true
106+ }
107+
33108func fromProtoPoint (startTime * timestamp.Timestamp , pt * metricspb.Point ) (* monitoringpb.Point , error ) {
34109 if pt == nil {
35110 return nil , nil
@@ -133,3 +208,33 @@ func bucketCounts(buckets []*metricspb.DistributionValue_Bucket) []int64 {
133208 }
134209 return bucketCounts
135210}
211+
212+ func protoMetricDescriptorTypeToMetricKind (m * metricspb.Metric ) (googlemetricpb.MetricDescriptor_MetricKind , googlemetricpb.MetricDescriptor_ValueType ) {
213+ dt := m .GetMetricDescriptor ()
214+ if dt == nil {
215+ return googlemetricpb .MetricDescriptor_METRIC_KIND_UNSPECIFIED , googlemetricpb .MetricDescriptor_VALUE_TYPE_UNSPECIFIED
216+ }
217+
218+ switch dt .Type {
219+ case metricspb .MetricDescriptor_CUMULATIVE_INT64 :
220+ return googlemetricpb .MetricDescriptor_CUMULATIVE , googlemetricpb .MetricDescriptor_INT64
221+
222+ case metricspb .MetricDescriptor_CUMULATIVE_DOUBLE :
223+ return googlemetricpb .MetricDescriptor_CUMULATIVE , googlemetricpb .MetricDescriptor_DOUBLE
224+
225+ case metricspb .MetricDescriptor_CUMULATIVE_DISTRIBUTION :
226+ return googlemetricpb .MetricDescriptor_CUMULATIVE , googlemetricpb .MetricDescriptor_DISTRIBUTION
227+
228+ case metricspb .MetricDescriptor_GAUGE_DOUBLE :
229+ return googlemetricpb .MetricDescriptor_GAUGE , googlemetricpb .MetricDescriptor_DOUBLE
230+
231+ case metricspb .MetricDescriptor_GAUGE_INT64 :
232+ return googlemetricpb .MetricDescriptor_GAUGE , googlemetricpb .MetricDescriptor_INT64
233+
234+ case metricspb .MetricDescriptor_GAUGE_DISTRIBUTION :
235+ return googlemetricpb .MetricDescriptor_GAUGE , googlemetricpb .MetricDescriptor_DISTRIBUTION
236+
237+ default :
238+ return googlemetricpb .MetricDescriptor_METRIC_KIND_UNSPECIFIED , googlemetricpb .MetricDescriptor_VALUE_TYPE_UNSPECIFIED
239+ }
240+ }
0 commit comments