# Collector

Reports your Elixir app's errors to [Collector](https://app.clt.chrom.ar),
which groups them into issues, emails you when one is new or comes back,
and shows you what broke and why.

## Installation

Add the dependency to `mix.exs`:

```elixir
def deps do
  [
    {:collector, ">= 0.1.0"}
  ]
end
```

Give it your project's DSN (from its setup page in Collector) in the
`COLLECTOR_DSN` environment variable of the deployed app. Or, to take it
from somewhere else, in `config/runtime.exs`:

```elixir
config :collector, dsn: System.get_env("MY_COLLECTOR_DSN")
```

That's it. From now on, crashes are reported on their own: controllers,
LiveViews, GenServers, Tasks, any process. Oban job failures too, when
Oban is around (not the jobs that return `{:cancel, _}` or
`{:discard, _}`). Exceptions that Plug turns into a 4xx, like
`Ecto.NoResultsError`, aren't bugs and aren't reported.

Without a DSN nothing is sent, so dev and test stay quiet: don't export
`COLLECTOR_DSN` there.

## Request details and users

Add the plug to your endpoint to see the request each error happened in
(credentials such as cookies are never sent):

```elixir
# lib/my_app_web/endpoint.ex
plug Collector.Plug
```

And say who hit the error, by id:

```elixir
Collector.set_user(current_user.id)
```

## Source lines in releases

Collector shows the lines around each frame of your code. Releases don't
ship source files, so package them right before building the release:

```sh
MIX_ENV=prod mix collector.package_source
MIX_ENV=prod mix release
```

In a Dockerfile, that's one line before `mix release`.

## Reporting by hand

```elixir
try do
  charge!(order)
rescue
  e ->
    Collector.capture_exception(e, stacktrace: __STACKTRACE__)
    {:error, :payment_failed}
end

Collector.capture_message("Payment gateway slow", level: :warning)
```

## Options

| Option | Default | |
|---|---|---|
| `:dsn` | `COLLECTOR_DSN` | `https://clt_…@app.clt.chrom.ar`: where Collector runs plus the project's key. Nothing is sent without it |
| `:key`, `:endpoint` | `COLLECTOR_KEY`, `https://app.clt.chrom.ar` | The DSN's two halves, set apart. A DSN wins over both |
| `:environment` | The Mix env the app was built in | `prod`, `staging`, … |
| `:release` | `RELEASE_VSN` | Version or git sha |
| `:in_app` | Your app's own applications | Which applications count as "your code" |
| `:repos` | none | Ecto repo telemetry prefixes, e.g. `[[:my_app, :repo]]`, to record queries as breadcrumbs |

## How it behaves

Events are sent in the background, one at a time, from a bounded queue
(the oldest is dropped past 1000), so a slow or unreachable Collector
never slows your app down. Failed sends are retried with the same id,
so nothing is counted twice; when Collector asks to slow down, it does.

The protocol is documented in Collector's `docs/protocol.md`, if you'd
like to report from another language.

## License

MIT. See [LICENSE](LICENSE).
