Current section
Files
Jump to
Current section
Files
lib/metric/gauge.ex
# Copyright 2024 Clivern. All rights reserved.
# Use of this source code is governed by the MIT
# license that can be found in the LICENSE file.
defmodule Oak.Metric.Gauge do
@moduledoc """
Represents a Gauge metric.
A Gauge is a metric that represents a single numerical value that can arbitrarily go up and down.
"""
defstruct [:name, :help, :labels, :value]
@doc """
Creates a new Gauge metric.
## Parameters
* `name` - The name of the gauge
* `help` - The help text of the gauge
* `labels` - The labels of the gauge
"""
def new(name, help, labels \\ %{}) do
if name == "" or help == "" do
raise "name and help cannot be empty"
end
%__MODULE__{
name: name,
help: help,
labels: labels,
value: 0
}
end
@doc """
Sets the gauge value to the given amount.
## Parameters
* `gauge` - The gauge to set
* `value` - The value to set
"""
def set(gauge, value) when is_number(value) do
%{gauge | value: value}
end
@doc """
Increments the gauge by the given amount.
## Parameters
* `gauge` - The gauge to increment
* `amount` - The amount to increment by (defaults to 1)
"""
def inc(gauge, amount \\ 1) when is_number(amount) do
%{gauge | value: gauge.value + amount}
end
@doc """
Decrements the gauge by the given amount.
## Parameters
* `gauge` - The gauge to decrement
* `amount` - The amount to decrement by (defaults to 1)
"""
def dec(gauge, amount \\ 1) when is_number(amount) do
%{gauge | value: gauge.value - amount}
end
@doc """
Returns the current value of the gauge.
## Parameters
* `gauge` - The gauge to get the value from
"""
def value(gauge), do: gauge.value
@doc """
Returns the id of the counter
## Parameters
* `counter` - The counter to get the id from
"""
def id(counter),
do:
"#{counter.name}|#{format_labels(counter.labels)}"
|> String.replace(" ", "")
|> String.downcase()
defp format_labels(labels) when is_map(labels) and map_size(labels) == 0, do: ""
defp format_labels(labels) when is_map(labels) do
labels
|> Enum.sort_by(fn {key, _value} -> key end)
|> Enum.map(fn {key, value} -> "#{key}_#{value}" end)
|> Enum.join(",")
end
@doc """
Returns a string representation of the gauge in Prometheus exposition format.
## Parameters
* `gauge` - The gauge to convert to a string
"""
def to_string(gauge) do
labels_str =
gauge.labels
|> Enum.sort_by(fn {key, _value} -> key end)
|> Enum.map(fn {key, value} -> "#{key}=\"#{value}\"" end)
|> Enum.join(",")
labels_formatted = if labels_str == "", do: "", else: "{#{labels_str}}"
"""
# HELP #{gauge.name} #{gauge.help}
# TYPE #{gauge.name} gauge
#{gauge.name}#{labels_formatted} #{gauge.value}
"""
end
end