Current section
Files
Jump to
Current section
Files
lib/fluxter.ex
defmodule Fluxter do
defmacro __using__(_opts) do
quote [unquote: false, location: :keep] do
@pool_size Application.get_env(__MODULE__, :pool_size, 5)
@worker_names Enum.map(0..(@pool_size - 1), &:'#{__MODULE__}-#{&1}')
def start_link() do
import Supervisor.Spec
{host, port, prefix} = Fluxter.config_for(__MODULE__)
conn = Fluxter.Conn.new(host, port)
conn = %{conn | header: [conn.header | prefix]}
Enum.map(@worker_names, &worker(Fluxter.Conn, [conn, &1], id: &1))
|> Supervisor.start_link(strategy: :one_for_one)
end
@compile {:inline, worker_name: 1}
for {name, index} <- Enum.with_index(@worker_names) do
defp worker_name(unquote(index)) do
unquote(name)
end
end
def write(name, tags \\ [], fields)
def write(name, tags, fields) when is_list(fields) do
System.unique_integer([:positive])
|> rem(@pool_size)
|> worker_name()
|> Fluxter.Conn.write(name, tags, fields)
end
def write(name, tags, value)
when is_float(value) or is_integer(value)
when is_boolean(value) or is_binary(value) do
write(name, tags, [value: value])
end
def measure(name, tags \\ [], fields \\ [], fun)
when is_function(fun, 0) do
{elapsed, result} = :timer.tc(fun)
write(name, tags, [value: elapsed] ++ fields)
result
end
end
end
@doc false
def config_for(module) do
{loc_env, glob_env} =
Application.get_all_env(:fluxter)
|> Keyword.pop(module, [])
host = loc_env[:host] || glob_env[:host]
port = loc_env[:port] || glob_env[:port]
prefix = make_prefix(glob_env[:prefix], loc_env[:prefix])
{host, port, prefix}
end
defp make_prefix(global, local) do
Enum.map_join([global, local], &(&1 && [&1, ?_]))
end
end