Adds spans to 15 previously-unmeasured hot paths so every question we might ask while tuning has a histogram to answer it: External I/O: - iem.fetch_iemre (gridded weather reanalysis) - mrms.list_latest / mrms.download (precip radar) - rtma.fetch_observation - ncei.fetch_metar (historical 5-min METAR backfill) - solar.fetch_indices (GFZ solar indices) - swpc.fetch (SWPC Kp/F10.7/X-ray) - giro.fetch (ionosonde) - qrz.request, geocoder.geocode (callsign enrichment) - srtm.download_tile (terrain tile download + gunzip) - hrrr.download_grib_ranges (parallel byte-range fetch phase) Subprocess: - wgrib2.extract_grid / extract_grid_from_file / extract_grid_from_file_mapped LiveView hot paths: - propagation.scores_at (map score fetch + cache hit/miss counter) - propagation.point_forecast (sparkline) - propagation.point_detail (click-to-inspect) - propagation.daily_outlook_at (/map outlook strip) Worker-level end-to-end: - worker.terrain_profile - worker.mechanism_classify - worker.mrms_fetch Each event is registered in Microwaveprop.PromEx.InstrumentPlugin as a Prometheus histogram (default / long buckets as appropriate) plus a counter for the scores_at cache hit/miss ratio. Prometheus at 10.0.15.25 will start seeing the new series on the next scrape after deploy.
45 lines
1.4 KiB
Elixir
45 lines
1.4 KiB
Elixir
defmodule Microwaveprop.Geocoder do
|
|
@moduledoc """
|
|
Thin wrapper around the Google Maps Geocoding API. Only used as a
|
|
fallback when QRZ's own `<lat>` / `<lon>` fields are missing on a
|
|
callsign record.
|
|
"""
|
|
|
|
@spec geocode(String.t()) :: {:ok, %{lat: float(), lon: float()}} | {:error, String.t()}
|
|
def geocode(address) do
|
|
Microwaveprop.Instrument.span([:geocoder, :geocode], %{}, fn ->
|
|
case Req.get(client(),
|
|
url: "/maps/api/geocode/json",
|
|
params: [address: address, key: api_key()]
|
|
) do
|
|
{:ok, %{status: 200, body: %{"status" => "OK", "results" => [first | _]}}} ->
|
|
%{"geometry" => %{"location" => %{"lat" => lat, "lng" => lon}}} = first
|
|
{:ok, %{lat: lat, lon: lon}}
|
|
|
|
{:ok, %{status: 200, body: %{"status" => "ZERO_RESULTS"}}} ->
|
|
{:error, "No results found"}
|
|
|
|
{:ok, %{status: 200, body: %{"status" => status}}} ->
|
|
{:error, "Geocoding failed: #{status}"}
|
|
|
|
{:error, reason} ->
|
|
{:error, "Geocoding request failed: #{inspect(reason)}"}
|
|
end
|
|
end)
|
|
end
|
|
|
|
defp client do
|
|
config = Application.get_env(:microwaveprop, __MODULE__, [])
|
|
|
|
[base_url: "https://maps.googleapis.com"]
|
|
|> Req.new()
|
|
|> Req.Request.register_options([:plug, :api_key])
|
|
|> Req.merge(config)
|
|
end
|
|
|
|
defp api_key do
|
|
:microwaveprop
|
|
|> Application.get_env(__MODULE__, [])
|
|
|> Keyword.get(:api_key, "")
|
|
end
|
|
end
|