2021-11-21 13:58:49 +00:00
|
|
|
package metrics
|
|
|
|
|
|
|
|
import (
|
2024-10-17 15:15:05 +00:00
|
|
|
"context"
|
|
|
|
|
|
|
|
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus"
|
2022-03-11 23:40:16 +00:00
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
2024-10-17 15:15:05 +00:00
|
|
|
"go.opentelemetry.io/otel/trace"
|
2021-11-21 13:58:49 +00:00
|
|
|
"google.golang.org/grpc"
|
|
|
|
|
2023-07-07 23:33:10 +00:00
|
|
|
"go.linka.cloud/grpc-toolkit/interceptors"
|
|
|
|
"go.linka.cloud/grpc-toolkit/service"
|
2021-11-21 13:58:49 +00:00
|
|
|
)
|
|
|
|
|
2024-10-17 15:15:05 +00:00
|
|
|
func DefaultExemplarFromCtx(ctx context.Context) prometheus.Labels {
|
|
|
|
if span := trace.SpanContextFromContext(ctx); span.IsSampled() {
|
|
|
|
return prometheus.Labels{"traceID": span.TraceID().String()}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-03-11 23:24:37 +00:00
|
|
|
type Registerer interface {
|
|
|
|
Register(svc service.Service)
|
|
|
|
}
|
|
|
|
|
|
|
|
type Interceptors interface {
|
2022-03-11 23:40:16 +00:00
|
|
|
ServerInterceptors
|
|
|
|
ClientInterceptors
|
2022-03-11 23:24:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type ServerInterceptors interface {
|
|
|
|
Registerer
|
2022-03-11 23:40:16 +00:00
|
|
|
interceptors.ServerInterceptors
|
|
|
|
prometheus.Collector
|
2022-03-11 23:24:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type ClientInterceptors interface {
|
|
|
|
interceptors.ClientInterceptors
|
|
|
|
}
|
2022-03-11 12:42:02 +00:00
|
|
|
|
2021-11-21 13:58:49 +00:00
|
|
|
type metrics struct {
|
|
|
|
s *grpc_prometheus.ServerMetrics
|
|
|
|
c *grpc_prometheus.ClientMetrics
|
2024-10-17 15:15:05 +00:00
|
|
|
o *options
|
2022-03-11 23:42:36 +00:00
|
|
|
}
|
|
|
|
|
2022-03-11 23:40:16 +00:00
|
|
|
func (m *metrics) Describe(descs chan<- *prometheus.Desc) {
|
|
|
|
if m.s != nil {
|
|
|
|
m.s.Describe(descs)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *metrics) Collect(c chan<- prometheus.Metric) {
|
|
|
|
if m.s != nil {
|
|
|
|
m.s.Collect(c)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-11 23:24:37 +00:00
|
|
|
func (m *metrics) Register(svc service.Service) {
|
|
|
|
if m.s != nil {
|
|
|
|
m.s.InitializeMetrics(svc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-17 15:15:05 +00:00
|
|
|
func NewInterceptors(opts ...Option) Interceptors {
|
|
|
|
o := (&options{}).apply(opts...)
|
|
|
|
s := grpc_prometheus.NewServerMetrics(
|
|
|
|
grpc_prometheus.WithServerCounterOptions(o.copts...),
|
|
|
|
grpc_prometheus.WithServerHandlingTimeHistogram(o.hopts...),
|
|
|
|
)
|
|
|
|
c := grpc_prometheus.NewClientMetrics(
|
|
|
|
grpc_prometheus.WithClientCounterOptions(o.copts...),
|
|
|
|
grpc_prometheus.WithClientHandlingTimeHistogram(o.hopts...),
|
|
|
|
)
|
|
|
|
m := &metrics{s: s, c: c, o: o}
|
|
|
|
o.reg.MustRegister(m)
|
|
|
|
return m
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewServerInterceptors(opts ...Option) ServerInterceptors {
|
|
|
|
o := (&options{}).apply(opts...)
|
|
|
|
s := grpc_prometheus.NewServerMetrics(
|
|
|
|
grpc_prometheus.WithServerCounterOptions(o.copts...),
|
|
|
|
grpc_prometheus.WithServerHandlingTimeHistogram(o.hopts...),
|
|
|
|
)
|
|
|
|
m := &metrics{s: s, o: o}
|
|
|
|
o.reg.MustRegister(m)
|
|
|
|
return m
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewClientInterceptors(opts ...Option) ClientInterceptors {
|
|
|
|
o := (&options{}).apply(opts...)
|
|
|
|
c := grpc_prometheus.NewClientMetrics(
|
|
|
|
grpc_prometheus.WithClientCounterOptions(o.copts...),
|
|
|
|
grpc_prometheus.WithClientHandlingTimeHistogram(o.hopts...),
|
|
|
|
)
|
|
|
|
m := &metrics{c: c, o: o}
|
|
|
|
o.reg.MustRegister(m)
|
|
|
|
return m
|
2021-11-21 13:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *metrics) UnaryServerInterceptor() grpc.UnaryServerInterceptor {
|
2024-10-17 15:15:05 +00:00
|
|
|
return m.s.UnaryServerInterceptor(grpc_prometheus.WithExemplarFromContext(m.o.fn))
|
2021-11-21 13:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *metrics) StreamServerInterceptor() grpc.StreamServerInterceptor {
|
|
|
|
return m.s.StreamServerInterceptor()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *metrics) UnaryClientInterceptor() grpc.UnaryClientInterceptor {
|
|
|
|
return m.c.UnaryClientInterceptor()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *metrics) StreamClientInterceptor() grpc.StreamClientInterceptor {
|
|
|
|
return m.c.StreamClientInterceptor()
|
|
|
|
}
|