Packages

Plug for request-trace-id generation

Current section

Files

Jump to
request_trace_id lib request_trace_id.ex
Raw

lib/request_trace_id.ex

defmodule RequestTraceId do
@moduledoc """
A plug for creating unique span-ids on each request. Based on:
https://github.com/elixir-plug/plug/blob/
3d48af2b97d58c183a7b8390abc42ac5367b0770/lib/plug/request_id.ex#L1
The difference being that this plug will append a new span-id to the
request-trace-id header if there is already a value set instead of only
passing along the existing request-trace-id.
"""
require Logger
alias Plug.Conn
@behaviour Plug
@trace_id_header "x-request-trace-id"
def init([]), do: []
def call(conn, []) do
conn
|> Conn.get_req_header(@trace_id_header)
|> update_request_trace_id()
|> set_request_trace_id(conn)
end
defp set_request_trace_id(request_trace_id, conn) do
Logger.metadata(request_id: request_trace_id)
Conn.put_resp_header(conn, @trace_id_header, request_trace_id)
end
@doc """
Updates the request-trace-id by appending a new span-id or returning just a
new span-id if the request-trace-id is empty.
"""
@spec update_request_trace_id([String.t]) :: String.t
def update_request_trace_id([]) do
generate_span_id()
end
def update_request_trace_id(ids) when is_list(ids) do
"#{Enum.join(ids, ";")};#{generate_span_id()}"
end
@doc """
Generates a random id to represent the request.
"""
def generate_span_id do
Base.hex_encode32(:crypto.strong_rand_bytes(20), case: :lower)
end
end