diff --git a/lib/plausible/application.ex b/lib/plausible/application.ex index b65d8c4a7fe9..2a4cb5e51a8f 100644 --- a/lib/plausible/application.ex +++ b/lib/plausible/application.ex @@ -16,7 +16,6 @@ defmodule Plausible.Application do children = [ Plausible.Session.BalancerSupervisor, - Plausible.Cache.Stats, Plausible.PromEx, {Plausible.Auth.TOTP.Vault, key: totp_vault_key()}, Plausible.Repo, @@ -152,7 +151,10 @@ defmodule Plausible.Application do Plausible.Ingestion.Source.init() Plausible.Geo.await_loader() - Supervisor.start_link(List.flatten(children), opts) + with {:ok, _pid} = ok <- Supervisor.start_link(List.flatten(children), opts) do + Plausible.Cache.Stats.attach() + ok + end end def config_change(changed, _new, removed) do diff --git a/lib/plausible/cache/adapter.ex b/lib/plausible/cache/adapter.ex index 644276004aa9..f5ecb55ee8a7 100644 --- a/lib/plausible/cache/adapter.ex +++ b/lib/plausible/cache/adapter.ex @@ -32,6 +32,7 @@ defmodule Plausible.Cache.Adapter do cache_name = Keyword.get(opts, :cache_name, name) child_id = Keyword.get(opts, :child_id, child_id) ttl_check_interval = Keyword.get(opts, :ttl_check_interval, false) + Plausible.Cache.Stats.create_counters(cache_name) opts = opts diff --git a/lib/plausible/cache/stats.ex b/lib/plausible/cache/stats.ex index 9ee4f0947f3b..e9d70c45db95 100644 --- a/lib/plausible/cache/stats.ex +++ b/lib/plausible/cache/stats.ex @@ -3,28 +3,13 @@ defmodule Plausible.Cache.Stats do Keeps track of hit/miss ratio for various caches. """ - use GenServer - @hit :hit @miss :miss @telemetry_hit ConCache.Operations.telemetry_hit() @telemetry_miss ConCache.Operations.telemetry_miss() @telemetry_events [@telemetry_hit, @telemetry_miss] - def start_link(_opts) do - GenServer.start_link(__MODULE__, nil) - end - - def init(nil) do - __MODULE__ = - :ets.new(__MODULE__, [ - :public, - :named_table, - :set, - read_concurrency: true, - write_concurrency: true - ]) - + def attach do :telemetry.attach_many( "plausible-cache-stats", @telemetry_events, @@ -35,6 +20,16 @@ defmodule Plausible.Cache.Stats do {:ok, nil} end + def create_counters(cache_name) do + :persistent_term.put({__MODULE__, cache_name, @hit}, :counters.new(1, [])) + :persistent_term.put({__MODULE__, cache_name, @miss}, :counters.new(1, [])) + end + + defp counter(cache_name, type) do + :persistent_term.get({__MODULE__, cache_name, type}, nil) || + raise "counter not found for #{cache_name} #{type}" + end + def handle_telemetry_event(@telemetry_hit, _measurments, %{cache: %{name: cache_name}}, _) do bump(cache_name, @hit) end @@ -54,12 +49,7 @@ defmodule Plausible.Cache.Stats do defdelegate size(cache_name), to: Plausible.Cache.Adapter def bump(cache_name, type) do - :ets.update_counter( - __MODULE__, - {cache_name, type}, - 1, - {{cache_name, type}, 0} - ) + :counters.add(counter(cache_name, type), 1, 1) end def hit_rate(cache_name) do @@ -68,23 +58,15 @@ defmodule Plausible.Cache.Stats do |> Enum.reduce( %{hit: 0, miss: 0, hit_miss: 0.0}, fn name, acc -> - hit = - acc.hit + :ets.lookup_element(__MODULE__, {name, @hit}, 2, 0) - - miss = - acc.miss + :ets.lookup_element(__MODULE__, {name, @miss}, 2, 0) - + hit = acc.hit + :counters.get(counter(name, @hit), 1) + miss = acc.miss + :counters.get(counter(name, @miss), 1) hit_miss = hit + miss - hit_miss = if(hit_miss == 0, do: 0.0, else: hit / hit_miss * 100) acc |> Map.put(:hit, hit) |> Map.put(:miss, miss) - |> Map.put( - :hit_miss, - hit_miss - ) + |> Map.put(:hit_miss, hit_miss) end ) |> Map.fetch!(:hit_miss)