From 1c400259fc8873422589ccd7f78a74763ac07050 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sun, 18 Jan 2026 12:52:29 -0600 Subject: [PATCH] fix: use microsecond precision for ICMP latency measurements - Changed ping module to use microsecond timer resolution instead of millisecond - Prevents 0ms readings for very fast pings (localhost, local network) - Updated response_time_ms to float type to store decimal precision - Migration converts existing integer values to float --- lib/towerops/monitoring/check.ex | 2 +- lib/towerops/monitoring/ping.ex | 11 +++++++---- .../20260118185149_change_response_time_to_float.exs | 9 +++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 priv/repo/migrations/20260118185149_change_response_time_to_float.exs diff --git a/lib/towerops/monitoring/check.ex b/lib/towerops/monitoring/check.ex index 41d8cf84..00247a05 100644 --- a/lib/towerops/monitoring/check.ex +++ b/lib/towerops/monitoring/check.ex @@ -12,7 +12,7 @@ defmodule Towerops.Monitoring.Check do @foreign_key_type :binary_id schema "monitoring_checks" do field :status, Ecto.Enum, values: [:success, :failure] - field :response_time_ms, :integer + field :response_time_ms, :float field :checked_at, :utc_datetime belongs_to :device, Towerops.Devices.Device diff --git a/lib/towerops/monitoring/ping.ex b/lib/towerops/monitoring/ping.ex index af5bfb3f..e6fc35ab 100644 --- a/lib/towerops/monitoring/ping.ex +++ b/lib/towerops/monitoring/ping.ex @@ -28,16 +28,19 @@ defmodule Towerops.Monitoring.Ping do Pings an IP address using raw ICMP echo request/reply. Returns {:ok, response_time_ms} on success, {:error, reason} on failure. + Response time is returned as a float with microsecond precision. """ @impl true def ping(ip_address, timeout_ms \\ 5000) do - start_time = System.monotonic_time(:millisecond) + start_time = System.monotonic_time(:microsecond) case send_icmp_echo(ip_address, timeout_ms) do :ok -> - end_time = System.monotonic_time(:millisecond) - response_time = end_time - start_time - {:ok, response_time} + end_time = System.monotonic_time(:microsecond) + response_time_us = end_time - start_time + # Convert to milliseconds with decimal precision + response_time_ms = response_time_us / 1000.0 + {:ok, response_time_ms} {:error, reason} -> {:error, reason} diff --git a/priv/repo/migrations/20260118185149_change_response_time_to_float.exs b/priv/repo/migrations/20260118185149_change_response_time_to_float.exs new file mode 100644 index 00000000..ac9ffcf5 --- /dev/null +++ b/priv/repo/migrations/20260118185149_change_response_time_to_float.exs @@ -0,0 +1,9 @@ +defmodule Towerops.Repo.Migrations.ChangeResponseTimeToFloat do + use Ecto.Migration + + def change do + alter table(:monitoring_checks) do + modify :response_time_ms, :float + end + end +end