Skip to content

Commit

Permalink
Add assign_as option for Plug.RequestId (#1172)
Browse files Browse the repository at this point in the history
- `:assign_as` - The name of the key that will be used to store the
  discovered or generated request id in `conn.private`. If not provided,
  the request id will not be stored.

  ```elixir
  plug Plug.RequestId, assign_as: :plug_request_id
  ```

Resolves: #1171
  • Loading branch information
halostatue authored Oct 6, 2023
1 parent 8f1bf1c commit 64087f6
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
22 changes: 17 additions & 5 deletions lib/plug/request_id.ex
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ defmodule Plug.RequestId do
plug Plug.RequestId, http_header: "custom-request-id"
* `:assign_as` - The name of the key that will be used to store the
discovered or generated request id in `conn.assigns`. If not provided,
the request id will not be stored.
plug Plug.RequestId, assign_as: :plug_request_id
"""

require Logger
Expand All @@ -42,14 +48,17 @@ defmodule Plug.RequestId do

@impl true
def init(opts) do
Keyword.get(opts, :http_header, "x-request-id")
{
Keyword.get(opts, :http_header, "x-request-id"),
Keyword.get(opts, :assign_as)
}
end

@impl true
def call(conn, req_id_header) do
def call(conn, {header, assign_as}) do
conn
|> get_request_id(req_id_header)
|> set_request_id(req_id_header)
|> get_request_id(header)
|> set_request_id(header, assign_as)
end

defp get_request_id(conn, header) do
Expand All @@ -59,8 +68,11 @@ defmodule Plug.RequestId do
end
end

defp set_request_id({conn, request_id}, header) do
defp set_request_id({conn, request_id}, header, assign_as) do
Logger.metadata(request_id: request_id)

conn = if assign_as, do: Conn.assign(conn, assign_as, request_id), else: conn

Conn.put_resp_header(conn, header, request_id)
end

Expand Down
16 changes: 16 additions & 0 deletions test/plug/request_id_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ defmodule Plug.RequestIdTest do
assert res_request_id == meta_request_id
end

test "assigns the request id to conn.assigns when given an assignment key" do
request_id = "existingidthatislongenough"

conn =
conn(:get, "/")
|> put_req_header("x-request-id", request_id)
|> call(assign_as: :plug_request_id)

[res_request_id] = get_resp_header(conn, "x-request-id")
meta_request_id = Logger.metadata()[:request_id]
assigned_request_id = conn.assigns.plug_request_id
assert assigned_request_id == request_id
assert res_request_id == assigned_request_id
assert res_request_id == meta_request_id
end

defp generated_request_id?(request_id) do
Regex.match?(~r/\A[A-Za-z0-9-_]+\z/, request_id)
end
Expand Down

0 comments on commit 64087f6

Please sign in to comment.