Class: AllStak::SessionTracker
- Inherits:
-
Object
- Object
- AllStak::SessionTracker
- Defined in:
- lib/allstak/session_tracker.rb
Overview
Server-mode “single session” release-health tracker.
Mirrors the AllStak Java SDK ‘SessionTracker` lifecycle + status model: on #start the SDK posts a `/ingest/v1/sessions/start` envelope with the process’s distinct session id, the resolved release, and SDK identity. On #end it posts ‘/ingest/v1/sessions/end` with the final status + total duration. ERRORED / CRASHED transitions are recorded in-memory only; only the terminal #end call performs network I/O for status, so per-error latency stays unaffected.
One instance per Client. Re-entrancy safe: once started a second #start is a no-op; once ended the tracker does not re-arm.
Sessions are NEVER sampled — they are always sent (when tracking is on and a release is resolvable). The whole tracker is fully fail-open: a network failure or any other error must never crash app boot or shutdown.
Constant Summary collapse
- PATH_START =
"/ingest/v1/sessions/start".freeze
- PATH_END =
"/ingest/v1/sessions/end".freeze
- STATUS_OK =
Lifecycle status. Vocabulary matches the backend ‘/sessions/end` contract and Sentry’s release-health conventions:
ok — ended normally, at most non-fatal logs. errored — at least one HANDLED error captured; process kept running. crashed — an UNHANDLED/fatal exception ended the process. abnormal — ended without a normal flush (reserved). "ok".freeze
- STATUS_ERRORED =
"errored".freeze
- STATUS_CRASHED =
"crashed".freeze
- STATUS_ABNORMAL =
"abnormal".freeze
Instance Attribute Summary collapse
-
#session_id ⇒ Object
readonly
Returns the value of attribute session_id.
-
#started_at ⇒ Object
readonly
Returns the value of attribute started_at.
Class Method Summary collapse
-
.test_runtime? ⇒ Boolean
Detect a unit-test runtime so session tracking self-disables there, matching register_runtime_release‘s own guard.
Instance Method Summary collapse
-
#current_session_id ⇒ Object
The active session id, or nil before start / after end.
-
#enabled? ⇒ Boolean
Should this runtime track sessions at all? Off when the user opted out via ‘enable_auto_session_tracking = false`, and automatically off under a unit test runtime (mirrors the Java SDK’s test guard) so the suite never emits session traffic.
-
#end(final_status = nil) ⇒ Object
Terminate the session and POST ‘/sessions/end` with durationMs + status.
-
#initialize(config, transport, logger = nil) ⇒ SessionTracker
constructor
A new instance of SessionTracker.
-
#record_crash ⇒ Object
Record an UNHANDLED/fatal crash: terminal status (overrides errored).
-
#record_error ⇒ Object
Record a HANDLED error: bump status ok -> errored (never downgrades a terminal crash).
-
#start ⇒ Object
Idempotent.
Constructor Details
#initialize(config, transport, logger = nil) ⇒ SessionTracker
Returns a new instance of SessionTracker.
38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/allstak/session_tracker.rb', line 38 def initialize(config, transport, logger = nil) @config = config @transport = transport @logger = logger @mutex = Mutex.new @session_id = nil @started_at = nil @status = STATUS_OK @error_count = 0 @started = false @ended = false end |
Instance Attribute Details
#session_id ⇒ Object (readonly)
Returns the value of attribute session_id.
36 37 38 |
# File 'lib/allstak/session_tracker.rb', line 36 def session_id @session_id end |
#started_at ⇒ Object (readonly)
Returns the value of attribute started_at.
36 37 38 |
# File 'lib/allstak/session_tracker.rb', line 36 def started_at @started_at end |
Class Method Details
.test_runtime? ⇒ Boolean
Detect a unit-test runtime so session tracking self-disables there, matching AllStak.register_runtime_release‘s own guard.
62 63 64 65 66 67 68 |
# File 'lib/allstak/session_tracker.rb', line 62 def self.test_runtime? return true if ENV["MT_TEST"] return true if ENV["RACK_ENV"] == "test" || ENV["RAILS_ENV"] == "test" return true if ENV["RUBYOPT"].to_s.include?("minitest") return true if $PROGRAM_NAME.to_s.include?("rspec") defined?(Minitest) ? true : false end |
Instance Method Details
#current_session_id ⇒ Object
The active session id, or nil before start / after end. Attached to every error/event payload so the backend can mark the session errored/crashed.
106 107 108 |
# File 'lib/allstak/session_tracker.rb', line 106 def current_session_id @mutex.synchronize { (@started && !@ended) ? @session_id : nil } end |
#enabled? ⇒ Boolean
Should this runtime track sessions at all? Off when the user opted out via ‘enable_auto_session_tracking = false`, and automatically off under a unit test runtime (mirrors the Java SDK’s test guard) so the suite never emits session traffic.
55 56 57 58 |
# File 'lib/allstak/session_tracker.rb', line 55 def enabled? return false unless @config.enable_auto_session_tracking !self.class.test_runtime? end |
#end(final_status = nil) ⇒ Object
Terminate the session and POST ‘/sessions/end` with durationMs + status. Idempotent. Best-effort with a short timeout; must not block or raise. `final_status` overrides the accumulated status when given.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/allstak/session_tracker.rb', line 133 def end(final_status = nil) sid = nil status = nil duration = nil @mutex.synchronize do return if @ended || !@started @ended = true sid = @session_id status = final_status || @status duration = [now_ms - @started_at.to_i, 0].max end return unless enabled? return if transport_disabled? return if effective_release.to_s.empty? payload = { sessionId: sid, durationMs: clamp_int(duration), status: status }.compact send_sync(PATH_END, payload, "session end") end |
#record_crash ⇒ Object
Record an UNHANDLED/fatal crash: terminal status (overrides errored). No I/O — the #end POST carries the status.
122 123 124 125 126 127 128 |
# File 'lib/allstak/session_tracker.rb', line 122 def record_crash @mutex.synchronize do next unless active_locked? @error_count += 1 @status = STATUS_CRASHED end end |
#record_error ⇒ Object
Record a HANDLED error: bump status ok -> errored (never downgrades a terminal crash). No I/O.
112 113 114 115 116 117 118 |
# File 'lib/allstak/session_tracker.rb', line 112 def record_error @mutex.synchronize do next unless active_locked? @error_count += 1 @status = STATUS_ERRORED if @status == STATUS_OK end end |
#start ⇒ Object
Idempotent. Records sessionStart, sets in-memory status = “ok”, and POSTs ‘/sessions/start` on a daemon thread so SDK init never blocks on a network round-trip. No-op when tracking is disabled, the transport is disabled, or no release/sdkVersion can be resolved. Never raises.
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 |
# File 'lib/allstak/session_tracker.rb', line 74 def start @mutex.synchronize do return self if @started @started = true @session_id = SecureRandom.uuid @started_at = now_ms @status = STATUS_OK @error_count = 0 end return self unless enabled? return self if transport_disabled? release = effective_release return self if release.to_s.empty? payload = { sessionId: @session_id, release: release, environment: @config.environment, userId: current_user_id, sdkName: @config.sdk_name, sdkVersion: @config.sdk_version, platform: @config.platform }.compact send_async(PATH_START, payload, "session start") self end |