Class: NewRelic::Agent::Transaction::AbstractSegment

Inherits:
Object
  • Object
show all
Defined in:
lib/new_relic/agent/transaction/abstract_segment.rb

Direct Known Subclasses

Segment

Constant Summary collapse

INSPECT_IGNORE =
[:@transaction, :@transaction_state].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name = nil, start_time = nil) ⇒ AbstractSegment

Returns a new instance of AbstractSegment.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 27

def initialize(name = nil, start_time = nil)
  @name = name
  @starting_segment_key = NewRelic::Agent::Tracer.current_segment_key
  @transaction_name = nil
  @transaction = nil
  @guid = NewRelic::Agent::GuidGenerator.generate_guid
  @parent = nil
  @params = nil
  @start_time = start_time if start_time
  @end_time = nil
  @duration = 0.0
  @exclusive_duration = 0.0
  @children_timings = []
  @children_time = 0.0
  @active_children = 0
  @range_recorded = false
  @concurrent_children = false
  @record_metrics = true
  @record_scoped_metric = true
  @record_on_finish = false
  @noticed_error = nil
  @code_filepath = nil
  @code_function = nil
  @code_lineno = nil
  @code_namespace = nil
end

Instance Attribute Details

#children_timeObject



23
24
25
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 23

def children_time
  @children_time
end

#durationObject (readonly)

This class is the base class for all segments. It is responsible for timing, naming, and defining lifecycle callbacks. One of the more complex responsibilities of this class is computing exclusive duration. One of the reasons for this complexity is that exclusive time will be computed using time ranges or by recording an aggregate value for a segments children time. The reason for this is that computing exclusive duration using time ranges is expensive and it’s only necessary if a segment’s children run concurrently, or a segment ends after its parent. We will use the optimized exclusive duration calculation in all other cases.



22
23
24
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 22

def duration
  @duration
end

#end_timeObject (readonly)

This class is the base class for all segments. It is responsible for timing, naming, and defining lifecycle callbacks. One of the more complex responsibilities of this class is computing exclusive duration. One of the reasons for this complexity is that exclusive time will be computed using time ranges or by recording an aggregate value for a segments children time. The reason for this is that computing exclusive duration using time ranges is expensive and it’s only necessary if a segment’s children run concurrently, or a segment ends after its parent. We will use the optimized exclusive duration calculation in all other cases.



22
23
24
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 22

def end_time
  @end_time
end

#exclusive_durationObject (readonly)

This class is the base class for all segments. It is responsible for timing, naming, and defining lifecycle callbacks. One of the more complex responsibilities of this class is computing exclusive duration. One of the reasons for this complexity is that exclusive time will be computed using time ranges or by recording an aggregate value for a segments children time. The reason for this is that computing exclusive duration using time ranges is expensive and it’s only necessary if a segment’s children run concurrently, or a segment ends after its parent. We will use the optimized exclusive duration calculation in all other cases.



22
23
24
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 22

def exclusive_duration
  @exclusive_duration
end

#guidObject (readonly)

This class is the base class for all segments. It is responsible for timing, naming, and defining lifecycle callbacks. One of the more complex responsibilities of this class is computing exclusive duration. One of the reasons for this complexity is that exclusive time will be computed using time ranges or by recording an aggregate value for a segments children time. The reason for this is that computing exclusive duration using time ranges is expensive and it’s only necessary if a segment’s children run concurrently, or a segment ends after its parent. We will use the optimized exclusive duration calculation in all other cases.



22
23
24
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 22

def guid
  @guid
end

#nameObject



23
24
25
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 23

def name
  @name
end

#noticed_errorObject (readonly)



25
26
27
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 25

def noticed_error
  @noticed_error
end

#parentObject



23
24
25
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 23

def parent
  @parent
end

#record_metrics=(value) ⇒ Object



24
25
26
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 24

def record_metrics=(value)
  @record_metrics = value
end

#record_on_finish=(value) ⇒ Object (writeonly)



24
25
26
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 24

def record_on_finish=(value)
  @record_on_finish = value
end

#record_scoped_metric=(value) ⇒ Object (writeonly)



24
25
26
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 24

def record_scoped_metric=(value)
  @record_scoped_metric = value
end

#start_timeObject (readonly)

This class is the base class for all segments. It is responsible for timing, naming, and defining lifecycle callbacks. One of the more complex responsibilities of this class is computing exclusive duration. One of the reasons for this complexity is that exclusive time will be computed using time ranges or by recording an aggregate value for a segments children time. The reason for this is that computing exclusive duration using time ranges is expensive and it’s only necessary if a segment’s children run concurrently, or a segment ends after its parent. We will use the optimized exclusive duration calculation in all other cases.



