From f5b4810313f5aad2ca36d42b1e92e8e1ac6d890c Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Tue, 24 Feb 2026 22:27:07 +0000 Subject: [PATCH 01/10] Bump version to 2.7.0 --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 11f21e2..c867229 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Instruments.Mixfile do use Mix.Project - @version "2.6.0" + @version "2.7.0" @github_url "https://github.com/discord/instruments" def project do From dc92cee86a96ad89b83f2a2b158aa48de6f1eec5 Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Tue, 24 Feb 2026 22:40:01 +0000 Subject: [PATCH 02/10] Upgrade statix to 1.6.0 --- mix.exs | 2 +- mix.lock | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mix.exs b/mix.exs index c867229..e6e7ad6 100644 --- a/mix.exs +++ b/mix.exs @@ -51,7 +51,7 @@ defmodule Instruments.Mixfile do {:benchee, "~> 1.4", only: :dev}, {:ex_doc, "~> 0.28", only: :dev, runtime: false}, {:recon, "~> 2.5.2"}, - {:statix, "~> 1.5.1", hex: :discord_statix}, + {:statix, "~> 1.6.0", hex: :discord_statix}, {:dialyxir, "~> 1.0", only: :dev, runtime: false} ] end diff --git a/mix.lock b/mix.lock index 793d38e..a722afe 100644 --- a/mix.lock +++ b/mix.lock @@ -2,7 +2,6 @@ "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dialyxir": {:hex, :dialyxir, "1.0.0", "6a1fa629f7881a9f5aaf3a78f094b2a51a0357c843871b8bc98824e7342d00a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "aeb06588145fac14ca08d8061a142d52753dbc2cf7f0d00fc1013f53f8654654"}, - "discord_statix": {:hex, :discord_statix, "1.5.1", "e0904aef402628beb91548f6e1b9d2f2a6923810605bc5a2ac56b22663c82610", [:mix], [], "hexpm", "dff9d1b114204fb7a49b429bdeaf24fe92576f63f2c756d9d89a3eadd2004a33"}, "earmark": {:hex, :earmark, "1.3.1", "73812f447f7a42358d3ba79283cfa3075a7580a3a2ed457616d6517ac3738cb9", [:mix], [], "hexpm", "000aaeff08919e95e7aea13e4af7b2b9734577b3e6a7c50ee31ee88cab6ec4fb"}, "earmark_parser": {:hex, :earmark_parser, "1.4.26", "f4291134583f373c7d8755566122908eb9662df4c4b63caa66a0eabe06569b0a", [:mix], [], "hexpm", "48d460899f8a0c52c5470676611c01f64f3337bad0b26ddab43648428d94aabc"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, @@ -13,5 +12,5 @@ "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, "recon": {:hex, :recon, "2.5.2", "cba53fa8db83ad968c9a652e09c3ed7ddcc4da434f27c3eaa9ca47ffb2b1ff03", [:mix, :rebar3], [], "hexpm", "2c7523c8dee91dff41f6b3d63cba2bd49eb6d2fe5bf1eec0df7f87eb5e230e1c"}, "statistex": {:hex, :statistex, "1.1.0", "7fec1eb2f580a0d2c1a05ed27396a084ab064a40cfc84246dbfb0c72a5c761e5", [:mix], [], "hexpm", "f5950ea26ad43246ba2cce54324ac394a4e7408fdcf98b8e230f503a0cba9cf5"}, - "statix": {:hex, :discord_statix, "1.5.1", "e0904aef402628beb91548f6e1b9d2f2a6923810605bc5a2ac56b22663c82610", [:mix], [], "hexpm", "dff9d1b114204fb7a49b429bdeaf24fe92576f63f2c756d9d89a3eadd2004a33"}, + "statix": {:hex, :discord_statix, "1.6.0", "4860b07ed7f3ac7085f55e3453003a29cc7ccc700b75db7bd999ace4c29be689", [:mix], [], "hexpm", "b093872d901005faff31dea0c0a6e05708461f62d6d41d824877b42fe444ba70"}, } From 0d3216cd42df5a412ce588d767a288fefcf04597 Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Tue, 24 Feb 2026 22:40:11 +0000 Subject: [PATCH 03/10] Bump version to 2.8.0 --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index e6e7ad6..3968a24 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Instruments.Mixfile do use Mix.Project - @version "2.7.0" + @version "2.8.0" @github_url "https://github.com/discord/instruments" def project do From a0516ff48510e072811be3027fb14fb1ce66e2e0 Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Fri, 6 Mar 2026 10:10:29 -0500 Subject: [PATCH 04/10] Add override for the number of logical processors in scheduler util reporting (#45) --- lib/probes/schedulers.ex | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/probes/schedulers.ex b/lib/probes/schedulers.ex index 26454e6..f03c933 100644 --- a/lib/probes/schedulers.ex +++ b/lib/probes/schedulers.ex @@ -10,8 +10,13 @@ defmodule Instruments.Probes.Schedulers do This module reports Erlang's internal view of its scheduler utilization and is a better gauge of how loaded your system is. It reports two values, the total - utilization, and a [weighted utilization](http://erlang.org/doc/man/erlang.html#statistics_scheduler_wall_time), - which can be used as a proxy for CPU usage. + utilization, and a [weighted + utilization](http://erlang.org/doc/man/erlang.html#statistics_scheduler_wall_time), + which can be used as a proxy for CPU usage. Weighted utilization is calculated + based on the number of logical CPUs available, but in containerized + environments, the number of CPUs available may differ from what erlang + reports. In these cases, you can override the count by configuring + `num_logical_processors_override` on the `instruments` application. To use this probe, add the following function somewhwere in your application's initialization: @@ -104,6 +109,16 @@ defmodule Instruments.Probes.Schedulers do end defp logical_processor_count() do + case Application.fetch_env(:instruments, :num_logical_processors_override) do + {:ok, override} when is_integer(override) -> + override + + :error -> + actual_logical_processor_count() + end + end + + defp actual_logical_processor_count() do case :erlang.system_info(:logical_processors_available) do :unknown -> :erlang.system_info(:logical_processors_online) From 45030d8ba6cdba896d67b98d5e9951a99309a4f6 Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Fri, 6 Mar 2026 15:11:24 +0000 Subject: [PATCH 05/10] Bump version to 2.9.0 --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 3968a24..00ec05a 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Instruments.Mixfile do use Mix.Project - @version "2.8.0" + @version "2.9.0" @github_url "https://github.com/discord/instruments" def project do From 2f545b38d0d83a6c769b299835c645f4f8e45f57 Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Fri, 6 Mar 2026 10:23:42 -0500 Subject: [PATCH 06/10] Upgrade statix to 1.7.0 (#46) --- mix.exs | 2 +- mix.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.exs b/mix.exs index 00ec05a..b68dc2e 100644 --- a/mix.exs +++ b/mix.exs @@ -51,7 +51,7 @@ defmodule Instruments.Mixfile do {:benchee, "~> 1.4", only: :dev}, {:ex_doc, "~> 0.28", only: :dev, runtime: false}, {:recon, "~> 2.5.2"}, - {:statix, "~> 1.6.0", hex: :discord_statix}, + {:statix, "~> 1.7.0", hex: :discord_statix}, {:dialyxir, "~> 1.0", only: :dev, runtime: false} ] end diff --git a/mix.lock b/mix.lock index a722afe..ae77b56 100644 --- a/mix.lock +++ b/mix.lock @@ -12,5 +12,5 @@ "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, "recon": {:hex, :recon, "2.5.2", "cba53fa8db83ad968c9a652e09c3ed7ddcc4da434f27c3eaa9ca47ffb2b1ff03", [:mix, :rebar3], [], "hexpm", "2c7523c8dee91dff41f6b3d63cba2bd49eb6d2fe5bf1eec0df7f87eb5e230e1c"}, "statistex": {:hex, :statistex, "1.1.0", "7fec1eb2f580a0d2c1a05ed27396a084ab064a40cfc84246dbfb0c72a5c761e5", [:mix], [], "hexpm", "f5950ea26ad43246ba2cce54324ac394a4e7408fdcf98b8e230f503a0cba9cf5"}, - "statix": {:hex, :discord_statix, "1.6.0", "4860b07ed7f3ac7085f55e3453003a29cc7ccc700b75db7bd999ace4c29be689", [:mix], [], "hexpm", "b093872d901005faff31dea0c0a6e05708461f62d6d41d824877b42fe444ba70"}, + "statix": {:hex, :discord_statix, "1.7.0", "f84140caed09177da1952bef3f92eb9b94a1acc8c2de0b7826bf7a6002c017b6", [:mix], [], "hexpm", "3c316994c334d4d41d45cb5e2a67efb399327c4de5e65f01e52ab61eefd7eed9"}, } From 68f64da7472d545baec982464907c7fe18981a5c Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Fri, 6 Mar 2026 15:24:03 +0000 Subject: [PATCH 07/10] Bump version to 2.10 --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index b68dc2e..d7a6ffb 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Instruments.Mixfile do use Mix.Project - @version "2.9.0" + @version "2.10.0" @github_url "https://github.com/discord/instruments" def project do From a1c605c7efd43ae3633d5ab540dd72fc6563ec67 Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Thu, 12 Mar 2026 08:58:47 -0400 Subject: [PATCH 08/10] Use Statix-based event sending (#47) --- lib/instruments.ex | 30 +----------------------------- lib/stats_reporter.ex | 7 +++++++ lib/stats_reporter/logger.ex | 5 +++++ lib/stats_reporter/null.ex | 3 +++ mix.exs | 2 +- mix.lock | 2 +- 6 files changed, 18 insertions(+), 31 deletions(-) diff --git a/lib/instruments.ex b/lib/instruments.ex index 953d13a..5f27282 100644 --- a/lib/instruments.ex +++ b/lib/instruments.ex @@ -175,35 +175,7 @@ defmodule Instruments do title_iodata = MacroHelpers.to_iolist(title_ast, __CALLER__) quote do - title = unquote(title_iodata) - - header = [ - "_e{", - Integer.to_charlist(IO.iodata_length(title)), - ",", - Integer.to_charlist(IO.iodata_length(unquote(text))), - "}:", - title, - "|", - unquote(text) - ] - - message = - case Keyword.get(unquote(opts), :tags) do - nil -> - header - - tag_list -> - [header, "|#", Enum.intersperse(tag_list, ",")] - end - - # Statix registers a port to the name of the metrics module. - # and this code assumes that the metrics module is bound to - # a port, and sends directly to it. If we move off of Statix, - # this will have to be changed. - unquote(@metrics_module) - |> Process.whereis() - |> :gen_udp.send('localhost', Instruments.statsd_port(), message) + unquote(@metrics_module).send_event(unquote(title_iodata), unquote(text), unquote(opts)) end end diff --git a/lib/stats_reporter.ex b/lib/stats_reporter.ex index 6b18029..e1c625f 100644 --- a/lib/stats_reporter.ex +++ b/lib/stats_reporter.ex @@ -52,4 +52,11 @@ defmodule Instruments.StatsReporter do Write the value into the set defined by `key` """ @callback set(key, integer, keyword) :: stats_return + + @doc """ + Send a DataDog event with the given title and text + """ + @callback send_event(title :: iodata, text :: iodata, keyword) :: stats_return + + @optional_callbacks [send_event: 3] end diff --git a/lib/stats_reporter/logger.ex b/lib/stats_reporter/logger.ex index ec99c78..129f273 100644 --- a/lib/stats_reporter/logger.ex +++ b/lib/stats_reporter/logger.ex @@ -45,4 +45,9 @@ defmodule Instruments.StatsReporter.Logger do def set(key, value, _options \\ []) do Logger.info("setting #{key} to #{value}") end + + @doc false + def send_event(title, text, _options \\ []) do + Logger.info("event #{title}: #{text}") + end end diff --git a/lib/stats_reporter/null.ex b/lib/stats_reporter/null.ex index c26fe42..cc20b26 100644 --- a/lib/stats_reporter/null.ex +++ b/lib/stats_reporter/null.ex @@ -28,4 +28,7 @@ defmodule Instruments.StatsReporter.Null do @doc false def set(_key, _value, _options \\ []), do: :ok + + @doc false + def send_event(_title, _text, _options \\ []), do: :ok end diff --git a/mix.exs b/mix.exs index d7a6ffb..f86fa30 100644 --- a/mix.exs +++ b/mix.exs @@ -51,7 +51,7 @@ defmodule Instruments.Mixfile do {:benchee, "~> 1.4", only: :dev}, {:ex_doc, "~> 0.28", only: :dev, runtime: false}, {:recon, "~> 2.5.2"}, - {:statix, "~> 1.7.0", hex: :discord_statix}, + {:statix, "~> 1.8.0", hex: :discord_statix}, {:dialyxir, "~> 1.0", only: :dev, runtime: false} ] end diff --git a/mix.lock b/mix.lock index ae77b56..3de1941 100644 --- a/mix.lock +++ b/mix.lock @@ -12,5 +12,5 @@ "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, "recon": {:hex, :recon, "2.5.2", "cba53fa8db83ad968c9a652e09c3ed7ddcc4da434f27c3eaa9ca47ffb2b1ff03", [:mix, :rebar3], [], "hexpm", "2c7523c8dee91dff41f6b3d63cba2bd49eb6d2fe5bf1eec0df7f87eb5e230e1c"}, "statistex": {:hex, :statistex, "1.1.0", "7fec1eb2f580a0d2c1a05ed27396a084ab064a40cfc84246dbfb0c72a5c761e5", [:mix], [], "hexpm", "f5950ea26ad43246ba2cce54324ac394a4e7408fdcf98b8e230f503a0cba9cf5"}, - "statix": {:hex, :discord_statix, "1.7.0", "f84140caed09177da1952bef3f92eb9b94a1acc8c2de0b7826bf7a6002c017b6", [:mix], [], "hexpm", "3c316994c334d4d41d45cb5e2a67efb399327c4de5e65f01e52ab61eefd7eed9"}, + "statix": {:hex, :discord_statix, "1.8.0", "11a5daa60029b39cfab2e11f7158bb1be3a426a9349731145184c3e257bd820a", [:mix], [], "hexpm", "a840f9c2f5789986830cb259e50947c5263c09eaf8c1662b9511f28e772a7acd"}, } From 906a6cd309533a16a71d39e158874a4a76fbc951 Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Thu, 12 Mar 2026 12:59:18 +0000 Subject: [PATCH 09/10] Bump version to 2.11 --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index f86fa30..cd2593d 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Instruments.Mixfile do use Mix.Project - @version "2.10.0" + @version "2.11.0" @github_url "https://github.com/discord/instruments" def project do From 0845a7c37ae32f57abe8b9ab0a80b31fd29967e4 Mon Sep 17 00:00:00 2001 From: itsWill Date: Tue, 24 Mar 2026 08:06:08 -0400 Subject: [PATCH 10/10] Restore custom distribution/3 implementation Statix 1.7.0 does not natively support the distribution metric type, so we need to keep our custom UDP-based implementation. --- lib/instruments/statix.ex | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/instruments/statix.ex b/lib/instruments/statix.ex index f14032f..3f09e31 100644 --- a/lib/instruments/statix.ex +++ b/lib/instruments/statix.ex @@ -3,4 +3,21 @@ defmodule Instruments.Statix do The default stats reporter. Uses the `Statix` library. """ use Statix, runtime_config: true + + def distribution(key, val, options \\ []) do + %{conn: %{prefix: prefix}} = current_statix() + + message = + case Keyword.get(options, :tags) do + nil -> + [prefix, key, ?:, to_string(val), "|d"] + + tag_list -> + [prefix, key, ?:, to_string(val), "|d|#", Enum.intersperse(tag_list, ",")] + end + + __MODULE__ + |> Process.whereis() + |> :gen_udp.send(Instruments.statsd_host(), Instruments.statsd_port(), message) + end end