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

CALLBACK =
:@callback
SEGMENT =
'segment'
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.



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

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
  invoke_callback
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

#llm_eventObject



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

def llm_event
  @llm_event
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)


128
129
130
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 128

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

#children_time_ranges?Boolean

Returns:

  • (Boolean)


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

def children_time_ranges?
  !@children_timings.empty?
end

#code_attributesObject



132
133
134
135
136
137
138
139
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 132

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



119
120
121
122
123
124
125
126
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 119

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)


115
116
117
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 115

def concurrent_children?
  @concurrent_children
end

#finalizeObject



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

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

#finishObject



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 65

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)


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

def finished?
  !!@end_time
end

#inspectObject



143
144
145
146
147
148
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 143

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



164
165
166
167
168
169
170
171
172
173
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 164

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



175
176
177
178
179
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 175

def noticed_error_attributes
  return unless @noticed_error

  @noticed_error.attributes_from_notice_error
end

#paramsObject



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

def params
  @params ||= {}
end

#params?Boolean

Returns:

  • (Boolean)


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

def params?
  !!@params
end

#record_metrics?Boolean

Returns:

  • (Boolean)


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

def record_metrics?
  @record_metrics
end

#record_on_finish?Boolean

Returns:

  • (Boolean)


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

def record_on_finish?
  @record_on_finish
end

#record_scoped_metric?Boolean

Returns:

  • (Boolean)


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

def record_scoped_metric?
  @record_scoped_metric
end

#set_noticed_error(noticed_error) ⇒ Object



154
155
156
157
158
159
160
161
162
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 154

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



58
59
60
61
62
63
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 58

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

  parent&.child_start(self)
end

#time_rangeObject



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

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

#transaction_assignedObject

callback for subclasses to override



151
152
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 151

def transaction_assigned
end