Current section
Files
Jump to
Current section
Files
lib/scout_apm/internal/layer.ex
defmodule ScoutApm.Internal.Layer do
@type t :: %__MODULE__{
type: String.t,
name: nil | String.t,
desc: nil | String.t,
backtrace: nil | list(any()),
uri: nil | String.t,
started_at: number(),
stopped_at: nil | Integer,
manual_duration: nil | ScoutApm.Internal.Duration.t,
children: list(%__MODULE__{})
}
defstruct [
:type,
:name,
:desc,
:backtrace,
:uri,
:children,
:started_at,
:stopped_at,
# If this is set, ignore started_at -> stopped_at valuse when calculating
# how long this layer ran
:manual_duration,
]
alias ScoutApm.Internal.Duration
##################
# Construction #
##################
@spec new(map) :: __MODULE__.t
def new(%{type: type, name: name, started_at: started_at}) do
%__MODULE__{type: type, name: name, desc: nil, backtrace: nil, started_at: started_at, children: []}
end
def new(%{type: type, started_at: started_at}) do
%__MODULE__{type: type, name: nil, desc: nil, backtrace: nil, started_at: started_at, children: []}
end
def new(%{type: type, name: name}) do
started_at = System.monotonic_time(:microseconds)
%__MODULE__{type: type, name: name, desc: nil, backtrace: nil, started_at: started_at, children: []}
end
def new(%{type: type}) do
started_at = System.monotonic_time(:microseconds)
%__MODULE__{type: type, name: nil, desc: nil, backtrace: nil, started_at: started_at, children: []}
end
#######################
# Updater Functions #
#######################
# Don't update a name to become nil
def update_name(layer, nil), do: layer
def update_name(layer, name), do: %{layer | name: name}
def update_stopped_at(layer), do: update_stopped_at(layer, System.monotonic_time(:microseconds))
def update_stopped_at(layer, stopped_at) do
%{layer | stopped_at: stopped_at}
end
def update_children(layer, children) do
%{layer | children: children}
end
def update_desc(layer, desc) do
%{layer | desc: desc}
end
def update_backtrace(layer, backtrace) do
%{layer | backtrace: backtrace}
end
def update_uri(layer, uri) do
%{layer | uri: uri}
end
def set_manual_duration(layer, %Duration{}=duration) do
%{layer | manual_duration: duration}
end
#############
# Queries #
#############
def total_time(layer) do
case layer.manual_duration do
nil ->
Duration.new(layer.stopped_at - layer.started_at, :microseconds)
%Duration{} ->
layer.manual_duration
end
end
def total_child_time(layer) do
Enum.reduce(layer.children, Duration.zero(),
fn(child, acc) ->
Duration.add(acc, total_time(child))
end)
end
def total_exclusive_time(layer) do
Duration.subtract(total_time(layer), total_child_time(layer))
end
end