posthog-rails 3.12.2 → 3.13.0
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 +4 -4
- data/lib/generators/posthog/templates/posthog.rb +6 -0
- data/lib/posthog/rails/capture_exceptions.rb +29 -9
- data/lib/posthog/rails/configuration.rb +5 -0
- data/lib/posthog/rails/facade.rb +100 -0
- data/lib/posthog/rails/railtie.rb +5 -88
- data/lib/posthog/rails.rb +3 -0
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dbadf59825cbf2d519a1eab2aa36e56cba2bc9c395076857e50bc126e41300b0
|
|
4
|
+
data.tar.gz: de897b215980ee6bcbbfe54416073fed3d5b9321fce30443dacb015a7785b073
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 33068f5f9b2673d0f9acf9f1acb20f50a8f99c04e1182911d9245c539e8d2566a3c42fb6da125d89853a7cadadf187754b3d49e24666a46d274800bc9badf82f
|
|
7
|
+
data.tar.gz: d94d7cff285e97a7769683f1349689b770d8ddb3610ceb0f21cf68067ca56b0fe2ffbb103f2c5720fd39270cc3d84f6c8fb9e9c4e39fb83e2fb65a8da35123c3
|
|
@@ -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
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PostHog
|
|
4
|
+
module Rails
|
|
5
|
+
# Install the Rails singleton-style PostHog facade at load time so Rails app
|
|
6
|
+
# initializers can call PostHog.init before Railtie initializers run.
|
|
7
|
+
#
|
|
8
|
+
# @api private
|
|
9
|
+
# @return [void]
|
|
10
|
+
def self.install_posthog_facade!
|
|
11
|
+
return if @posthog_facade_installed
|
|
12
|
+
|
|
13
|
+
PostHog.class_eval do
|
|
14
|
+
class << self
|
|
15
|
+
attr_accessor :client
|
|
16
|
+
|
|
17
|
+
# Initialize the singleton PostHog client used by Rails delegators.
|
|
18
|
+
#
|
|
19
|
+
# @param options [Hash] Core {PostHog::Client} options.
|
|
20
|
+
# @yieldparam config [PostHog::Rails::InitConfig] Block-based core SDK configuration.
|
|
21
|
+
# @return [PostHog::Client]
|
|
22
|
+
def init(options = {})
|
|
23
|
+
# If block given, yield to configuration
|
|
24
|
+
if block_given?
|
|
25
|
+
config = PostHog::Rails::InitConfig.new(options)
|
|
26
|
+
yield config
|
|
27
|
+
options = config.to_client_options
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Let the PostHog Logs pipeline reuse the same api_key/host without
|
|
31
|
+
# the core client exposing public readers.
|
|
32
|
+
PostHog::Rails::Logs::Setup.remember_client_options(options) if defined?(PostHog::Rails::Logs::Setup)
|
|
33
|
+
|
|
34
|
+
# Create the PostHog client. If a client already exists, shut it down
|
|
35
|
+
# after replacement so repeated init calls do not leave background
|
|
36
|
+
# resources from the previous instance running.
|
|
37
|
+
previous_client = @client
|
|
38
|
+
@client = PostHog::Client.new(options)
|
|
39
|
+
begin
|
|
40
|
+
previous_client&.shutdown
|
|
41
|
+
rescue StandardError => e
|
|
42
|
+
PostHog::Logging.logger.warn("Failed to shut down previous PostHog client: #{e.message}")
|
|
43
|
+
end
|
|
44
|
+
@client
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @return [Boolean] Whether {PostHog.init} has created a client.
|
|
48
|
+
def initialized?
|
|
49
|
+
!@client.nil?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Fallback for any client methods not explicitly defined.
|
|
53
|
+
#
|
|
54
|
+
# @api private
|
|
55
|
+
def method_missing(method_name, ...)
|
|
56
|
+
ensure_initialized!
|
|
57
|
+
|
|
58
|
+
if client.respond_to?(method_name)
|
|
59
|
+
client.public_send(method_name, ...)
|
|
60
|
+
else
|
|
61
|
+
super
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @api private
|
|
66
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
67
|
+
ensure_initialized!
|
|
68
|
+
client.respond_to?(method_name, include_private) || super
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
def ensure_initialized!
|
|
74
|
+
return if initialized?
|
|
75
|
+
|
|
76
|
+
@client = PostHog::Client.new(api_key: nil, silence_disabled_client_error: true)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
%i[
|
|
82
|
+
capture
|
|
83
|
+
capture_exception
|
|
84
|
+
identify
|
|
85
|
+
alias
|
|
86
|
+
group_identify
|
|
87
|
+
is_feature_enabled
|
|
88
|
+
get_feature_flag
|
|
89
|
+
get_all_flags
|
|
90
|
+
].each do |method_name|
|
|
91
|
+
PostHog.define_singleton_method(method_name) do |*args, **kwargs, &block|
|
|
92
|
+
ensure_initialized!
|
|
93
|
+
client.public_send(method_name, *args, **kwargs, &block)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
@posthog_facade_installed = true
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -1,97 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'posthog/rails/facade'
|
|
4
|
+
|
|
3
5
|
module PostHog
|
|
4
6
|
module Rails
|
|
5
7
|
class Railtie < ::Rails::Railtie
|
|
6
|
-
#
|
|
8
|
+
# Keep the historical Railtie initializer name, but install the facade at
|
|
9
|
+
# load time so application initializers can call PostHog.init.
|
|
7
10
|
initializer 'posthog.set_configs' do |_app|
|
|
8
|
-
PostHog.
|
|
9
|
-
class << self
|
|
10
|
-
attr_accessor :client
|
|
11
|
-
|
|
12
|
-
# Methods explicitly delegated to the client
|
|
13
|
-
DELEGATED_METHODS = %i[
|
|
14
|
-
capture
|
|
15
|
-
capture_exception
|
|
16
|
-
identify
|
|
17
|
-
alias
|
|
18
|
-
group_identify
|
|
19
|
-
is_feature_enabled
|
|
20
|
-
get_feature_flag
|
|
21
|
-
get_all_flags
|
|
22
|
-
].freeze
|
|
23
|
-
|
|
24
|
-
# Initialize the singleton PostHog client used by Rails delegators.
|
|
25
|
-
#
|
|
26
|
-
# @param options [Hash] Core {PostHog::Client} options.
|
|
27
|
-
# @yieldparam config [PostHog::Rails::InitConfig] Block-based core SDK configuration.
|
|
28
|
-
# @return [PostHog::Client]
|
|
29
|
-
def init(options = {})
|
|
30
|
-
# If block given, yield to configuration
|
|
31
|
-
if block_given?
|
|
32
|
-
config = PostHog::Rails::InitConfig.new(options)
|
|
33
|
-
yield config
|
|
34
|
-
options = config.to_client_options
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Let the PostHog Logs pipeline reuse the same api_key/host without
|
|
38
|
-
# the core client exposing public readers.
|
|
39
|
-
PostHog::Rails::Logs::Setup.remember_client_options(options) if defined?(PostHog::Rails::Logs::Setup)
|
|
40
|
-
|
|
41
|
-
# Create the PostHog client. If a client already exists, shut it down
|
|
42
|
-
# after replacement so repeated init calls do not leave background
|
|
43
|
-
# resources from the previous instance running.
|
|
44
|
-
previous_client = @client
|
|
45
|
-
@client = PostHog::Client.new(options)
|
|
46
|
-
begin
|
|
47
|
-
previous_client&.shutdown
|
|
48
|
-
rescue StandardError => e
|
|
49
|
-
PostHog::Logging.logger.warn("Failed to shut down previous PostHog client: #{e.message}")
|
|
50
|
-
end
|
|
51
|
-
@client
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Define delegated methods using metaprogramming
|
|
55
|
-
DELEGATED_METHODS.each do |method_name|
|
|
56
|
-
define_method(method_name) do |*args, **kwargs, &block|
|
|
57
|
-
ensure_initialized!
|
|
58
|
-
client.public_send(method_name, *args, **kwargs, &block)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# @return [Boolean] Whether {PostHog.init} has created a client.
|
|
63
|
-
def initialized?
|
|
64
|
-
!@client.nil?
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Fallback for any client methods not explicitly defined.
|
|
68
|
-
#
|
|
69
|
-
# @api private
|
|
70
|
-
def method_missing(method_name, ...)
|
|
71
|
-
ensure_initialized!
|
|
72
|
-
|
|
73
|
-
if client.respond_to?(method_name)
|
|
74
|
-
client.public_send(method_name, ...)
|
|
75
|
-
else
|
|
76
|
-
super
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# @api private
|
|
81
|
-
def respond_to_missing?(method_name, include_private = false)
|
|
82
|
-
ensure_initialized!
|
|
83
|
-
client.respond_to?(method_name, include_private) || super
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
private
|
|
87
|
-
|
|
88
|
-
def ensure_initialized!
|
|
89
|
-
return if initialized?
|
|
90
|
-
|
|
91
|
-
@client = PostHog::Client.new(api_key: nil, silence_disabled_client_error: true)
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
|
11
|
+
PostHog::Rails.install_posthog_facade!
|
|
95
12
|
end
|
|
96
13
|
|
|
97
14
|
# Insert middleware for request context and exception capturing
|
data/lib/posthog/rails.rb
CHANGED
|
@@ -12,6 +12,7 @@ require 'posthog/rails/logs/severity'
|
|
|
12
12
|
require 'posthog/rails/logs/rate_limiter'
|
|
13
13
|
require 'posthog/rails/logs/appender'
|
|
14
14
|
require 'posthog/rails/logs/setup'
|
|
15
|
+
require 'posthog/rails/facade'
|
|
15
16
|
require 'posthog/rails/railtie'
|
|
16
17
|
|
|
17
18
|
module PostHog
|
|
@@ -63,3 +64,5 @@ module PostHog
|
|
|
63
64
|
end
|
|
64
65
|
end
|
|
65
66
|
end
|
|
67
|
+
|
|
68
|
+
PostHog::Rails.install_posthog_facade!
|
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.0
|
|
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
|
|
@@ -52,6 +52,7 @@ files:
|
|
|
52
52
|
- lib/posthog/rails/capture_exceptions.rb
|
|
53
53
|
- lib/posthog/rails/configuration.rb
|
|
54
54
|
- lib/posthog/rails/error_subscriber.rb
|
|
55
|
+
- lib/posthog/rails/facade.rb
|
|
55
56
|
- lib/posthog/rails/logs/appender.rb
|
|
56
57
|
- lib/posthog/rails/logs/rate_limiter.rb
|
|
57
58
|
- lib/posthog/rails/logs/setup.rb
|