Module: AllStak

Defined in:
lib/allstak.rb,
lib/allstak/client.rb,
lib/allstak/config.rb,
lib/allstak/version.rb,
lib/allstak/sampling.rb,
lib/allstak/sanitizer.rb,
lib/allstak/propagation.rb,
lib/allstak/modules/cron.rb,
lib/allstak/modules/logs.rb,
lib/allstak/global_handler.rb,
lib/allstak/modules/errors.rb,
lib/allstak/modules/tracing.rb,
lib/allstak/session_tracker.rb,
lib/allstak/modules/database.rb,
lib/allstak/integrations/rack.rb,
lib/allstak/integrations/rails.rb,
lib/allstak/integrations/logger.rb,
lib/allstak/models/user_context.rb,
lib/allstak/integrations/sidekiq.rb,
lib/allstak/modules/http_monitor.rb,
lib/allstak/integrations/net_http.rb,
lib/allstak/transport/event_spool.rb,
lib/allstak/transport/flush_buffer.rb,
lib/allstak/transport/http_transport.rb,
lib/allstak/integrations/active_record.rb

Overview

Official AllStak Ruby SDK.

Quick start:

require "allstak"

AllStak.configure do |c|
  c.api_key      = ENV["ALLSTAK_API_KEY"]
  c.environment  = "production"
  c.release      = "myapp@1.2.3"
  c.service_name = "myapp-api"
end

# Rails: auto-installed via Railtie — no manual wiring needed.
# Plain Rack: add the middleware yourself
use AllStak::Integrations::Rack::Middleware
# Sidekiq: server middleware auto-registered on configure.

# Manual:
AllStak.capture_exception(exc)
AllStak.log.info("hello", metadata: { foo: "bar" })
AllStak.cron.job("daily-report") { generate_report }

Defined Under Namespace

Modules: GitRelease, GlobalHandler, Integrations, Models, Modules, Propagation, Sampling, Sanitizer, Transport Classes: Client, Config, SessionTracker

Constant Summary collapse

VERSION =
"0.3.0"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.loggerObject (readonly)

Returns the value of attribute logger.



59
60
61
# File 'lib/allstak.rb', line 59

def logger
  @logger
end

Class Method Details

.add_breadcrumb(type:, message:, level: "info", data: nil) ⇒ Object

Manually record a breadcrumb on the current thread’s ring buffer. It is attached to the next captured exception on this thread. Cross-SDK parity with JS addBreadcrumb / Python add_breadcrumb. Safe no-op when the SDK is not configured. Manual breadcrumbs are always recorded (independent of the enable_auto_breadcrumbs toggle, which only gates auto-instrumentation).



175
176
177
# File 'lib/allstak.rb', line 175

def add_breadcrumb(type:, message:, level: "info", data: nil)
  @client&.errors&.add_breadcrumb(type: type, message: message, level: level, data: data)
end

.capture_error(exception_class, message, **kw) ⇒ Object



150
151
152
# File 'lib/allstak.rb', line 150

def capture_error(exception_class, message, **kw)
  @client&.capture_error(exception_class, message, **kw)
end

.capture_exception(exc, **kw) ⇒ Object



146
147
148
# File 'lib/allstak.rb', line 146

def capture_exception(exc, **kw)
  @client&.capture_exception(exc, **kw)
end

.capture_message(message, level: "info", **kw) ⇒ Object

Cross-SDK parity with JS captureMessage / Python capture_message / Java captureMessage. Emits a string as an error-group entry at the given level. Safe no-op if the SDK is not configured.



157
158
159
# File 'lib/allstak.rb', line 157

def capture_message(message, level: "info", **kw)
  @client&.capture_message(message, level: level, **kw)
end

.capture_unhandled(exc) ⇒ Object

Manually capture an exception as a global, unhandled event (mechanism=at_exit, handled=false) and flush synchronously. Use this at the top of a worker/thread/process boundary where the framework would not otherwise route the exception through the Rack middleware. Safe no-op when the SDK is not configured.



166
167
168
# File 'lib/allstak.rb', line 166

def capture_unhandled(exc)
  AllStak::GlobalHandler.capture_unhandled(exc)
end

.clear_userObject



183
184
185
# File 'lib/allstak.rb', line 183

def clear_user
  @client&.clear_user
end

.clientObject



116
117
118
# File 'lib/allstak.rb', line 116

def client
  @client or raise "AllStak not configured. Call AllStak.configure { |c| ... } first."
end

.configureObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/allstak.rb', line 61

