otel_beacon 0.1.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.
@@ -0,0 +1,169 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "zeitwerk"
4
+ require "active_support"
5
+ require "active_support/core_ext/module/attribute_accessors"
6
+
7
+ loader = Zeitwerk::Loader.for_gem
8
+ loader.ignore("#{__dir__}/otel_beacon/rails")
9
+ loader.ignore("#{__dir__}/otel_beacon/integrations")
10
+ loader.setup
11
+
12
+ module OtelBeacon
13
+ extend self
14
+
15
+ mattr_accessor :logger, default: nil
16
+ mattr_accessor :service_name, default: ENV.fetch("OTEL_SERVICE_NAME") { ENV.fetch("SERVICE_NAME", "ruby_app") }
17
+ mattr_accessor :service_version, default: ENV.fetch("APP_VERSION", "0.0.0")
18
+ mattr_accessor :environment, default: ENV.fetch("RAILS_ENV") { ENV.fetch("RACK_ENV", "development") }
19
+ mattr_accessor :enabled, default: true
20
+ mattr_accessor :capture_exceptions, default: true
21
+ mattr_accessor :capture_logs, default: true
22
+ mattr_accessor :sanitize_fields, default: %w[password token secret key auth credential api_key access_token]
23
+ mattr_accessor :max_breadcrumbs, default: 50
24
+ mattr_accessor :max_stacktrace_lines, default: 20
25
+ mattr_accessor :before_capture, default: nil
26
+ mattr_accessor :before_breadcrumb, default: nil
27
+ mattr_accessor :current_user_method, default: :current_user
28
+ mattr_accessor :user_attributes, default: { id: :id, email: :email, username: %i[username name] }
29
+ mattr_accessor :on_thread_error, default: nil
30
+
31
+ def enabled? = enabled
32
+ def capture_exceptions? = capture_exceptions
33
+ def capture_logs? = capture_logs
34
+
35
+ def instrument(channel, **options, &block)
36
+ ActiveSupport::Notifications.instrument("#{channel}.otel_beacon", **options, &block)
37
+ end
38
+
39
+ def config
40
+ self
41
+ end
42
+
43
+ def sanitize_pattern
44
+ @sanitize_pattern ||= Regexp.new(sanitize_fields.join("|"), Regexp::IGNORECASE)
45
+ end
46
+
47
+ def reset_sanitize_pattern!
48
+ @sanitize_pattern = nil
49
+ end
50
+
51
+ def extract_user_attributes(user)
52
+ return {} unless user
53
+
54
+ result = {}
55
+ user_attributes.each do |key, methods|
56
+ methods = [ methods ] unless methods.is_a?(Array)
57
+ value = methods.lazy.filter_map { |m| safe_send(user, m) }.first
58
+ result[key] = value if value
59
+ end
60
+ result
61
+ end
62
+
63
+ def resolve_current_user(context = nil)
64
+ return nil unless current_user_method
65
+
66
+ case current_user_method
67
+ when Proc
68
+ current_user_method.call(context)
69
+ when String
70
+ resolve_string_method(current_user_method)
71
+ when Symbol
72
+ resolve_symbol_method(current_user_method, context)
73
+ end
74
+ rescue StandardError
75
+ nil
76
+ end
77
+
78
+ def reset_context!
79
+ Client.reset_context!
80
+ end
81
+
82
+ def set_user(...)
83
+ Client.set_user(...)
84
+ end
85
+
86
+ def set_tags(...)
87
+ Client.set_tags(...)
88
+ end
89
+
90
+ def set_extra(...)
91
+ Client.set_extra(...)
92
+ end
93
+
94
+ def set_context(...)
95
+ Client.set_context(...)
96
+ end
97
+
98
+ def set_fingerprint(...)
99
+ Client.set_fingerprint(...)
100
+ end
101
+
102
+ def with_scope(&block)
103
+ Client.with_scope(&block)
104
+ end
105
+
106
+ def add_breadcrumb(...)
107
+ Client.add_breadcrumb(...)
108
+ end
109
+
110
+ def in_span(...)
111
+ Client.in_span(...)
112
+ end
113
+
114
+ def capture_message(...)
115
+ Client.capture_message(...)
116
+ end
117
+
118
+ def capture_exception(...)
119
+ Client.capture_exception(...)
120
+ end
121
+
122
+ def record_event(...)
123
+ Client.record_event(...)
124
+ end
125
+
126
+ def set_runtime_context
127
+ RuntimeContext.set_defaults
128
+ end
129
+
130
+ def flush_context_to_span
131
+ Client.flush_context_to_span
132
+ end
133
+
134
+ class Error < StandardError; end
135
+
136
+ private
137
+
138
+ def safe_send(obj, method)
139
+ return nil unless obj.respond_to?(method)
140
+
141
+ obj.public_send(method)
142
+ rescue StandardError
143
+ nil
144
+ end
145
+
146
+ def resolve_string_method(method_string)
147
+ parts = method_string.split(".")
148
+ obj = Object.const_get(parts.first)
149
+ parts[1..].reduce(obj) { |o, m| o.public_send(m) }
150
+ rescue StandardError
151
+ nil
152
+ end
153
+
154
+ def resolve_symbol_method(method_name, context)
155
+ return nil unless context
156
+ return nil unless context.respond_to?(method_name, true)
157
+
158
+ context.send(method_name)
159
+ end
160
+ end
161
+
162
+ if defined?(Rails::Railtie)
163
+ require_relative "otel_beacon/rails/controller_methods"
164
+ require_relative "otel_beacon/rails/job_methods"
165
+ require_relative "otel_beacon/rails/mailer_methods"
166
+ require_relative "otel_beacon/rails/railtie"
167
+ end
168
+
169
+ loader.eager_load if defined?(Rails) && Rails.env.production?
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: otel_beacon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - BoringCache
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: activesupport
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '7.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '7.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: opentelemetry-api
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: opentelemetry-sdk
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: zeitwerk
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.6'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2.6'
68
+ - !ruby/object:Gem::Dependency
69
+ name: minitest
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '5.20'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '5.20'
82
+ - !ruby/object:Gem::Dependency
83
+ name: rake
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '13.0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '13.0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: rubocop
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.50'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.50'
110
+ description: Add Sentry-like developer experience (breadcrumbs, user context, tags,
111
+ fingerprinting) to any OpenTelemetry backend
112
+ email:
113
+ - oss@boringcache.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - CHANGELOG.md
119
+ - LICENSE.txt
120
+ - README.md
121
+ - UPGRADING.md
122
+ - lib/otel_beacon.rb
123
+ - lib/otel_beacon/breadcrumb.rb
124
+ - lib/otel_beacon/client.rb
125
+ - lib/otel_beacon/context.rb
126
+ - lib/otel_beacon/integrations/sidekiq.rb
127
+ - lib/otel_beacon/log_subscriber.rb
128
+ - lib/otel_beacon/rails/controller_methods.rb
129
+ - lib/otel_beacon/rails/job_methods.rb
130
+ - lib/otel_beacon/rails/logger.rb
131
+ - lib/otel_beacon/rails/mailer_methods.rb
132
+ - lib/otel_beacon/rails/railtie.rb
133
+ - lib/otel_beacon/runtime_context.rb
134
+ - lib/otel_beacon/sanitizer.rb
135
+ - lib/otel_beacon/scope.rb
136
+ - lib/otel_beacon/version.rb
137
+ homepage: https://github.com/boringcache/otel_beacon
138
+ licenses:
139
+ - MIT
140
+ metadata:
141
+ homepage_uri: https://github.com/boringcache/otel_beacon
142
+ source_code_uri: https://github.com/boringcache/otel_beacon
143
+ changelog_uri: https://github.com/boringcache/otel_beacon/blob/main/CHANGELOG.md
144
+ rubygems_mfa_required: 'true'
145
+ rdoc_options: []
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '3.2'
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ requirements: []
159
+ rubygems_version: 3.6.9
160
+ specification_version: 4
161
+ summary: Sentry-style error tracking and context for OpenTelemetry
162
+ test_files: []