aws_ex_ray v0.1.3 AwsExRay
Preparation
Setup your AWS environment.
Run xray
daemon on an EC2 instance which you want your application run on.
https://docs.aws.amazon.com/xray/latest/devguide/xray-daemon.html
USAGE
trace = Trace.new()
segment = AwsExRay.start_tracing(trace, "root_segment_name")
do_your_job()
AwsExRay.finish_tracing(segment)
def do_your_job() do
current_trace = AwsExRay.start_subsegment("subsegment-name")
do_some_work()
case current_trace do
{:ok, subsegment} ->
AwsExRay.finish_subsegment(subsegment)
{:error, :out_of_xray} -> :ok # you need to do nothing.
end
AwsExRay.finish_subsegment(subsegment)
end
Multi Processes
Following example doesn’t work.
start_subsegment
returns always {:error, :out_of_xray}
.
Because the subsegment is not on the process which start tracing.
Pay attention when you use Task.Supervisor or GenServer.
segment = AwsExRay.start_tracing(trace, "root_segment_name")
Task.Supervisor.start_child(MyTaskSupervisor, fn ->
####################################################################
# this function is executed on different process as root-segment!!!
####################################################################
current_trace = AwsExRay.start_subsegment("subsegment-name")
do_some_work()
case current_trace do
{:ok, subsegment} ->
AwsExRay.finish_subsegment(subsegment)
{:error, :out_of_xray} -> :ok
end
end)
The solution.
Call AwsExRay.Process.keep_tracing(process_which_starts_tracing)
like following
segment = AwsExRay.start_tracing(trace, "root_segment_name")
tracing_pid = self()
Task.Supervisor.start_child(MyTaskSupervisor, fn ->
AwsExRay.Process.keep_tracing(tracing_pid)
current_trace = AwsExRay.start_subsegment("subsegment-name")
do_some_work()
case current_trace do
{:ok, subsegment} ->
AwsExRay.finish_subsegment(subsegment)
{:error, :out_of_xray} -> :ok
end
end)
Multi Servers
[client] --> [1: front_server] --> [2: internal_api or job_worker]
You can tracking Trace including (2) not only (1). If (2) server is HTTP server. You can put X-Amzn-Trace-Id into your requests HTTP headers.
calling internal api on (1)
If you use AwsExRay.HTTPoison, it’s easy. all you have to do is to set :traced
option.
options = [traced: true]
result = AwsExRay.HTTPoison.get(url, headers, options)
received internal request on (2)
If you setup AwsExRay.Plug, it automatically takes over tracing.
defmodule MyInternalAPIRouter do
use Plug.Router
plug AwsExRay.Plug, name: "my-internal-api"
WITHOUT SUPPORT LIBRARIES
You can directory pass Trace value
case AwsExRay.start_subsegment("internal-api-request", namespace: :remote) do
{:error, :out_of_xray} ->
pass_job_in_some_way(%{
your_job_data: ...
})
{:ok, subsegment} ->
pass_job_in_some_way(%{
your_job_data: ...
trace_value: Subsegment.generate_trace_value(subsegment)
})
AwsExRay.finish_subsegment(subsegment)
end
And job worker side, it can take over the Trace
job = receive_job_in_some_way()
case AwsExRay.Trace.parse(job.trace_value) do
{:ok, trace}
AwsExRay.start_tracing(trace, "internal-job-name")
:ok
{:error, :not_found} ->
:ok
end
Link to this section Summary
Link to this section Functions
finish_subsegment(subsegment :: AwsExRay.Subsegment.t(), end_time :: number()) :: :ok
finish_tracing(segment :: AwsExRay.Segment.t()) :: :ok
start_subsegment(name :: String.t(), opts :: keyword()) :: {:ok, AwsExRay.Subsegment.t()} | {:error, :out_of_xray}
start_tracing(trace :: AwsExRay.Trace.t(), name :: String.t()) :: AwsExRay.Segment.t()