lapsoss 0.4.2 ā 0.4.5
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 +129 -0
- data/lib/lapsoss/adapters/concerns/level_mapping.rb +1 -0
- data/lib/lapsoss/adapters/telebugs_adapter.rb +58 -0
- data/lib/lapsoss/configuration.rb +6 -0
- data/lib/lapsoss/railtie.rb +1 -1
- data/lib/lapsoss/version.rb +1 -1
- data/lib/lapsoss.rb +23 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5db26196bdbf6e69d90c126041f7310681e240ef22e61f0a3aee12035f7616da
|
4
|
+
data.tar.gz: 93a2c75b6af04e776aca9c24f3704ddba51b4a2432d5d6db0f736874bef17c69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38d9d2d1c1e2f67997b71cae8776b2c7ef8b3aca5d13d563080304c63b84b1db227eb923618b1ae078223cfc20dfebf5d1620dcf01eed92ee62d53461bf36e1e
|
7
|
+
data.tar.gz: 1831cda3198ad594c850fd5579fed77aa9097ee4f497dd81374bb265ee237addc4d31fab0447d6164cff6fb64695869eba42366e0820647725d0725566158ff8
|
data/README.md
CHANGED
@@ -163,6 +163,7 @@ All adapters are pure Ruby implementations with no external SDK dependencies:
|
|
163
163
|
- **Rollbar** - Complete error tracking with grouping
|
164
164
|
- **AppSignal** - Error tracking and deploy markers
|
165
165
|
- **Insight Hub** (formerly Bugsnag) - Error tracking with breadcrumbs
|
166
|
+
- **Telebugs** - Sentry-compatible protocol (perfect for self-hosted alternatives)
|
166
167
|
|
167
168
|
## Configuration
|
168
169
|
|
@@ -186,6 +187,17 @@ Lapsoss.configure do |config|
|
|
186
187
|
end
|
187
188
|
```
|
188
189
|
|
190
|
+
### Using Sentry-Compatible Services
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
# Telebugs, Glitchtip, or any Sentry-compatible service
|
194
|
+
Lapsoss.configure do |config|
|
195
|
+
config.use_telebugs(dsn: ENV['TELEBUGS_DSN'])
|
196
|
+
# Or use use_sentry with a custom endpoint
|
197
|
+
config.use_sentry(dsn: ENV['SELF_HOSTED_SENTRY_DSN'])
|
198
|
+
end
|
199
|
+
```
|
200
|
+
|
189
201
|
### Advanced Configuration
|
190
202
|
|
191
203
|
```ruby
|
@@ -310,6 +322,103 @@ config.transport_timeout = 10
|
|
310
322
|
config.transport_jitter = true # Prevent thundering herd
|
311
323
|
```
|
312
324
|
|
325
|
+
## Testing in Rails Console
|
326
|
+
|
327
|
+
Want to see Lapsoss in action? Try this in your Rails console:
|
328
|
+
|
329
|
+
```ruby
|
330
|
+
# Configure Lapsoss with the logger adapter for immediate visibility
|
331
|
+
Lapsoss.configure do |config|
|
332
|
+
config.use_logger(name: :console_test)
|
333
|
+
config.async = false # Synchronous for immediate output
|
334
|
+
config.debug = true # Verbose logging
|
335
|
+
end
|
336
|
+
|
337
|
+
# Create a class that demonstrates error handling
|
338
|
+
class Liberation
|
339
|
+
def self.liberate!
|
340
|
+
Rails.error.handle do
|
341
|
+
raise StandardError, "Freedom requires breaking chains!"
|
342
|
+
end
|
343
|
+
puts "ā
Continued execution after error"
|
344
|
+
end
|
345
|
+
|
346
|
+
def self.revolt!
|
347
|
+
Rails.error.record do
|
348
|
+
raise RuntimeError, "Revolution cannot be stopped!"
|
349
|
+
end
|
350
|
+
puts "This won't print - error was re-raised"
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
# Test error capture (error is swallowed)
|
355
|
+
Liberation.liberate!
|
356
|
+
# You'll see the error logged but execution continues
|
357
|
+
|
358
|
+
# Test error recording (error is re-raised)
|
359
|
+
begin
|
360
|
+
Liberation.revolt!
|
361
|
+
rescue => e
|
362
|
+
puts "Caught re-raised error: #{e.message}"
|
363
|
+
end
|
364
|
+
|
365
|
+
# Manual error reporting with context
|
366
|
+
begin
|
367
|
+
1 / 0
|
368
|
+
rescue => e
|
369
|
+
Rails.error.report(e, context: { user_id: 42, action: "console_test" })
|
370
|
+
end
|
371
|
+
|
372
|
+
# Check what was captured
|
373
|
+
puts "\nš Lapsoss captured all errors through Rails.error!"
|
374
|
+
```
|
375
|
+
|
376
|
+
You'll see all errors logged to your console with full backtraces and context. This same integration works automatically for all Rails controllers, jobs, and mailers.
|
377
|
+
|
378
|
+
## Using Lapsoss Outside Rails
|
379
|
+
|
380
|
+
Lapsoss provides the same convenient error handling methods directly, perfect for background jobs, rake tasks, or standalone scripts:
|
381
|
+
|
382
|
+
```ruby
|
383
|
+
# In your Sidekiq job, rake task, or any Ruby code
|
384
|
+
require 'lapsoss'
|
385
|
+
|
386
|
+
Lapsoss.configure do |config|
|
387
|
+
config.use_sentry(dsn: ENV['SENTRY_DSN'])
|
388
|
+
end
|
389
|
+
|
390
|
+
# Handle errors (swallow them)
|
391
|
+
result = Lapsoss.handle do
|
392
|
+
risky_operation
|
393
|
+
end
|
394
|
+
# Returns nil if error occurred, or the block's result
|
395
|
+
|
396
|
+
# Handle with fallback
|
397
|
+
user = Lapsoss.handle(fallback: User.anonymous) do
|
398
|
+
User.find(id)
|
399
|
+
end
|
400
|
+
|
401
|
+
# Record errors (re-raise them)
|
402
|
+
Lapsoss.record do
|
403
|
+
critical_operation # Error is captured then re-raised
|
404
|
+
end
|
405
|
+
|
406
|
+
# Report errors manually
|
407
|
+
begin
|
408
|
+
something_dangerous
|
409
|
+
rescue => e
|
410
|
+
Lapsoss.report(e, user_id: user.id, context: 'background_job')
|
411
|
+
# Continue processing...
|
412
|
+
end
|
413
|
+
|
414
|
+
# These methods mirror Rails.error exactly:
|
415
|
+
# - Lapsoss.handle ā Rails.error.handle
|
416
|
+
# - Lapsoss.record ā Rails.error.record
|
417
|
+
# - Lapsoss.report ā Rails.error.report
|
418
|
+
```
|
419
|
+
|
420
|
+
This means your error handling code works the same way everywhere - in Rails controllers, background jobs, rake tasks, or standalone scripts.
|
421
|
+
|
313
422
|
## Creating Custom Adapters
|
314
423
|
|
315
424
|
```ruby
|
@@ -323,6 +432,26 @@ end
|
|
323
432
|
Lapsoss::Registry.register(:my_service, MyAdapter)
|
324
433
|
```
|
325
434
|
|
435
|
+
### Extending Existing Adapters
|
436
|
+
|
437
|
+
For Sentry-compatible services, just extend the SentryAdapter:
|
438
|
+
|
439
|
+
```ruby
|
440
|
+
class TelebugsAdapter < Lapsoss::Adapters::SentryAdapter
|
441
|
+
def initialize(name = :telebugs, settings = {})
|
442
|
+
super(name, settings)
|
443
|
+
end
|
444
|
+
|
445
|
+
private
|
446
|
+
|
447
|
+
def build_headers(public_key)
|
448
|
+
super(public_key).merge(
|
449
|
+
"X-Telebugs-Client" => "lapsoss/#{Lapsoss::VERSION}"
|
450
|
+
)
|
451
|
+
end
|
452
|
+
end
|
453
|
+
```
|
454
|
+
|
326
455
|
## Contributing
|
327
456
|
|
328
457
|
1. Fork it
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "sentry_adapter"
|
4
|
+
|
5
|
+
module Lapsoss
|
6
|
+
module Adapters
|
7
|
+
# Telebugs adapter - uses Sentry protocol with Telebugs endpoints
|
8
|
+
# Telebugs is compatible with Sentry's API, so we inherit from SentryAdapter
|
9
|
+
class TelebugsAdapter < SentryAdapter
|
10
|
+
def initialize(name = :telebugs, settings = {})
|
11
|
+
super(name, settings)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
# Override to parse Telebugs DSN format
|
17
|
+
def parse_dsn(dsn_string)
|
18
|
+
uri = URI.parse(dsn_string)
|
19
|
+
{
|
20
|
+
public_key: uri.user,
|
21
|
+
project_id: uri.path.split("/").last,
|
22
|
+
host: uri.host,
|
23
|
+
path: uri.path
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
# Override to build Telebugs-specific API path
|
28
|
+
def build_api_path(uri)
|
29
|
+
# Telebugs DSN: https://[key]@[host]/api/v1/sentry_errors/[project_id]
|
30
|
+
# But needs to hit: /api/v1/sentry_errors/api/[project_id]/envelope/
|
31
|
+
# Extract base path without project_id
|
32
|
+
path_parts = uri.path.split("/")
|
33
|
+
project_id = path_parts.last
|
34
|
+
base_path = path_parts[0..-2].join("/")
|
35
|
+
|
36
|
+
# Build the envelope path
|
37
|
+
"#{base_path}/api/#{project_id}/envelope/"
|
38
|
+
end
|
39
|
+
|
40
|
+
# Override to setup Telebugs endpoint
|
41
|
+
def setup_endpoint
|
42
|
+
uri = URI.parse(@settings[:dsn])
|
43
|
+
# For Telebug, we use the full URL without port (unless non-standard)
|
44
|
+
port = (uri.port == 443 || uri.port == 80) ? "" : ":#{uri.port}"
|
45
|
+
self.class.api_endpoint = "#{uri.scheme}://#{uri.host}#{port}"
|
46
|
+
self.class.api_path = build_api_path(uri)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Override headers builder to add Telebugs-specific headers
|
50
|
+
def headers_for(envelope)
|
51
|
+
base_headers = super(envelope)
|
52
|
+
base_headers.merge(
|
53
|
+
"X-Telebugs-Client" => "lapsoss/#{Lapsoss::VERSION}"
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "logger"
|
3
4
|
require "active_support/configurable"
|
4
5
|
|
5
6
|
module Lapsoss
|
@@ -84,6 +85,11 @@ module Lapsoss
|
|
84
85
|
register_adapter(name, :sentry, **settings)
|
85
86
|
end
|
86
87
|
|
88
|
+
# Convenience method for Telebugs (Sentry-compatible)
|
89
|
+
def use_telebugs(name: :telebugs, **settings)
|
90
|
+
register_adapter(name, :telebugs, **settings)
|
91
|
+
end
|
92
|
+
|
87
93
|
# Convenience method for AppSignal
|
88
94
|
def use_appsignal(name: :appsignal, **settings)
|
89
95
|
register_adapter(name, :appsignal, **settings)
|
data/lib/lapsoss/railtie.rb
CHANGED
@@ -49,7 +49,7 @@ module Lapsoss
|
|
49
49
|
end
|
50
50
|
|
51
51
|
initializer "lapsoss.rails_error_subscriber", after: "lapsoss.add_middleware" do |app|
|
52
|
-
|
52
|
+
Rails.error.subscribe(Lapsoss::RailsErrorSubscriber.new)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
data/lib/lapsoss/version.rb
CHANGED
data/lib/lapsoss.rb
CHANGED
@@ -44,6 +44,29 @@ module Lapsoss
|
|
44
44
|
client.capture_message(message, level: level, **context)
|
45
45
|
end
|
46
46
|
|
47
|
+
# Rails.error-compatible methods for non-Rails environments
|
48
|
+
|
49
|
+
# Handle errors and swallow them (like Rails.error.handle)
|
50
|
+
def handle(error_class = StandardError, fallback: nil, **context)
|
51
|
+
yield
|
52
|
+
rescue error_class => e
|
53
|
+
capture_exception(e, **context.merge(handled: true))
|
54
|
+
fallback.respond_to?(:call) ? fallback.call : fallback
|
55
|
+
end
|
56
|
+
|
57
|
+
# Record errors and re-raise them (like Rails.error.record)
|
58
|
+
def record(error_class = StandardError, **context)
|
59
|
+
yield
|
60
|
+
rescue error_class => e
|
61
|
+
capture_exception(e, **context.merge(handled: false))
|
62
|
+
raise
|
63
|
+
end
|
64
|
+
|
65
|
+
# Report an error manually (like Rails.error.report)
|
66
|
+
def report(exception, handled: true, **context)
|
67
|
+
capture_exception(exception, **context.merge(handled: handled))
|
68
|
+
end
|
69
|
+
|
47
70
|
def add_breadcrumb(message, type: :default, **metadata)
|
48
71
|
client.add_breadcrumb(message, type: type, **metadata)
|
49
72
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lapsoss
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Abdelkader Boudih
|
@@ -225,6 +225,7 @@ files:
|
|
225
225
|
- lib/lapsoss/adapters/logger_adapter.rb
|
226
226
|
- lib/lapsoss/adapters/rollbar_adapter.rb
|
227
227
|
- lib/lapsoss/adapters/sentry_adapter.rb
|
228
|
+
- lib/lapsoss/adapters/telebugs_adapter.rb
|
228
229
|
- lib/lapsoss/backtrace_frame.rb
|
229
230
|
- lib/lapsoss/backtrace_frame_factory.rb
|
230
231
|
- lib/lapsoss/backtrace_processor.rb
|