Logging Elixir/Phoenix:如何定制HTTP请求日志格式?
默认情况下,我的Phoenix应用程序会跨5行日志输出记录每个HTTP请求的基本信息。只要我将日志级别设置为Logging Elixir/Phoenix:如何定制HTTP请求日志格式?,logging,elixir,phoenix-framework,Logging,Elixir,Phoenix Framework,默认情况下,我的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 Par
: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
这是一个很好的起点。但我想定制应用程序,将所有这些信息记录在一行中,这很有帮助,例如,在像这样的工具中筛选大量日志输出时。我特别希望每个请求以如下格式显示:
[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
[PUT/manage/projects/74/prompts/290]参数=%%{“project\u uuid”=>“74”,“prompt”=>%%{“html”=>“测试问题3”},“prompt\u uuid”=>“290”}用户=38(Topher Hunt)状态=302重定向到=/manage/projects/74持续时间=423ms
在我看来,我可以为Phoenix控制器日志配置日志级别,或者完全禁用它,但我看不到自定义格式的方法。如何做到这一点?这不是自定义输出的问题,而是1)禁用与请求相关的默认日志语句(通过分离相关的
:遥测
处理程序),然后2)添加新的插件以记录我想要的格式
我是这样做的:
- 在
中的application.ex
功能中,默认情况下分离Phoenix为您连接的遥测处理程序。(调用start/2
以查看所有连接的侦听器。):遥测。列出\u处理程序([])
def start(_type,_args)do # ... #vvv添加这些vvv :ok=:telemetry.detach({Phoenix.Logger,[:Phoenix,:socket\u connected]}) :ok=:telemetry.detach({Phoenix.Logger,[:Phoenix,:channel_joined]}) :ok=:telemetry.detach({Phoenix.Logger,[:Phoenix,:router_dispatch,:start]}) # ... 主管。启动链接(儿童、选项)
- 在
中,注释掉lib/my\u app\u web/endpoint.ex
插件Plug.Telemetry
- 在
中,在plug.Session之前添加此自定义插件:lib/my\u app\u web/endpoint.ex
#单行请求日志记录。必须在会话和路由器插头之前到达。 插入MyAppWeb.RequestLogger
- 最后,添加
。(相应地调整详细信息;此实现假定登录的用户结构存储在lib/my\u app\u web/plugs/request\u logger.ex
)中:conn.assigns.current_user
#一行完整请求日志记录源于Plug.Logger。 #看https://github.com/elixir-plug/plug/blob/v1.8.0/lib/plug/logger.ex #更新此文件后需要重新启动服务器。 defmodule MyAppWeb.RequestLogger do 需要记录器 @行为插头 def初始化(选项),do:opts def呼叫(连接,选择)do 开始时间=系统。单调时间() 在发送前注册插头连接(连接,fn(连接)-> #我们不希望记录密码等 参数=检查(Phoenix.Logger.filter_值(conn.params)) #记录任何重要的会话数据,例如登录用户 user=conn.assigns[:当前用户] user_string=if user,do:“#{user.id}(#{user.name})”,否则:“(无)” #注:如有重定向 重定向=Plug.Conn.get_resp_头(Conn,“位置”) redirect_string=如果redirect!=[],则执行:“redirected_to=#{redirect}”,否则为“ #计算所用时间(一致性以毫秒为单位) 停止时间=系统。单调时间() 时间=系统。转换时间单位(停止时间-开始时间,:本机,:微秒) 时间=div(时间=100)/10 Logger.log(:info, "■ 方法=#{conn.method}path=#{conn.request_path}params=#{params}” “用户=#{user_string}状态=#{conn.status}#{redirect_string}持续时间=#{time_ms}ms” ) 康涅狄格州 (完) 结束 结束
- 重新启动服务器,现在每个请求只能看到一行日志,格式如下:
2019-06-0918:18:51.410[信息]■ [PUT/manage/projects/7qDjSk/prompts/3tUrF9]参数=%%{“project_uuid”=>“7qDjSk”,“prompt”=>%%{“html”=>“Test question 3”},“prompt_uuid”=>“3tUrF9”}用户=1(Topher Hunt)状态=302重定向到=/manage/projects/7qDjSk持续时间=21ms
(注意:另一个更好的实践方法是:遥测。将附加到phoenix已经发出的[:phoenix,:router\u dispatch,:stop]
事件。这提供了我们需要的所有数据;有关更多详细信息,请参阅。)
有用的参考资料:
如果您想要JSON输出,还有一个: