telemetry_metrics_prometheus v0.2.1 TelemetryMetricsPrometheus View Source

Prometheus Reporter for Telemetry.Metrics definitions.

Provide a list of metric definitions to the init/2 function. It's recommended to initialize the reporter during application startup.

def start(_type, _args) do
  TelemetryMetricsPrometheus.init([
    counter("http.request.count"),
    sum("http.request.payload_size", unit: :byte),
    last_value("vm.memory.total", unit: :byte)
  ])

  # List all child processes to be supervised
  children = [
  ...
  ]

  opts = [strategy: :one_for_one, name: ExampleApp.Supervisor]
  Supervisor.start_link(children, opts)
end

By default, metrics are exposed on port 9568 at /metrics. The port number can be configured if necessary. You are not required to use the included server, though it is recommended. https is not supported yet, in which case exposing a /metrics endpoint and calling the scrape/1 function is your best option until TLS is supported.

Note that aggregations for distributions (histogram) only occur at scrape time. These aggregations only have to process events that have occurred since the last scrape, so it's recommended at this time to keep an eye on scrape durations if you're reporting a large number of disributions or you have a high tag cardinality.

Telemetry.Metrics to Prometheus Equivalents

Metric types:

  • Counter - Counter
  • Distribution - Histogram
  • LastValue - Gauge
  • Sum - Counter
  • Summary - Summary (Not supported)

Units

Prometheus recommends the usage of base units for compatibility - Base Units. This is simple to do with :telemetry and Telemetry.Metrics as all memory related measurements in the BEAM are reported in bytes and Metrics provides automatic time unit conversions.

Note that measurement unit should used as part of the reported name in the case of histograms and gauges to Prometheus. As such, it is important to explicitly define the unit of measure for these types when the unit is time or memory related.

It is suggested to not mix units, e.g. seconds with milliseconds.

It is required to define your buckets according to the end unit translation since this measurements are converted at the time of handling the event, prior to bucketing.

Memory

Report memory as :byte.

Time

Report durations as :second. The BEAM and :telemetry events use :native time units. Converting to seconds is as simple as adding the conversion tuple for the unit - {:native, :second}

Naming

Telemetry.Metrics definition names do not translate easily to Prometheus naming conventions. By default, the name provided when creating your definition uses parts of the provided name to determine what event to listen to and which event measurement to use.

For example, "http.request.duration" results in listening for [:http, :request] events and use :duration from the event measurements. Prometheus would recommend a name of http_request_duration_seconds as a good name.

It is therefore recommended to use the name in your definition to reflect the name you wish to see reported, e.g. http.request.duration.seconds or [:http, :request, :duration, :seconds] and use the :event_name override and :measurement options in your definition.

Example:

Metrics.distribution(
  "http.request.duration.seconds",
  buckets: [0.01, 0.025, 0.05, 0.1, 0.2, 0.5, 1],
  event_name: [:http, :request, :complete],
  measurement: :duration,
  unit: {:native, :second}
)

The exporter sanitizes names to Prometheus' requirements (Metric Naming) and joins the event name parts with an underscore.

Labels

Labels in Prometheus are referred to as :tags in Telemetry.Metrics - see the docs for more information on tag usage.

Important: Each tag + value results in a separate time series. For distributions, this is further complicated as a time series is created for each bucket plus one for measurements exceeding the limit of the last bucket - +Inf.

It is recommended, but not required, to abide by Prometheus' best practices regarding labels - Label Best Practices

Link to this section Summary

Functions

Initializes a reporter instance with the provided Telemetry.Metrics definitions.

Returns a metrics scrape in Prometheus exposition format for the given reporter name - defaults to :prometheus_metrics.

Link to this section Types

Link to this type

metrics() View Source
metrics() :: [metric()]

Link to this type

prometheus_option() View Source
prometheus_option() ::
  {:name, atom()}
  | {:port, pos_integer()}
  | {:monitor_reporter, bool()}
  | {:validations,
     TelemetryMetricsPrometheus.Registry.validation_opts() | false}

Link to this type

prometheus_options() View Source
prometheus_options() :: [prometheus_option()]

Link to this section Functions

Link to this function

init(metrics, options \\ []) View Source
init(metrics(), prometheus_options()) :: :ok

Initializes a reporter instance with the provided Telemetry.Metrics definitions.

Available options:

  • :name - name of the reporter instance. Defaults to :prometheus_metrics
  • :port - port number for the reporter instance's server. Defaults to 9568
  • :monitor_reporter - collects metrics on the reporter's ETS table usage. Defaults to false
  • :validations - Keyword options list to control validations. All validations can be disabled by setting validations: false.

    • :consistent_units - logs a warning when mixed time units are found in your definitions. Defaults to true
    • :require_seconds - logs a warning if units other than seconds are found in your definitions. Defaults to true
Link to this function

scrape(name \\ :prometheus_metrics) View Source
scrape(name :: atom()) :: String.t()

Returns a metrics scrape in Prometheus exposition format for the given reporter name - defaults to :prometheus_metrics.

Use this function if you wish to expose your metrics through your own server implementation, though this is not recommended. See the Overview for further discussion.