Packages

Behaviour and use macro for Raven monitor integrations

Current section

Files

Jump to
raven_observer_sdk lib code_name_raven channel notification.ex
Raw

lib/code_name_raven/channel/notification.ex

defmodule CodeNameRaven.Channel.Notification do
@moduledoc """
The payload delivered to a channel when an alert fires.
Produced by the Handler when a monitor's status changes to a condition
that matches a configured alert rule. Passed to `Channel.deliver/2`.
Never crosses node or version boundaries — created and consumed within a
single handler process — so it carries no `vsn`/upcast machinery.
"""
@type status :: :up | :degraded | :down | :unknown
@type t :: %__MODULE__{
monitor_id: String.t(),
monitor_name: String.t() | nil,
status: status(),
previous_status: status() | nil,
occurred_at: DateTime.t(),
node: node() | nil,
instance_id: String.t() | nil,
alert_started_at: DateTime.t() | nil
}
defstruct [
:monitor_id,
:monitor_name,
:status,
:previous_status,
:occurred_at,
:node,
:instance_id,
:alert_started_at
]
@doc """
Seconds between `alert_started_at` and `occurred_at`, or nil when the
alert's start is unknown. Shared by channel formatters so "was down
N minutes" is computed one way everywhere.
"""
@spec duration_down(t()) :: non_neg_integer() | nil
def duration_down(%__MODULE__{alert_started_at: nil}), do: nil
def duration_down(%__MODULE__{occurred_at: nil}), do: nil
def duration_down(%__MODULE__{alert_started_at: started, occurred_at: occurred}) do
max(DateTime.diff(occurred, started, :second), 0)
end
@doc """
Human-readable duration-down ("14m", "3h 12m", "2d 5h"), or nil when the
alert's start is unknown. Sub-minute durations render as "<1m".
"""
@spec format_duration_down(t()) :: String.t() | nil
def format_duration_down(%__MODULE__{} = n) do
case duration_down(n) do
nil -> nil
s when s < 60 -> "<1m"
s when s < 3600 -> "#{div(s, 60)}m"
s when s < 86_400 -> "#{div(s, 3600)}h #{rem(s, 3600) |> div(60)}m"
s -> "#{div(s, 86_400)}d #{rem(s, 86_400) |> div(3600)}h"
end
end
end