bleacherreport / plug_logger_json

Elixir Plug that formats http request logs as json
https://dev.bleacherreport.com/elixir-phoenix-centralized-http-logging-aa50efe3105b#.k00ri7og7
Apache License 2.0
132 stars 32 forks source link
elixir json logger logging plug

PlugLoggerJson

Hex pm Build Status License

A comprehensive JSON logger Plug.

Dependencies

Elixir & Erlang Support

The support policy is to support the last 2 major versions of Erlang and the three last minor versions of Elixir.

Installation

  1. add plug_logger_json to your list of dependencies in mix.exs:

    def deps do
     [{:plug_logger_json, "~> 0.7.0"}]
    end
  2. ensure plug_logger_json is started before your application (Skip if using Elixir 1.4 or greater):

    def application do
     [applications: [:plug_logger_json]]
    end
  3. Replace Plug.Logger with either:

    • Plug.LoggerJSON, log: Logger.level,
    • Plug.LoggerJSON, log: Logger.level, extra_attributes_fn: &MyPlug.extra_attributes/1 in your plug pipeline (in endpoint.ex for Phoenix apps),

Recommended Setup

Configure plug_logger_json

Add to your config/config.exs or config/env_name.exs if you want to filter params or headers or suppress any logged keys:

config :plug_logger_json,
  filtered_keys: ["password", "authorization"],
  suppressed_keys: ["api_version", "log_type"]

Configure the logger (console)

In your config/config.exs or config/env_name.exs:

config :logger, :console,
  format: "$message\n",
  level: :info, # You may want to make this an env variable to change verbosity of the logs
  metadata: [:request_id]

Configure the logger (file)

Do the following:

Error Logging

In router.ex of your Phoenix project or in your plug pipeline:

Extra Attributes

Additional data can be logged alongside the request by specifying a function to call which returns a map:

def extra_attributes(conn) do
  map = %{
    "user_id" => get_in(conn.assigns, [:user, :user_id]),
    "other_id" => get_in(conn.private, [:private_resource, :id]),
    "should_not_appear" => conn.private[:does_not_exist]
  }

  map
  |> Enum.filter(&(&1 !== nil))
  |> Enum.into(%{})
end

plug Plug.LoggerJSON,
  log: Logger.level(),
  extra_attributes_fn: &MyPlug.extra_attributes/1

In this example, the :user_id is retrieved from conn.assigns.user.user_id and added to the log if it exists. In the example, any values that are nil are filtered from the map. It is a requirement that the value is serialiazable as JSON by the Poison library, otherwise an error will be raised when attempting to encode the value.

Log Verbosity

LoggerJSON plug supports two levels of logging:

The above are default. It is possible to override them by setting a include_debug_logging option to:

Example:

plug Plug.LoggerJSON,
  log: Logger.level,
  include_debug_logging: true

Contributing

Before submitting your pull request, please run:

Please squash your pull request's commits into a single commit with a message and detailed description explaining the commit.