lapsoss 0.2.0 → 0.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/README.md +153 -733
- data/lib/lapsoss/adapters/appsignal_adapter.rb +22 -22
- data/lib/lapsoss/adapters/base.rb +0 -3
- data/lib/lapsoss/adapters/insight_hub_adapter.rb +108 -104
- data/lib/lapsoss/adapters/logger_adapter.rb +1 -1
- data/lib/lapsoss/adapters/rollbar_adapter.rb +108 -68
- data/lib/lapsoss/adapters/sentry_adapter.rb +24 -24
- data/lib/lapsoss/backtrace_frame.rb +37 -206
- data/lib/lapsoss/backtrace_frame_factory.rb +228 -0
- data/lib/lapsoss/backtrace_processor.rb +26 -23
- data/lib/lapsoss/client.rb +2 -4
- data/lib/lapsoss/configuration.rb +28 -32
- data/lib/lapsoss/current.rb +10 -2
- data/lib/lapsoss/event.rb +28 -5
- data/lib/lapsoss/exception_backtrace_frame.rb +39 -0
- data/lib/lapsoss/exclusion_configuration.rb +30 -0
- data/lib/lapsoss/exclusion_filter.rb +0 -273
- data/lib/lapsoss/exclusion_presets.rb +249 -0
- data/lib/lapsoss/fingerprinter.rb +28 -28
- data/lib/lapsoss/http_client.rb +8 -8
- data/lib/lapsoss/merged_scope.rb +63 -0
- data/lib/lapsoss/middleware/base.rb +15 -0
- data/lib/lapsoss/middleware/conditional_filter.rb +18 -0
- data/lib/lapsoss/middleware/event_enricher.rb +19 -0
- data/lib/lapsoss/middleware/event_transformer.rb +19 -0
- data/lib/lapsoss/middleware/exception_filter.rb +43 -0
- data/lib/lapsoss/middleware/metrics_collector.rb +44 -0
- data/lib/lapsoss/middleware/rate_limiter.rb +31 -0
- data/lib/lapsoss/middleware/release_tracker.rb +117 -0
- data/lib/lapsoss/middleware/sample_filter.rb +23 -0
- data/lib/lapsoss/middleware/sampling_middleware.rb +18 -0
- data/lib/lapsoss/middleware/user_context_enhancer.rb +46 -0
- data/lib/lapsoss/middleware.rb +0 -339
- data/lib/lapsoss/pipeline.rb +0 -68
- data/lib/lapsoss/pipeline_builder.rb +69 -0
- data/lib/lapsoss/rails_error_subscriber.rb +42 -0
- data/lib/lapsoss/rails_middleware.rb +78 -0
- data/lib/lapsoss/railtie.rb +22 -50
- data/lib/lapsoss/registry.rb +18 -5
- data/lib/lapsoss/release_providers.rb +110 -0
- data/lib/lapsoss/release_tracker.rb +159 -232
- data/lib/lapsoss/sampling/adaptive_sampler.rb +46 -0
- data/lib/lapsoss/sampling/base.rb +11 -0
- data/lib/lapsoss/sampling/composite_sampler.rb +26 -0
- data/lib/lapsoss/sampling/consistent_hash_sampler.rb +30 -0
- data/lib/lapsoss/sampling/exception_type_sampler.rb +44 -0
- data/lib/lapsoss/sampling/health_based_sampler.rb +19 -0
- data/lib/lapsoss/sampling/rate_limiter.rb +32 -0
- data/lib/lapsoss/sampling/sampling_factory.rb +69 -0
- data/lib/lapsoss/sampling/time_based_sampler.rb +44 -0
- data/lib/lapsoss/sampling/uniform_sampler.rb +15 -0
- data/lib/lapsoss/sampling/user_based_sampler.rb +42 -0
- data/lib/lapsoss/sampling.rb +0 -322
- data/lib/lapsoss/scope.rb +12 -48
- data/lib/lapsoss/scrubber.rb +7 -7
- data/lib/lapsoss/user_context.rb +30 -203
- data/lib/lapsoss/user_context_integrations.rb +39 -0
- data/lib/lapsoss/user_context_middleware.rb +50 -0
- data/lib/lapsoss/user_context_provider.rb +93 -0
- data/lib/lapsoss/utils.rb +13 -0
- data/lib/lapsoss/validators.rb +15 -15
- data/lib/lapsoss/version.rb +1 -1
- data/lib/lapsoss.rb +3 -3
- metadata +54 -5
data/lib/lapsoss/registry.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "singleton"
|
4
|
+
require "concurrent"
|
5
5
|
|
6
6
|
module Lapsoss
|
7
7
|
class Registry
|
@@ -36,11 +36,17 @@ module Lapsoss
|
|
36
36
|
#
|
37
37
|
# @param adapter [Adapter] The adapter instance to register
|
38
38
|
def register_adapter(adapter)
|
39
|
+
# Ensure we're getting an adapter instance, not a config hash
|
40
|
+
raise ArgumentError, "Expected an adapter instance, got #{adapter.class}" unless adapter.respond_to?(:capture)
|
41
|
+
|
39
42
|
name = if adapter.respond_to?(:name) && adapter.name
|
40
43
|
adapter.name.to_sym
|
41
|
-
|
42
|
-
adapter.class.name.split(
|
43
|
-
|
44
|
+
elsif adapter.class.name
|
45
|
+
adapter.class.name.split("::").last.to_sym
|
46
|
+
else
|
47
|
+
# Generate a unique name if class name is nil (anonymous class)
|
48
|
+
:"adapter_#{adapter.object_id}"
|
49
|
+
end
|
44
50
|
@adapters[name] = adapter
|
45
51
|
end
|
46
52
|
|
@@ -98,6 +104,13 @@ module Lapsoss
|
|
98
104
|
@adapters.keys
|
99
105
|
end
|
100
106
|
|
107
|
+
# Get all registered adapters (alias for all)
|
108
|
+
#
|
109
|
+
# @return [Array<Adapter>] All adapter instances
|
110
|
+
def adapters
|
111
|
+
all
|
112
|
+
end
|
113
|
+
|
101
114
|
private
|
102
115
|
|
103
116
|
# Resolve adapter type to class
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module Lapsoss
|
6
|
+
# Built-in release providers for common scenarios
|
7
|
+
class ReleaseProviders
|
8
|
+
def self.from_file(file_path)
|
9
|
+
lambda do
|
10
|
+
return nil unless File.exist?(file_path)
|
11
|
+
|
12
|
+
content = File.read(file_path).strip
|
13
|
+
return nil if content.empty?
|
14
|
+
|
15
|
+
# Try to parse as JSON first
|
16
|
+
begin
|
17
|
+
JSON.parse(content)
|
18
|
+
rescue JSON::ParserError
|
19
|
+
# Treat as plain text version
|
20
|
+
{ version: content }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_ruby_constant(constant_name)
|
26
|
+
lambda do
|
27
|
+
constant = Object.const_get(constant_name)
|
28
|
+
{ version: constant.to_s }
|
29
|
+
rescue NameError
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.from_gemfile_lock
|
35
|
+
lambda do
|
36
|
+
return nil unless File.exist?("Gemfile.lock")
|
37
|
+
|
38
|
+
content = File.read("Gemfile.lock")
|
39
|
+
|
40
|
+
# Extract gems with versions
|
41
|
+
gems = {}
|
42
|
+
content.scan(/^\s{4}(\w+)\s+\(([^)]+)\)/).each do |name, version|
|
43
|
+
gems[name] = version
|
44
|
+
end
|
45
|
+
|
46
|
+
{ gems: gems }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.from_package_json
|
51
|
+
lambda do
|
52
|
+
return nil unless File.exist?("package.json")
|
53
|
+
|
54
|
+
begin
|
55
|
+
package_info = JSON.parse(File.read("package.json"))
|
56
|
+
{
|
57
|
+
version: package_info["version"],
|
58
|
+
name: package_info["name"],
|
59
|
+
dependencies: package_info["dependencies"]&.keys
|
60
|
+
}.compact
|
61
|
+
rescue JSON::ParserError
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.from_rails_application
|
68
|
+
lambda do
|
69
|
+
return nil unless defined?(Rails) && Rails.respond_to?(:application)
|
70
|
+
|
71
|
+
app = Rails.application
|
72
|
+
return nil unless app
|
73
|
+
|
74
|
+
info = {
|
75
|
+
rails_version: Rails.version,
|
76
|
+
environment: Rails.env,
|
77
|
+
root: Rails.root.to_s
|
78
|
+
}
|
79
|
+
|
80
|
+
# Get application version if defined
|
81
|
+
info[:app_version] = app.class.version if app.class.respond_to?(:version)
|
82
|
+
|
83
|
+
# Get application name
|
84
|
+
info[:app_name] = app.class.name if app.class.respond_to?(:name)
|
85
|
+
|
86
|
+
info
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.from_capistrano
|
91
|
+
lambda do
|
92
|
+
# Check for Capistrano deployment files
|
93
|
+
%w[REVISION current/REVISION].each do |file|
|
94
|
+
next unless File.exist?(file)
|
95
|
+
|
96
|
+
revision = File.read(file).strip
|
97
|
+
next if revision.empty?
|
98
|
+
|
99
|
+
return {
|
100
|
+
revision: revision,
|
101
|
+
deployed_at: File.mtime(file),
|
102
|
+
deployment_method: "capistrano"
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
nil
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|