Settings-backed configuration for the Web Analytics module.
Everything an operator can change lives in the host's phoenix_kit_settings
table under a web_analytics_ prefix, so it is editable from the admin
Settings tab with no redeploy. This module is the only place that knows the
key names and their defaults.
Hot path
collection_config/0 is called on every tracked request, so it reads
through PhoenixKit.Settings.get_settings_cached/2 — one ETS multi-get, not
a query per key — and every accessor degrades to its default (tracking off)
if the settings table isn't reachable. Nothing here may raise: a broken
settings read must cost the host a missing analytics row, never a failed
page render.
Keys
| Key | Default | What it does |
|---|---|---|
web_analytics_enabled | false | Master switch (the module toggle) |
web_analytics_track_bots | false | Store hits whose User-Agent looks automated |
web_analytics_detect_bots | true | Also flag bots by behaviour — see PhoenixKitWebAnalytics.BotSignals |
web_analytics_respect_dnt | true | Skip requests sending DNT: 1 |
web_analytics_exclude_paths | /admin* … | Newline/comma separated path patterns to ignore |
web_analytics_session_timeout_minutes | 30 | Inactivity gap that ends a session |
web_analytics_retention_days | 365 | Age at which raw events are rolled up and deleted |
web_analytics_beacon_enabled | false | Accept hits from the JS beacon / pixel endpoints |
web_analytics_track_interactions | true | Record LiveView events (clicks, submits) as interactions |
web_analytics_ignore_events | validate | LiveView event names never recorded as interactions |
web_analytics_event_params | tab, view, … | Event param names whose short values are kept |
web_analytics_client_script | false | Accept clicks / scroll / leave from the optional client script |
web_analytics_recording | false | Record pointer movement, clicks, hovers and scrolling (session recordings) |
web_analytics_recording_sample | 100 | Percent of visitors recorded while recording is on |
web_analytics_recording_retention_days | 30 | Age at which recordings are deleted |
web_analytics_exclude_internal_network | true | Leave internal-network traffic out of the statistics |
web_analytics_exclude_admin | true | Leave the site staff's own visits out of the statistics |
web_analytics_exclude_admin_network | true | Leave visits from the staff's networks out of the statistics |
web_analytics_internal_roles | Owner, Admin | Roles whose holders are site staff (comma-separated; - is no one) |
web_analytics_admin_network_hours | 24 | How long a staff sign-in marks its network; 0 turns that off |
web_analytics_hash_secret | generated | Secret mixed into the daily visitor hash |
The flags behind the three exclude_* keys are described in
PhoenixKitWebAnalytics.TrafficFlags. The internal networks themselves are
not a setting: every settings change is a permanent activity-log entry, and
this one would be the operator's own addresses. They come from the host's
runtime config instead:
config :phoenix_kit_web_analytics,
internal_networks: ["203.0.113.0/24", "2001:db8::/48"]
Summary
Functions
Whether the beacon / pixel endpoints accept hits.
Whether the optional client script's hits (clicks, scroll, leave) are accepted.
Every setting the collection path needs, in one cached read.
Default hours a staff sign-in marks its network for.
Default event param names whose values are kept.
The default path exclusions, used when the setting was never written.
Default LiveView event names that are never recorded.
The default staff roles: core's Owner and Admin.
Whether tracking is switched on.
Settings key for the module's master switch.
LiveView event param names whose short values an interaction keeps.
Raw path-exclusion setting value, for the settings form.
Whether path matches any exclusion pattern.
The PhoenixKitWebAnalytics.TrafficFlags bits the statistics leave out —
every bit unless a setting counts that kind of traffic in.
Generates and persists a new visitor hash salt, returning the one that ended
up stored (nil if it couldn't be written) — a rotation. The first salt is
created through hash_salt/0 instead, under a lock, so concurrent first
hits agree on it.
The geo resolver module, or nil when none is configured.
The secret mixed into the daily visitor hash, or nil when it can't be read
or created — in which case the hit is dropped rather than hashed with a
guessable fallback.
Whether a LiveView event is left out of the interaction record — either
interaction tracking is off, or the name is in the ignore list. A trailing
* in the list matches a prefix, as with path exclusions.
Every entry of internal_networks as configured, strings or not — so the
ones that aren't networks can be counted.
The networks whose traffic is the site's own, from the host's runtime
config (config :phoenix_kit_web_analytics, internal_networks: [...]) —
CIDR strings, IPv4 or IPv6. Read as configured; see
PhoenixKitWebAnalytics.InternalTraffic for how they are matched.
The module_key/0 these settings are attributed to.
Days of session recordings to keep (30 by default).
Days of raw events to keep. 0 disables pruning entirely (rollups are still
written).
Inactivity gap, in minutes, after which a new session starts.
Settings keys owned by this module, for the admin settings form.
Types
@type collection_config() :: %{ enabled?: boolean(), track_bots?: boolean(), detect_bots?: boolean(), respect_dnt?: boolean(), beacon_enabled?: boolean(), exclusions: [String.t()], session_timeout_minutes: pos_integer(), track_interactions?: boolean(), client_script?: boolean(), recording?: boolean(), recording_sample: 1..100, ignore_events: [String.t()], event_params: [String.t()], excluded_flags: non_neg_integer(), internal_roles: [String.t()], admin_network_hours: non_neg_integer() }
Functions
@spec beacon_enabled?() :: boolean()
Whether the beacon / pixel endpoints accept hits.
@spec client_script?() :: boolean()
Whether the optional client script's hits (clicks, scroll, leave) are accepted.
@spec collection_config() :: collection_config()
Every setting the collection path needs, in one cached read.
Returns defaults (with enabled?: false) if settings are unavailable, so a
caller can treat the result as authoritative without a rescue of its own.
@spec default_admin_network_hours() :: pos_integer()
Default hours a staff sign-in marks its network for.
@spec default_event_params() :: String.t()
Default event param names whose values are kept.
@spec default_exclusions() :: String.t()
The default path exclusions, used when the setting was never written.
@spec default_ignore_events() :: String.t()
Default LiveView event names that are never recorded.
@spec default_internal_roles() :: String.t()
The default staff roles: core's Owner and Admin.
@spec enabled?() :: boolean()
Whether tracking is switched on.
@spec enabled_key() :: String.t()
Settings key for the module's master switch.
@spec event_params() :: [String.t()]
LiveView event param names whose short values an interaction keeps.
@spec exclude_paths_raw() :: String.t()
Raw path-exclusion setting value, for the settings form.
Whether path matches any exclusion pattern.
A pattern is a literal path, optionally ending in * to match a prefix.
Matching is case-sensitive and anchored at the start of the path.
iex> PhoenixKitWebAnalytics.Config.excluded?("/admin/users", ["/admin*"])
true
iex> PhoenixKitWebAnalytics.Config.excluded?("/blog", ["/admin*"])
false
@spec excluded_flags() :: non_neg_integer()
The PhoenixKitWebAnalytics.TrafficFlags bits the statistics leave out —
every bit unless a setting counts that kind of traffic in.
@spec generate_salt() :: String.t() | nil
Generates and persists a new visitor hash salt, returning the one that ended
up stored (nil if it couldn't be written) — a rotation. The first salt is
created through hash_salt/0 instead, under a lock, so concurrent first
hits agree on it.
@spec geo_resolver() :: module() | nil
The geo resolver module, or nil when none is configured.
A resolver implements PhoenixKitWebAnalytics.Geo and turns an IP tuple
into %{country_code: _, region: _, city: _}. There is no bundled
implementation — no IP database ships with this package.
config :phoenix_kit_web_analytics, geo_resolver: MyApp.GeoIP
@spec hash_salt() :: String.t() | nil
The secret mixed into the daily visitor hash, or nil when it can't be read
or created — in which case the hit is dropped rather than hashed with a
guessable fallback.
Generated and persisted on first use. Losing it is harmless — it only means visitor IDs computed before and after the change don't line up — but it must never be exposed to clients, since the hash could then be recomputed from a guessed IP + User-Agent pair.
Whether a LiveView event is left out of the interaction record — either
interaction tracking is off, or the name is in the ignore list. A trailing
* in the list matches a prefix, as with path exclusions.
@spec internal_network_entries() :: list()
Every entry of internal_networks as configured, strings or not — so the
ones that aren't networks can be counted.
@spec internal_networks() :: [String.t()]
The networks whose traffic is the site's own, from the host's runtime
config (config :phoenix_kit_web_analytics, internal_networks: [...]) —
CIDR strings, IPv4 or IPv6. Read as configured; see
PhoenixKitWebAnalytics.InternalTraffic for how they are matched.
@spec module_key() :: String.t()
The module_key/0 these settings are attributed to.
@spec recording_retention_days() :: pos_integer()
Days of session recordings to keep (30 by default).
@spec retention_days() :: non_neg_integer()
Days of raw events to keep. 0 disables pruning entirely (rollups are still
written).
@spec session_timeout_minutes() :: pos_integer()
Inactivity gap, in minutes, after which a new session starts.
Settings keys owned by this module, for the admin settings form.