fxmetrics

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 19, 2024 License: MIT Imports: 5 Imported by: 1

README

Fx Metrics Module

ci go report codecov Deps PkgGoDev

Fx module for prometheus.

Installation

go get github.com/ankorstore/yokai/fxmetrics

Documentation

Dependencies

This module is intended to be used alongside:

Loading

To load the module in your Fx application:

package main

import (
	"github.com/ankorstore/yokai/fxconfig"
	"github.com/ankorstore/yokai/fxlog"
	"github.com/ankorstore/yokai/fxmetrics"
	"github.com/prometheus/client_golang/prometheus"
	"go.uber.org/fx"
)

func main() {
	fx.New(
		fxconfig.FxConfigModule,                        // load the module dependencies
		fxlog.FxLogModule,
		fxmetrics.FxMetricsModule,                      // load the module
		fx.Invoke(func(registry *prometheus.Registry) { // invoke the metrics registry
			// ...
		}),
	).Run()
}
Configuration

Configuration reference:

# ./configs/config.yaml
app:
  name: app
  env: dev
  version: 0.1.0
  debug: true
modules:
  metrics:
    collect:
      build: true    # to collect build infos metrics (disabled by default)
      go: true       # to collect go metrics (disabled by default)
      process: true  # to collect process metrics (disabled by default)
Registration

This module provides the possibility to register your metrics collectors in a common *prometheus.Registry via AsMetricsCollector():

package main

import (
	"github.com/ankorstore/yokai/fxconfig"
	"github.com/ankorstore/yokai/fxlog"
	"github.com/ankorstore/yokai/fxmetrics"
	"github.com/prometheus/client_golang/prometheus"
	"go.uber.org/fx"
)

var SomeCounter = prometheus.NewCounter(prometheus.CounterOpts{
	Name: "some_total",
	Help: "some help",
})

func main() {
	fx.New(
		fxconfig.FxConfigModule,                       // load the module dependencies
		fxlog.FxLogModule,
		fxmetrics.FxMetricsModule,                     // load the module
		fx.Options(
			fxmetrics.AsMetricsCollector(SomeCounter), // register the counter
		),
		fx.Invoke(func() {
			SomeCounter.Inc()                          // manipulate the counter
		}),
	).Run()
}

Important: even if convenient, it's recommended to NOT use the promauto way of registering metrics, but to use instead fxmetrics.AsMetricsCollector(), as promauto uses a global registry that leads to data race conditions in testing.

Also, if you want to register several collectors at once, you can use fxmetrics.AsMetricsCollectors()

Override

By default, the *prometheus.Registry is created by the DefaultMetricsRegistryFactory.

If needed, you can provide your own factory and override the module:

package main

import (
	"github.com/ankorstore/yokai/fxconfig"
	"github.com/ankorstore/yokai/fxlog"
	"github.com/ankorstore/yokai/fxmetrics"
	"github.com/prometheus/client_golang/prometheus"
	"go.uber.org/fx"
)

type CustomMetricsRegistryFactory struct{}

func NewCustomMetricsRegistryFactory() fxmetrics.MetricsRegistryFactory {
	return &CustomMetricsRegistryFactory{}
}

func (f *CustomMetricsRegistryFactory) Create() (*prometheus.Registry, error) {
	return prometheus.NewPedanticRegistry(), nil
}

func main() {
	fx.New(
		fxconfig.FxConfigModule,                        // load the module dependencies
		fxlog.FxLogModule,
		fxmetrics.FxMetricsModule,                      // load the module
		fx.Decorate(NewCustomMetricsRegistryFactory),   // override the module with a custom factory
		fx.Invoke(func(registry *prometheus.Registry) { // invoke the custom registry
			// ...
		}),
	).Run()
}
Testing

This module provides the possibility to easily test your metrics with the prometheus package testutil helpers.

package main_test

import (
	"strings"
	"testing"

	"github.com/ankorstore/yokai/fxconfig"
	"github.com/ankorstore/yokai/fxlog"
	"github.com/ankorstore/yokai/fxmetrics"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/testutil"
	"github.com/stretchr/testify/assert"
	"go.uber.org/fx"
	"go.uber.org/fx/fxtest"
)

var SomeCounter = prometheus.NewCounter(prometheus.CounterOpts{
	Name: "some_total",
	Help: "some help",
})

func TestSomeCounter(t *testing.T) {
	t.Setenv("APP_CONFIG_PATH", "testdata/config")

	var registry *prometheus.Registry

	fxtest.New(
		t,
		fx.NopLogger,
		fxconfig.FxConfigModule,
		fxlog.FxLogModule,
		fxmetrics.FxMetricsModule,
		fx.Options(
			fxmetrics.AsMetricsCollector(SomeCounter),
		),
		fx.Invoke(func() {
			SomeCounter.Add(9)
		}),
		fx.Populate(&registry),
	).RequireStart().RequireStop()

	// metric assertions
	expectedHelp := `
		# HELP some_total some help
		# TYPE some_total counter
	`
	expectedMetric := `
		some_total 9
	`

	err := testutil.GatherAndCompare(
		registry,
		strings.NewReader(expectedHelp+expectedMetric),
		"some_total",
	)
	assert.NoError(t, err)
}

Documentation

Index

Constants

View Source
const ModuleName = "metrics"

ModuleName is the module name.

Variables

FxMetricsModule is the Fx metrics module.

Functions

func AsMetricsCollector

func AsMetricsCollector(collector prometheus.Collector) fx.Option

AsMetricsCollector registers a prometheus.Collector into Fx.

func AsMetricsCollectors

func AsMetricsCollectors(collectors ...prometheus.Collector) fx.Option

AsMetricsCollectors registers a list of prometheus.Collector into Fx.

func NewFxMetricsRegistry

func NewFxMetricsRegistry(p FxMetricsRegistryParam) (*prometheus.Registry, error)

NewFxMetricsRegistry returns a prometheus.Registry.

Types

type DefaultMetricsRegistryFactory

type DefaultMetricsRegistryFactory struct{}

DefaultMetricsRegistryFactory is the default MetricsRegistryFactory implementation.

func (*DefaultMetricsRegistryFactory) Create

Create returns a new prometheus.Registry.

type FxMetricsRegistryParam

type FxMetricsRegistryParam struct {
	fx.In
	Factory    MetricsRegistryFactory
	Config     *config.Config
	Logger     *log.Logger
	Collectors []prometheus.Collector `group:"metrics-collectors"`
}

FxMetricsRegistryParam allows injection of the required dependencies in NewFxMetricsRegistry.

type MetricsRegistryFactory

type MetricsRegistryFactory interface {
	Create() (*prometheus.Registry, error)
}

MetricsRegistryFactory is the interface for prometheus.Registry factories.

func NewDefaultMetricsRegistryFactory

func NewDefaultMetricsRegistryFactory() MetricsRegistryFactory

NewDefaultMetricsRegistryFactory returns a DefaultMetricsRegistryFactory, implementing MetricsRegistryFactory.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL