我创建了我的第一个Elixir / Phoenix应用,我想记录访问者的IP地址。
在我的router.ex中,我正在"记录"实际存在的页面的IP地址。
def log_ip(conn, _) do
conn.remote_ip
|> Tuple.to_list
|> Enum.join(".")
|> IO.puts
conn
end
...
defmodule Mysite.Router do
use Mysite.Web, :router
pipeline :browser do
plug :log_ip
...
scope "/", Mysite do
pipe_through :browser
这一切通常都很好,但我在终端看到有些机器人试图访问不存在的页面,例如" /admin.php" ;," /command.php"。我想记录这些IP地址,但上面的代码不起作用。
潜在无关,但我也有这个代码来处理打到不存在的链接的人(例如/ blog / non-existing-page)
defimpl Plug.Exception, for: Phoenix.Template.UndefinedError do
def status(_exception), do: 404
end
有没有办法在返回404之前访问conn并记录remote_ip(或者更好的方法来处理所有这些)?
答案 0 :(得分:3)
您可以将记录器插头插入端点而不是路由器。端点位于lib/<yourapp>/endpoint.ex
。你会看到类似的东西:
...
plug Plug.RequestId
plug Plug.Logger
...
您可以将功能定义和plug :log_ip
调用放在这些之后。
答案 1 :(得分:0)
根据以上信息以及对Elixir登录的一些了解,这就是我的实现方式。
lib/myapp_web/plugs/client_ip_plug.ex
defmodule MyAppWeb.Plugs.ClientIp do
require Logger
@behaviour Plug
def init(opts), do: opts
def call(conn, _opts) do
Logger.metadata(client_ip: get_ip(conn))
conn
end
@doc """
This code is from Plausible Analytics https://github.com/plausible/analytics/blob/3a1c9e67cd67d5cb1fec68a4dee34f8cd0e056fd/lib/plausible_web/remote_ip.ex
"""
defp get_ip(conn) do
forwarded_for = List.first(Plug.Conn.get_req_header(conn, "x-forwarded-for"))
if forwarded_for do
String.split(forwarded_for, ",")
|> Enum.map(&String.trim/1)
|> List.first()
else
to_string(:inet_parse.ntoa(conn.remote_ip))
end
end
end
endpoint.ex
文件的这些行之间添加了我的Plug plug Plug.RequestId
plug MyAppWeb.Plugs.ClientIp
plug Plug.Logger
config/release.ex
config :logger, :console,
level: :info,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id, :client_ip]