---
title: "Logs"
description: "Structured logs allow you to send, view and query logs sent from your applications within Sentry."
url: https://docs.sentry.io/platforms/elixir/logs/
---

# Set Up Logs | Sentry for Elixir

With Sentry Structured Logs, you can send text-based log information from your applications to Sentry. Once in Sentry, these logs can be viewed alongside relevant errors, searched by text-string, or searched using their individual attributes.

## [Requirements](https://docs.sentry.io/platforms/elixir/logs.md#requirements)

Logs for Elixir are supported in Sentry Elixir SDK version `12.0.0` and above.

```bash
mix deps.get sentry
```

Or add it to your `mix.exs`:

```elixir
defp deps do
  [
    {:sentry, "~> 12.0"}
  ]
end
```

## [Setup](https://docs.sentry.io/platforms/elixir/logs.md#setup)

To enable logging, set `enable_logs: true` in your Sentry configuration:

```elixir
# In config/config.exs or config/runtime.exs
config :sentry,
  dsn: "___PUBLIC_DSN___",
  enable_logs: true
```

When `enable_logs` is `true`, the SDK **automatically attaches** a `Sentry.LoggerHandler` (registered as `:sentry_log_handler`) on application startup. No manual handler setup is required.

If you already have a `Sentry.LoggerHandler` registered (for example, for crash and error reporting), the SDK will not add a second one — your existing handler will also capture logs.

To configure the minimum log level and other options, use the `:logs` key:

```elixir
config :sentry,
  dsn: "___PUBLIC_DSN___",
  enable_logs: true,
  logs: [
    level: :info,         # minimum log level (default: :info)
    excluded_domains: [], # logger domains to exclude (default: [])
    metadata: []          # metadata keys to include as attributes (default: [])
  ]
```

Log events are automatically batched and delivered through the SDK's Telemetry Processor, which buffers log entries and sends them to Sentry efficiently. See the [Telemetry Processor options](https://docs.sentry.io/platforms/elixir/configuration/options.md#telemetry-processor-options) for configuration details.

## [Usage](https://docs.sentry.io/platforms/elixir/logs.md#usage)

Once `enable_logs: true` is set in your Sentry configuration, you can send logs using Elixir's standard `Logger` module.

The logs will be sent to Sentry at or above the level configured by the `:level` option under `:logs` (default: `:info`). The supported log levels in Elixir are: `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, and `emergency`.

```elixir
require Logger

Logger.info("Updated global cache")

Logger.debug("Cache miss for user", user_id: 123)

Logger.warning("Rate limit reached for endpoint", endpoint: "/api/results/")

Logger.error("Failed to process payment", order_id: "or_2342", amount: 99.99)
```

### [Message Templates with Parameters](https://docs.sentry.io/platforms/elixir/logs.md#message-templates-with-parameters)

You can use message templates with positional or named parameters. To use message templates, pass parameters via the `:sentry` metadata key with `:log_parameters`:

```elixir
# Using named parameters (Elixir format)
Logger.info("User %{name} logged in",
  sentry: [log_parameters: %{name: "Jane Doe"}]
)

# Using positional parameters
Logger.info("User %s logged in",
  sentry: [log_parameters: ["Jane Doe"]]
)
```

### [Adding Custom Attributes](https://docs.sentry.io/platforms/elixir/logs.md#adding-custom-attributes)

Any metadata passed to `Logger` calls will be included as log attributes if configured via the `:metadata` option under `:logs`. To include all metadata as attributes:

```elixir
config :sentry,
  enable_logs: true,
  logs: [
    level: :info,
    metadata: :all  # or [:user_id, :request_id] for specific keys
  ]
