Module: Condux::Scope

Defined in:
lib/condux/scope.rb

Overview

Ambient event enrichment: who the user is, which tags and contexts apply, and the breadcrumb trail leading up to an error. Set once (or as the app's state changes) and every subsequent event carries it — the first triage questions ("which customer, which plan, what did they do last") answered without threading anything through capture calls. The relay already scrubs all of these at ingest and derives the pseudonymous users-affected key from the user fields.

Constant Summary collapse

MAX_BREADCRUMBS =

Newest trail wins: a long-lived process drops the oldest crumbs rather than growing without bound.

30

Class Method Summary collapse

Class Method Details

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

Record a breadcrumb; the trail (newest last, capped) rides every subsequent event.



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/condux/scope.rb', line 48

def add_breadcrumb(message, category: nil, level: nil, type: nil, data: nil, timestamp: nil)
  crumb = { "message" => message, "timestamp" => timestamp || Time.now.to_f }
  crumb["category"] = category if category
  crumb["level"] = level if level
  crumb["type"] = type if type
  crumb["data"] = data if data

  @mutex.synchronize do
    @breadcrumbs << crumb
    @breadcrumbs.shift while @breadcrumbs.length > MAX_BREADCRUMBS
  end
end

.clearObject

Reset all ambient state (tests, or a full sign-out).



62
63
64
65
66
67
68
69
# File 'lib/condux/scope.rb', line 62

def clear
  @mutex.synchronize do
    @user = nil
    @tags = {}
    @contexts = {}
    @breadcrumbs = []
  end
end

.fieldsObject

The scope's contribution to an event, holding only the keys that are actually set so an unenriched event keeps its exact wire shape. Breadcrumbs use the Sentry => [] envelope.



73
74
75
76
77
78
79
80
81
82
# File 'lib/condux/scope.rb', line 73

def fields
  @mutex.synchronize do
    fields = {}
    fields["user"] = @user.dup if @user
    fields["tags"] = @tags.dup unless @tags.empty?
    fields["contexts"] = @contexts.dup unless @contexts.empty?
    fields["breadcrumbs"] = { "values" => @breadcrumbs.dup } unless @breadcrumbs.empty?
    fields
  end
end

.set_context(name, context) ⇒ Object

Attach a named context object to subsequent events; nil removes it.



37
38
39
40
41
42
43
44
45
# File 'lib/condux/scope.rb', line 37

def set_context(name, context)
  @mutex.synchronize do
    if context.nil?
      @contexts.delete(name.to_s)
    else
      @contexts[name.to_s] = context.transform_keys(&:to_s)
    end
  end
end

.set_tag(key, value) ⇒ Object

Attach a tag to subsequent events; a nil value removes it.



26
27
28
29
30
31
32
33
34
# File 'lib/condux/scope.rb', line 26

def set_tag(key, value)
  @mutex.synchronize do
    if value.nil?
      @tags.delete(key.to_s)
    else
      @tags[key.to_s] = value
    end
  end
end

.user=(user) ⇒ Object

Attach the signed-in user (id/email/username) to subsequent events; nil clears.



21
22
23
# File 'lib/condux/scope.rb', line 21

def user=(user)
  @mutex.synchronize { @user = user&.transform_keys(&:to_s) }
end