posthog-rails 3.12.3 → 3.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bc1787c8bae17ac624fd59a956284a92e996082c0774a83e27cf8b7554ae5393
|
|
4
|
+
data.tar.gz: d13ef6ae2d87f8820050f4fd86e9588b09d5cfea1591548d9a70a0b0d38810d3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8cf28fe0b562b377d411bc259c3f72a8e0ea9a28051714f2fa933f8082c1a58e1fa1f24f58759413fb4d0f1ad83b684ba74930183836da1f5c3e3bacfe07842d
|
|
7
|
+
data.tar.gz: 897e312969d310aaf1559bd5e9c02f9684faaa755375dc2f1dc36759d35db7f1a8766981474ecb5c13e431cb1e0ed34d265e42762c41f54f2ce99ee169ec3313
|
|
@@ -37,6 +37,12 @@ PostHog::Rails.configure do |config|
|
|
|
37
37
|
# making it easier to identify affected users and debug user-specific issues.
|
|
38
38
|
# config.current_user_method = :current_user
|
|
39
39
|
|
|
40
|
+
# Or provide a resolver for apps that store user context outside controllers,
|
|
41
|
+
# such as ActiveSupport::CurrentAttributes. The resolver takes precedence over
|
|
42
|
+
# current_user_method and may accept the controller as an argument.
|
|
43
|
+
# config.current_user_resolver = proc { Current.user }
|
|
44
|
+
# config.current_user_resolver = proc { |controller| controller.current_user }
|
|
45
|
+
|
|
40
46
|
# Additional exception classes to exclude from reporting
|
|
41
47
|
# These are added to the default excluded exceptions
|
|
42
48
|
# config.excluded_exceptions = [
|
|
@@ -69,20 +69,40 @@ module PostHog
|
|
|
69
69
|
def extract_distinct_id(env)
|
|
70
70
|
# Prefer authenticated Rails user context. Request/tracing context is
|
|
71
71
|
# applied later by the core capture path if this returns nil.
|
|
72
|
-
|
|
73
|
-
controller = env['action_controller.instance']
|
|
74
|
-
method_name = PostHog::Rails.config&.current_user_method || :current_user
|
|
72
|
+
return nil unless PostHog::Rails.config&.capture_user_context
|
|
75
73
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return user_id if present?(user_id)
|
|
80
|
-
end
|
|
81
|
-
end
|
|
74
|
+
user = extract_current_user(env['action_controller.instance'])
|
|
75
|
+
user_id = extract_user_id(user) if user
|
|
76
|
+
return user_id if present?(user_id)
|
|
82
77
|
|
|
83
78
|
nil
|
|
84
79
|
end
|
|
85
80
|
|
|
81
|
+
def extract_current_user(controller)
|
|
82
|
+
resolver = PostHog::Rails.config&.current_user_resolver
|
|
83
|
+
return resolve_current_user(resolver, controller) if resolver
|
|
84
|
+
|
|
85
|
+
method_name = PostHog::Rails.config&.current_user_method || :current_user
|
|
86
|
+
return unless controller.respond_to?(method_name, true)
|
|
87
|
+
|
|
88
|
+
controller.send(method_name)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def resolve_current_user(resolver, controller)
|
|
92
|
+
call_current_user_resolver(resolver, controller)
|
|
93
|
+
rescue StandardError => e
|
|
94
|
+
PostHog::Logging.logger.warn("current_user_resolver failed: #{e.message}")
|
|
95
|
+
nil
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def call_current_user_resolver(resolver, controller)
|
|
99
|
+
if resolver.arity.zero?
|
|
100
|
+
controller ? controller.instance_exec(&resolver) : resolver.call
|
|
101
|
+
elsif controller
|
|
102
|
+
resolver.call(controller)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
86
106
|
def extract_user_id(user)
|
|
87
107
|
# Use configured method if specified
|
|
88
108
|
method_name = PostHog::Rails.config&.user_id_method
|
|
@@ -32,6 +32,10 @@ module PostHog
|
|
|
32
32
|
# @return [Symbol] Method name to call on controller to get the current user. Defaults to :current_user.
|
|
33
33
|
attr_accessor :current_user_method
|
|
34
34
|
|
|
35
|
+
# @return [Proc, nil] Callable used to resolve the current user. When set, this takes precedence over
|
|
36
|
+
# current_user_method. The callable may accept the controller instance or no arguments.
|
|
37
|
+
attr_accessor :current_user_resolver
|
|
38
|
+
|
|
35
39
|
# @return [Symbol, nil] Method name to call on the user object to get distinct_id. When nil, tries:
|
|
36
40
|
# posthog_distinct_id, distinct_id, id, pk, uuid in order.
|
|
37
41
|
attr_accessor :user_id_method
|
|
@@ -68,6 +72,7 @@ module PostHog
|
|
|
68
72
|
@use_tracing_headers = true
|
|
69
73
|
@capture_user_context = true
|
|
70
74
|
@current_user_method = :current_user
|
|
75
|
+
@current_user_resolver = nil
|
|
71
76
|
@user_id_method = nil
|
|
72
77
|
@logs_enabled = false
|
|
73
78
|
@logs_forward_rails_logger = true
|
|
@@ -64,24 +64,137 @@ module PostHog
|
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
MISSING_MIDDLEWARE_MESSAGE = 'No such middleware to insert'
|
|
68
|
+
MIDDLEWARE_FALLBACK_OPERATION = :posthog_insert_middleware_with_fallback
|
|
69
|
+
|
|
70
|
+
module MiddlewareStackFallback
|
|
71
|
+
def posthog_insert_middleware_with_fallback(location, target, middleware)
|
|
72
|
+
PostHog::Rails::Railtie.instance.send(
|
|
73
|
+
:insert_middleware_with_fallback,
|
|
74
|
+
self,
|
|
75
|
+
location,
|
|
76
|
+
target,
|
|
77
|
+
middleware
|
|
78
|
+
)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private :posthog_insert_middleware_with_fallback
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
private_constant :MISSING_MIDDLEWARE_MESSAGE,
|
|
85
|
+
:MIDDLEWARE_FALLBACK_OPERATION,
|
|
86
|
+
:MiddlewareStackFallback
|
|
87
|
+
|
|
67
88
|
# @api private
|
|
68
89
|
# @return [void]
|
|
69
90
|
def insert_middleware_after(app, target, middleware)
|
|
70
|
-
|
|
71
|
-
# which only supports recording operations (insert_after, use, etc.)
|
|
72
|
-
# and does NOT support query methods like include?.
|
|
73
|
-
app.config.middleware.insert_after(target, middleware)
|
|
91
|
+
insert_middleware(app.config.middleware, :after, target, middleware)
|
|
74
92
|
end
|
|
75
93
|
|
|
76
94
|
# @api private
|
|
77
95
|
# @return [void]
|
|
78
96
|
def insert_middleware_before(app, target, middleware)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
97
|
+
insert_middleware(app.config.middleware, :before, target, middleware)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# During initialization, app.config.middleware is usually a
|
|
101
|
+
# Rails::Configuration::MiddlewareStackProxy. The proxy only records
|
|
102
|
+
# operations, so missing-target errors happen later when Rails builds the
|
|
103
|
+
# real ActionDispatch::MiddlewareStack. Add our own deferred operation so
|
|
104
|
+
# we can fall back at build time instead of crashing or silently skipping.
|
|
105
|
+
def insert_middleware(middleware_stack, location, target, middleware)
|
|
106
|
+
if middleware_stack_proxy?(middleware_stack)
|
|
107
|
+
append_middleware_operation(middleware_stack, location, target, middleware)
|
|
108
|
+
else
|
|
109
|
+
insert_middleware_with_fallback(middleware_stack, location, target, middleware)
|
|
110
|
+
end
|
|
83
111
|
end
|
|
84
112
|
|
|
113
|
+
def middleware_stack_proxy?(middleware_stack)
|
|
114
|
+
defined?(::Rails::Configuration::MiddlewareStackProxy) &&
|
|
115
|
+
middleware_stack.instance_of?(::Rails::Configuration::MiddlewareStackProxy) &&
|
|
116
|
+
middleware_stack.instance_variable_defined?(:@operations)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def append_middleware_operation(middleware_stack, location, target, middleware)
|
|
120
|
+
operations = middleware_stack.instance_variable_get(:@operations)
|
|
121
|
+
|
|
122
|
+
if callable_middleware_operations?(middleware_stack, operations)
|
|
123
|
+
operations << lambda do |resolved_stack|
|
|
124
|
+
insert_middleware_with_fallback(resolved_stack, location, target, middleware)
|
|
125
|
+
end
|
|
126
|
+
else
|
|
127
|
+
ensure_middleware_stack_fallback_operation!
|
|
128
|
+
operations << [MIDDLEWARE_FALLBACK_OPERATION, [location, target, middleware], nil]
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def callable_middleware_operations?(middleware_stack, operations)
|
|
133
|
+
operation = operations.first || probe_middleware_operation(middleware_stack)
|
|
134
|
+
|
|
135
|
+
operation.respond_to?(:call)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def probe_middleware_operation(middleware_stack)
|
|
139
|
+
probe = middleware_stack.class.new
|
|
140
|
+
probe.use(Object)
|
|
141
|
+
probe.instance_variable_get(:@operations).first
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def ensure_middleware_stack_fallback_operation!
|
|
145
|
+
require 'action_dispatch/middleware/stack' unless defined?(::ActionDispatch::MiddlewareStack)
|
|
146
|
+
return if ::ActionDispatch::MiddlewareStack < MiddlewareStackFallback
|
|
147
|
+
|
|
148
|
+
::ActionDispatch::MiddlewareStack.include(MiddlewareStackFallback)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def insert_middleware_with_fallback(middleware_stack, location, target, middleware)
|
|
152
|
+
perform_middleware_insert(middleware_stack, location, target, middleware)
|
|
153
|
+
rescue RuntimeError => e
|
|
154
|
+
raise unless missing_middleware_error?(e)
|
|
155
|
+
|
|
156
|
+
fallback_insert_middleware(middleware_stack, location, target, middleware)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def perform_middleware_insert(middleware_stack, location, target, middleware)
|
|
160
|
+
if location == :after
|
|
161
|
+
middleware_stack.insert_after(target, middleware)
|
|
162
|
+
else
|
|
163
|
+
middleware_stack.insert_before(target, middleware)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def fallback_insert_middleware(middleware_stack, location, target, middleware)
|
|
168
|
+
fallback_position = if location == :before && middleware_stack.respond_to?(:unshift)
|
|
169
|
+
middleware_stack.unshift(middleware)
|
|
170
|
+
'beginning'
|
|
171
|
+
else
|
|
172
|
+
middleware_stack.use(middleware)
|
|
173
|
+
'end'
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
PostHog::Logging.logger.warn(
|
|
177
|
+
"Could not find #{target.inspect} in the Rails middleware stack; " \
|
|
178
|
+
"inserted #{middleware.inspect} at the #{fallback_position} " \
|
|
179
|
+
'of the stack instead.'
|
|
180
|
+
)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def missing_middleware_error?(error)
|
|
184
|
+
error.message.start_with?(MISSING_MIDDLEWARE_MESSAGE)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
private :insert_middleware,
|
|
188
|
+
:middleware_stack_proxy?,
|
|
189
|
+
:append_middleware_operation,
|
|
190
|
+
:callable_middleware_operations?,
|
|
191
|
+
:probe_middleware_operation,
|
|
192
|
+
:ensure_middleware_stack_fallback_operation!,
|
|
193
|
+
:insert_middleware_with_fallback,
|
|
194
|
+
:perform_middleware_insert,
|
|
195
|
+
:fallback_insert_middleware,
|
|
196
|
+
:missing_middleware_error?
|
|
197
|
+
|
|
85
198
|
# Build the PostHog Logs pipeline and broadcast Rails.logger into it.
|
|
86
199
|
#
|
|
87
200
|
# @api private
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: posthog-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.13.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- PostHog
|
|
@@ -29,14 +29,14 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '3.
|
|
32
|
+
version: '3.13'
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '3.
|
|
39
|
+
version: '3.13'
|
|
40
40
|
description: Automatic exception tracking and instrumentation for Ruby on Rails applications
|
|
41
41
|
using PostHog
|
|
42
42
|
email: engineering@posthog.com
|