【问题标题】:Logging IP Addresses for all visitors记录所有访问者的 IP 地址
【发布时间】:2023-04-11 10:51:02
【问题描述】:

我创建了我的第一个 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-existent-page)

defimpl Plug.Exception, for: Phoenix.Template.UndefinedError do
  def status(_exception), do: 404
end

有没有办法在我返回 404 之前访问 conn 并记录 remote_ip(或更好的方法来处理所有这些)?

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

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

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

    例如,您可以将函数定义和 plug :log_ip 调用放在这些之后。

    【讨论】:

    • 谢谢!我创建了一个模块插件(而不是使用功能插件),然后将“plug Mysite.Plugs.LogIp”添加到 endpoint.ex。
    【解决方案2】:

    根据上述信息和一些关于登录 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.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]
    

    【讨论】:

      猜你喜欢
      • 2013-02-05
      • 2015-02-09
      • 2021-01-20
      • 2023-03-31
      • 2023-03-31
      • 1970-01-01
      • 2015-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多