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
57
# 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
  @thread_id = Thread.current.object_id
  @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

#thread_idObject (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 thread_id
  @thread_id
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)


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

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

#children_time_ranges?Boolean

Returns:

  • (Boolean)


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

def children_time_ranges?
  !@children_timings.empty?
end

#code_attributesObject



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

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



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

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)


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

def concurrent_children?
  @concurrent_children
end

#finalizeObject



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

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

#finishObject



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

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)


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

def finished?
  !!@end_time
end

#inspectObject



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

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



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

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



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

def noticed_error_attributes
  return unless @noticed_error

  @noticed_error.attributes_from_notice_error
end

#paramsObject



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

def params
  @params ||= {}
end

#params?Boolean

Returns:

  • (Boolean)


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

def params?
  !!@params
end

#record_metrics?Boolean

Returns:

  • (Boolean)


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

def record_metrics?
  @record_metrics
end

#record_on_finish?Boolean

Returns:

  • (Boolean)


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

def record_on_finish?
  @record_on_finish
end

#record_scoped_metric?Boolean

Returns:

  • (Boolean)


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

def record_scoped_metric?
  @record_scoped_metric
end

#set_noticed_error(noticed_error) ⇒ Object



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

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



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

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

  parent&.child_start(self)
end

#time_rangeObject



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

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

#transaction_assignedObject

callback for subclasses to override



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

def transaction_assigned
end