From fdd4b523edc5a26b56e98a5e02755dfc5b90618c Mon Sep 17 00:00:00 2001 From: crbelaus Date: Mon, 21 Apr 2025 16:48:23 +0200 Subject: [PATCH 1/2] Customize the Logger metadata key name In certain scenarios we may want to use the Plug.RequestID multiple times with different configuration options (maybe different headers or different assigns). While this is possible, the issue is that every call adds a `:request_id` key to the Logger metadata. When using the plug muliple times, the last call will override the metadata of the previous one. This commit adds a new `:log_as` option that allows users to customize how the request ID will be added to the logger metadata. If not provided, this option defaults to `:request_id` for backwards compatibility. --- lib/plug/request_id.ex | 13 ++++++++++--- test/plug/request_id_test.exs | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/plug/request_id.ex b/lib/plug/request_id.ex index 66e1116a..6280ef46 100644 --- a/lib/plug/request_id.ex +++ b/lib/plug/request_id.ex @@ -47,6 +47,12 @@ defmodule Plug.RequestId do plug Plug.RequestId, assign_as: :plug_request_id + * `:log_as` - The name of the key that will be used to store the + discovered or generated request id in `Logger` metadata. If not provided, + the request id will be stored as `:request_id`. + + plug Plug.RequestId, log_as: :my_request_id + """ require Logger @@ -57,15 +63,16 @@ defmodule Plug.RequestId do def init(opts) do { Keyword.get(opts, :http_header, "x-request-id"), - Keyword.get(opts, :assign_as) + Keyword.get(opts, :assign_as), + Keyword.get(opts, :log_as, :request_id) } end @impl true - def call(conn, {header, assign_as}) do + def call(conn, {header, assign_as, log_as}) do request_id = get_request_id(conn, header) - Logger.metadata(request_id: request_id) + Logger.metadata([{log_as, request_id}]) conn = if assign_as, do: Conn.assign(conn, assign_as, request_id), else: conn Conn.put_resp_header(conn, header, request_id) diff --git a/test/plug/request_id_test.exs b/test/plug/request_id_test.exs index 6c6bbaa7..fb37cf7b 100644 --- a/test/plug/request_id_test.exs +++ b/test/plug/request_id_test.exs @@ -82,6 +82,20 @@ defmodule Plug.RequestIdTest do assert res_request_id == meta_request_id end + test "adds the request id to Logger metadata with the given log key" do + request_id = "existingidthatislongenough" + + conn = + conn(:get, "/") + |> put_req_header("x-request-id", request_id) + |> call(log_as: :plug_request_id) + + [res_request_id] = get_resp_header(conn, "x-request-id") + meta_request_id = Logger.metadata()[:plug_request_id] + assert generated_request_id?(res_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 From 0442e0910bd862f17cb8811506a9e0418475013e Mon Sep 17 00:00:00 2001 From: crbelaus Date: Mon, 21 Apr 2025 20:38:35 +0200 Subject: [PATCH 2/2] Address pull request suggestions --- lib/plug/request_id.ex | 13 +++++++------ test/plug/request_id_test.exs | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/plug/request_id.ex b/lib/plug/request_id.ex index 6280ef46..7aaffc22 100644 --- a/lib/plug/request_id.ex +++ b/lib/plug/request_id.ex @@ -47,11 +47,12 @@ defmodule Plug.RequestId do plug Plug.RequestId, assign_as: :plug_request_id - * `:log_as` - The name of the key that will be used to store the + * `:logger_metadata_key` - The name of the key that will be used to store the discovered or generated request id in `Logger` metadata. If not provided, - the request id will be stored as `:request_id`. + the request ID Logger metadata will be stored as `:request_id`. *Available + since v1.18.0*. - plug Plug.RequestId, log_as: :my_request_id + plug Plug.RequestId, logger_metadata_key: :my_request_id """ @@ -64,15 +65,15 @@ defmodule Plug.RequestId do { Keyword.get(opts, :http_header, "x-request-id"), Keyword.get(opts, :assign_as), - Keyword.get(opts, :log_as, :request_id) + Keyword.get(opts, :logger_metadata_key, :request_id) } end @impl true - def call(conn, {header, assign_as, log_as}) do + def call(conn, {header, assign_as, logger_metadata_key}) do request_id = get_request_id(conn, header) - Logger.metadata([{log_as, request_id}]) + Logger.metadata([{logger_metadata_key, request_id}]) conn = if assign_as, do: Conn.assign(conn, assign_as, request_id), else: conn Conn.put_resp_header(conn, header, request_id) diff --git a/test/plug/request_id_test.exs b/test/plug/request_id_test.exs index fb37cf7b..d535fdd8 100644 --- a/test/plug/request_id_test.exs +++ b/test/plug/request_id_test.exs @@ -88,7 +88,7 @@ defmodule Plug.RequestIdTest do conn = conn(:get, "/") |> put_req_header("x-request-id", request_id) - |> call(log_as: :plug_request_id) + |> call(logger_metadata_key: :plug_request_id) [res_request_id] = get_resp_header(conn, "x-request-id") meta_request_id = Logger.metadata()[:plug_request_id]