-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathmetrics.go
136 lines (113 loc) · 3.61 KB
/
metrics.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package metrics
import (
"context"
"fmt"
"net/http"
"github.com/hyperledger-labs/yui-relayer/log"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.opentelemetry.io/otel/exporters/prometheus"
api "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/sdk/metric"
)
const (
meterName = "github.com/hyperledger-labs/yui-relayer"
namespaceRoot = "relayer"
)
var (
meterProvider *metric.MeterProvider
meter api.Meter
ProcessedBlockHeightGauge *Int64SyncGauge
BacklogSizeGauge *Int64SyncGauge
BacklogOldestTimestampGauge *Int64SyncGauge
ReceivePacketsFinalizedCounter api.Int64Counter
)
type ExporterConfig interface {
exporterType() string
}
var (
_ ExporterConfig = ExporterNull{}
_ ExporterConfig = ExporterProm{}
)
type ExporterNull struct{}
func (e ExporterNull) exporterType() string { return "null" }
type ExporterProm struct {
Addr string
}
func (e ExporterProm) exporterType() string { return "prometheus" }
func InitializeMetrics(exporterConf ExporterConfig) error {
var err error
switch exporterConf := exporterConf.(type) {
case ExporterNull:
meterProvider = metric.NewMeterProvider()
case ExporterProm:
if exporter, err := NewPrometheusExporter(exporterConf.Addr); err != nil {
return err
} else {
meterProvider = metric.NewMeterProvider(metric.WithReader(exporter))
}
default:
panic("unexpected exporter type")
}
meter = meterProvider.Meter(meterName)
// create the instrument "relayer.processed_block_height"
name := fmt.Sprintf("%s.processed_block_height", namespaceRoot)
if ProcessedBlockHeightGauge, err = NewInt64SyncGauge(
meter,
name,
api.WithUnit("1"),
api.WithDescription("latest finalized height"),
); err != nil {
return fmt.Errorf("failed to create the instrument %s: %v", name, err)
}
// create the instrument "relayer.backlog_size"
name = fmt.Sprintf("%s.backlog_size", namespaceRoot)
if BacklogSizeGauge, err = NewInt64SyncGauge(
meter,
name,
api.WithUnit("1"),
api.WithDescription("number of packets that are unreceived or received but unfinalized"),
); err != nil {
return fmt.Errorf("failed to create the instrument %s: %v", name, err)
}
// create the instrument "relayer.backlog_oldest_timestamp"
name = fmt.Sprintf("%s.backlog_oldest_timestamp", namespaceRoot)
if BacklogOldestTimestampGauge, err = NewInt64SyncGauge(
meter,
name,
api.WithUnit("nsec"),
api.WithDescription("timestamp when the oldest packet in backlog was sent"),
); err != nil {
return fmt.Errorf("failed to create the instrument %s: %v", name, err)
}
// create the instrument "relayer.receive_packets_finalized"
name = fmt.Sprintf("%s.receive_packets_finalized", namespaceRoot)
if ReceivePacketsFinalizedCounter, err = meter.Int64Counter(
name,
api.WithUnit("1"),
api.WithDescription("number of packets that are received and finalized"),
); err != nil {
return fmt.Errorf("failed to create the instrument %s: %v", name, err)
}
return nil
}
func ShutdownMetrics(ctx context.Context) error {
if err := meterProvider.Shutdown(ctx); err != nil {
return fmt.Errorf("failed to shutdown the MeterProvider: %v", err)
}
return nil
}
func NewPrometheusExporter(addr string) (*prometheus.Exporter, error) {
go func() {
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.Handler())
if err := http.ListenAndServe(addr, mux); err != nil {
logger := log.GetLogger().WithModule("core.metrics")
logger.Fatal("Prometheus exporter server failed", err)
}
}()
exporter, err := prometheus.New()
if err != nil {
return nil, fmt.Errorf("failed to create the Prometheus Exporter: %v", err)
}
return exporter, nil
}