如何解决您如何在Phoenix框架中运行响应后的中间件功能?
我正在与Phoenix一起在Elixir中开发一个简单的网站。我想添加一些在生成响应后 运行的自定义中间件。例如,为了记录每个响应中的字节总数,我想要一个这样的插件
defmodule HelloWeb.Plugs.ByteLogger do
import Plug.Conn
require Logger
def init(default),do: default
def call(conn,default) do
log("bytes sent: #{String.length(conn.resp_body)}")
end
end
尝试在路由器中的Phoenix管道之一中使用此插件无法正常工作,它们都在呈现响应之前运行。相反,它会导致FunctionClauseError
,因为conn.resp_body
是nil
。我不确定如何使用此插件,以便在响应呈现后即可运行。
解决方法
我认为您正在寻找register_before_send/2。
这允许将在resp_body
设置为nil之前将被调用的回调注册为explained here。
应该像这样:
defmodule HelloWeb.Plugs.ByteLogger do
import Plug.Conn
require Logger
def init(default),do: default
def call(conn,default) do
register_before_send(conn,fn conn ->
log("bytes sent: #{String.length(conn.resp_body)}")
conn
end)
end
end
编辑:我不认为您应该使用String.length
作为字节大小:
-
resp_body
不一定是字符串,可以是I / O列表 -
byte_size/1
用于计数字节,String.length/1
返回UTF-8字素计数
以下方法可以完成此任务,但是由于需要连接身体,因此对性能产生重大影响:
conn.resp_body |> to_string() |> byte_size()
:erlang.iolist_size/1似乎运行良好,我认为在性能方面要好得多。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。