Current section
Files
Jump to
Current section
Files
lib/chaperon/export/influx_db.ex
if Application.get_env(:doma_chaperon, Chaperon.Export.InfluxDB, false) do
defmodule Chaperon.Export.InfluxDB do
@moduledoc """
InfluxDB metric export module.
"""
defmodule LoadTestMeasurement do
@moduledoc false
use Instream.Series
alias Chaperon.Scenario.Metrics
alias Chaperon.Util
series do
measurement("load_test")
tag(:tag)
tag(:action)
tag(:session)
tag(:load_test)
field(:duration)
field(:total_count)
field(:max)
field(:mean)
field(:min)
for p <- Metrics.percentiles() do
field(Util.percentile_name(p))
end
end
end
@behaviour Chaperon.Exporter
use Instream.Connection, otp_app: :doma_chaperon
alias Chaperon.Util
alias __MODULE__.LoadTestMeasurement
require Logger
@impl Chaperon.Exporter
def write_output(lt_mod, _options, data, _) do
Logger.info("Writing data for #{Chaperon.LoadTest.name(lt_mod)} to InfluxDB")
for d <- data do
:ok = __MODULE__.write(d)
end
:ok
end
@doc """
Sends metrics of given `session` to InfluxDB in `LoadTestMeasurement` format.
"""
@impl Chaperon.Exporter
def encode(session, opts \\ []) do
data =
session.metrics
|> Enum.flat_map(fn
{{:call, {mod, func}}, vals} ->
mod_name = Util.shortened_module_name(mod)
encode_runs(vals, "call(#{mod_name}.#{func})", opts)
{{{:error, {:http, code}}, {action, url}}, vals} ->
encode_runs(vals, "error.http.#{code}(#{action}(#{url}))", opts)
{{action, url}, vals} ->
encode_runs(vals, "#{action}(#{url})", opts)
{action, vals} ->
encode_runs(vals, "#{action}", opts)
end)
{:ok, data}
end
def encode_runs(runs, action_name, opts) when is_list(runs) do
runs
|> Enum.map(&encode_run(&1, action_name, opts))
end
def encode_runs(run, action_name, opts) do
[encode_run(run, action_name, opts)]
end
def encode_run(vals, action_name, opts) do
session_name = vals[:session_name]
data = %LoadTestMeasurement{}
%{
data
| tags: %{
data.tags
| tag: opts[:tag],
session: session_name,
action: action_name,
load_test: opts[:load_test]
},
fields: Map.merge(data.fields, measurement_fields(vals, opts))
}
end
defp measurement_fields(vals, opts) do
vals
|> percentile_fields
|> Map.merge(%{
duration: opts[:duration],
total_count: vals[:total_count],
max: vals[:max],
mean: vals[:mean],
min: vals[:min]
})
end
defp percentile_fields(vals) do
Chaperon.Scenario.Metrics.percentiles()
|> Enum.map(fn p ->
{Util.percentile_name(p), vals[{:percentile, p}]}
end)
|> Enum.into(%{})
end
end
end