```

Then all metadata will be sent as extra attributes that Sentry Logs UI displays:

```elixir
# Here `user_id` and `action` will be sent as extra attributes
Logger.info("User logged in", user_id: 123, action: "create")
```

### [OpenTelemetry Integration](https://docs.sentry.io/platforms/elixir/logs.md#opentelemetry-integration)

If you're using [tracing](https://docs.sentry.io/platforms/elixir/tracing.md) with OpenTelemetry, you can correlate logs with traces so that log events appear alongside spans in the Sentry Trace Explorer.

To enable this, add the `opentelemetry_logger_metadata` package to your dependencies:

`mix.exs`

```elixir
defp deps do
  [
    {:opentelemetry_logger_metadata, "~> 0.2"},
    # ... your other dependencies
  ]
end
```

Then call `OpentelemetryLoggerMetadata.setup()` in your application's `start/2` callback:

`lib/my_app/application.ex`

```elixir
def start(_type, _args) do
  OpentelemetryLoggerMetadata.setup()

  # ... rest of your application setup
end
```

This package injects the active OpenTelemetry `trace_id` and `span_id` into Elixir's logger metadata. The Sentry SDK automatically picks up these IDs and includes them in every log event sent to Sentry, linking your logs to the trace they occurred within.

Without `opentelemetry_logger_metadata`, the SDK generates a random `trace_id` for each log event. Logs will still appear in Sentry, but they won't be connected to any trace.

## [Integrations](https://docs.sentry.io/platforms/elixir/logs.md#integrations)

Logs are sent to Sentry through Erlang's `:logger` system via `Sentry.LoggerHandler`. When `enable_logs: true` is set in your Sentry configuration, the SDK automatically attaches the handler — no manual setup is needed. Any logs from your application or libraries that use Elixir's `Logger` or Erlang's `:logger` will be captured and sent to Sentry at or above the configured level.

The logs behavior is configured globally via the `:logs` key — not through the handler config map:

```elixir
config :sentry,
  enable_logs: true,
  logs: [
    level: :info,
    metadata: [:request_id, :user_id]
  ]
```

With this configuration, logs at or above `:info` will be sent to Sentry:

```elixir
require Logger

Logger.debug("Debug message")  # Not sent (below :info level)
Logger.info("Info message")    # Sent to Sentry
Logger.warning("Warning")      # Sent to Sentry
Logger.error("Error occurred") # Sent to Sentry
```

### [Excluding Domains](https://docs.sentry.io/platforms/elixir/logs.md#excluding-domains)

You can exclude specific logger domains from being sent to Sentry using the `:excluded_domains` option under `:logs`:

```elixir
config :sentry,
  enable_logs: true,
  logs: [
    level: :info,
    excluded_domains: [:ecto, :phoenix]
  ]
```

##### Logs vs Error Reporting

The logs feature (configured under `:logs`) is separate from error reporting (configured via `Sentry.LoggerHandler`'s `:level` option). Error reporting captures crash reports and exceptions, while logs captures structured log events. You can configure both independently.

## [Options](https://docs.sentry.io/platforms/elixir/logs.md#options)

### [before\_send\_log](https://docs.sentry.io/platforms/elixir/logs.md#before_send_log)

To filter or modify logs before they are sent to Sentry, use the `before_send_log` callback. Return `false` to skip a log, or return the log event to send it.

```elixir
config :sentry,
  dsn: "___PUBLIC_DSN___",
  enable_logs: true,
  before_send_log: fn log_event ->
    # Skip info logs
    if log_event.level == :info do
      false
    else
      log_event
    end
  end
```

You can also use a module/function tuple:

```elixir
config :sentry,
  dsn: "___PUBLIC_DSN___",
  enable_logs: true,
  before_send_log: {MyApp.Sentry, :before_send_log}

# In lib/my_app/sentry.ex
defmodule MyApp.Sentry do
  def before_send_log(%Sentry.LogEvent{} = log_event) do
    # Filter out logs from specific domains or modify attributes
    if String.contains?(log_event.body, "sensitive") do
      false
    else
      log_event
    end
  end
