Add posthog-rails gem for automatic Rails exception tracking#81
Conversation
2967d45 to
1dfe144
Compare
| def extract_distinct_id_from_job | ||
| # Try to find a user ID in job arguments | ||
| arguments.each do |arg| | ||
| if arg.respond_to?(:id) | ||
| return arg.id | ||
| elsif arg.is_a?(Hash) && arg['user_id'] | ||
| return arg['user_id'] | ||
| elsif arg.is_a?(Hash) && arg[:user_id] | ||
| return arg[:user_id] | ||
| end | ||
| end | ||
|
|
||
| nil # No user context found | ||
| end |
There was a problem hiding this comment.
I am not super-happy with this. Will probably change it to use a proc-based / dynamic configuration.
So you'll be able to define distinct ID in the job itself like this:
class MyJob < ApplicationJob
posthog_distinct_id ->(user, arg1, arg2) { user.id }
def perform(user, arg1, arg2)
# ...
end
end1dfe144 to
b4d5947
Compare
This commit introduces the posthog-rails gem which provides automatic exception tracking for Rails applications, including: - Automatic capture of unhandled exceptions via Rails middleware - Automatic capture of rescued exceptions (configurable) - Automatic instrumentation of ActiveJob failures - Integration with Rails 7.0+ error reporter - Configurable exception exclusion list - User context capture from controllers Core library improvements: - Added comprehensive logging throughout exception capture flow - Added ExceptionCapture module for standardized exception parsing - Fixed field handling in Transport to strip internal-only fields (type, library, library_version, messageId) that are not part of PostHog's RawEvent struct - Fixed UUID field handling to avoid sending null values - Added capture_exception method to Client for explicit exception tracking The posthog-rails gem includes: - Railtie for automatic initialization and middleware insertion - Multiple middleware layers for capturing different exception types - ErrorSubscriber for Rails 7.0+ error reporter integration - ActiveJob extensions for job failure tracking - Comprehensive configuration options
b4d5947 to
e2e4e6d
Compare
|
Hey @rafaeelaudibert, I saw you closing another PR for automating Rails error tracking because it was too big and included many integrations at once. This one hooks into Rails middleware and ActiveJob, and also lets you integrate with error reporter if you're on Rails >7.0. Can you take a look? |
|
cc @dmarticus @daibhin @mariusandra I cannot add any reviewers for this PR, so I'm tagging you. Please let me know if you're ok with this approach to implementing Rails SDK. |
|
@daibhin, it seems @hpouillot triggered a few CI actions that are failing. I'll sort it out tomorrow or during the weekend. In the meantime, let me know if you agree with the general approach. |
rafaeelaudibert
left a comment
There was a problem hiding this comment.
This looks very very good! Sorry for taking this long to review, but here it is!
I've left a handful of comments on things I'd like to see changed/improved. This is already 95% of the way there!
|
Hey @popcorn pinging you just in case you're still interested in getting this merged :) |
|
I'd certainly be interested in getting it merged for my own selfish reasons 😅 |
|
hey @popcorn i'd be happy to lend a hand |
Hey @johnnagro, I'd love it if you could take over. I've been super-busy lately and will be for the next few months at least. I can help with a review once you do the changes. Would that work for you? My apologies I can't be more helpful atm. |
|
@popcorn no worries, let me see what i can do. thanks for getting a start on this feature. |
|
@popcorn mind adding me with write permissions to your fork of the repo? so i can push to your branch. seems like the simplest way to continue the PR and maintain all the history |
Just added you as collaborator on the forked repo, cheers! |
…tracking Resolve CHANGELOG.md conflict by keeping both the Unreleased posthog-rails entry and the 3.4.0 release notes.
|
I'm all set up now. Resolved the CHANGELOG conflict. I will begin to address the review feedback. |
Co-authored-by: Rafael Audibert <32079912+rafaeelaudibert@users.noreply.github.com>
Co-authored-by: Rafael Audibert <32079912+rafaeelaudibert@users.noreply.github.com>
Added direct links to PostHog settings pages: - Project API key: https://app.posthog.com/settings/project-details#variables - Personal API key: https://app.posthog.com/settings/user-api-keys
Keep it as an example users can uncomment if needed, consistent with other optional callbacks like before_send.
Move Rails-specific configuration from PostHog.rails_config to PostHog::Rails.config for cleaner namespacing.
Add configurable `user_id_method` option and support for `posthog_distinct_id`, `distinct_id`, and `pk` methods when extracting user IDs for exception tracking.
Co-authored-by: Rafael Audibert <32079912+rafaeelaudibert@users.noreply.github.com>
Move Rails-specific options (auto_capture_exceptions, etc.) to PostHog::Rails.configure, keeping core SDK options in PostHog.init. This follows the common Rails gem pattern of namespaced configuration.
Replace repetitive method definitions with define_method loop and add method_missing fallback for future client methods.
- Use request.session.id instead of session_options.dig(:id) - session_options returns Session::Options, not a Hash
|
@rafaeelaudibert cc @popcorn - please take another look. I think i've addressed all of your feedback and even went a bit further in a couple spots. I've been testing these changes on a local test rails app and noticed some potential issues in the main gem, see #87 and #88. I could work on fixes there too in dedicated PRs if you're interested. Let me know your thoughts, happy to continue to iterate on this if need be. |
Add safe_serialize to handle circular references and complex objects in exception context. Tracks visited objects, limits depth/size, and converts non-serializable objects to safe string representations. Prevents SystemStackError when Rails error reporter context contains ActiveRecord models or other objects with circular references.
When auto_capture_exceptions was enabled, exceptions in web requests were being captured twice: 1. By CaptureExceptions middleware (after ShowExceptions) 2. By ErrorSubscriber (via Rails.error.subscribe in Rails 7.0+) The ErrorSubscriber fires from within DebugExceptions before the CaptureExceptions middleware catches the exception, causing both to report the same error to PostHog. Fix by tracking web request context via thread-local flag: - CaptureExceptions sets flag at request start, clears in ensure block - ErrorSubscriber checks flag and skips if in web request context This ensures web requests are captured only by the middleware (which has richer context: URL, params, controller, action), while ErrorSubscriber still handles non-web contexts (ActiveJob, manual Rails.error.record).
|
I was doing some addition testing and saw a couple further changes that needed to be made. I noticed exceptions were being captured twice in PostHog - two |
|
Thanks, John! I'll be reviewing this tomorrow, this looks very good! If we merge this in, I'll gladly add some docs about it too. |
rafaeelaudibert
left a comment
There was a problem hiding this comment.
There's only one change I'd like to see here. Can automatic error tracking be off by default? This will match the behavior we have for our other SDKs.
You should update the defaults, docs and examples/posthog.rb to make sure we appropriately clone this
Change auto_capture_exceptions, report_rescued_exceptions, and auto_instrument_active_job to default to false, requiring explicit opt-in for automatic error tracking features.
|
@rafaeelaudibert i changed |
|
@rafaeelaudibert This is ready for another look whenever you have time. (I can't use the formal review request since I took over the PR.) |
|
@johnnagro I'll be reviewing this on Monday, thank you! |
This must be prepended to make sure it works as expected
Tiny bugfixes found by Claude
rafaeelaudibert
left a comment
There was a problem hiding this comment.
Thank you! I've added a couple fixes and will be merging this now, appreciate your help!
What is this?
This PR introduces the
posthog-railsgem which provides automatic exception tracking for Rails applications, inspired by Sentry's gem.Features:
Please read
posthog-ruby/posthog-rails/IMPLEMENTATION.mdto learn more.How to test this?
Put both gems in your Rails app's
Gemfile, and then reference them via path on your local machine:PS