{"id":13508072,"url":"https://github.com/mneudert/plug_accesslog","last_synced_at":"2025-03-17T03:31:36.746Z","repository":{"id":25623207,"uuid":"29058427","full_name":"mneudert/plug_accesslog","owner":"mneudert","description":"Plug for writing access logs","archived":false,"fork":false,"pushed_at":"2022-01-04T10:50:55.000Z","size":334,"stargazers_count":31,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-27T17:35:10.762Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mneudert.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-10T13:46:02.000Z","updated_at":"2023-06-18T14:46:10.000Z","dependencies_parsed_at":"2022-08-24T14:09:43.540Z","dependency_job_id":null,"html_url":"https://github.com/mneudert/plug_accesslog","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mneudert%2Fplug_accesslog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mneudert%2Fplug_accesslog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mneudert%2Fplug_accesslog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mneudert%2Fplug_accesslog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mneudert","download_url":"https://codeload.github.com/mneudert/plug_accesslog/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243841207,"owners_count":20356443,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T02:00:47.461Z","updated_at":"2025-03-17T03:31:36.345Z","avatar_url":"https://github.com/mneudert.png","language":"Elixir","funding_links":[],"categories":["Framework Components"],"sub_categories":[],"readme":"# Plug.AccessLog\n\nPlug for writing access logs.\n\n## Setup\n\nTo use the plug in your projects, edit your mix.exs file and add the project as a dependency:\n\n```elixir\ndefp deps do\n  [\n    # ...\n    {:plug_accesslog, \"~\u003e 0.15.0\"},\n    # ...\n  ]\nend\n```\n\n## Usage\n\nAdd the plug to your plug pipeline/router:\n\n```elixir\ndefmodule AppRouter do\n  use Plug.Router\n\n  plug Plug.AccessLog,\n    format: :clf,\n    file: \"/path/to/your/logs/access.log\"\n\n  plug :match\n  plug :dispatch\n\n  get \"/hello\" do\n    send_resp(conn, 200, \"world\")\n  end\n\n  match _ do\n    send_resp(conn, 404, \"oops\")\n  end\nend\n```\n\n__Note__: The usage examples apply to a usecase where your are using `plug` directly without any framework. Using the `plug Plug.AccessLog` line in a framework based on `plug` should be no problem. Please refer to your frameworks individual documentation or source to find a suitable place.\n\n### WAL Configuration\n\nAll log messages that will be written to a file are collected in a WAL process\nbefore actual writing. The messages will be fetched in a configurable interval\nto be written to the logfiles:\n\n```elixir\nconfig :plug_accesslog,\n  :wal,\n    flush_interval: 100\n```\n\nThe time is configured as \"milliseconds between writing and flushing\". The default value is `100` milliseconds.\n\n### Custom Formatters\n\nIf you want to extend the formatting capabilities or replace existing ones you can define a custom formatter pipeline to use:\n\n```elixir\ndefmodule CustomFormatter do\n  @behaviour Plug.AccessLog.Formatter\n\n  def format(format, conn) do\n    # manipulate to your liking\n    format\n  end\nend\n\ndefmodule Router do\n  use Plug.Router\n\n  plug Plug.AccessLog,\n    format: :clf,\n    formatters: [CustomFormatter, Plug.AccessLog.DefaultFormatter],\n    file: \"/path/to/your/logs/access.log\"\nend\n```\n\nIf you do not configure a list of formatters only the `DefaultFormatter` will be used. If you define an empty list then no formatting will take place.\n\nAll formatters are called in the order they are defined in.\n\n### File Configuration\n\nThere are two ways to define the file you want log entries to be written to:\n\n```elixir\ndefmodule Router do\n  use Plug.Router\n\n  plug Plug.AccessLog, file: \"/static/configuration.log\"\n  plug Plug.AccessLog, file: {:system, \"SYS_ENV_VAR_WITH_FILE_PATH\"}\n  plug Plug.AccessLog, file: {:system, \"SYS_ENV_VAR\", \"/path/to/default.log\"}\nend\n```\n\n### Do Not Log Filter\n\nTo filter the requests before logging you can configure a \"do not log\" filter function:\n\n```elixir\ndefmodule LogFilter do\n  def dontlog?(%{request_path: \"/favicon.ico\"}), do: true\n  def dontlog?(_conn), do: false\nend\n\ndefmodule Router do\n  use Plug.Router\n\n  plug Plug.AccessLog,\n    dontlog: \u0026LogFilter.dontlog?/1,\n    format: :clf,\n    file: \"/path/to/your/logs/access.log\"\nend\n```\n\nIf the function you pass to the plug returns `true` the request will not be logged.\n\n### Logging Functions\n\nTo have the parsed log message sent to a logging function instead of writing it to a file you can configure a logging function:\n\n```elixir\ndefmodule InfoLogger do\n  def log(msg), do: Logger.log(:info, msg)\nend\n\ndefmodule Router do\n  use Plug.Router\n\n  plug Plug.AccessLog,\n    format: :clf,\n    fun: \u0026InfoLogger.log/1\nend\n```\n\nIf a logging function is configured the configured file (if any) will be ignored.\n\n## Log Format\n\nThe default format is [CLF](http://en.wikipedia.org/wiki/Common_Log_Format).\n\n### Available formats\n\nBesides a self defined format you can use one of the predefined aliases:\n\n```\n:agent\n\u003e %{User-Agent}i\n\u003e curl/7.35.0\n\n:clf\n\u003e %h %l %u %t \"%r\" %\u003es %b\n\u003e 127.0.0.1 - - [10/Jan/2015:14:46:18 +0100] \"GET / HTTP/1.1\" 200 31337\n\n:clf_vhost\n\u003e %v %h %l %u %t \"%r\" %\u003es %b\n\u003e www.example.com 127.0.0.1 - - [10/Jan/2015:14:46:18 +0100] \"GET / HTTP/1.1\" 200 31337\n\n:combined\n\u003e %h %l %u %t \"%r\" %\u003es %b \"%{Referer}i\" \"%{User-Agent}i\"\n\u003e 127.0.0.1 - - [22/Jan/2015:19:33:58 +0100] \"GET / HTTP/1.1\" 200 2 \"http://www.example.com/previous_page\" \"curl/7.35.0\"\n\n:combined_vhost\n\u003e %v %h %l %u %t \"%r\" %\u003es %b \"%{Referer}i\" \"%{User-Agent}i\"\n\u003e www.example.com 127.0.0.1 - - [22/Jan/2015:19:33:58 +0100] \"GET / HTTP/1.1\" 200 2 \"http://www.example.com/previous_page\" \"curl/7.35.0\"\n\n:referer\n\u003e %{Referer}i -\u003e %U\n\u003e http://www.example.com/previous_page -\u003e /\n```\n\nFor more details about each formatting token and potential modifications please refer to the `Plug.AccessLog.DefaultFormatter` module.\n\n## Benchmarking\n\nA small utility script is provided to check how long it might take to process requests and write the log messages to your disk:\n\n```shell\nmix run utils/bench.exs\n```\n\nThis call will send of a total of 10k requests and wait for them to be written to the disk.\n\nLooking at the data written to `utils/bench.log` might give a hint at what overhead the log writing is introducing. As with all \"benchmarks\" of any kind: take the measurements with a pinch of salt and run them in dozens of different conditions yourself.\n\n## License\n\n[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmneudert%2Fplug_accesslog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmneudert%2Fplug_accesslog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmneudert%2Fplug_accesslog/lists"}