Plug.Metadata: Set Logger.metadata to provide conn request/response information

27 views
Skip to first unread message

Stephan Epping

unread,
Jul 21, 2017, 3:51:24 AM7/21/17
to elixir-lang-core
Hi,

I need to log additional request/response information, thus I came up with something like that:

defmodule Plug.Metadata do
  @moduledoc """
  A plug for setting request meta data for logging
  """

  require Logger
  alias Plug.Conn
  @behaviour Plug

  def init(opts) do
    Keyword.get(opts, :metadata, [:request_path])
  end

  def call(conn, metadata) do
    conn |> collect(metadata) |> Logger.metadata

    Conn.register_before_send(conn, fn conn ->
      conn |> collect([:status]) |> Logger.metadata
      conn
    end)

    conn
  end

  defp collect(conn, metadata) do
    for key <- metadata do
      {key, conn |> Map.get(key)}
    end
  end
end

Then I can use the plug as follows:

  plug Plug.RequestId
  plug Plug.Metadata
  plug Plug.Logger

One Issue here is that the Conn.register_before_send will be called after the Plug.Logger is being called, thus the response metadata are not available for the logger. One Solution would be to have a RequestMetadata and ResponseMetadata Plug like

  plug Plug.RequestId
  plug Plug.RequestMetadata
  plug Plug.Logger
  plug Plug.ResponseMetadata

Or would it be better to add a custom plug Plug.CommonLogger (like in rails/sinatra)?  The CommonLogger could in turn use the Plug.Logger? Is this something generally useful for the standard plugs? Then I would be happy to contribute.
Reply all
Reply to author
Forward
0 new messages