autometrics-go

module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: May 17, 2023 License: Apache-2.0, MIT

README

Autometrics Go

Autometrics is a Go Generator bundled with a library that instruments your functions and gives direct links to inspect usage metrics from your code.

Documentation comments of instrumented function is augmented with links

You can optionally add alerting rules so that code annotations make Prometheus trigger alerts directly from production usage:

a Slack bot is posting an alert directly in the channel

A fully working use-case and example of library usage is available in the examples/web subdirectory. You can build and run load on the example server using:

git submodule update --init
docker compose -f docker-compose.prometheus-example.yaml up

And then explore the generated links by opening the main file in your editor.

How to use

There is a one-time setup phase to prime the code for autometrics. Once this phase is accomplished, only calling go generate is necessary.

Install the go generator.

The generator is the binary in cmd/autometrics, so the easiest way to get it is to install it through go:

go install github.com/autometrics-dev/autometrics-go/cmd/autometrics@latest

In order to have autometrics visible then, make sure that the directory $GOBIN (or the default $GOPATH/bin) is in your $PATH:

$ echo "$PATH" | grep -q "${GOBIN:-$GOPATH/bin}" && echo "GOBIN in PATH" || echo "GOBIN not in PATH, please add it"
GOBIN in PATH
Import the libraries and initialize the metrics

In the main entrypoint of your program, you need to both add package

import (
	autometrics "github.com/autometrics-dev/autometrics-go/pkg/autometrics/prometheus"
)

And then in your main function initialize the metrics

	// Everything in BuildInfo is optional.
	// You can also use any string variable whose value is
	// injected at build time by ldflags.
	autometrics.Init(
		nil,
		autometrics.DefBuckets,
		autometrics.BuildInfo{
			Version: "0.4.0",
			Commit: "anySHA",
			Branch: "",
		},
	)

Warning If you want to enable alerting from Autometrics, you MUST have the --latency-ms values to match the values given in your buckets. The values in the buckets are given in seconds. By default, the generator will error and tell you the valid default values if they don't match. If the default values do not match your use case, you can change the buckets in the init call, and add a --custom-latency argument to the //go:generate invocation.

-//go:generate autometrics
+//go:generate autometrics --custom-latency
Add cookies in your code

Given a starting function like:

func RouteHandler(args interface{}) error {
        // Do stuff
        return nil
}

The manual changes you need to do are:

//go:generate autometrics

//autometrics:doc
func RouteHandler(args interface{}) (err error) { // Name the error return value; this is an optional but recommended change
        // Do stuff
        return nil
}

If you want the generated metrics to contain the function success rate, you must name the error return value. This is why we recommend to name the error value you return for the function you want to instrument.

Generate the documentation and instrumentation code

Install the go generator using go install as usual:

go install https://github.com/autometrics-dev/autometrics-go/cmd/autometrics

Once you've done this, the autometrics generator takes care of the rest, and you can simply call go generate with an optional environment variable:

$ AM_PROMETHEUS_URL=http://localhost:9090/ go generate ./...

The generator will augment your doc comment to add quick links to metrics (using the Prometheus URL as base URL), and add a unique defer statement that will take care of instrumenting your code.

The environment variable AM_PROMETHEUS_URL controls the base URL of the instance that is scraping the deployed version of your code. Having an environment variable means you can change the generated links without touching your code. The default value, if absent, is http://localhost:9090/.

You can have any value here, the only adverse impact it can have is that the links in the doc comment might lead nowhere useful.

Expose metrics outside

The last step now is to actually expose the generated metrics to the Prometheus instance.

For Prometheus the shortest way is to add the handler code in your main entrypoint:

import (
	autometrics "github.com/autometrics-dev/autometrics-go/pkg/autometrics/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)


func main() {
	autometrics.Init(
		nil,
		autometrics.DefBuckets,
		autometrics.BuildInfo{
			Version: "0.4.0",
			Commit: "anySHA",
			Branch: "",
		},
	)
	http.Handle("/metrics", promhttp.Handler())
}

This is the shortest way to initialize and expose the metrics that autometrics will use in the generated code.

(OPTIONAL) Generate alerts automatically

Change the annotation of the function to automatically generate alerts for it:

//autometrics:doc --slo "Api" --success-target 90
func RouteHandler(args interface{}) (err error) {
        // Do stuff
        return nil
}

Then you need to add the bundled recording rules to your prometheus configuration.

The valid arguments for alert generation are:

  • --slo (MANDATORY for alert generation): name of the service for which the objective is relevant
  • --success-rate : target success rate of the function, between 0 and 100 (you must name the error return value of the function for detection to work.)
  • --latency-ms : maximum latency allowed for the function, in milliseconds.
  • --latency-target : latency target for the threshold, between 0 and 100 (so X% of calls must last less than latency-ms milliseconds). You must specify both latency options, or none.

Warning The generator will error out if you use targets that are not supported by the bundled Alerting rules file. Support for custom target is planned but not present at the moment

(OPTIONAL) OpenTelemetry Support

Autometrics supports using OpenTelemetry with a prometheus exporter instead of using Prometheus to publish the metrics. The changes you need to make are:

  • change where the autometrics import points to
import (
-	autometrics "github.com/autometrics-dev/autometrics-go/pkg/autometrics/prometheus"
+	autometrics "github.com/autometrics-dev/autometrics-go/pkg/autometrics/otel"
)
  • change the call to autometrics.Init to the new signature: instead of a registry, the Init function takes a meter name for the otel_scope label of the exported metric. You can use the name of the application or its version for example
	autometrics.Init(
-		nil,
+		"myApp/v2/prod",
		autometrics.DefBuckets,
		autometrics.BuildInfo{
			Version: "2.1.37",
			Commit: "anySHA",
			Branch: "",
		},
	)
  • add the --otel flag to the //go:generate directive
-//go:generate autometrics
+//go:generate autometrics --otel

(OPTIONAL) Git hook

As autometrics is a Go generator that modifies the source code when run, it might be interesting to set up go generate ./... to run in a git pre-commit hook so that you never forget to run it if you change the source code.

If you use a tool like pre-commit, see their documentation about how to add a hook that will run go generate ./....

Otherwise, a simple example has been added in the configs folder as an example. You can copy this file in your copy of your project's repository, within .git/hooks and make sure that the file is executable.

Status

The library is usable but not over, this section mentions the relevant points about the current status

Comments welcome

The first version of the library has not been written by Go experts. Any comment or code suggestion as Pull Request is more than welcome!

Support for custom alerting rules generation

The alerting system for SLOs that Autometrics uses is based on Sloth, and it has native Go types for marshalling/unmarshalling rules, so it should be possible to provide an extra binary in this repository, that only takes care of generating a new rules file with custom objectives.

Directories

Path Synopsis
cmd
autometrics command
Autometrics instruments annotated functions, and adds links in their doc comments to graphs of their live usage.
Autometrics instruments annotated functions, and adds links in their doc comments to graphs of their live usage.
internal
pkg
autometrics
Package autometrics provides automatic metric collection and reporting to functions.
Package autometrics provides automatic metric collection and reporting to functions.
autometrics/otel
Package otel implements the automatic metric registration and collection for autometrics using [OpenTelemetry metrics] and a Prometheus exporter.
Package otel implements the automatic metric registration and collection for autometrics using [OpenTelemetry metrics] and a Prometheus exporter.
autometrics/prometheus
Package prometheus implements the automatic metric registration and collection for autometrics using the [Prometheus client library].
Package prometheus implements the automatic metric registration and collection for autometrics using the [Prometheus client library].

Jump to

Keyboard shortcuts

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