你如何 运行 中间件函数 post 在 Phoenix 框架中响应?
How do you run middleware functions post response in Phoenix framework?
我正在使用 Phoenix 在 Elixir 中开发一个简单的网站。我想添加一些自定义中间件,运行s after 已生成响应。例如,为了记录每个响应中的总字节数,我想要一个这样的插件
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-list
byte_size/1
应该用字节计数,String.length/1
returnsUTF-8字素计数
以下内容可以完成这项工作,但由于需要连接正文,因此会对性能产生重大影响:
conn.resp_body |> to_string() |> byte_size()
:erlang.iolist_size/1 似乎运作良好,我想更好 performance-wise.
我正在使用 Phoenix 在 Elixir 中开发一个简单的网站。我想添加一些自定义中间件,运行s after 已生成响应。例如,为了记录每个响应中的总字节数,我想要一个这样的插件
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-listbyte_size/1
应该用字节计数,String.length/1
returnsUTF-8字素计数
以下内容可以完成这项工作,但由于需要连接正文,因此会对性能产生重大影响:
conn.resp_body |> to_string() |> byte_size()
:erlang.iolist_size/1 似乎运作良好,我想更好 performance-wise.