Packages
S3-compatible object storage monitor (AWS S3, MinIO, Ceph RGW, Cloudflare R2, etc.), with its dashboard panel bundled in the same package as a separate module (Integrations.S3.Display) — one install, both halves; a release without raven_web simply runs the monitor headless.
Current section
Files
Jump to
Current section
Files
lib/integrations/s3/display.ex
defmodule Integrations.S3.Display do
@moduledoc """
Dashboard panel for `Integrations.S3` (same package).
Nested under the monitor's own namespace deliberately — the package's
top-level module name never changes, and this module's name is
guaranteed distinct from any separately-published standalone display
package. `Display.BundledDefault` auto-hooks this whenever
`Integrations.S3` starts, the same as if they were still one module.
"""
use CodeNameRaven.Display, category: :infrastructure, size_hint: :medium
@impl true
def display_name, do: "S3 Storage"
@impl true
def compatible_monitors, do: [Integrations.S3]
@impl true
def render(assigns) do
result = assigns[:result]
assigns = Map.merge(assigns, %{result: result})
~H"""
<div class="space-y-3">
<div class="flex items-start justify-between gap-2">
<div class="min-w-0">
<h2 class="text-sm font-semibold text-base-content truncate">
<%= @config.name || storage_title(@config.params) %>
</h2>
<p class="text-xs font-mono text-base-content/40 truncate">
<%= get_in(@config.params, [:endpoint]) || get_in(@config.params, ["endpoint"]) %>
</p>
</div>
<CodeNameRaven.MonitorComponents.status_chip status={@status} />
</div>
<div :if={@result} class="flex gap-2 flex-wrap">
<CodeNameRaven.MonitorComponents.stat
label="Liveness"
value={status_label(@result.liveness)} />
<CodeNameRaven.MonitorComponents.stat
:if={@result.readiness != :skipped}
label="Readiness"
value={status_label(@result.readiness)} />
<CodeNameRaven.MonitorComponents.stat
:if={@result.bucket_check != :skipped}
label={@result.bucket || "Bucket"}
value={status_label(@result.bucket_check)} />
</div>
<CodeNameRaven.MonitorComponents.error_message message={@last_error} />
<CodeNameRaven.MonitorComponents.check_time checked_at={@last_checked_at} />
</div>
"""
end
# ---------------------------------------------------------------------------
# Private helpers
# ---------------------------------------------------------------------------
defp status_label(:up), do: "OK"
defp status_label(:degraded), do: "Degraded"
defp status_label(:down), do: "Down"
defp status_label(:skipped), do: "—"
defp status_label(_), do: "?"
defp storage_title(params) do
ep = params[:endpoint] || params["endpoint"] || "S3"
bucket = params[:bucket] || params["bucket"]
if bucket, do: "#{ep}/#{bucket}", else: ep
end
end