Class: NewRelic::Agent::Transaction::AbstractSegment
- Inherits:
-
Object
- Object
- NewRelic::Agent::Transaction::AbstractSegment
- Defined in:
- lib/new_relic/agent/transaction/abstract_segment.rb
Direct Known Subclasses
Constant Summary collapse
- CALLBACK =
:@callback- SEGMENT =
'segment'- INSPECT_IGNORE =
[:@transaction, :@transaction_state].freeze
Instance Attribute Summary collapse
- #children_time ⇒ Object
-
#duration ⇒ Object
readonly
This class is the base class for all segments.
-
#end_time ⇒ Object
readonly
This class is the base class for all segments.
-
#exclusive_duration ⇒ Object
readonly
This class is the base class for all segments.
-
#guid ⇒ Object
readonly
This class is the base class for all segments.
- #llm_event ⇒ Object
- #name ⇒ Object
- #noticed_error ⇒ Object readonly
- #parent ⇒ Object
- #record_metrics ⇒ Object writeonly
- #record_on_finish ⇒ Object writeonly
- #record_scoped_metric ⇒ Object writeonly
- #span_kind ⇒ Object
-
#start_time ⇒ Object
readonly
This class is the base class for all segments.
-
#starting_segment_key ⇒ Object
readonly
This class is the base class for all segments.
-
#thread_id ⇒ Object
readonly
This class is the base class for all segments.
- #transaction ⇒ Object
- #transaction_name ⇒ Object
Class Method Summary collapse
-
.set_segment_callback(callback_proc) ⇒ Object
Setting and invoking a segment callback ======================================= Each individual segment class such as
ExternalRequestSegmentallows for exactly one instance of aProc(meaning a proc or lambda) to be set as a callback.
Instance Method Summary collapse
- #all_code_information_present? ⇒ Boolean
- #children_time_ranges? ⇒ Boolean
- #code_attributes ⇒ Object
- #code_information=(info = {}) ⇒ Object
- #concurrent_children? ⇒ Boolean
- #finalize ⇒ Object
- #finish ⇒ Object
- #finished? ⇒ Boolean
-
#initialize(name = nil, start_time = nil) ⇒ AbstractSegment
constructor
A new instance of AbstractSegment.
- #inspect ⇒ Object
- #notice_error(exception, options = {}) ⇒ Object
- #noticed_error_attributes ⇒ Object
- #params ⇒ Object
- #params? ⇒ Boolean
- #record_metrics? ⇒ Boolean
- #record_on_finish? ⇒ Boolean
- #record_scoped_metric? ⇒ Boolean
- #set_noticed_error(noticed_error) ⇒ Object
- #start ⇒ Object
- #time_range ⇒ Object
-
#transaction_assigned ⇒ Object
callback for subclasses to override.
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 58 |
# 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 = NewRelic::Agent::TransactionTimeAggregator.current_execution_context_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 @span_kind = nil invoke_callback end |
Instance Attribute Details
#children_time ⇒ Object
23 24 25 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 23 def children_time @children_time end |
#duration ⇒ Object (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_time ⇒ Object (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_duration ⇒ Object (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 |
#guid ⇒ Object (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_event ⇒ Object
23 24 25 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 23 def llm_event @llm_event end |
#name ⇒ Object
23 24 25 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 23 def name @name end |
#noticed_error ⇒ Object (readonly)
25 26 27 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 25 def noticed_error @noticed_error end |
#parent ⇒ Object
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 |
#span_kind ⇒ Object
23 24 25 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 23 def span_kind @span_kind end |
#start_time ⇒ Object (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_key ⇒ Object (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_id ⇒ Object (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 |
#transaction ⇒ Object
23 24 25 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 23 def transaction @transaction end |
#transaction_name ⇒ Object
23 24 25 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 23 def transaction_name @transaction_name end |
Class Method Details
.set_segment_callback(callback_proc) ⇒ Object
Setting and invoking a segment callback
Each individual segment class such as ExternalRequestSegment allows
for exactly one instance of a Proc (meaning a proc or lambda) to be
set as a callback. A callback can be set on a segment class by calling
.set_segment_callback with a proc or lambda as the only argument.
If set, the callback will be invoked with #call at segment class
initialization time.
Example usage:
callback = -> { puts 'Hello, World! }
ExternalRequestSegment.set_segment_callback(callback)
ExternalRequestSegment.new(library, uri, procedure)
A callback set on a segment class will only be called when that specific segment class is initialized. Other segment classes will not be impacted.
Great caution should be taken in the defining of the callback block to not have the block perform anything too time consuming or resource intensive in order to keep the New Relic Ruby agent operating normally.
Given that callbacks are user defined, they must be set entirely at the user's own risk. It is recommended that each callback use conditional logic that only performs work for certain qualified segments. It is recommended that each callback be thoroughly tested in non-production environments before being introduced to production environments.
379 380 381 382 383 384 385 386 387 388 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 379 def self.set_segment_callback(callback_proc) unless callback_proc.is_a?(Proc) NewRelic::Agent.logger.error("#{self}.#{__method__}: expected an argument of type Proc, " \ "got #{callback_proc.class}") return end NewRelic::Agent.record_api_supportability_metric(:set_segment_callback) instance_variable_set(CALLBACK, callback_proc) end |
Instance Method Details
#all_code_information_present? ⇒ Boolean
130 131 132 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 130 def all_code_information_present? @code_filepath && @code_function && @code_lineno && @code_namespace end |
#children_time_ranges? ⇒ Boolean
113 114 115 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 113 def children_time_ranges? !@children_timings.empty? end |
#code_attributes ⇒ Object
134 135 136 137 138 139 140 141 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 134 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
121 122 123 124 125 126 127 128 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 121 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
117 118 119 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 117 def concurrent_children? @concurrent_children end |
#finalize ⇒ Object
95 96 97 98 99 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 95 def finalize force_finish unless finished? record_exclusive_duration record_metrics if record_metrics? end |
#finish ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 67 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
79 80 81 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 79 def finished? !!@end_time end |
#inspect ⇒ Object
145 146 147 148 149 150 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 145 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
166 167 168 169 170 171 172 173 174 175 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 166 def notice_error(exception, = {}) 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, ) end end |
#noticed_error_attributes ⇒ Object
177 178 179 180 181 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 177 def noticed_error_attributes return unless @noticed_error @noticed_error.attributes_from_notice_error end |
#params ⇒ Object
101 102 103 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 101 def params @params ||= {} end |
#params? ⇒ Boolean
105 106 107 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 105 def params? !!@params end |
#record_metrics? ⇒ Boolean
83 84 85 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 83 def record_metrics? @record_metrics end |
#record_on_finish? ⇒ Boolean
91 92 93 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 91 def record_on_finish? @record_on_finish end |
#record_scoped_metric? ⇒ Boolean
87 88 89 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 87 def record_scoped_metric? @record_scoped_metric end |
#set_noticed_error(noticed_error) ⇒ Object
156 157 158 159 160 161 162 163 164 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 156 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 |
#start ⇒ Object
60 61 62 63 64 65 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 60 def start @start_time ||= Process.clock_gettime(Process::CLOCK_REALTIME) return unless transaction parent&.child_start(self) end |
#time_range ⇒ Object
109 110 111 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 109 def time_range @start_time.to_f..@end_time.to_f end |
#transaction_assigned ⇒ Object
callback for subclasses to override
153 154 |
# File 'lib/new_relic/agent/transaction/abstract_segment.rb', line 153 def transaction_assigned end |