记录所有访问者的IP地址

时间:2016-09-02 02:37:44

标签: elixir phoenix-framework

我创建了我的第一个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(或者更好的方法来处理所有这些)?

2 个答案:

答案 0 :(得分:3)

您可以将记录器插头插入端点而不是路由器。端点位于lib/<yourapp>/endpoint.ex。你会看到类似的东西:

  ...
  plug Plug.RequestId
  plug Plug.Logger
  ...

您可以将功能定义和plug :log_ip调用放在这些之后。

答案 1 :(得分:0)

根据以上信息以及对Elixir登录的一些了解,这就是我的实现方式。

  1. 创建了文件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
  1. 像上面一样,我在endpoint.ex文件的这些行之间添加了我的Plug
  plug Plug.RequestId
  plug MyAppWeb.Plugs.ClientIp
  plug Plug.Logger
  1. 最后在要记录日志的记录器中使用,例如在config/release.ex
config :logger, :console,
  level: :info,
  format: "$time $metadata[$level] $message\n",
  metadata: [:request_id, :client_ip]