Module: Alplus

Defined in:
lib/alplus.rb,
lib/alplus/id.rb,
lib/alplus/dedup.rb,
lib/alplus/retry.rb,
lib/alplus/scope.rb,
lib/alplus/stack.rb,
lib/alplus/client.rb,
lib/alplus/worker.rb,
lib/alplus/railtie.rb,
lib/alplus/session.rb,
lib/alplus/sidekiq.rb,
lib/alplus/testing.rb,
lib/alplus/version.rb,
lib/alplus/envelope.rb,
lib/alplus/scrubber.rb,
lib/alplus/heartbeat.rb,
lib/alplus/transport.rb,
lib/alplus/active_job.rb,
lib/alplus/configuration.rb,
lib/alplus/pending_window.rb,
lib/alplus/rack_middleware.rb,
lib/alplus/logger_breadcrumbs.rb,
lib/alplus/rails_error_subscriber.rb,
lib/alplus/notifications_subscriber.rb

Overview

Error reporting for POST /e/errors on AL+ Observe. Mirrors the wire contract of @alplus/sdk (TypeScript) and the Elixir SDK (see docs/ARCHITECTURE.md §8, docs/BUILD.md §5).

Alplus.configure do |config|
config.key = ENV["ALPLUS_KEY"]      # alp_... ingest key, `ingest` scope
config.environment = "production"
config.release = "v1.2.3"
end

Alplus.capture_exception(exception)
Alplus.capture_message("something happened", level: "warning")

Never raises into the host app: every public method here swallows its own internal errors and always returns the generated err_ event id.

Defined Under Namespace

Modules: ActiveJob, Dedup, Envelope, Heartbeat, Id, LoggerBreadcrumbs, NotificationsSubscriber, Retry, ScopeMerge, Scrubber, Sidekiq, Stack, Testing Classes: Client, Configuration, PendingWindow, RackMiddleware, RailsErrorSubscriber, Railtie, Scope, Session, TestTransport, Transport, Worker

Constant Summary collapse

VERSION =
"0.1.0"
SDK_NAME =
"alplus-ruby"
UNSET =

Sentinel default for user: on Client#capture_exception/ #capture_message — distinguishes "no per-call override given" (fall back to the ambient Scope user) from an explicit user: nil (clear the ambient user for this one capture), matching the JS SDK's overrides.user !== undefined check in scope.ts's mergeScope.

Object.new.freeze

Class Method Summary collapse

Class Method Details

.add_breadcrumb(message: nil, category: nil, level: nil, data: nil, ts: nil) ⇒ Object



126
127
128
129
130
131
# File 'lib/alplus.rb', line 126

def add_breadcrumb(message: nil, category: nil, level: nil, data: nil, ts: nil)
  Scope.current.add_breadcrumb(message: message, category: category, level: level, data: data, ts: ts)
  nil
rescue StandardError
  nil
end

.capture_exception(exception, **options) ⇒ Object



70
71
72
73
74
# File 'lib/alplus.rb', line 70

def capture_exception(exception, **options)
  client.capture_exception(exception, **options)
rescue StandardError
  Id.generate_event_id
end

.capture_message(message, **options) ⇒ Object



76
77
78
79
80
# File 'lib/alplus.rb', line 76

def capture_message(message, **options)
  client.capture_message(message, **options)
rescue StandardError
  Id.generate_event_id
end

.clientObject

Memoized under a mutex: two threads racing the very first capture call must not each construct a Client (and, with it, a second background Worker thread).



57
58
59
60
61
# File 'lib/alplus.rb', line 57

def client
  return @client if @client

  CLIENT_MUTEX.synchronize { @client ||= Client.new(configuration) }
end

.close_sessionObject

Closes the current thread's request-scoped Session (issue #12), if one is active (see RackMiddleware): reports it to POST /e/sessions via Client#report_session. A no-op if no session is active. Fail-safe: never raises. Not typically called directly — RackMiddleware calls this once @app.call returns or raises.



138
139
140
141
142
143
144
145
146
# File 'lib/alplus.rb', line 138

def close_session
  session = Session.current
  return nil unless session

  client.report_session(session)
  nil
rescue StandardError
  nil
end

.configurationObject



44
45
46
# File 'lib/alplus.rb', line 44

def configuration
  @configuration ||= Configuration.new
end

.configure {|configuration| ... } ⇒ Object

Yields:



48
49
50
51
52
# File 'lib/alplus.rb', line 48

def configure
  yield(configuration) if block_given?
  CLIENT_MUTEX.synchronize { @client = nil }
  configuration
end

.flush(timeout: 2) ⇒ Object

Blocks up to timeout seconds for the background queue to drain. Mainly useful in tests and at the end of a short-lived script.



84
85
86
87
88
# File 'lib/alplus.rb', line 84

def flush(timeout: 2)
  client.flush(timeout: timeout)
rescue StandardError
  false
end

.heartbeat(token, state: "finish") ⇒ Object

Pings AL+ Monitor's GET|POST /h/:token for cron/job liveness (issue #16): state: is "start", "finish" (the default), or "fail". Reuses the same retry/backoff as event delivery (Retry). Fail-safe: never raises into the caller, always returns nil.



94
95
96
97
98
99
# File 'lib/alplus.rb', line 94

def heartbeat(token, state: "finish")
  Heartbeat.ping(token, state: state, config: configuration)
  nil
rescue StandardError
  nil
end

.initialized_clientObject

The memoized client if one exists, without constructing it. The log-breadcrumb hook (issue #47) uses this: a boot-time log line must not force client construction before the host finishes configuring.



66
67
68
# File 'lib/alplus.rb', line 66

def initialized_client
  @client
end

.reset!Object

:nodoc: host tests use Alplus::Testing.reset!.



154
155
156
157
158
# File 'lib/alplus.rb', line 154

def reset!
  CLIENT_MUTEX.synchronize { @client = nil }
  @configuration = nil
  Dedup.reset!
end

.set_context(name, data) ⇒ Object



119
120
121
122
123
124
# File 'lib/alplus.rb', line 119

def set_context(name, data)
  Scope.current.set_context(name, data)
  nil
rescue StandardError
  nil
end

.set_tag(key, value) ⇒ Object



112
113
114
115
116
117
# File 'lib/alplus.rb', line 112

def set_tag(key, value)
  Scope.current.set_tag(key, value)
  nil
rescue StandardError
  nil
end

.set_user(user) ⇒ Object

Request-scoped scope ergonomics (issue #17): set once (typically at the top of a request, e.g. in a before_action) and applied to every capture_exception/capture_message call for the rest of the current thread/request. See Scope. Every setter is fail-safe.



105
106
107
108
109
110
# File 'lib/alplus.rb', line 105

def set_user(user)
  Scope.current.set_user(user)
  nil
rescue StandardError
  nil
end

.test_transportObject

:nodoc: host tests use Alplus::Testing.



149
150
151
# File 'lib/alplus.rb', line 149

def test_transport
  client.transport
end