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
This commit is contained in:
Graham McIntire 2026-01-18 12:52:29 -06:00
parent 16bfd7667d
commit 1c400259fc
No known key found for this signature in database
3 changed files with 17 additions and 5 deletions

View file

@ -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

View file

@ -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}

View file

@ -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