Skip to content
Merged
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
8 changes: 8 additions & 0 deletions docs/platforms/ruby/common/configuration/options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,14 @@ Provides a lambda or proc that's called with an SDK-specific transaction event o

</SdkOption>

<SdkOption name="before_send_log" type="lambda | proc">

Provides a lambda or proc that's called with an SDK-specific log object, and can return a modified log object, or `nil` to skip reporting the log. This can be used to filter logs before they are sent to Sentry.

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

</SdkOption>

<SdkOption name="backtrace_cleanup_callback" type="lambda">

If you want to clean up the backtrace of an exception before it's sent to Sentry, you can specify a callback with `backtrace_cleanup_callback`, for example:
Expand Down
25 changes: 25 additions & 0 deletions docs/platforms/ruby/guides/rails/logs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,28 @@ With Sentry Structured Logs, you can send text-based log information from your R
## Default Attributes

<PlatformContent includePath="logs/default-attributes" />

## Troubleshooting

If logs aren't appearing in Sentry:

**Verify configuration:**
```ruby
Sentry.init do |config|
config.enable_logs = true # Must be set
end
```

**Test your setup:**

```ruby
Sentry.logger.info("Test log message")
Sentry.get_current_client.flush
```

Then verify if the log appears in Sentry.

**Enable debug mode:**
```ruby
config.debug = true # See SDK diagnostic output
```
14 changes: 14 additions & 0 deletions platform-includes/configuration/before-send-log/ruby.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
```ruby
Sentry.init do |config|
config.dsn = "___PUBLIC_DSN___"
config.enable_logs = true

config.before_send_log = lambda do |log|
# Skip info logs
return if log.level == :info

log
end
end
```

120 changes: 52 additions & 68 deletions platform-includes/logs/options/ruby.rails.mdx
Original file line number Diff line number Diff line change
@@ -1,44 +1,28 @@
### Available Built-in Subscribers
### before_send_log

The Rails SDK includes several built-in log subscribers that you can enable:
To filter logs before they are sent to Sentry, use the `before_send_log` callback. Return `nil` to skip a log, or return the log object to send it.

#### Default Subscribers (enabled automatically)
- **ActiveRecord**: Database queries with SQL, duration, connection info, and caching status
- **ActionController**: HTTP requests with controller, action, parameters, response status, and timing
<PlatformContent includePath="configuration/before-send-log" />

#### Additional Subscribers (opt-in)
- **ActiveJob**: Background job execution (`perform`), enqueueing (`enqueue`), retry failures (`retry_stopped`), and job discarding (`discard`)
- **ActionMailer**: Email delivery (`deliver`) and processing (`process`) events
### Structured Logging Subscribers

### Custom Subscriber Configuration
Structured logging is enabled by default when you set `enable_logs = true`. You can customize which Rails events are captured.

You can customize which subscribers are active:
**Default subscribers (enabled automatically):**
- `active_record` - Database queries
- `action_controller` - HTTP requests

```ruby
Sentry.init do |config|
config.dsn = "___PUBLIC_DSN___"
**Additional subscribers (opt-in):**
- `active_job` - Background jobs
- `action_mailer` - Email delivery

config.enable_logs = true

config.rails.structured_logging.enabled = true

config.rails.structured_logging.subscribers = {
active_record: Sentry::Rails::LogSubscribers::ActiveRecordSubscriber,
action_controller: Sentry::Rails::LogSubscribers::ActionControllerSubscriber
}
end
```

To enable additional subscribers, add them to the configuration:
**Enable additional subscribers:**

```ruby
Sentry.init do |config|
config.dsn = "___PUBLIC_DSN___"

config.enable_logs = true

config.rails.structured_logging.enabled = true

config.rails.structured_logging.subscribers = {
active_record: Sentry::Rails::LogSubscribers::ActiveRecordSubscriber,
action_controller: Sentry::Rails::LogSubscribers::ActionControllerSubscriber,
Expand All @@ -48,30 +32,37 @@ Sentry.init do |config|
end
```

To disable specific subscribers:
**Disable default subscribers:**

