| // Copyright (c) The go-grpc-middleware Authors. |
| // Licensed under the Apache License 2.0. |
| |
| package prometheus |
| |
| import ( |
| "github.com/prometheus/client_golang/prometheus" |
| "google.golang.org/grpc" |
| "google.golang.org/grpc/status" |
| ) |
| |
| // FromError returns a grpc status. If the error code is neither a valid grpc status nor a context error, codes.Unknown |
| // will be set. |
| func FromError(err error) *status.Status { |
| s, ok := status.FromError(err) |
| // Mirror what the grpc server itself does, i.e. also convert context errors to status |
| if !ok { |
| s = status.FromContextError(err) |
| } |
| return s |
| } |
| |
| // A CounterOption lets you add options to Counter metrics using With* funcs. |
| type CounterOption func(*prometheus.CounterOpts) |
| |
| type counterOptions []CounterOption |
| |
| func (co counterOptions) apply(o prometheus.CounterOpts) prometheus.CounterOpts { |
| for _, f := range co { |
| f(&o) |
| } |
| return o |
| } |
| |
| // WithConstLabels allows you to add ConstLabels to Counter metrics. |
| func WithConstLabels(labels prometheus.Labels) CounterOption { |
| return func(o *prometheus.CounterOpts) { |
| o.ConstLabels = labels |
| } |
| } |
| |
| // WithSubsystem allows you to add a Subsystem to Counter metrics. |
| func WithSubsystem(subsystem string) CounterOption { |
| return func(o *prometheus.CounterOpts) { |
| o.Subsystem = subsystem |
| } |
| } |
| |
| // A HistogramOption lets you add options to Histogram metrics using With* |
| // funcs. |
| type HistogramOption func(*prometheus.HistogramOpts) |
| |
| type histogramOptions []HistogramOption |
| |
| func (ho histogramOptions) apply(o prometheus.HistogramOpts) prometheus.HistogramOpts { |
| for _, f := range ho { |
| f(&o) |
| } |
| return o |
| } |
| |
| // WithHistogramBuckets allows you to specify custom bucket ranges for histograms if EnableHandlingTimeHistogram is on. |
| func WithHistogramBuckets(buckets []float64) HistogramOption { |
| return func(o *prometheus.HistogramOpts) { o.Buckets = buckets } |
| } |
| |
| // WithHistogramOpts allows you to specify HistogramOpts but makes sure the correct name and label is used. |
| // This function is helpful when specifying more than just the buckets, like using NativeHistograms. |
| func WithHistogramOpts(opts *prometheus.HistogramOpts) HistogramOption { |
| // TODO: This isn't ideal either if new fields are added to prometheus.HistogramOpts. |
| // Maybe we can change the interface to accept abitrary HistogramOpts and |
| // only make sure to overwrite the necessary fields (name, labels). |
| return func(o *prometheus.HistogramOpts) { |
| o.Buckets = opts.Buckets |
| o.NativeHistogramBucketFactor = opts.NativeHistogramBucketFactor |
| o.NativeHistogramZeroThreshold = opts.NativeHistogramZeroThreshold |
| o.NativeHistogramMaxBucketNumber = opts.NativeHistogramMaxBucketNumber |
| o.NativeHistogramMinResetDuration = opts.NativeHistogramMinResetDuration |
| o.NativeHistogramMaxZeroThreshold = opts.NativeHistogramMaxZeroThreshold |
| } |
| } |
| |
| // WithHistogramConstLabels allows you to add custom ConstLabels to |
| // histograms metrics. |
| func WithHistogramConstLabels(labels prometheus.Labels) HistogramOption { |
| return func(o *prometheus.HistogramOpts) { |
| o.ConstLabels = labels |
| } |
| } |
| |
| // WithHistogramSubsystem allows you to add a Subsystem to histograms metrics. |
| func WithHistogramSubsystem(subsystem string) HistogramOption { |
| return func(o *prometheus.HistogramOpts) { |
| o.Subsystem = subsystem |
| } |
| } |
| |
| func typeFromMethodInfo(mInfo *grpc.MethodInfo) grpcType { |
| if !mInfo.IsClientStream && !mInfo.IsServerStream { |
| return Unary |
| } |
| if mInfo.IsClientStream && !mInfo.IsServerStream { |
| return ClientStream |
| } |
| if !mInfo.IsClientStream && mInfo.IsServerStream { |
| return ServerStream |
| } |
| return BidiStream |
| } |
| |
| // An Option lets you add options to prometheus interceptors using With* funcs. |
| type Option func(*config) |
| |
| type config struct { |
| exemplarFn exemplarFromCtxFn |
| } |
| |
| func (c *config) apply(opts []Option) { |
| for _, o := range opts { |
| o(c) |
| } |
| } |
| |
| // WithExemplarFromContext sets function that will be used to deduce exemplar for all counter and histogram metrics. |
| func WithExemplarFromContext(exemplarFn exemplarFromCtxFn) Option { |
| return func(o *config) { |
| o.exemplarFn = exemplarFn |
| } |
| } |