【问题标题】:Elixir / Phoenix: How to customize HTTP request log format?Elixir / Phoenix:如何自定义 HTTP 请求日志格式?
【发布时间】:2019-10-29 05:40:57
【问题描述】:

默认情况下,我的 Phoenix 应用程序会在大约 5 行日志输出中记录有关每个 HTTP 请求的基本信息。只要我将日志级别设置为:debug,我就可以看到每个请求的方法、路径、控制器和操作、参数、响应代码和持续时间:

2019-06-14 16:05:35.099 [info] GET /manage/projects/7qDjSk
2019-06-14 16:05:35.103 [debug] Processing with RTLWeb.Manage.ProjectController.show/2
  Parameters: %{"project_uuid" => "7qDjSk"}
  Pipelines: [:browser, :require_login]
2019-06-14 16:05:35.116 [info] Sent 200 in 17ms

这是一个很好的起点。但我想自定义应用程序以将所有这些信息记录在一行上,这很有帮助,例如。在Papertrail 等工具中筛选大量日志输出时。特别是我希望每个请求都以如下格式显示:

[PUT /manage/projects/74/prompts/290] params=%{"project_uuid" => "74", "prompt" => %{"html" => "<div>Test question 3</div>"}, "prompt_uuid" => "290"} user=38 (Topher Hunt) status=302 redirected_to=/manage/projects/74 duration=423ms

the Phoenix.Controller docs 我看到我可以为 Phoenix 控制器日志配置日志级别,或者完全禁用它,但我没有看到自定义格式的方法。我该怎么做?

【问题讨论】:

    标签: logging elixir phoenix-framework


    【解决方案1】:

    这不是自定义输出的问题,而是 1) 禁用默认的与请求相关的日志语句(通过分离相关的 :telemetry 处理程序)然后 2) 添加一个新插件来记录格式 I想要。

    我是这样做的:

    • application.exstart/2 函数中,分离Phoenix 默认为您附加的遥测处理程序。 (致电:telemetry.list_handlers([]) 以查看所有已连接的侦听器。)

      def start(_type, _args) do
        # ...
      
        # vvv ADD THESE vvv
        :ok = :telemetry.detach({Phoenix.Logger, [:phoenix, :socket_connected]})
        :ok = :telemetry.detach({Phoenix.Logger, [:phoenix, :channel_joined]})
        :ok = :telemetry.detach({Phoenix.Logger, [:phoenix, :router_dispatch, :start]})
      
        # ...
        Supervisor.start_link(children, opts)
      
    • lib/my_app_web/endpoint.ex 中,注释掉Plug.Telemetry 插件。

    • lib/my_app_web/endpoint.ex 中,在 Plug.Session 之前添加这个自定义插件:

      # One-line request logging. Must come before the session & router plugs.
      plug MyAppWeb.RequestLogger
      
    • 最后,添加lib/my_app_web/plugs/request_logger.ex。 (相应地调整细节;这个实现假设登录的用户结构存储在conn.assigns.current_user):

      # One-line full request logging inspired by Plug.Logger.
      # See https://github.com/elixir-plug/plug/blob/v1.8.0/lib/plug/logger.ex
      # Need to restart the server after updating this file.
      defmodule MyAppWeb.RequestLogger do
        require Logger
      
        @behaviour Plug
      
        def init(opts), do: opts
      
        def call(conn, _opts) do
          start_time = System.monotonic_time()
      
          Plug.Conn.register_before_send(conn, fn(conn) ->
            # We don't want passwords etc. being logged
            params = inspect(Phoenix.Logger.filter_values(conn.params))
      
            # Log any important session data eg. logged-in user
            user = conn.assigns[:current_user]
            user_string = if user, do: "#{user.id} (#{user.name})", else: "(none)"
      
            # Note redirect, if any
            redirect = Plug.Conn.get_resp_header(conn, "location")
            redirect_string = if redirect != [], do: " redirected_to=#{redirect}", else: ""
      
            # Calculate time taken (in ms for consistency)
            stop_time = System.monotonic_time()
            time_us = System.convert_time_unit(stop_time - start_time, :native, :microsecond)
            time_ms = div(time_us, 100) / 10
      
            Logger.log(:info,
              "■ method=#{conn.method} path=#{conn.request_path} params=#{params} "<>
              "user=#{user_string} status=#{conn.status}#{redirect_string} duration=#{time_ms}ms"
            )
      
            conn
          end)
        end
      end
      
    • 重新启动服务器,您现在应该会看到每个请求只有一个日志行,格式如下:

    2019-06-09 18:18:51.410 [info] ■ [PUT /manage/projects/7qDjSk/prompts/3tUrF9] params=%{"project_uuid" =&gt; "7qDjSk", "prompt" =&gt; %{"html" =&gt; "&lt;div&gt;Test question 3&lt;/div&gt;"}, "prompt_uuid" =&gt; "3tUrF9"} user=1 (Topher Hunt) status=302 redirected_to=/manage/projects/7qDjSk duration=21ms

    (注意:另一种更好的最佳实践方法是 :telemetry.attach 到 Phoenix 已经发出的 [:phoenix, :router_dispatch, :stop] 事件。这提供了我们需要的所有数据;有关更多详细信息,请参阅 the Phoenix.Endpoint docs。)

    有用的参考资料:

    【讨论】:

      【解决方案2】:

      还有这个,如果你想要 JSON 输出:https://github.com/Nebo15/logger_json/tree/master/lib/logger_json

      【讨论】:

        猜你喜欢
        • 2019-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-08
        • 2023-01-17
        • 1970-01-01
        • 1970-01-01
        • 2022-12-09
        相关资源
        最近更新 更多