```ruby
Sentry.init do |config|
config.dsn = "___PUBLIC_DSN___"
config.rails.structured_logging.subscribers = {
active_record: Sentry::Rails::LogSubscribers::ActiveRecordSubscriber
# ActionController disabled
}
```

config.enable_logs = true
**Disable structured logging entirely:**

```ruby
config.rails.structured_logging.enabled = false
```

config.rails.structured_logging.enabled = true
### Sensitive Data Filtering

config.rails.structured_logging.subscribers = {
active_record: Sentry::Rails::LogSubscribers::ActiveRecordSubscriber
# ActionController subscriber disabled
}
end
Structured logging automatically respects Rails' parameter filtering:

```ruby {filename:config/application.rb}
config.filter_parameters += [:password, :credit_card, :ssn]
```

### Creating Custom Log Subscribers
This filters sensitive data from ActionController parameters, ActiveJob arguments, and ActionMailer parameters.

You can create custom log subscribers by extending the base class:
### Custom Log Subscribers

You can create custom subscribers to capture your own Rails instrumentation events:

```ruby
class MyCustomSubscriber < Sentry::Rails::LogSubscriber
# Attach to your component's instrumentation events
attach_to :my_component

def my_event(event)
Expand All @@ -80,48 +71,41 @@ class MyCustomSubscriber < Sentry::Rails::LogSubscriber
level: :info,
attributes: {
duration_ms: event.duration,
custom_data: event.payload[:custom_data],
user_id: event.payload[:user_id]
}
)
end

def another_event(event)
log_structured_event(
message: "Another custom event",
level: :warn,
attributes: {
event_type: event.payload[:type],
metadata: event.payload[:metadata]
}
)
end
end
```

Then register your custom subscriber:
Register it in your configuration:

```ruby
Sentry.init do |config|
config.dsn = "___PUBLIC_DSN___"
config.rails.structured_logging.subscribers = {
active_record: Sentry::Rails::LogSubscribers::ActiveRecordSubscriber,
my_component: MyCustomSubscriber
}
```

config.enable_logs = true
### Using `Rails.logger`

config.rails.structured_logging.enabled = true
If you want all Rails logs to go to Sentry, you can enable the `:logger` patch:

config.rails.structured_logging.subscribers = {
active_record: Sentry::Rails::LogSubscribers::ActiveRecordSubscriber,
action_controller: Sentry::Rails::LogSubscribers::ActionControllerSubscriber,
my_component: MyCustomSubscriber
}
```ruby
Sentry.init do |config|
config.dsn = "___PUBLIC_DSN___"
config.enable_logs = true
config.enabled_patches = [:logger]
end
```

### Sensitive Data Filtering

Log subscribers automatically respect Rails' parameter filtering configuration. Sensitive parameters defined in `config.filter_parameters` will be filtered from structured logs:
This will send all `Rails.logger` calls to Sentry:

```ruby
# config/application.rb
config.filter_parameters += [:password, :credit_card, :ssn]
Rails.logger.info("Processing user request")
Rails.logger.error("Failed to save record")
```

<Alert level="warning">
This captures ALL Rails framework logs as well as ANY OTHER logs produced by instances of the `Logger` class and this can be very noisy. We recommend using `Sentry.logger` for better control over what gets logged.
</Alert>
62 changes: 5 additions & 57 deletions platform-includes/logs/setup/ruby.rails.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
To enable logging, you need to initialize the SDK with the `enable_logs` option set to `true`.
To enable logging, initialize the SDK with `enable_logs` set to `true`:

```ruby
Sentry.init do |config|
Expand All @@ -7,60 +7,8 @@ Sentry.init do |config|
end
```

### Structured Logging with Log Subscribers
This enables:
- The `Sentry.logger` API for explicit logging
- Automatic structured logging of Rails framework events (ActiveRecord queries, controller actions, etc.)

<Alert level="info" title="Note on structured logging">
Structured logging with Log Subscribers provides rich context and metadata compared to plain logger messages. This enables better filtering, searching, and analysis of your application's behavior in Sentry.
</Alert>

Rails applications can benefit from structured logging using ActiveSupport's Log Subscribers. This feature captures Rails instrumentation events and sends them as structured logs to Sentry with relevant context and metadata.

