Ruby on Rails Logs installation
Contents
posthog-rails forwards Rails.logger output and optional structured Rails notification logs to PostHog Logs over OpenTelemetry (OTLP), correlated with each request's distinct ID and session ID. Requires Ruby 3.3+.
- 1
Add the OpenTelemetry gems
RequiredAdd the following gems to your
Gemfilewithrequire: false—posthog-railsloads them only when log forwarding is enabled:GemfileThen run:
Terminalopentelemetry-logs-sdkmust be>= 0.6.0. The OTLP exporter requiresLogRecordData#event_name, which only exists from that version onward. - 2
Enable log forwarding
RequiredIn
config/initializers/posthog.rb, enable log forwarding:config/initializers/posthog.rbLogs reuse the same project token (
api_key) and host configured inPostHog.init— nothing extra to set. Records are sent to<host>/i/v1/logs.When the OpenTelemetry gems are absent, the integration logs a single warning and no-ops — it's safe to enable conditionally.
- 3
Optional configuration
OptionalFilter by severity
logs_levelcontrols which severity levels are forwarded. It never changes what your app logs locally:RubyRate limiting
Forwarding is capped at 6,000 records per minute by default. When the cap is reached, one warning record is emitted and further records are dropped for the remainder of that minute:
RubyScrub PII
Set
logs_before_sendto a proc that receives each record and returns a modified hash to send ornilto drop it:RubyThe record hash has keys
:timestamp,:severity(a symbol such as:warn),:body, and:attributes. If the callback raises, the record is dropped.Trace correlation
If your app uses OpenTelemetry tracing instrumentation gems (for example,
opentelemetry-instrumentation-railsoropentelemetry-instrumentation-rack), log records emitted during a traced request automatically carry the activetrace_idandspan_id— no additional configuration needed. - 4
Test your setup
Recommended- Start your Rails server and trigger a request that logs output.
- Check the PostHog Logs interface for your log entries.
- If logs don't appear, check for a startup warning in your server output (a line starting with
[PostHog]indicates a configuration issue such as missing gems or an unresolved project token).
Next steps
CheckpointWhat you can do with your logsAction Description Why you need logs What logs show you that nothing else does Search logs Use the search interface to find specific log entries Filter by level Filter by INFO,WARN,ERROR, etc.Link session replay Connect logs to users and session replays by passing posthogDistinctIdandsessionIdLink logs to a person Surface every log emitted on behalf of a user on their PostHog person profile Logging best practices Learn what to log, how to structure logs, and patterns that make logs useful in production
Structured notification logs
From posthog-rails 3.23.0, use logs_notifications to capture structured controller, SQL, job, and mailer logs:
This defaults to []. Restart your app after changing the selection.
| Component | Captures |
|---|---|
:action_controller | Controller, action, HTTP method, response status, and filtered parameters. |
:active_record | Query name, cache status, and SQL operation. No SQL statements or bind values. |
:active_job | Enqueue, execution, retry, and discard events with job details and filtered arguments. |
:action_mailer | Mailer class and action. No recipients, subject, or message content. |
Set logs_level = :debug to include SQL records. Other successful operations use info, controller 4xx responses use warn, and failures use error. A failed retry attempt uses error even if retries remain.
Notification logs share the existing severity filter, rate cap, and logs_before_send hook. Set logs_forward_rails_logger = false to collect only notification logs.
Filter sensitive notification data
Controller and job parameters use Rails' parameter filters. Unkeyed job arguments are redacted. Jobs with log_arguments = false and mail delivery jobs omit arguments. With no parameter filters configured, job hash arguments are redacted.
Review your filters and use logs_before_send to remove sensitive data. These protections do not filter arbitrary text passed to Rails.logger.
Enable auto_instrument_active_job to carry user and session IDs into job logs. Notification logs alone do not enable exception capture.
Configuration reference
| Option | Type | Default | Description |
|---|---|---|---|
logs_enabled | Boolean | false | Master switch for log forwarding. Requires Ruby 3.3+ and the three OpenTelemetry gems above. |
logs_forward_rails_logger | Boolean | true | Broadcast Rails.logger into the PostHog Logs sink. Takes effect only when logs_enabled is true. |
logs_notifications | Array of symbols | [] | Components to log: :action_controller, :active_record, :active_job, and :action_mailer. Requires logs_enabled. |
logs_level | Symbol/Integer | nil | Minimum severity to forward (:debug, :info, :warn, :error, :fatal, :unknown, or a Logger constant). Inherits the Rails logger level when nil. |
logs_max_records_per_minute | Integer/String | 6000 | Records-per-minute cap. Numeric strings (e.g. from ENV) are coerced. Set to nil, 0, or a negative value to disable. |
logs_before_send | Proc | nil | Called with each record hash (:timestamp, :severity, :body, :attributes) before sending. Return a modified hash to send or nil to drop. Records are dropped if the callback raises. |
Troubleshooting
Logs not appearing in PostHog
- Check the OTel gems are installed:
bundle list | grep opentelemetry. You should seeopentelemetry-sdk,opentelemetry-logs-sdk(≥ 0.6.0), andopentelemetry-exporter-otlp-logs. - Check for a startup warning — if the gems are missing or the project token can't be resolved, PostHog logs a warning to stderr at boot (look for a line starting with
[PostHog]). - Verify
logs_enabled = trueis set in your initializer and that the initializer runs before the railtie (it should if it lives inconfig/initializers/). - Check test mode —
PostHog.initwithtest_mode: truedisables the logs pipeline entirely. Ensure test mode is only set in the test environment.
For general Logs troubleshooting (authentication, connection issues, format problems), see the Logs troubleshooting guide.





