Elixir 如何在Phoenix框架中运行响应后中间件功能?
我正在开发一个简单的网站在长生不老药与凤凰城。我想添加一些在生成响应后运行的自定义中间件。例如,为了记录每个响应中的总字节数,我希望有这样一个插件Elixir 如何在Phoenix框架中运行响应后中间件功能?,elixir,phoenix,plug,Elixir,Phoenix,Plug,我正在开发一个简单的网站在长生不老药与凤凰城。我想添加一些在生成响应后运行的自定义中间件。例如,为了记录每个响应中的总字节数,我希望有这样一个插件 defmodule HelloWeb.Plugs.ByteLogger do import Plug.Conn require Logger def init(default), do: default def call(conn, default) do log("bytes sent: #{String.le
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管道中使用此插件将无法工作,它们都是在响应呈现之前运行的。相反,它会导致
函数子句错误
,因为conn.resp_body
是nil
。我不知道如何使用此插件,以便在呈现响应后运行。我想您正在寻找
这允许注册在resp_body
设置为nil as之前调用的回调
应该是这样的:
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
作为字节大小:
不一定是字符串,可以是I/O列表resp\u body
应用于计数字节,byte\u size/1
返回UTF-8字形计数String.length/1
conn.resp_body |> to_string() |> byte_size()
似乎工作得很好,我想性能会更好。谢谢!我切换到
IO.iodata\u length(conn.resp\u body)
来设置响应大小,它似乎工作得很好,我不知道IO.iodata\u length/1
。显然,它在引擎盖下是完全相同的(&IO.iodata_length/1
的计算结果是&:erlang.iolist_size/1
,因为它是内联的),但使用起来感觉更好。直到,谢谢!