/
to_domain.go
110 lines (98 loc) · 3.66 KB
/
to_domain.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright (c) 2021 The Jaeger 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 dbmodel
import (
"fmt"
"github.com/gogo/protobuf/types"
"github.com/prometheus/common/model"
"github.com/jaegertracing/jaeger/proto-gen/api_v2/metrics"
)
// Translator translates Prometheus's metrics model to Jaeger's.
type Translator struct {
labelMap map[string]string
}
// New returns a new Translator.
func New(spanNameLabel string) Translator {
return Translator{
// "operator" is the label name that Jaeger UI expects.
labelMap: map[string]string{spanNameLabel: "operation"},
}
}
// ToDomainMetricsFamily converts Prometheus' representation of metrics query results to Jaeger's.
func (d Translator) ToDomainMetricsFamily(name, description string, mv model.Value) (*metrics.MetricFamily, error) {
if mv.Type() != model.ValMatrix {
return &metrics.MetricFamily{}, fmt.Errorf("unexpected metrics ValueType: %s", mv.Type())
}
return &metrics.MetricFamily{
Name: name,
Type: metrics.MetricType_GAUGE,
Help: description,
Metrics: d.toDomainMetrics(mv.(model.Matrix)),
}, nil
}
// toDomainMetrics converts Prometheus' representation of metrics to Jaeger's.
func (d Translator) toDomainMetrics(matrix model.Matrix) []*metrics.Metric {
ms := make([]*metrics.Metric, matrix.Len())
for i, ss := range matrix {
ms[i] = &metrics.Metric{
Labels: d.toDomainLabels(ss.Metric),
MetricPoints: toDomainMetricPoints(ss.Values),
}
}
return ms
}
// toDomainLabels converts Prometheus' representation of metric labels to Jaeger's.
func (d Translator) toDomainLabels(promLabels model.Metric) []*metrics.Label {
labels := make([]*metrics.Label, len(promLabels))
j := 0
for k, v := range promLabels {
labelName := string(k)
if newLabel, ok := d.labelMap[labelName]; ok {
labelName = newLabel
}
labels[j] = &metrics.Label{Name: labelName, Value: string(v)}
j++
}
return labels
}
// toDomainMetricPoints convert's Prometheus' representation of metrics data points to Jaeger's.
func toDomainMetricPoints(promDps []model.SamplePair) []*metrics.MetricPoint {
domainMps := make([]*metrics.MetricPoint, len(promDps))
for i, promDp := range promDps {
mp := &metrics.MetricPoint{
Timestamp: toDomainTimestamp(promDp.Timestamp),
Value: toDomainMetricPointValue(promDp.Value),
}
domainMps[i] = mp
}
return domainMps
}
// toDomainTimestamp converts Prometheus' representation of timestamps to Jaeger's.
func toDomainTimestamp(timeMs model.Time) *types.Timestamp {
return &types.Timestamp{
Seconds: int64(timeMs / 1000),
Nanos: int32((timeMs % 1000) * 1_000_000),
}
}
// toDomainMetricPointValue converts Prometheus' representation of a double gauge value to Jaeger's.
// The gauge metric type is used because latency, call and error rates metrics do not consist of monotonically
// increasing values; rather, they are a series of any positive floating number which can fluctuate in any
// direction over time.
func toDomainMetricPointValue(promVal model.SampleValue) *metrics.MetricPoint_GaugeValue {
return &metrics.MetricPoint_GaugeValue{
GaugeValue: &metrics.GaugeValue{
Value: &metrics.GaugeValue_DoubleValue{DoubleValue: float64(promVal)},
},
}
}