59 lines
1.5 KiB
Elixir
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
|