Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions docs/platforms/elixir/logs/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: Set Up Logs
sidebar_title: Logs
description: "Structured logs allow you to send, view and query logs sent from your applications within Sentry."
sidebar_order: 4
sidebar_section: features
new: true
---

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

<PlatformContent includePath="logs/requirements" />

## Setup

<PlatformContent includePath="logs/setup" />

## Usage

<PlatformContent includePath="logs/usage" />

## Integrations

<PlatformContent includePath="logs/integrations" />

## Options

<PlatformContent includePath="logs/options" />

## Default Attributes

<PlatformContent includePath="logs/default-attributes" />
34 changes: 34 additions & 0 deletions platform-includes/configuration/before-send-log/elixir.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
```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
```
16 changes: 16 additions & 0 deletions platform-includes/logs/default-attributes/elixir.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
The Elixir SDK automatically sets several default attributes on all log entries to provide context and improve debugging:

<Include name="logs/default-attributes/core" />

<Include name="logs/default-attributes/message-template" />

<Include name="logs/default-attributes/server" />

### OpenTelemetry Attributes

If you're using OpenTelemetry with the `opentelemetry_logger_metadata` package, the following attributes are automatically included:

- `trace_id`: The OpenTelemetry trace ID associated with the log event.
- `span_id`: The OpenTelemetry span ID associated with the log event.

If no OpenTelemetry context is available, a random trace ID is generated to allow log correlation within Sentry.
40 changes: 40 additions & 0 deletions platform-includes/logs/integrations/elixir.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Logs are sent to Sentry through Erlang's `:logger` system via `Sentry.LoggerHandler`. This means 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 `:logs_level`).

```elixir
# In your application's start/2 callback
:logger.add_handler(:sentry_handler, Sentry.LoggerHandler, %{
config: %{
logs_level: :info,
logs_metadata: [:request_id, :user_id]
}
})
```

Then all logs at the configured level 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

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

```elixir
config: %{
logs_level: :info,
logs_excluded_domains: [:ecto, :phoenix]
}
```

<Alert level="info" title="Logs vs Error Reporting">
The logs feature (controlled by `:logs_level`) is separate from error
reporting (controlled by `:level`). Error reporting captures crash reports and
exceptions, while logs captures structured log events. You can configure both
independently.
</Alert>
31 changes: 31 additions & 0 deletions platform-includes/logs/options/elixir.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
### 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.

<PlatformContent includePath="configuration/before-send-log" />

### LoggerHandler Options

When configuring `Sentry.LoggerHandler`, you can use these options specific to logs:

- **`:logs_level`** - The minimum log level to send to Sentry's Logs Protocol. If `nil` (default), logs sending is disabled. Set to `:debug`, `:info`, `:notice`, `:warning`, `:error`, `:critical`, `:alert`, or `:emergency`.

- **`:logs_excluded_domains`** - A list of logger domains to exclude from logs sending. The `:sentry` domain is always excluded automatically.

- **`:logs_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]`.

### Global Configuration Options

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

- **`:enable_logs`** - Set to `true` to enable the logs feature. Default is `false`.

- **`:max_log_events`** - The maximum number of log events to buffer before flushing to Sentry. Default is `100`. Logs are also flushed every 5 seconds.

```elixir
config :sentry,
dsn: "___PUBLIC_DSN___",
enable_logs: true,
max_log_events: 50,
before_send_log: {MyApp.Sentry, :before_send_log}
```
15 changes: 15 additions & 0 deletions platform-includes/logs/requirements/elixir.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
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
```
46 changes: 46 additions & 0 deletions platform-includes/logs/setup/elixir.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
To enable logging, you need to configure the SDK with the `enable_logs` option set to `true`:

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

You'll also need to add the `Sentry.LoggerHandler` to your application and configure it to send logs:

```elixir
# In your application's start/2 callback (e.g., lib/my_app/application.ex)
def start(_type, _args) do
:logger.add_handler(:sentry_handler, Sentry.LoggerHandler, %{
config: %{
logs_level: :info
}
})

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

Alternatively, you can configure the handler through your application's logger configuration:

```elixir
# In config/config.exs
config :my_app, :logger, [
{:handler, :sentry_handler, Sentry.LoggerHandler, %{
config: %{
logs_level: :info
}
}}
]
```

Then in your application startup:

```elixir
def start(_type, _args) do
Logger.add_handlers(:my_app)

# ... rest of your application startup
end
```
54 changes: 54 additions & 0 deletions platform-includes/logs/usage/elixir.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
Once the feature is enabled and the `Sentry.LoggerHandler` is configured, you can send logs using Elixir's standard `Logger` module.

The logs will be sent to Sentry at or above the level configured in `:logs_level`. 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

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

Any metadata passed to `Logger` calls will be included as log attributes if configured in `:logs_metadata`. To include all metadata as attributes:

```elixir
# In your LoggerHandler configuration:
config: %{
logs_level: :info,
logs_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

If you're using OpenTelemetry with the `opentelemetry_logger_metadata` package, trace and span IDs will automatically be extracted from your log metadata and included in the log events sent to Sentry. This allows you to correlate logs with traces in the Sentry UI.