Current section
Files
Jump to
Current section
Files
lib/utils/recorder.ex
defmodule SmartTracer.Utils.Recorder do
@moduledoc false
use Agent
require Logger
def start_recording() do
Agent.start_link(fn -> [] end, name: :trace_recorder)
end
def record(trace) do
if is_alive?() do
Agent.update(:trace_recorder, fn recordings -> [build_record(trace) | recordings] end)
else
recording_not_started_error()
end
end
def playback() do
if is_alive?() do
Agent.get(:trace_recorder, fn recordings -> Enum.reverse(recordings) end)
else
recording_not_started_error()
end
end
def stop() do
if is_alive?(), do: Agent.stop(:trace_recorder), else: :ok
end
def is_alive?() do
pid = Process.whereis(:trace_recorder)
not is_nil(pid)
end
defp build_record({:call, {module, func_name, args, erl_ts}}) do
%SmartTracer.Utils.Recorder.Call{
type: :call,
module: module,
function: func_name,
args: args,
arity: Enum.count(args),
datetime: get_datetime(erl_ts)
}
end
defp build_record({:return, {module, func_name, arity, return_value, erl_ts}}) do
%SmartTracer.Utils.Recorder.Return{
type: :return,
module: module,
function: func_name,
arity: arity,
return_value: return_value,
datetime: get_datetime(erl_ts)
}
end
defp get_datetime({megasec, sec, _}) do
unix_timestamp = megasec * 1_000_000 + sec
DateTime.from_unix!(unix_timestamp)
end
defp recording_not_started_error() do
Logger.error("""
Trace recording was not started.
Be sure to start the recording by using SmartTracer.start_recording/0
or by using `record: true` option when starting a trace.
""")
end
end