posthog-ruby 3.2.0 → 3.3.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/posthog/client.rb +29 -0
- data/lib/posthog/exception_capture.rb +116 -0
- data/lib/posthog/version.rb +1 -1
- data/lib/posthog.rb +1 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e895ef67d6f423e89151951d6868fa464c1efe64cee6dd37be8923351bf88467
|
4
|
+
data.tar.gz: 7bf79b2a93e79c8717e52ed2a6ca3261f0d3933859e05e0cee1c9c22aaaa77db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 881cd65e3634adc8fe539fad751591876ffd070ed712b4de8533fdf38e231ba15fd126daa0afece1b1f06b27306c3afa00c1129e37c98202391593f439cfa886
|
7
|
+
data.tar.gz: 2333ef174f7f08858cf518d66ac60bd6c5fa8246d06b61c73c89c5e7d08cf2986b5b45bc952d6d18476b3b73257402ee5838a362da100da1b64d7c72f4ae38eb
|
data/lib/posthog/client.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'time'
|
4
|
+
require 'securerandom'
|
4
5
|
|
5
6
|
require 'posthog/defaults'
|
6
7
|
require 'posthog/logging'
|
@@ -9,6 +10,7 @@ require 'posthog/send_worker'
|
|
9
10
|
require 'posthog/noop_worker'
|
10
11
|
require 'posthog/feature_flags'
|
11
12
|
require 'posthog/send_feature_flags_options'
|
13
|
+
require 'posthog/exception_capture'
|
12
14
|
|
13
15
|
module PostHog
|
14
16
|
class Client
|
@@ -144,6 +146,33 @@ module PostHog
|
|
144
146
|
enqueue(FieldParser.parse_for_capture(attrs))
|
145
147
|
end
|
146
148
|
|
149
|
+
# Captures an exception as an event
|
150
|
+
#
|
151
|
+
# @param [Exception, String, Object] exception The exception to capture, a string message, or exception-like object
|
152
|
+
# @param [String] distinct_id The ID for the user (optional, defaults to a generated UUID)
|
153
|
+
# @param [Hash] additional_properties Additional properties to include with the exception event (optional)
|
154
|
+
def capture_exception(exception, distinct_id = nil, additional_properties = {})
|
155
|
+
exception_info = ExceptionCapture.build_parsed_exception(exception)
|
156
|
+
|
157
|
+
return if exception_info.nil?
|
158
|
+
|
159
|
+
no_distinct_id_was_provided = distinct_id.nil?
|
160
|
+
distinct_id ||= SecureRandom.uuid
|
161
|
+
|
162
|
+
properties = { '$exception_list' => [exception_info] }
|
163
|
+
properties.merge!(additional_properties) if additional_properties && !additional_properties.empty?
|
164
|
+
properties['$process_person_profile'] = false if no_distinct_id_was_provided
|
165
|
+
|
166
|
+
event_data = {
|
167
|
+
distinct_id: distinct_id,
|
168
|
+
event: '$exception',
|
169
|
+
properties: properties,
|
170
|
+
timestamp: Time.now
|
171
|
+
}
|
172
|
+
|
173
|
+
capture(event_data)
|
174
|
+
end
|
175
|
+
|
147
176
|
# Identifies a user
|
148
177
|
#
|
149
178
|
# @param [Hash] attrs
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Portions of this file are derived from getsentry/sentry-ruby by Software, Inc. dba Sentry
|
4
|
+
# Licensed under the MIT License
|
5
|
+
# - sentry-ruby/lib/sentry/interfaces/single_exception.rb
|
6
|
+
# - sentry-ruby/lib/sentry/interfaces/stacktrace_builder.rb
|
7
|
+
# - sentry-ruby/lib/sentry/backtrace.rb
|
8
|
+
# - sentry-ruby/lib/sentry/interfaces/stacktrace.rb
|
9
|
+
# - sentry-ruby/lib/sentry/linecache.rb
|
10
|
+
|
11
|
+
# 💖 open source (under MIT License)
|
12
|
+
|
13
|
+
module PostHog
|
14
|
+
module ExceptionCapture
|
15
|
+
RUBY_INPUT_FORMAT = /
|
16
|
+
^ \s* (?: [a-zA-Z]: | uri:classloader: )? ([^:]+ | <.*>):
|
17
|
+
(\d+)
|
18
|
+
(?: :in\s('|`)(?:([\w:]+)\#)?([^']+)')?$
|
19
|
+
/x
|
20
|
+
|
21
|
+
def self.build_parsed_exception(value)
|
22
|
+
title, message, backtrace = coerce_exception_input(value)
|
23
|
+
return nil if title.nil?
|
24
|
+
|
25
|
+
build_single_exception_from_data(title, message, backtrace)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.build_single_exception_from_data(title, message, backtrace)
|
29
|
+
{
|
30
|
+
'type' => title,
|
31
|
+
'value' => message || '',
|
32
|
+
'mechanism' => {
|
33
|
+
'type' => 'generic',
|
34
|
+
'handled' => true
|
35
|
+
},
|
36
|
+
'stacktrace' => build_stacktrace(backtrace)
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.build_stacktrace(backtrace)
|
41
|
+
return nil unless backtrace && !backtrace.empty?
|
42
|
+
|
43
|
+
frames = backtrace.first(50).map do |line|
|
44
|
+
parse_backtrace_line(line)
|
45
|
+
end.compact.reverse
|
46
|
+
|
47
|
+
{
|
48
|
+
'type' => 'raw',
|
49
|
+
'frames' => frames
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.parse_backtrace_line(line)
|
54
|
+
match = line.match(RUBY_INPUT_FORMAT)
|
55
|
+
return nil unless match
|
56
|
+
|
57
|
+
file = match[1]
|
58
|
+
lineno = match[2].to_i
|
59
|
+
method_name = match[5]
|
60
|
+
|
61
|
+
frame = {
|
62
|
+
'filename' => File.basename(file),
|
63
|
+
'abs_path' => file,
|
64
|
+
'lineno' => lineno,
|
65
|
+
'function' => method_name,
|
66
|
+
'in_app' => !gem_path?(file),
|
67
|
+
'platform' => 'ruby'
|
68
|
+
}
|
69
|
+
|
70
|
+
add_context_lines(frame, file, lineno) if File.exist?(file)
|
71
|
+
|
72
|
+
frame
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.gem_path?(path)
|
76
|
+
path.include?('/gems/') ||
|
77
|
+
path.include?('/ruby/') ||
|
78
|
+
path.include?('/.rbenv/') ||
|
79
|
+
path.include?('/.rvm/')
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.add_context_lines(frame, file_path, lineno, context_size = 5)
|
83
|
+
lines = File.readlines(file_path)
|
84
|
+
return if lines.empty?
|
85
|
+
|
86
|
+
return unless lineno.positive? && lineno <= lines.length
|
87
|
+
|
88
|
+
pre_context_start = [lineno - context_size, 1].max
|
89
|
+
post_context_end = [lineno + context_size, lines.length].min
|
90
|
+
|
91
|
+
frame['context_line'] = lines[lineno - 1].chomp
|
92
|
+
|
93
|
+
frame['pre_context'] = lines[(pre_context_start - 1)...(lineno - 1)].map(&:chomp) if pre_context_start < lineno
|
94
|
+
|
95
|
+
frame['post_context'] = lines[lineno...(post_context_end)].map(&:chomp) if post_context_end > lineno
|
96
|
+
rescue StandardError
|
97
|
+
# Silently ignore file read errors
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.coerce_exception_input(value)
|
101
|
+
if value.is_a?(String)
|
102
|
+
title = 'Error'
|
103
|
+
message = value
|
104
|
+
backtrace = nil
|
105
|
+
elsif value.respond_to?(:backtrace) && value.respond_to?(:message)
|
106
|
+
title = value.class.to_s
|
107
|
+
message = value.message || ''
|
108
|
+
backtrace = value.backtrace
|
109
|
+
else
|
110
|
+
return [nil, nil, nil]
|
111
|
+
end
|
112
|
+
|
113
|
+
[title, message, backtrace]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/posthog/version.rb
CHANGED
data/lib/posthog.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: posthog-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
8
|
+
autorequire:
|
8
9
|
bindir: bin
|
9
10
|
cert_chain: []
|
10
|
-
date: 2025-
|
11
|
+
date: 2025-09-23 00:00:00.000000000 Z
|
11
12
|
dependencies:
|
12
13
|
- !ruby/object:Gem::Dependency
|
13
14
|
name: concurrent-ruby
|
@@ -38,6 +39,7 @@ files:
|
|
38
39
|
- lib/posthog/backoff_policy.rb
|
39
40
|
- lib/posthog/client.rb
|
40
41
|
- lib/posthog/defaults.rb
|
42
|
+
- lib/posthog/exception_capture.rb
|
41
43
|
- lib/posthog/feature_flag.rb
|
42
44
|
- lib/posthog/feature_flags.rb
|
43
45
|
- lib/posthog/field_parser.rb
|
@@ -55,6 +57,7 @@ licenses:
|
|
55
57
|
- MIT
|
56
58
|
metadata:
|
57
59
|
rubygems_mfa_required: 'true'
|
60
|
+
post_install_message:
|
58
61
|
rdoc_options: []
|
59
62
|
require_paths:
|
60
63
|
- lib
|
@@ -69,7 +72,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
72
|
- !ruby/object:Gem::Version
|
70
73
|
version: '0'
|
71
74
|
requirements: []
|
72
|
-
rubygems_version: 3.
|
75
|
+
rubygems_version: 3.5.3
|
76
|
+
signing_key:
|
73
77
|
specification_version: 4
|
74
78
|
summary: PostHog library
|
75
79
|
test_files: []
|