22
23
24
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 22

def start_time
  @start_time
end

#starting_segment_keyObject (readonly)

This class is the base class for all segments. It is responsible for timing, naming, and defining lifecycle callbacks. One of the more complex responsibilities of this class is computing exclusive duration. One of the reasons for this complexity is that exclusive time will be computed using time ranges or by recording an aggregate value for a segments children time. The reason for this is that computing exclusive duration using time ranges is expensive and it’s only necessary if a segment’s children run concurrently, or a segment ends after its parent. We will use the optimized exclusive duration calculation in all other cases.



22
23
24
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 22

def starting_segment_key
  @starting_segment_key
end

#transactionObject



23
24
25
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 23

def transaction
  @transaction
end

#transaction_nameObject



23
24
25
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 23

def transaction_name
  @transaction_name
end

Instance Method Details

#all_code_information_present?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 124

def all_code_information_present?
  @code_filepath && @code_function && @code_lineno && @code_namespace
end

#children_time_ranges?Boolean

Returns:

  • (Boolean)


107
108
109
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 107

def children_time_ranges?
  !@children_timings.empty?
end

#code_attributesObject



128
129
130
131
132
133
134
135
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 128

def code_attributes
  return ::NewRelic::EMPTY_HASH unless all_code_information_present?

  @code_attributes ||= {'code.filepath' => @code_filepath,
                        'code.function' => @code_function,
                        'code.lineno' => @code_lineno,
                        'code.namespace' => @code_namespace}
end

#code_information=(info = {}) ⇒ Object



115
116
117
118
119
120
121
122
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 115

def code_information=(info = {})
  return unless info[:filepath]

  @code_filepath = info[:filepath]
  @code_function = info[:function]
  @code_lineno = info[:lineno]
  @code_namespace = info[:namespace]
end

#concurrent_children?Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 111

def concurrent_children?
  @concurrent_children
end

#finalizeObject



89
90
91
92
93
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 89

def finalize
  force_finish unless finished?
  record_exclusive_duration
  record_metrics if record_metrics?
end

#finishObject



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 61

def finish
  @end_time = Process.clock_gettime(Process::CLOCK_REALTIME)
  @duration = end_time - start_time

  return unless transaction

  run_complete_callbacks
  finalize if record_on_finish?
rescue => e
  NewRelic::Agent.logger.error("Exception finishing segment: #{name}", e)
end

#finished?Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 73

def finished?
  !!@end_time
end

#inspectObject



139
140
141
142
143
144
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 139

def inspect
  ivars = (instance_variables - INSPECT_IGNORE).inject([]) do |memo, var_name|
    memo << "#{var_name}=#{instance_variable_get(var_name).inspect}"
  end
  sprintf('#<%s:0x%x %s>', self.class.name, object_id, ivars.join(', '))
end

#notice_error(exception, options = {}) ⇒ Object



160
161
162
163
164
165
166
167
168
169
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 160

def notice_error(exception, options = {})
  if Agent.config[:high_security]
    NewRelic::Agent.logger.debug( \
      "Segment: #{name} ignores notice_error for " \
      "error: #{exception.inspect} because :high_security is enabled"
    )
  else
    NewRelic::Agent.instance.error_collector.notice_segment_error(self, exception, options)
  end
end

#noticed_error_attributesObject



171
172
173
174
175
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 171

def noticed_error_attributes
  return unless @noticed_error

  @noticed_error.attributes_from_notice_error
end

#paramsObject



95
96
97
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 95

def params
  @params ||= {}
end

#params?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 99

def params?
  !!@params
end

#record_metrics?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 77

def record_metrics?
  @record_metrics
end

#record_on_finish?Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 85

def record_on_finish?
  @record_on_finish
end

#record_scoped_metric?Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 81

def record_scoped_metric?
  @record_scoped_metric
end

#set_noticed_error(noticed_error) ⇒ Object



150
151
152
153
154
155
156
157
158
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 150

def set_noticed_error(noticed_error)
  if @noticed_error
    NewRelic::Agent.logger.debug( \
      "Segment: #{name} overwriting previously noticed " \
      "error: #{@noticed_error.inspect} with: #{noticed_error.inspect}"
    )
  end
  @noticed_error = noticed_error
end

#startObject



54
55
56
57
58
59
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 54

def start
  @start_time ||= Process.clock_gettime(Process::CLOCK_REALTIME)
  return unless transaction

  parent&.child_start(self)
end

#time_rangeObject



103
104
105
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 103

def time_range
  @start_time.to_f..@end_time.to_f
end

#transaction_assignedObject

callback for subclasses to override



147
148
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 147

def transaction_assigned
end