#### Default Setup

To enable structured logging with default subscribers:

```ruby
Sentry.init do |config|
config.dsn = "___PUBLIC_DSN___"
config.enable_logs = true
config.rails.structured_logging.enabled = true
end
```

By default, this enables structured logging for:

- **ActiveRecord**: Database queries with SQL, duration, connection info, and caching status
- **ActionController**: HTTP requests with controller, action, parameters, response status, and timing

Additional subscribers are available but not enabled by default:

- **ActiveJob**: Background job execution (`perform`), enqueueing (`enqueue`), retry failures (`retry_stopped`), and job discarding (`discard`)
- **ActionMailer**: Email delivery (`deliver`) and processing (`process`) events

See the [Options](#options) section for information on how to enable additional subscribers.

### Basic Rails Logger Integration

If you enable `:logger` patch, this will affect Rails' built-in logger. This means that anything that Rails logs, and any custom usage of the Rails logger, will result in sending log entries to Sentry:

```ruby
Sentry.init do |config|
config.dsn = "___PUBLIC_DSN___"
config.enable_logs = true
config.enabled_patches = [:logger]
end
```

Then all logs from Rails logger will be sent to Sentry, for example:

```ruby
# All these calls will result in log entries in Sentry
# if :logger patch is enabled
Rails.logger.debug("Hello from Rails logger")
Rails.logger.info("Hello from Rails logger")
Rails.logger.error("Hello from Rails logger")
```

<Alert level="warning" title="Note on logger patch">
Enabling `:logger` patch will send all logs from Rails logger to Sentry. This includes logs from Rails framework itself, which might not be desired. In that case we recommend using [Sentry logger](#using-sentry-logger) or [structured logging with log subscribers](#structured-logging-with-log-subscribers).
</Alert>
See the [Usage](#usage) section for examples and [Options](#options) to customize which events are captured.
58 changes: 11 additions & 47 deletions platform-includes/logs/usage/ruby.rails.mdx
Original file line number Diff line number Diff line change
@@ -1,56 +1,20 @@
Once the feature is enabled on the SDK, you can send logs using the `Sentry.logger` API.

### Using Sentry Logger

The `logger` namespace exposes common logging methods that you can use to log messages at different log levels: `trace`, `debug`, `info`, `warning`, `error`, and `fatal`.

You can pass additional attributes directly to the logging functions. These properties will be sent to Sentry, and can be searched from within the Logs UI, and even added to the Logs views as a dedicated column.
Use the `Sentry.logger` API to send logs to Sentry:

```ruby
Sentry.logger.info("Updated global cache")

Sentry.logger.debug("Cache miss for user %{user_id}", user_id: 123)

Sentry.logger.trace(
"Starting database connection %{database}",
database: "users"
)

Sentry.logger.warn(
"Rate limit reached for endpoint %{endpoint}",
endpoint: "/api/results/"
)

Sentry.logger.error(
"Failed to process payment. Order: %{order_id}. Amount: %{amount}",
order_id: "or_2342", amount: 99.99
)

Sentry.logger.fatal(
"Database %{database} connection pool exhausted",
database: "users"
)
Sentry.logger.info("User logged in successfully")
Sentry.logger.error("Payment processing failed")
```

### Message Templates

You can use message templates with positional or hash parameters:
You can include additional context data as attributes:

```ruby
# Using named parameters
Sentry.logger.info("User %{name} logged in", name: "Jane Doe")

# Using positional parameters
Sentry.logger.info("User %s logged in", ["Jane Doe"])
Sentry.logger.error(
"Failed to process payment. Order: %{order_id}",
order_id: "or_2342",
amount: 99.99
)
```

Any other arbitrary attributes will be sent as part of the log event payload:
Additional attributes like `amount` are sent as searchable metadata in Sentry's Logs UI.

```ruby
# Here `user_id` and `action` will be sent as extra attributes that
# Sentry Logs UI displays
Sentry.logger.info(
"User %{user} logged in",
user: "Jane", user_id: 123, action: "create"
)
```
See [Default Attributes](#default-attributes) for the complete list of metadata and [Options](#options) to customize which events are captured.
Loading