From d5ba5613cee67767bdb997cd74e0914a86cae631 Mon Sep 17 00:00:00 2001 From: Yaroslav Martsynyuk Date: Fri, 30 Mar 2018 17:41:54 +0300 Subject: [PATCH 1/3] Add ability to set global sample rate in config --- lib/statix.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/statix.ex b/lib/statix.ex index 1aea06a..024f89c 100644 --- a/lib/statix.ex +++ b/lib/statix.ex @@ -335,7 +335,7 @@ defmodule Statix do @doc false def transmit(conn, type, key, val, options) when (is_binary(key) or is_list(key)) and is_list(options) do - sample_rate = Keyword.get(options, :sample_rate) + sample_rate = Keyword.get(options, :sample_rate, Application.get_env(:statix, :sample_rate)) if is_nil(sample_rate) or sample_rate >= :rand.uniform() do Conn.transmit(conn, type, key, to_string(val), options) else From dc7ee61da67f9d71bceb336a30ec5bb2c935d5dd Mon Sep 17 00:00:00 2001 From: Yaroslav Martsynyuk Date: Fri, 30 Mar 2018 18:36:32 +0300 Subject: [PATCH 2/3] Update README.md --- README.md | 6 ++++++ lib/statix.ex | 1 + 2 files changed, 7 insertions(+) diff --git a/README.md b/README.md index 8ad14fd..68e2f8b 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,12 @@ Sampling is supported via the `:sample_rate` option: MyApp.Statix.increment("page_view", 1, sample_rate: 0.5) ``` +Or by setting global `:sample_rate` in config: +```elixir +config :statix, + sample_rate: 0.1 +``` + The UDP packet will only be sent to the server about half of the time, but the resulting value will be adjusted on the server according to the given sample rate. diff --git a/lib/statix.ex b/lib/statix.ex index 024f89c..bcb3a49 100644 --- a/lib/statix.ex +++ b/lib/statix.ex @@ -337,6 +337,7 @@ defmodule Statix do when (is_binary(key) or is_list(key)) and is_list(options) do sample_rate = Keyword.get(options, :sample_rate, Application.get_env(:statix, :sample_rate)) if is_nil(sample_rate) or sample_rate >= :rand.uniform() do + options = Keyword.put_new(options, :sample_rate, sample_rate) Conn.transmit(conn, type, key, to_string(val), options) else :ok From 4833f62e69b7e44e47dace6375e5b83b2a68a5ef Mon Sep 17 00:00:00 2001 From: Yaroslav Martsynyuk Date: Tue, 17 Apr 2018 18:09:33 +0300 Subject: [PATCH 3/3] Store global sample_rate in Conn struct --- README.md | 1 + lib/statix.ex | 17 ++++++++++------- lib/statix/conn.ex | 12 ++++++------ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 68e2f8b..e75db57 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,7 @@ The defaults are: * prefix: `nil` * host: `"127.0.0.1"` * port: `8125` +* sample_rate: `1.0` __Note:__ by default, configuration is evaluated once, at compile time. If you plan using other configuration at runtime, you must specify the `:runtime_config` option: diff --git a/lib/statix.ex b/lib/statix.ex index bcb3a49..5a62569 100644 --- a/lib/statix.ex +++ b/lib/statix.ex @@ -236,10 +236,12 @@ defmodule Statix do if Keyword.get(opts, :runtime_config, false) do quote do @statix_header_key Module.concat(__MODULE__, :__statix_header__) + @statix_sample_rate_key Module.concat(__MODULE__, :__statix_sample_rate__) def connect() do conn = Statix.new_conn(__MODULE__) Application.put_env(:statix, @statix_header_key, conn.header) + Application.put_env(:statix, @statix_sample_rate_key, conn.sample_rate) Statix.open_conn(conn) :ok @@ -248,7 +250,8 @@ defmodule Statix do @compile {:inline, [current_conn: 0]} defp current_conn() do header = Application.fetch_env!(:statix, @statix_header_key) - %Statix.Conn{header: header, sock: __MODULE__} + sample_rate = Application.fetch_env!(:statix, @statix_sample_rate_key) + %Statix.Conn{header: header, sock: __MODULE__, sample_rate: sample_rate} end end else @@ -320,10 +323,10 @@ defmodule Statix do @doc false def new_conn(module) do - {host, port, prefix} = load_config(module) - conn = Conn.new(host, port) + {host, port, prefix, sample_rate} = load_config(module) + conn = Conn.new(host, port, sample_rate) header = IO.iodata_to_binary([conn.header | prefix]) - %{conn | header: header, sock: module} + %{conn | header: header, sock: module, sample_rate: sample_rate} end @doc false @@ -335,9 +338,8 @@ defmodule Statix do @doc false def transmit(conn, type, key, val, options) when (is_binary(key) or is_list(key)) and is_list(options) do - sample_rate = Keyword.get(options, :sample_rate, Application.get_env(:statix, :sample_rate)) + sample_rate = Keyword.get(options, :sample_rate, conn.sample_rate) if is_nil(sample_rate) or sample_rate >= :rand.uniform() do - options = Keyword.put_new(options, :sample_rate, sample_rate) Conn.transmit(conn, type, key, to_string(val), options) else :ok @@ -354,8 +356,9 @@ defmodule Statix do host = Keyword.get(env, :host, "127.0.0.1") port = Keyword.get(env, :port, 8125) + sample_rate = Keyword.get(env, :sample_rate, 1.0) prefix = build_prefix(prefix1, prefix2) - {host, port, prefix} + {host, port, prefix, sample_rate} end defp build_prefix(part1, part2) do diff --git a/lib/statix/conn.ex b/lib/statix/conn.ex index 8dc4c77..a27906c 100644 --- a/lib/statix/conn.ex +++ b/lib/statix/conn.ex @@ -1,18 +1,18 @@ defmodule Statix.Conn do @moduledoc false - defstruct [:sock, :header] + defstruct [:sock, :header, :sample_rate] alias Statix.Packet - def new(host, port) when is_binary(host) do - new(string_to_charlist(host), port) + def new(host, port, sample_rate) when is_binary(host) do + new(string_to_charlist(host), port, sample_rate) end - def new(host, port) when is_list(host) or is_tuple(host) do + def new(host, port, sample_rate) when is_list(host) or is_tuple(host) do {:ok, addr} = :inet.getaddr(host, :inet) header = Packet.header(addr, port) - %__MODULE__{header: header} + %__MODULE__{header: header, sample_rate: sample_rate} end def open(%__MODULE__{} = conn) do @@ -32,7 +32,7 @@ defmodule Statix.Conn do {:inet_reply, _port, status} -> status end end - + if Version.match?(System.version(), ">= 1.3.0") do defp string_to_charlist(string), do: String.to_charlist(string) else