README.md

# Canonical Logs

Inspired by the [legendary Stripe blog post](https://stripe.com/blog/canonical-log-lines), this library consolidates your Plug/Phoenix/Absinthe request logs into a single log line with all of their relevant information for easier querying.

<!-- ## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `canonical_logs` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:canonical_logs, "~> 0.1.0"}
  ]
end
```

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at <https://hexdocs.pm/canonical_logs>.
 -->
## Installation

Add `canonical_logs` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:canonical_logs, "~> 0.1.0"}
  ]
end
```

## Usage

In your `application.ex`, add the following to the top of your `start/2` function:

```elixir
  CanonicalLogs.attach()
```

or

```elixir
  CanonicalLogs.attach(
    conn_metadata: [:request_path, :method, :status, :params]
    filter_metadata_recursively: []
  )
```

Canonical Logs is built off of `Plug.Telemetry` events. If you use Phoenix, you'll find it called in your `<APP_NAME>Web.Endpoint` module.

Wherever the plug is used, modify the line to add the option `log: false`, like so:

```elixir
  plug(Plug.Telemetry, event_prefix: [:phoenix, :endpoint], log: false)
```

That's it! There's configuration options and more in [the docs](https://hexdocs.pm/canonical_logs).

### Absinthe

`CanonicalLogs.Absinthe` is included to allow providing the GraphQL operation name and variables as metadata. Just after `CanonicalLogs.attach/1`, add:

```elixir
  CanonicalLogs.Absinthe.attach()
```

Additionally, it would make sense to update the `:conn_metadata` configuration to not include `:params`.

### Configuration

* `:conn_metadata`: Metadata to be pulled from the [`Plug.Conn`](https://hexdocs.pm/plug/Plug.Conn.html) during a `Plug.Telemetry` `:stop` event.
* `filter_metadata_recursively`: Metadata that if if the key includes this string at any depth will have its value replaced with `"[FILTERED]"`.

## Todo

- [ ] Use `Application.get_env/3`-based config, like what's often used in `config/config.exs` and `config/test.exs`, which would be merged with(and overridden by) anything passed to `CanonicalLogs.attach/1`.
- [ ] Add `:absinthe_metadata` config option:
  * `:absinthe_metadata`: Metadata to be pulled from the `Absinthe.Blueprint` during the `[:absinthe, :execute, :operation, :stop]` call. Some special metadata is made available as well:
    * `:graphql_operation_name`: The top-level operation name of the GraphQL call. Defaults to "#NULL" if not found.