def configure
  @mutex.synchronize do
    @config ||= Config.new
    yield @config if block_given?
    # Resolve release now that explicit user config has been applied:
    # explicit > env (set in #initialize) > local git > SDK version.
    @config.finalize_release!
    @logger = Logger.new($stderr).tap do |l|
      l.level = @config.debug ? Logger::DEBUG : Logger::WARN
      l.progname = "allstak"
    end
    if @config.valid?
      @client = Client.new(@config, @logger)
      register_runtime_release(@config, @logger)
      # Release-health: open one session per process now that config +
      # release are resolved. Idempotent + fully fail-open; self-disables
      # under a unit-test runtime and when enable_auto_session_tracking is
      # false.
      @client.start_session
      # Offline durability: replay telemetry persisted by a previous
      # process/outage through the live transport (respects retry/backoff +
      # circuit breaker). Async + fully fail-open; no-op when disabled.
      @client.drain_offline_queue
      # Auto-wire integrations that are safe to install
      AllStak::Integrations::ActiveRecordIntegration::Subscriber.install!
      AllStak::Integrations::NetHTTP.install!
      # Sidekiq + Rails self-guard: each is a graceful no-op when its host
      # framework is absent, and idempotent when present.
      AllStak::Integrations::Sidekiq.install!
      AllStak::Integrations::Rails.install!
      # Global uncaught-exception capture via at_exit. Idempotent and
      # opt-out via config.install_at_exit_handler.
      if @config.install_at_exit_handler
        # report_on_exception makes Ruby print (and lets us reason about)
        # exceptions that kill non-main threads; keep it on so background
        # thread crashes are at least visible. Best-effort.
        begin
          Thread.report_on_exception = true if Thread.respond_to?(:report_on_exception=)
        rescue StandardError
          # never let observability config break startup
        end
        AllStak::GlobalHandler.install!(@logger)
      end
    else
      @logger.warn("[AllStak] api_key not set — SDK not started")
      @client = nil
    end
    @client
  end
end

.cronObject



219
220
221
# File 'lib/allstak.rb', line 219

def cron
  @client&.cron
end

.databaseObject



215
216
217
# File 'lib/allstak.rb', line 215

def database
  @client&.database
end

.flushObject



223
224
225
# File 'lib/allstak.rb', line 223

def flush
  @client&.flush
end

.httpObject



211
212
213
# File 'lib/allstak.rb', line 211

def http
  @client&.http
end

.initialized?Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/allstak.rb', line 112

def initialized?
  !@client.nil?
end

.logObject



203
204
205
# File 'lib/allstak.rb', line 203

def log
  @client&.logs
end

.register_runtime_release(config, logger) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/allstak.rb', line 120

def register_runtime_release(config, logger)
  return unless config.auto_register_release
  return if config.release.to_s.empty? || config.api_key.to_s.empty?
  return if ENV["MT_TEST"] ||
            ENV["RACK_ENV"] == "test" ||
            ENV["RAILS_ENV"] == "test" ||
            ENV["RUBYOPT"].to_s.include?("minitest") ||
            $PROGRAM_NAME.to_s.include?("rspec")

  thread = Thread.new do
    begin
      AllStak::Transport::HttpTransport.new(config, logger).post("/ingest/v1/releases", {
        version: config.release,
        environment: config.environment || "production",
        commitSha: config.commit_sha,
        branch: config.branch,
        author: "#{config.sdk_name}/#{config.sdk_version}",
        message: "Registered automatically by AllStak Ruby SDK at runtime"
      })
    rescue StandardError => e
      logger.debug("[AllStak] runtime release registration failed: #{e.class}: #{e.message}") if logger
    end
  end
  thread.abort_on_exception = false
end

.reset!Object

Test helper.



232
233
234
235
236
237
238
# File 'lib/allstak.rb', line 232

def reset!
  @mutex.synchronize do
    @client&.shutdown rescue nil
    @client = nil
    @config = nil
  end
end

.set_context(key, value) ⇒ Object

Attach a custom context entry to every future event. Cross-SDK parity with JS/Python setContext.



199
200
201
# File 'lib/allstak.rb', line 199

def set_context(key, value)
  @client&.set_context(key, value)
end

.set_tag(key, value) ⇒ Object

Attach a tag that sticks to every future event. Cross-SDK parity with JS setTag / Python set_tag.



189
190
191
# File 'lib/allstak.rb', line 189

def set_tag(key, value)
  @client&.set_tag(key, value)
end

.set_tags(pairs) ⇒ Object



193
194
195
# File 'lib/allstak.rb', line 193

def set_tags(pairs)
  @client&.set_tags(pairs)
end

.set_user(**kw) ⇒ Object



179
180
181
# File 'lib/allstak.rb', line 179

def set_user(**kw)
  @client&.set_user(**kw)
end

.shutdownObject



227
228
229
# File 'lib/allstak.rb', line 227

def shutdown
  @client&.shutdown
end

.tracingObject



207
208
209
# File 'lib/allstak.rb', line 207

def tracing
  @client&.tracing
end