towerops/lib/towerops/monitoring/ping.ex
2026-01-03 14:41:28 -06:00

59 lines
1.5 KiB
Elixir

defmodule Towerops.Monitoring.Ping do
@moduledoc """
Handles ping operations for equipment monitoring.
"""
@behaviour Towerops.Monitoring.PingBehaviour
@doc """
Pings an IP address and returns the result.
Returns {:ok, response_time_ms} on success, {:error, reason} on failure.
"""
@impl true
def ping(ip_address, timeout_ms \\ 5000) do
start_time = System.monotonic_time(:millisecond)
case run_ping(ip_address, timeout_ms) do
:ok ->
end_time = System.monotonic_time(:millisecond)
response_time = end_time - start_time
{:ok, response_time}
{:error, reason} ->
{:error, reason}
end
end
defp run_ping(ip_address, timeout_ms) do
timeout_seconds = div(timeout_ms, 1000)
timeout_seconds = max(timeout_seconds, 1)
case :os.type() do
{:unix, :darwin} ->
# macOS
run_system_ping(ip_address, ["-c", "1", "-W", "#{timeout_seconds}"])
{:unix, _} ->
# Linux
run_system_ping(ip_address, ["-c", "1", "-W", "#{timeout_seconds}"])
{:win32, _} ->
# Windows
run_system_ping(ip_address, ["-n", "1", "-w", "#{timeout_ms}"])
end
end
defp run_system_ping(ip_address, args) do
case System.cmd("ping", args ++ [ip_address], stderr_to_stdout: true) do
{_output, 0} ->
:ok
{_output, _exit_code} ->
{:error, :timeout_or_unreachable}
end
rescue
e ->
{:error, {:exception, Exception.message(e)}}
end
end