Skip to content

Commit 74a8674

Browse files
authored
Expose generate_id function and make it configurable in request id (#1294)
1 parent a0e274b commit 74a8674

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

lib/plug/request_id.ex

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ defmodule Plug.RequestId do
5454
5555
plug Plug.RequestId, logger_metadata_key: :my_request_id
5656
57+
* `:generate_request_id` - The function used to generate the request ID, defaults to `generate_request_id/0`.
58+
59+
plug Plug.RequestId, generate_request_id: fn -> "myapp-" <> Plug.RequestId.generate_request_id() end
5760
"""
5861

5962
alias Plug.Conn
@@ -64,28 +67,31 @@ defmodule Plug.RequestId do
6467
{
6568
Keyword.get(opts, :http_header, "x-request-id"),
6669
Keyword.get(opts, :assign_as),
67-
Keyword.get(opts, :logger_metadata_key, :request_id)
70+
Keyword.get(opts, :logger_metadata_key, :request_id),
71+
Keyword.get(opts, :generate_request_id, &__MODULE__.generate_request_id/0)
6872
}
6973
end
7074

7175
@impl true
72-
def call(conn, {header, assign_as, logger_metadata_key}) do
73-
request_id = get_request_id(conn, header)
76+
def call(conn, {header, assign_as, logger_metadata_key, generate_request_id}) do
77+
request_id = get_request_id(conn, header, generate_request_id)
7478

7579
Logger.metadata([{logger_metadata_key, request_id}])
7680
conn = if assign_as, do: Conn.assign(conn, assign_as, request_id), else: conn
7781

7882
Conn.put_resp_header(conn, header, request_id)
7983
end
8084

81-
defp get_request_id(conn, header) do
85+
defp get_request_id(conn, header, generate_request_id) do
8286
case Conn.get_req_header(conn, header) do
83-
[] -> generate_request_id()
84-
[val | _] -> if valid_request_id?(val), do: val, else: generate_request_id()
87+
[val | _] when byte_size(val) in 20..200 -> val
88+
_ -> generate_request_id.()
8589
end
8690
end
8791

88-
defp generate_request_id do
92+
@doc "Generates Base64 encoded request ID."
93+
@spec generate_request_id :: binary()
94+
def generate_request_id do
8995
binary = <<
9096
System.system_time(:nanosecond)::64,
9197
:erlang.phash2({node(), self()}, 16_777_216)::24,
@@ -94,6 +100,4 @@ defmodule Plug.RequestId do
94100

95101
Base.url_encode64(binary)
96102
end
97-
98-
defp valid_request_id?(s), do: byte_size(s) in 20..200
99103
end

test/plug/request_id_test.exs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ defmodule Plug.RequestIdTest do
77
Plug.RequestId.call(conn, Plug.RequestId.init(opts))
88
end
99

10+
test "generates new request id with generate_request_id" do
11+
conn =
12+
call(conn(:get, "/"),
13+
generate_request_id: fn -> "myapp-" <> Plug.RequestId.generate_request_id() end
14+
)
15+
16+
[res_request_id] = get_resp_header(conn, "x-request-id")
17+
meta_request_id = Logger.metadata()[:request_id]
18+
assert generated_request_id?(res_request_id)
19+
assert res_request_id == meta_request_id
20+
assert String.starts_with?(res_request_id, "myapp-")
21+
end
22+
1023
test "generates new request id if none exists" do
1124
conn = call(conn(:get, "/"), [])
1225
[res_request_id] = get_resp_header(conn, "x-request-id")

0 commit comments

Comments
 (0)