blob: bdd171e295f64e3bd3ee86912df6877449c87cb3 [file] [log] [blame]
Abhay Kumara2ae5992025-11-10 14:02:24 +00001// Copyright (c) The go-grpc-middleware Authors.
2// Licensed under the Apache License 2.0.
3
4package prometheus
5
6import (
7 "github.com/prometheus/client_golang/prometheus"
8 "google.golang.org/grpc"
9 "google.golang.org/grpc/status"
10)
11
12// FromError returns a grpc status. If the error code is neither a valid grpc status nor a context error, codes.Unknown
13// will be set.
14func FromError(err error) *status.Status {
15 s, ok := status.FromError(err)
16 // Mirror what the grpc server itself does, i.e. also convert context errors to status
17 if !ok {
18 s = status.FromContextError(err)
19 }
20 return s
21}
22
23// A CounterOption lets you add options to Counter metrics using With* funcs.
24type CounterOption func(*prometheus.CounterOpts)
25
26type counterOptions []CounterOption
27
28func (co counterOptions) apply(o prometheus.CounterOpts) prometheus.CounterOpts {
29 for _, f := range co {
30 f(&o)
31 }
32 return o
33}
34
35// WithConstLabels allows you to add ConstLabels to Counter metrics.
36func WithConstLabels(labels prometheus.Labels) CounterOption {
37 return func(o *prometheus.CounterOpts) {
38 o.ConstLabels = labels
39 }
40}
41
42// WithSubsystem allows you to add a Subsystem to Counter metrics.
43func WithSubsystem(subsystem string) CounterOption {
44 return func(o *prometheus.CounterOpts) {
45 o.Subsystem = subsystem
46 }
47}
48
49// A HistogramOption lets you add options to Histogram metrics using With*
50// funcs.
51type HistogramOption func(*prometheus.HistogramOpts)
52
53type histogramOptions []HistogramOption
54
55func (ho histogramOptions) apply(o prometheus.HistogramOpts) prometheus.HistogramOpts {
56 for _, f := range ho {
57 f(&o)
58 }
59 return o
60}
61
62// WithHistogramBuckets allows you to specify custom bucket ranges for histograms if EnableHandlingTimeHistogram is on.
63func WithHistogramBuckets(buckets []float64) HistogramOption {
64 return func(o *prometheus.HistogramOpts) { o.Buckets = buckets }
65}
66
67// WithHistogramOpts allows you to specify HistogramOpts but makes sure the correct name and label is used.
68// This function is helpful when specifying more than just the buckets, like using NativeHistograms.
69func WithHistogramOpts(opts *prometheus.HistogramOpts) HistogramOption {
70 // TODO: This isn't ideal either if new fields are added to prometheus.HistogramOpts.
71 // Maybe we can change the interface to accept abitrary HistogramOpts and
72 // only make sure to overwrite the necessary fields (name, labels).
73 return func(o *prometheus.HistogramOpts) {
74 o.Buckets = opts.Buckets
75 o.NativeHistogramBucketFactor = opts.NativeHistogramBucketFactor
76 o.NativeHistogramZeroThreshold = opts.NativeHistogramZeroThreshold
77 o.NativeHistogramMaxBucketNumber = opts.NativeHistogramMaxBucketNumber
78 o.NativeHistogramMinResetDuration = opts.NativeHistogramMinResetDuration
79 o.NativeHistogramMaxZeroThreshold = opts.NativeHistogramMaxZeroThreshold
80 }
81}
82
83// WithHistogramConstLabels allows you to add custom ConstLabels to
84// histograms metrics.
85func WithHistogramConstLabels(labels prometheus.Labels) HistogramOption {
86 return func(o *prometheus.HistogramOpts) {
87 o.ConstLabels = labels
88 }
89}
90
91// WithHistogramSubsystem allows you to add a Subsystem to histograms metrics.
92func WithHistogramSubsystem(subsystem string) HistogramOption {
93 return func(o *prometheus.HistogramOpts) {
94 o.Subsystem = subsystem
95 }
96}
97
98func typeFromMethodInfo(mInfo *grpc.MethodInfo) grpcType {
99 if !mInfo.IsClientStream && !mInfo.IsServerStream {
100 return Unary
101 }
102 if mInfo.IsClientStream && !mInfo.IsServerStream {
103 return ClientStream
104 }
105 if !mInfo.IsClientStream && mInfo.IsServerStream {
106 return ServerStream
107 }
108 return BidiStream
109}
110
111// An Option lets you add options to prometheus interceptors using With* funcs.
112type Option func(*config)
113
114type config struct {
115 exemplarFn exemplarFromCtxFn
116}
117
118func (c *config) apply(opts []Option) {
119 for _, o := range opts {
120 o(c)
121 }
122}
123
124// WithExemplarFromContext sets function that will be used to deduce exemplar for all counter and histogram metrics.
125func WithExemplarFromContext(exemplarFn exemplarFromCtxFn) Option {
126 return func(o *config) {
127 o.exemplarFn = exemplarFn
128 }
129}