Class: Traceable::Tracer

Inherits:
Object
  • Object
show all
Defined in:
lib/traceable/tracer.rb

Overview

rubocop:disable Metrics/ClassLength

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent_tracer, tags: nil, logger: nil) ⇒ Tracer

Returns a new instance of Tracer.



15
16
17
18
19
20
# File 'lib/traceable/tracer.rb', line 15

def initialize(parent_tracer, tags: nil, logger: nil)
  @parent = which_parent(parent_tracer)
  @logger = logger || (@parent ? @parent.logger : Tracer.default_logger)
  @tags = @parent ? @parent.tags.dup : Tracer.default_tags
  @tags.merge!(tags) if tags
end

Instance Attribute Details

#loggerObject

Returns the value of attribute logger.



11
12
13
# File 'lib/traceable/tracer.rb', line 11

def logger
  @logger
end

#parentObject (readonly)

Returns the value of attribute parent.



12
13
14
# File 'lib/traceable/tracer.rb', line 12

def parent
  @parent
end

#tagsObject (readonly)

Returns the value of attribute tags.



13
14
15
# File 'lib/traceable/tracer.rb', line 13

def tags
  @tags
end

Class Method Details

.default_loggerObject



22
23
24
# File 'lib/traceable/tracer.rb', line 22

def self.default_logger
  Traceable.config.logger
end

.default_parentObject

rubocop:enable Metrics/AbcSize rubocop:enable Metrics/MethodLength



108
109
110
# File 'lib/traceable/tracer.rb', line 108

def self.default_parent
  tracer_stack.last # nil if nothing currently on the stack
end

.default_tagsObject



26
27
28
29
30
31
32
33
34
35
# File 'lib/traceable/tracer.rb', line 26

def self.default_tags
  tags = Traceable.config.default_tags.merge(
    trace: SecureRandom.uuid
  )
  tags.each_key do |k|
    value = tags[k]
    tags[k] = value.call if value.respond_to?(:call)
  end
  tags
end

.tracer_stackObject

The tracer stack is a thread-local list of tracer instances, allowing the current tracer context to be automatically inherited by any other tracer instances created further down in the stack.

The current tracer is pushed onto the stack when entering a traced block, then popped from the stack when leaving the traced block.



119
120
121
# File 'lib/traceable/tracer.rb', line 119

def self.tracer_stack
  Thread.current[:tracer_stack] ||= []
end

Instance Method Details

#debug(msg, **tags) ⇒ Object



68
69
70
# File 'lib/traceable/tracer.rb', line 68

def debug(msg, **tags)
  emit :debug, msg, **tags
end

#do_block(msg, **tags, &_) ⇒ Object

rubocop:disable Metrics/AbcSize rubocop:disable Metrics/MethodLength



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
# File 'lib/traceable/tracer.rb', line 74

def do_block(msg, **tags, &_)
  info "START: #{msg}", enter: true, **tags
  block_start_time = Time.now.utc

  begin
    push
    yield tags
  rescue StandardError => ex
    elapsed = Time.now.utc - block_start_time
    if ex.instance_variable_defined?(:@traceable_rescued)
      origin = ex.instance_variable_get(:@traceable_rescued)
      ex_message = " [propagated from #{origin}]"
    else
      ex.instance_variable_set(:@traceable_rescued, msg)
      ex_message = ", #{ex.message}"
      tags[:backtrace] ||= ex.backtrace.join('\n')
    end

    warn "EXCEPTION: #{msg} => #{ex.class.name}#{ex_message}",
         exception: true, elapsed: elapsed, class: ex.class.name, **tags

    raise
  ensure
    pop

    unless ex
      elapsed = Time.now.utc - block_start_time
      info "END: #{msg}", exit: true, elapsed: elapsed, **tags
    end
  end
end

#emit(method, msg, **tags) ⇒ Object



37
38
39
40
# File 'lib/traceable/tracer.rb', line 37

def emit(method, msg, **tags)
  final_tags = make_tags(message: msg, **tags)
  emit_tags(method, final_tags)
end

#emit_tags(method, tags) ⇒ Object



46
47
48
49
50
# File 'lib/traceable/tracer.rb', line 46

def emit_tags(method, tags)
  logger.send(method, tags)
rescue StandardError => ex
  warn "EXCEPTION in trace: #{ex}"
end

#error(msg, **tags) ⇒ Object



56
57
58
# File 'lib/traceable/tracer.rb', line 56

def error(msg, **tags)
  emit :error, msg, **tags
end

#fatal(msg, **tags) ⇒ Object



52
53
54
# File 'lib/traceable/tracer.rb', line 52

def fatal(msg, **tags)
  emit :fatal, msg, **tags
end

#info(msg, **tags) ⇒ Object



64
65
66
# File 'lib/traceable/tracer.rb', line 64

def info(msg, **tags)
  emit :info, msg, **tags
end

#make_tags(**tags) ⇒ Object



42
43
44
# File 'lib/traceable/tracer.rb', line 42

def make_tags(**tags)
  @tags.merge(tags)
end

#warn(msg, **tags) ⇒ Object



60
61
62
# File 'lib/traceable/tracer.rb', line 60

def warn(msg, **tags)
  emit :warn, msg, **tags
end