View Source Uinta.Plug (Uinta v0.15.1)

This plug combines the request and response logs into a single line. This brings many benefits including:

  • Removing the need to visually match up the request and response makes it easier to read your logs and get a full picture of what has happened.

  • Having a single line for both request and response halves the number of request logs that your log aggregator will need to process and index, which leads to saved costs

In addition to combining the log lines, it also gives you the ability to output request logs in JSON format so that you can easily have your log aggregator parse the fields. To do this, pass json: true in the options when calling the plug.

You will also gain the ability to not log certain paths that are requested, as long as those paths return a 200-level status code. This can be particularly useful for things like not showing health checks in your logs to cut down on noise. To do this, just pass ignored_paths: ["/path_to_ignore"] in the options.

Finally, GraphQL requests will replace POST /graphql with the GraphQL operation type and name like QUERY getUser or MUTATION createUser if an operation name is provided. This will give you more visibility into your GraphQL requests without having to log out the entire request body or go into debug mode. If desired, the GraphQL variables can be included in the log line as well. The query can also be included if unnamed.

Installation

Installation of the plug will depend on how your app currently logs requests. Open YourApp.Endpoint and look for the following line:

plug Plug.Logger

If it exists in your endpoint, replace it with this (using the options you want):

plug Uinta.Plug,
  log: :info,
  format: :string,
  include_variables: false,
  ignored_paths: [],
  filter_variables: [],
  success_log_sampling_ratio: 1.0,
  include_datadog_fields: false

If your endpoint didn't call Plug.Logger, add the above line above the line that looks like this:

plug Plug.RequestId

Now you will also want to add the following anywhere in your main config file to make sure that you aren't logging each request twice:

config :phoenix, logger: false

Options

  • :log - The log level at which this plug should log its request info. Default is :info
    • Can be a {module, function_name, args} tuple where function is applied with conn prepended to args to determine log level.
  • :format - Output format, either :json, :string, or :map. Default is :string
  • :json - Whether or not plug should log in JSON format. Default is false (obsolete)
  • :ignored_paths - A list of paths that should not log requests. Default is [].
  • :include_variables - Whether or not to include any GraphQL variables in the log line when applicable. Default is false.
  • :filter_variables - A list of variable names that should be filtered out from the logs. By default password, passwordConfirmation, idToken, and refreshToken will be filtered.
  • :include_unnamed_queries - Whether or not to include the full query body for queries with no name supplied
  • :success_log_sampling_ratio - What percentage of successful requests should be logged. Defaults to 1.0
  • :include_datadog_fields - Whether or not to add logger specific field based on Datadog logger. Default is false. See https://docs.datadoghq.com/logs/log_configuration/attributes_naming_convention/#http-requests for details

Summary

Types

format()

@type format() :: :json | :map | :string

graphql_info()

@type graphql_info() :: %{
  type: String.t(),
  operation: String.t(),
  variables: String.t(),
  query: String.t() | nil
}

opts()

@type opts() :: %{
  level: Logger.level() | {module(), atom(), list()},
  format: format(),
  include_unnamed_queries: boolean(),
  include_variables: boolean(),
  include_datadog_fields: boolean(),
  ignored_paths: [String.t()],
  filter_variables: [String.t()]
}

Functions

client_ip(conn)