end
```

### [Logs Configuration](https://docs.sentry.io/platforms/elixir/logs.md#logs-configuration)

Logs behavior is configured under the `:logs` key in your Sentry configuration. These options control the auto-attached `Sentry.LoggerHandler`:

* **`:level`** - The minimum log level to send to Sentry's Logs Protocol. Default: `:info`. Supported values: `:debug`, `:info`, `:notice`, `:warning`, `:error`, `:critical`, `:alert`, `:emergency`.

* **`:excluded_domains`** - A list of logger domains to exclude from logs sent to Sentry. Default: `[]`.

* **`:metadata`** - Logger metadata keys to include as attributes in log events. Set to `:all` to include all metadata, or a list of specific keys like `[:request_id, :user_id]`. Default: `[]`.

```elixir
config :sentry,
  dsn: "___PUBLIC_DSN___",
  enable_logs: true,
  logs: [
    level: :info,
    excluded_domains: [:ecto],
    metadata: [:request_id, :user_id] # or :all
  ]
```

### [Global Configuration Options](https://docs.sentry.io/platforms/elixir/logs.md#global-configuration-options)

These options are set in your Sentry configuration (`config :sentry`):

* **`:enable_logs`** - Set to `true` to enable the logs feature. When enabled, the SDK automatically attaches a `Sentry.LoggerHandler` and routes log events through the SDK's Telemetry Processor. Default is `false`.

* **`:before_send_log`** - A callback function to filter or modify log events before they are sent.

Log events are buffered by the Telemetry Processor with a capacity of 1000 entries and flushed in batches of 100 or every 5 seconds, whichever comes first. You can customize these defaults through the [Telemetry Processor options](https://docs.sentry.io/platforms/elixir/configuration/options.md#telemetry-processor-options).

```elixir
config :sentry,
  dsn: "___PUBLIC_DSN___",
  enable_logs: true,
  before_send_log: {MyApp.Sentry, :before_send_log}
```

## [Default Attributes](https://docs.sentry.io/platforms/elixir/logs.md#default-attributes)

The Elixir SDK automatically sets several default attributes on all log entries to provide context and improve debugging:

### [Core Attributes](https://docs.sentry.io/platforms/elixir/logs.md#core-attributes)

* `environment`: The environment set in the SDK if defined. This is sent from the SDK as `sentry.environment`.
* `release`: The release set in the SDK if defined. This is sent from the SDK as `sentry.release`.
* `sdk.name`: The name of the SDK that sent the log. This is sent from the SDK as `sentry.sdk.name`.
* `sdk.version`: The version of the SDK that sent the log. This is sent from the SDK as `sentry.sdk.version`.

### [Message Template Attributes](https://docs.sentry.io/platforms/elixir/logs.md#message-template-attributes)

If the log was parameterized, Sentry adds the message template and parameters as log attributes.

* `message.template`: The parameterized template string. This is sent from the SDK as `sentry.message.template`.
* `message.parameter.X`: The parameters to fill the template string. X can either be the number that represent the parameter's position in the template string (`sentry.message.parameter.0`, `sentry.message.parameter.1`, etc) or the parameter's name (`sentry.message.parameter.item_id`, `sentry.message.parameter.user_id`, etc). This is sent from the SDK as `sentry.message.parameter.X`.

### [Server Attributes](https://docs.sentry.io/platforms/elixir/logs.md#server-attributes)

* `server.address`: The address of the server that sent the log. Equivalent to `server_name` that gets attached to Sentry errors.

### [OpenTelemetry Attributes](https://docs.sentry.io/platforms/elixir/logs.md#opentelemetry-attributes)

If you're using OpenTelemetry with the [`opentelemetry_logger_metadata`](https://hex.pm/packages/opentelemetry_logger_metadata) package, the following attributes are automatically included:

* `trace_id`: The OpenTelemetry trace ID from the active trace context. Links the log to a specific trace in Sentry's Trace Explorer.
* `span_id`: The OpenTelemetry span ID from the active span context. Links the log to a specific span within the trace.

These attributes allow you to navigate from a log entry directly to the trace it occurred within, and vice versa.

If no OpenTelemetry context is available (for example, if `opentelemetry_logger_metadata` is not installed or the log occurs outside a traced operation), the SDK generates a random `trace_id` for each log event. In this case, `span_id` is not set, and logs are not connected to any trace in Sentry.
