2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ElixirのPlugで作ったWebサーバのログ出力をカスタマイズする

2
Last updated at Posted at 2019-10-23

まえがき

以前の記事「ElixirとPlugで静的Webサーバを作ってみる」で、Plug.Loggerモジュールの標準の形式でアクセスログの出力を行った。しかし、このままでは、出力サンプル程度のログ情報しか出力されないので、出力内容をカスタマイズする。

PlugパイプラインでのPlug.Loggerモジュール呼び出し

上記の記事のプログラムでは、Plugパイプラインの中でPlug.Loggerモジュールを呼び出している。ログ出力をカスタマイズするには、Plug.Loggerモジュールの代わりに、カスタマイズしたモジュールを呼び出す。

lib/simple_httpd/plug_top.ex
defmodule SimpleHttpd.PlugTop do
  ...
  def call(conn, [app: app]) do
    ...
    conn = Plug.Logger.call(conn, :debug)
    ...

ログ出力モジュールのカスタマイズ

Plug.Loggerモジュールの挙動は単純で、Plugパイプラインから呼び出される call/2ファンクションで、Conn.register_before_send/2ファンクションを使って、リクエストに対する処理が終わったときに、Logger.log/2ファンクションを呼び出して、ログ出力を行う。

Plugモジュールに組み込まれている Plug.Loggerモジュールの大まかな構成を図示する。

logger.ex
defmodule Plug.Logger do
  ...
  def  call(conn, level) do
    Logger.log(level, ...)      # リクエストに対する処理開始時点のログ出力
    ...
    Conn.register_before_send(conn, fn conn ->
      Logger.log(level, ...)    # リクエストに対する処理終了時点のログ出力
      conn
    end)
  end
end

ログ出力をカスタマイズするには、Plug.Loggerモジュールをひな形にして、自身のログ出力モジュールを作成すれば良い。以下に、サンプルを掲げる。

lib/simple_httpd/logger.ex
defmodule SimpleHttpd.Logger do
    require Logger

    def init(plug_opts) do
        plug_opts
    end

    def call(conn, level) do
        start = System.monotonic_time()
        Plug.Conn.register_before_send(conn, fn conn ->
            Logger.log(level, fn ->
                stop = System.monotonic_time()
                diff = System.convert_time_unit(stop - start, :native, :microsecond)
                # ログ出力データ。不正な文字のエスケープ等、適切なフォーマッティングを行うこと。
                [to_string(conn.scheme), ?,,
                 conn.method, ?,,
                 conn.request_path, ?,,
                 conn.query_string, ?,,
                 Integer.to_string(conn.status), ?,,
                 conn.host, ?,,
                 Integer.to_string(diff)]
            end)
            conn
        end)
    end
end

最後に、Plugパイプラインから、作成したモジュールを呼び出す。

    conn = SimpleHttpd.Logger.call(conn, :debug)

あるいは、Plug Builderで呼び出す。

    plug SimpleHttpd.Logger, log: :debug

Loggerによるログ出力は、実行のやり方に応じて、コンソールやファイルに出力される。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?