Documentation
¶
Overview ¶
package fxmetrics provides a convenient way to expose prometheus metrics.
Example ¶
package main
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
sconfig "github.com/exoscale/stelling/config"
"github.com/exoscale/stelling/fxmetrics"
"github.com/prometheus/client_golang/prometheus"
"go.uber.org/fx"
"go.uber.org/fx/fxevent"
"go.uber.org/zap"
)
type Config struct {
fxmetrics.Metrics
}
func main() {
conf := &Config{}
args := []string{"metrics-test"}
if err := sconfig.Load(conf, args); err != nil {
panic(err)
}
opts := fx.Options(
// Suppressing fx logs to ensure deterministic output
fx.WithLogger(func() fxevent.Logger { return fxevent.NopLogger }),
fxmetrics.NewModule(conf),
fx.Provide(
zap.NewNop,
provideMetrics,
),
fx.Invoke(registerMetrics),
fx.Invoke(run),
)
if err := fx.ValidateApp(opts); err != nil {
panic(err)
}
fx.New(opts).Run()
}
func provideMetrics() prometheus.Collector {
counter := prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: "app",
Subsystem: "component",
Name: "example_total",
Help: "Total number of times run was called",
}, []string{})
// Metrics are provisioned lazily, by reading it here we ensure it's present
counter.GetMetricWithLabelValues() //nolint:errcheck
return counter
}
func registerMetrics(metric prometheus.Collector, reg *prometheus.Registry) error {
return reg.Register(metric)
}
func run(lc fx.Lifecycle, sd fx.Shutdowner) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
go func() {
// By default the metrics server binds to 0.0.0.0:9091
resp, err := http.DefaultClient.Get("http://localhost:9091/metrics") //nolint:noctx
if err != nil {
panic(err)
}
fmt.Println("Response code for GET http://localhost:9091/metrics", resp.StatusCode)
body := resp.Body
metrics, err := io.ReadAll(body)
if err != nil {
panic(err)
}
hasMetric := bytes.Contains(metrics, []byte("app_component_example_total 0"))
fmt.Println("Payload contains the custom metric", hasMetric)
defer body.Close()
sd.Shutdown() //nolint:errcheck
}()
return nil
},
})
}
Output: Response code for GET http://localhost:9091/metrics 200 Payload contains the custom metric true
Index ¶
- Constants
- func GetCertReloaderConfig(conf PushMetricsConfig) *reloader.CertReloaderConfig
- func InitializeGrpcServerMetrics(metrics *grpc_prometheus.ServerMetrics, server reflection.ServiceInfoProvider)
- func InvokeOtlpMeterProvider(lc fx.Lifecycle, mp metric.MeterProvider)
- func NewMetricsHandlers(p RegisterParams) http.Handler
- func NewModule(conf MetricsConfig) fx.Option
- func NewOtlpMeterProvider(lc fx.Lifecycle, conf OtlpMetricsConfig, reg *prometheus.Registry, ...) (metric.MeterProvider, error)
- func NewOtlpModule(conf OtlpMetricsConfig) fx.Option
- func NewPrometheusRegistry(conf MetricsConfig) (*prometheus.Registry, error)
- func NewPushModule(conf PushMetricsConfig) fx.Option
- func NewVersionCollector() prometheus.GaugeFunc
- func ProvideMetricsPusher(lc fx.Lifecycle, conf PushMetricsConfig, reloader *reloader.CertReloader, ...) (*push.Pusher, error)
- func RegisterPushMetrics(reg *prometheus.Registry, pusher *push.Pusher)
- type GrpcClientInterceptorParams
- type GrpcClientInterceptorsResult
- type GrpcServerInterceptorParams
- type GrpcServerInterceptorsResult
- type HttpMetrics
- type HttpMiddlewareResult
- type Metrics
- type MetricsConfig
- type OtlpMetrics
- type OtlpMetricsConfig
- type PushMetrics
- type PushMetricsConfig
- type RegisterParams
Examples ¶
Constants ¶
const GrpcInterceptorWeight = 60
Variables ¶
This section is empty.
Functions ¶
func GetCertReloaderConfig ¶
func GetCertReloaderConfig(conf PushMetricsConfig) *reloader.CertReloaderConfig
func InitializeGrpcServerMetrics ¶
func InitializeGrpcServerMetrics(metrics *grpc_prometheus.ServerMetrics, server reflection.ServiceInfoProvider)
func InvokeOtlpMeterProvider ¶
func InvokeOtlpMeterProvider(lc fx.Lifecycle, mp metric.MeterProvider)
InvokeOtlpMeterProvider can be embedded in a system to ensure the metric.MeterProvider is created
func NewMetricsHandlers ¶
func NewMetricsHandlers(p RegisterParams) http.Handler
func NewOtlpMeterProvider ¶
func NewOtlpMeterProvider(lc fx.Lifecycle, conf OtlpMetricsConfig, reg *prometheus.Registry, logger *zap.Logger) (metric.MeterProvider, error)
func NewOtlpModule ¶
func NewOtlpModule(conf OtlpMetricsConfig) fx.Option
func NewPrometheusRegistry ¶
func NewPrometheusRegistry(conf MetricsConfig) (*prometheus.Registry, error)
func NewPushModule ¶
func NewPushModule(conf PushMetricsConfig) fx.Option
func NewVersionCollector ¶
func NewVersionCollector() prometheus.GaugeFunc
NewVersionCollector returns a collector collecting a single metric "go_version_info" with the constant value of 1 and 2 labels "revision" and "revision_timestamp". Their values can be set at link time. `go build -ldflags="-X 'github.com/exoscale/stelling/fxmetrics.revision=v1.0.0'"` `go build -ldflags="-X 'github.com/exoscale/stelling/fxmetrics.revisionTimestamp=2024-06-18T14:28:57Z'"` If not set at link time, the labels will contain the values of "vcs.revision" and "vcs.time" from the BuildInfo.Settings map. If neither way returns an output, the value will be set to "unknown".
func ProvideMetricsPusher ¶
func ProvideMetricsPusher(lc fx.Lifecycle, conf PushMetricsConfig, reloader *reloader.CertReloader, logger *zap.Logger) (*push.Pusher, error)
func RegisterPushMetrics ¶
func RegisterPushMetrics(reg *prometheus.Registry, pusher *push.Pusher)
Types ¶
type GrpcClientInterceptorParams ¶
type GrpcClientInterceptorParams struct {
fx.In
Conf MetricsConfig
Reg *prometheus.Registry
HistogramOps []grpc_prometheus.HistogramOption `optional:"true"`
}
type GrpcClientInterceptorsResult ¶
type GrpcClientInterceptorsResult struct {
fx.Out
*fxgrpc.UnaryClientInterceptor `group:"unary_client_interceptor"`
*fxgrpc.StreamClientInterceptor `group:"stream_client_interceptor"`
}
func NewGrpcClientInterceptors ¶
func NewGrpcClientInterceptors(p GrpcClientInterceptorParams) (GrpcClientInterceptorsResult, error)
type GrpcServerInterceptorParams ¶
type GrpcServerInterceptorParams struct {
fx.In
Conf MetricsConfig
Reg *prometheus.Registry
HistogramOps []grpc_prometheus.HistogramOption `optional:"true"`
}
type GrpcServerInterceptorsResult ¶
type GrpcServerInterceptorsResult struct {
fx.Out
*fxgrpc.UnaryServerInterceptor `group:"unary_server_interceptor"`
*fxgrpc.StreamServerInterceptor `group:"stream_server_interceptor"`
*grpc_prometheus.ServerMetrics
}
func NewGrpcServerInterceptors ¶
func NewGrpcServerInterceptors(p GrpcServerInterceptorParams) (GrpcServerInterceptorsResult, error)
type HttpMetrics ¶
type HttpMetrics struct {
// contains filtered or unexported fields
}
func NewHttpMetrics ¶
func NewHttpMetrics() *HttpMetrics
func (*HttpMetrics) Collect ¶
func (m *HttpMetrics) Collect(ch chan<- prometheus.Metric)
Collect is called by the Prometheus registry when collecting metrics. The implementation sends each collected metric via the provided channel and returns once the last metric has been sent.
func (*HttpMetrics) Describe ¶
func (m *HttpMetrics) Describe(ch chan<- *prometheus.Desc)
Describe sends the super-set of all possible descriptors of metrics collected by this Collector to the provided channel and returns once the last descriptor has been sent.
type HttpMiddlewareResult ¶
type HttpMiddlewareResult struct {
fx.Out
Middleware *fxhttp.Middleware `group:"http_middleware"`
}
func NewHttpMiddleware ¶
func NewHttpMiddleware(reg *prometheus.Registry) (HttpMiddlewareResult, error)
type Metrics ¶
type Metrics struct {
fxhttp.Server
// indicates whether Prometheus grpc middleware exports Histograms or not
Histograms bool `default:"false"`
// ProcessName is used as a prefix for certain metrics that can clash
ProcessName string
}
func (*Metrics) ApplyDefaults ¶
func (m *Metrics) ApplyDefaults()
func (*Metrics) MarshalLogObject ¶
func (m *Metrics) MarshalLogObject(enc zapcore.ObjectEncoder) error
func (*Metrics) MetricsConfig ¶
type MetricsConfig ¶
type MetricsConfig interface {
MetricsConfig() *Metrics
}
type OtlpMetrics ¶
type OtlpMetrics struct {
// Enabled allows otlp metrics support to be toggled on and off
Enabled bool
// PushInterval is the frequency with which metrics are pushed
PushInterval time.Duration `default:"15s"`
// indicates whether Prometheus grpc middleware exports Histograms or not
Histograms bool `default:"false"`
// ProcessName is used as a prefix for certain metrics that can clash
ProcessName string
// GrpcClient is the client used to talk to the collector
GrpcClient fxgrpc.Client `validate:"required_with=Enabled,omitempty"`
}
func (*OtlpMetrics) MarshalLogObject ¶
func (m *OtlpMetrics) MarshalLogObject(enc zapcore.ObjectEncoder) error
func (*OtlpMetrics) MetricsConfig ¶
func (om *OtlpMetrics) MetricsConfig() *Metrics
func (*OtlpMetrics) OtlpMetricsConfig ¶
func (om *OtlpMetrics) OtlpMetricsConfig() *OtlpMetrics
type OtlpMetricsConfig ¶
type OtlpMetricsConfig interface {
OtlpMetricsConfig() *OtlpMetrics
MetricsConfig() *Metrics
}
type PushMetrics ¶
type PushMetrics struct {
// InsecureConnection indicates whether TLS needs to be disabled when connecting to PushGateway
InsecureConnection bool
// CertFile is the path to the pem encoded TLS certificate
CertFile string `validate:"omitempty,file"`
// KeyFile is the path to the pem encoded private key of the TLS certificate
KeyFile string `validate:"required_with=CertFile,omitempty,file"`
// RootCAFile is the path to a pem encoded CA cert bundle used to validate server connections
RootCAFile string `validate:"omitempty,file"`
// indicates whether Prometheus grpc middleware exports Histograms or not
Histograms bool `default:"false"`
// ProcessName is used as a prefix for certain metrics that can clash
ProcessName string
// Endpoint is the URL on which the prometheus pushgateway can be reached
Endpoint string `validate:"omitempty,url"`
// JobName is the name of the job in PushGateway
JobName string `validate:"required_with=Endpoint"`
// GroupingLabelKey is the label on which PushGateway groups metrics
// (ie: you can keep a copy of each metric for each value of the GroupingLabelKey)
// Deprecated: Use GroupingLabels
GroupingLabelKey string ``
// The value for this instance of the GroupingLabel (see GroupingLabelKey)
// Deprecated: Use GroupingLabels
GroupingLabelValue string `validate:"required_with=GroupingLabelKey"`
// GroupingLabels are labels on which PushGateway groups metrics
GroupingLabels map[string]string `validate:"excluded_with=GroupingLabelKey"`
// PushInterval is the frequency with which metrics are pushed
// If the PushInterval is set to 0, metrics will only be pushed when the system stops
PushInterval time.Duration `default:"15s"`
// ExtraLabels will add each key as a label with the corresponding value in all produced metrics
ExtraLabels map[string]string
}
func (*PushMetrics) MarshalLogObject ¶
func (m *PushMetrics) MarshalLogObject(enc zapcore.ObjectEncoder) error
func (*PushMetrics) MetricsConfig ¶
func (m *PushMetrics) MetricsConfig() *Metrics
func (*PushMetrics) PushMetricsConfig ¶
func (m *PushMetrics) PushMetricsConfig() *PushMetrics
type PushMetricsConfig ¶
type PushMetricsConfig interface {
PushMetricsConfig() *PushMetrics
MetricsConfig() *Metrics
}
type RegisterParams ¶
type RegisterParams struct {
fx.In
Reg *prometheus.Registry
}