GoodAnalytics.Geo (GoodAnalytics v0.1.1)

Copy Markdown View Source

Facade for IP → geo lookup.

Reads configuration from config :good_analytics, :geo:

config :good_analytics, :geo,
  provider: GoodAnalytics.Geo.Locus,
  loader: {:maxmind, "GeoLite2-City"},
  normalizer: GoodAnalytics.Geo.Normalizer.MaxMind  # default

Returns the normalized canonical map (see GoodAnalytics.Geo.Normalizer.normalized) on success.

Failure modes

  • {:error, :geo_disabled} — the :locus dependency is not loaded OR no :provider is configured. Callers SHOULD treat this as non-fatal and continue without enrichment.

  • {:error, :loader_not_ready} — provider is configured but the MMDB loader has not finished initialising (cold start, or fetch failure). The redirect path falls back to the link's default URL and skips geo_targeting.

  • {:error, :not_found} — IP did not match any range in the loaded database (private/reserved range, etc.).

  • {:error, {:invalid_ip, value}} — the input could not be parsed as an IP address.

Summary

Functions

True when geo enrichment is configured AND :locus is loaded.

Fire-and-forget geo enrichment for a known visitor.

Looks up the geo data for an IP.

Parses a value into an :inet.ip_address/0 tuple.

Functions

enabled?()

@spec enabled?() :: boolean()

True when geo enrichment is configured AND :locus is loaded.

enqueue_enrichment(visitor_id, ip)

@spec enqueue_enrichment(Ecto.UUID.t(), term()) :: :ok

Fire-and-forget geo enrichment for a known visitor.

No-op when geo is not enabled. Tasks run under GoodAnalytics.GeoTaskSupervisor which is capped at 10,000 in-flight tasks; when the cap is reached the enrichment is dropped and a single info-level log line is emitted. Event ingest is never affected — enrichment is purely advisory.

lookup(ip)

@spec lookup(term()) ::
  {:ok, GoodAnalytics.Geo.Normalizer.normalized()} | {:error, term()}

Looks up the geo data for an IP.

Accepts a string, an :inet.ip_address/0 tuple, or an EctoNetwork.INET struct.

parse_ip(ip)

@spec parse_ip(term()) :: {:ok, :inet.ip_address()} | {:error, {:invalid_ip, term()}}

Parses a value into an :inet.ip_address/0 tuple.

Accepts: