newrelic_rpm 5.4.0.347 → 5.5.0.348
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/config.dot +0 -7
- data/lib/new_relic/agent/cross_app_monitor.rb +34 -64
- data/lib/new_relic/agent/cross_app_payload.rb +43 -0
- data/lib/new_relic/agent/cross_app_tracing.rb +93 -5
- data/lib/new_relic/agent/external.rb +17 -24
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +3 -1
- data/lib/new_relic/agent/instrumentation/active_job.rb +12 -9
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +7 -15
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +8 -8
- data/lib/new_relic/agent/instrumentation/curb.rb +14 -6
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +1 -1
- data/lib/new_relic/agent/instrumentation/excon/middleware.rb +1 -1
- data/lib/new_relic/agent/instrumentation/http.rb +1 -1
- data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +3 -3
- data/lib/new_relic/agent/instrumentation/mongo.rb +1 -1
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +3 -4
- data/lib/new_relic/agent/instrumentation/redis.rb +3 -3
- data/lib/new_relic/agent/javascript_instrumentor.rb +14 -8
- data/lib/new_relic/agent/messaging.rb +14 -14
- data/lib/new_relic/agent/system_info.rb +3 -7
- data/lib/new_relic/agent/threading/agent_thread.rb +4 -2
- data/lib/new_relic/agent/transaction.rb +46 -120
- data/lib/new_relic/agent/transaction/abstract_segment.rb +4 -0
- data/lib/new_relic/agent/transaction/datastore_segment.rb +3 -2
- data/lib/new_relic/agent/transaction/external_request_segment.rb +3 -3
- data/lib/new_relic/agent/transaction/message_broker_segment.rb +1 -2
- data/lib/new_relic/agent/transaction/tracing.rb +1 -0
- data/lib/new_relic/agent/transaction_sampler.rb +1 -8
- data/lib/new_relic/agent/transaction_state.rb +122 -76
- data/lib/new_relic/version.rb +1 -1
- data/lib/sequel/extensions/newrelic_instrumentation.rb +2 -2
- data/lib/sequel/plugins/newrelic_instrumentation.rb +1 -1
- metadata +3 -3
- data/lib/new_relic/agent/transaction_timings.rb +0 -57
@@ -165,15 +165,11 @@ module NewRelic
|
|
165
165
|
|
166
166
|
container_id = case cpu_cgroup
|
167
167
|
# docker native driver w/out systemd (fs)
|
168
|
-
when
|
168
|
+
when /[0-9a-f]{64}/ then $&
|
169
169
|
# docker native driver with systemd
|
170
|
-
when
|
171
|
-
# docker lxc driver
|
172
|
-
when %r{^/lxc/([0-9a-f]+)$} then $1
|
173
|
-
# not in any cgroup
|
174
|
-
when '/' then nil
|
170
|
+
when '/' then nil
|
175
171
|
# in a cgroup, but we don't recognize its format
|
176
|
-
when
|
172
|
+
when /docker/ then
|
177
173
|
::NewRelic::Agent.logger.debug("Cgroup indicates docker but container_id unrecognized: '#{cpu_cgroup}'")
|
178
174
|
::NewRelic::Agent.increment_metric "Supportability/utilization/docker/error"
|
179
175
|
return
|
@@ -38,9 +38,11 @@ module NewRelic
|
|
38
38
|
profile_agent_code ? :agent : :ignore
|
39
39
|
else
|
40
40
|
state = TransactionState.tl_state_for(thread)
|
41
|
-
|
41
|
+
txn = state.current_transaction
|
42
|
+
|
43
|
+
if txn && !txn.recording_web_transaction?
|
42
44
|
:background
|
43
|
-
elsif
|
45
|
+
elsif txn && txn.recording_web_transaction?
|
44
46
|
:request
|
45
47
|
else
|
46
48
|
:other
|
@@ -2,7 +2,6 @@
|
|
2
2
|
# This file is distributed under New Relic's license terms.
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
|
-
require 'new_relic/agent/transaction_timings'
|
6
5
|
require 'new_relic/agent/instrumentation/queue_time'
|
7
6
|
require 'new_relic/agent/transaction_metrics'
|
8
7
|
require 'new_relic/agent/method_tracer_helpers'
|
@@ -22,6 +21,7 @@ module NewRelic
|
|
22
21
|
class Transaction
|
23
22
|
include Tracing
|
24
23
|
include DistributedTracing
|
24
|
+
include CrossAppTracing
|
25
25
|
|
26
26
|
# for nested transactions
|
27
27
|
SUBTRANSACTION_PREFIX = 'Nested/'.freeze
|
@@ -65,12 +65,12 @@ module NewRelic
|
|
65
65
|
:gc_start_snapshot,
|
66
66
|
:category,
|
67
67
|
:frame_stack,
|
68
|
-
:cat_path_hashes,
|
69
68
|
:attributes,
|
70
69
|
:payload,
|
71
70
|
:nesting_max_depth,
|
72
71
|
:segments,
|
73
|
-
:end_time
|
72
|
+
:end_time,
|
73
|
+
:duration
|
74
74
|
|
75
75
|
attr_writer :sampled,
|
76
76
|
:priority
|
@@ -123,7 +123,7 @@ module NewRelic
|
|
123
123
|
txn = state.current_transaction
|
124
124
|
|
125
125
|
if txn
|
126
|
-
txn.create_nested_frame(
|
126
|
+
txn.create_nested_frame(category, options)
|
127
127
|
else
|
128
128
|
txn = start_new_transaction(state, category, options)
|
129
129
|
end
|
@@ -138,13 +138,13 @@ module NewRelic
|
|
138
138
|
txn = Transaction.new(category, options)
|
139
139
|
state.reset(txn)
|
140
140
|
txn.state = state
|
141
|
-
txn.start
|
141
|
+
txn.start
|
142
142
|
txn
|
143
143
|
end
|
144
144
|
|
145
145
|
FAILED_TO_STOP_MESSAGE = "Failed during Transaction.stop because there is no current transaction"
|
146
146
|
|
147
|
-
def self.stop(state
|
147
|
+
def self.stop(state)
|
148
148
|
txn = state.current_transaction
|
149
149
|
|
150
150
|
if txn.nil?
|
@@ -155,7 +155,7 @@ module NewRelic
|
|
155
155
|
nested_frame = txn.frame_stack.pop
|
156
156
|
|
157
157
|
if txn.frame_stack.empty?
|
158
|
-
txn.stop(
|
158
|
+
txn.stop(nested_frame) if nested_frame
|
159
159
|
state.reset
|
160
160
|
else
|
161
161
|
nested_frame.finish
|
@@ -181,7 +181,7 @@ module NewRelic
|
|
181
181
|
def self.abort_transaction! #THREAD_LOCAL_ACCESS
|
182
182
|
state = NewRelic::Agent::TransactionState.tl_get
|
183
183
|
txn = state.current_transaction
|
184
|
-
txn.abort_transaction!
|
184
|
+
txn.abort_transaction! if txn
|
185
185
|
end
|
186
186
|
|
187
187
|
# See NewRelic::Agent.notice_error for options and commentary
|
@@ -269,6 +269,7 @@ module NewRelic
|
|
269
269
|
@category = category
|
270
270
|
@start_time = Time.now
|
271
271
|
@end_time = nil
|
272
|
+
@duration = nil
|
272
273
|
@apdex_start = options[:apdex_start_time] || @start_time
|
273
274
|
@jruby_cpu_start = jruby_cpu_time
|
274
275
|
@process_cpu_start = process_cpu
|
@@ -278,7 +279,6 @@ module NewRelic
|
|
278
279
|
@exceptions = {}
|
279
280
|
@metrics = TransactionMetrics.new
|
280
281
|
@guid = generate_guid
|
281
|
-
@cat_path_hashes = nil
|
282
282
|
|
283
283
|
@ignore_this_transaction = false
|
284
284
|
@ignore_apdex = options.fetch(:ignore_apdex, false)
|
@@ -401,10 +401,6 @@ module NewRelic
|
|
401
401
|
alias_method :transaction_name, :best_name
|
402
402
|
|
403
403
|
attr_accessor :xray_session_id
|
404
|
-
|
405
|
-
def duration
|
406
|
-
(@end_time - @start_time).to_f
|
407
|
-
end
|
408
404
|
# End common interface
|
409
405
|
|
410
406
|
def name_set?
|
@@ -442,7 +438,7 @@ module NewRelic
|
|
442
438
|
@frozen_name ? true : false
|
443
439
|
end
|
444
440
|
|
445
|
-
def start
|
441
|
+
def start
|
446
442
|
return if !state.is_execution_traced?
|
447
443
|
|
448
444
|
sql_sampler.on_start_transaction(state, start_time, request_path)
|
@@ -481,7 +477,7 @@ module NewRelic
|
|
481
477
|
segment
|
482
478
|
end
|
483
479
|
|
484
|
-
def create_nested_frame(
|
480
|
+
def create_nested_frame(category, options)
|
485
481
|
if options[:filtered_params] && !options[:filtered_params].empty?
|
486
482
|
@filtered_params = options[:filtered_params]
|
487
483
|
merge_request_parameters(options[:filtered_params])
|
@@ -503,7 +499,7 @@ module NewRelic
|
|
503
499
|
|
504
500
|
# Call this to ensure that the current transaction trace is not saved
|
505
501
|
# To fully ignore all metrics and errors, use ignore! instead.
|
506
|
-
def abort_transaction!
|
502
|
+
def abort_transaction!
|
507
503
|
@ignore_trace = true
|
508
504
|
end
|
509
505
|
|
@@ -531,10 +527,12 @@ module NewRelic
|
|
531
527
|
name.start_with?(MIDDLEWARE_PREFIX)
|
532
528
|
end
|
533
529
|
|
534
|
-
def stop(
|
530
|
+
def stop(outermost_frame = nil)
|
535
531
|
return if !state.is_execution_traced?
|
532
|
+
return self.class.stop(state) unless outermost_frame
|
536
533
|
|
537
|
-
@end_time =
|
534
|
+
@end_time = Time.now
|
535
|
+
@duration = @end_time.to_f - @start_time.to_f
|
538
536
|
freeze_name_and_execute_if_not_ignored
|
539
537
|
|
540
538
|
if nesting_max_depth == 1
|
@@ -543,9 +541,9 @@ module NewRelic
|
|
543
541
|
|
544
542
|
outermost_frame.finish
|
545
543
|
|
546
|
-
NewRelic::Agent::TransactionTimeAggregator.transaction_stop(end_time)
|
544
|
+
NewRelic::Agent::TransactionTimeAggregator.transaction_stop(@end_time)
|
547
545
|
|
548
|
-
commit!(
|
546
|
+
commit!(outermost_frame.name) unless @ignore_this_transaction
|
549
547
|
end
|
550
548
|
|
551
549
|
def user_defined_rules_ignore?
|
@@ -557,22 +555,22 @@ module NewRelic
|
|
557
555
|
end
|
558
556
|
end
|
559
557
|
|
560
|
-
def commit!(
|
561
|
-
generate_payload
|
558
|
+
def commit!(outermost_node_name)
|
559
|
+
generate_payload
|
562
560
|
|
563
561
|
assign_agent_attributes
|
564
|
-
assign_intrinsics
|
562
|
+
assign_intrinsics
|
565
563
|
|
566
564
|
finalize_segments
|
567
565
|
|
568
|
-
@transaction_trace = transaction_sampler.on_finishing_transaction(
|
566
|
+
@transaction_trace = transaction_sampler.on_finishing_transaction(self)
|
569
567
|
sql_sampler.on_finishing_transaction(state, @frozen_name)
|
570
568
|
|
571
|
-
record_summary_metrics(outermost_node_name
|
569
|
+
record_summary_metrics(outermost_node_name)
|
572
570
|
record_total_time_metrics
|
573
|
-
record_apdex
|
571
|
+
record_apdex unless ignore_apdex?
|
574
572
|
record_queue_time
|
575
|
-
|
573
|
+
record_cross_app_metrics
|
576
574
|
record_distributed_tracing_metrics
|
577
575
|
|
578
576
|
record_exceptions
|
@@ -608,7 +606,7 @@ module NewRelic
|
|
608
606
|
end
|
609
607
|
end
|
610
608
|
|
611
|
-
def assign_intrinsics
|
609
|
+
def assign_intrinsics
|
612
610
|
attributes.add_intrinsic_attribute(:priority, priority)
|
613
611
|
|
614
612
|
if gc_time = calculate_gc_time
|
@@ -627,9 +625,8 @@ module NewRelic
|
|
627
625
|
|
628
626
|
if Agent.config[:'distributed_tracing.enabled']
|
629
627
|
assign_distributed_trace_intrinsics
|
630
|
-
elsif
|
631
|
-
|
632
|
-
attributes.add_intrinsic_attribute(:path_hash, cat_path_hash)
|
628
|
+
elsif is_cross_app?
|
629
|
+
assign_cross_app_intrinsics
|
633
630
|
end
|
634
631
|
end
|
635
632
|
|
@@ -640,10 +637,10 @@ module NewRelic
|
|
640
637
|
|
641
638
|
# The summary metrics recorded by this method all end up with a duration
|
642
639
|
# equal to the transaction itself, and an exclusive time of zero.
|
643
|
-
def record_summary_metrics(outermost_node_name
|
640
|
+
def record_summary_metrics(outermost_node_name)
|
644
641
|
metrics = summary_metrics
|
645
642
|
metrics << @frozen_name unless @frozen_name == outermost_node_name
|
646
|
-
@metrics.record_unscoped(metrics,
|
643
|
+
@metrics.record_unscoped(metrics, duration, 0)
|
647
644
|
end
|
648
645
|
|
649
646
|
# This event is fired when the transaction is fully completed. The metric
|
@@ -652,8 +649,7 @@ module NewRelic
|
|
652
649
|
agent.events.notify(:transaction_finished, payload)
|
653
650
|
end
|
654
651
|
|
655
|
-
def generate_payload
|
656
|
-
duration = end_time.to_f - start_time.to_f
|
652
|
+
def generate_payload
|
657
653
|
@payload = {
|
658
654
|
:name => @frozen_name,
|
659
655
|
:bucket => recording_web_transaction? ? :request : :background,
|
@@ -665,38 +661,14 @@ module NewRelic
|
|
665
661
|
:priority => priority
|
666
662
|
}
|
667
663
|
|
668
|
-
append_cat_info(
|
664
|
+
append_cat_info(@payload)
|
669
665
|
append_distributed_trace_info(@payload)
|
670
|
-
append_apdex_perf_zone(
|
671
|
-
append_synthetics_to(
|
672
|
-
append_referring_transaction_guid_to(state, @payload)
|
673
|
-
end
|
674
|
-
|
675
|
-
def include_guid?(state, duration)
|
676
|
-
state.is_cross_app? || is_synthetics_request?
|
677
|
-
end
|
678
|
-
|
679
|
-
def cat_trip_id
|
680
|
-
NewRelic::Agent.instance.cross_app_monitor.client_referring_transaction_trip_id(state) || guid
|
681
|
-
end
|
682
|
-
|
683
|
-
def cat_path_hash
|
684
|
-
referring_path_hash = cat_referring_path_hash(state) || '0'
|
685
|
-
seed = referring_path_hash.to_i(16)
|
686
|
-
result = NewRelic::Agent.instance.cross_app_monitor.path_hash(best_name, seed)
|
687
|
-
record_cat_path_hash(result)
|
688
|
-
result
|
689
|
-
end
|
690
|
-
|
691
|
-
def record_cat_path_hash(hash)
|
692
|
-
@cat_path_hashes ||= []
|
693
|
-
if @cat_path_hashes.size < 10 && !@cat_path_hashes.include?(hash)
|
694
|
-
@cat_path_hashes << hash
|
695
|
-
end
|
666
|
+
append_apdex_perf_zone(@payload)
|
667
|
+
append_synthetics_to(@payload)
|
696
668
|
end
|
697
669
|
|
698
|
-
def
|
699
|
-
|
670
|
+
def include_guid?
|
671
|
+
is_cross_app? || is_synthetics_request?
|
700
672
|
end
|
701
673
|
|
702
674
|
def is_synthetics_request?
|
@@ -732,7 +704,7 @@ module NewRelic
|
|
732
704
|
APDEX_T = 'T'.freeze
|
733
705
|
APDEX_F = 'F'.freeze
|
734
706
|
|
735
|
-
def append_apdex_perf_zone(
|
707
|
+
def append_apdex_perf_zone(payload)
|
736
708
|
if recording_web_transaction?
|
737
709
|
bucket = apdex_bucket(duration, apdex_t)
|
738
710
|
elsif background_apdex_t = transaction_specific_apdex_t
|
@@ -750,29 +722,7 @@ module NewRelic
|
|
750
722
|
payload[:apdex_perf_zone] = bucket_str if bucket_str
|
751
723
|
end
|
752
724
|
|
753
|
-
def
|
754
|
-
return unless include_guid?(state, duration)
|
755
|
-
payload[:guid] = guid
|
756
|
-
|
757
|
-
return unless state.is_cross_app?
|
758
|
-
trip_id = cat_trip_id
|
759
|
-
path_hash = cat_path_hash
|
760
|
-
referring_path_hash = cat_referring_path_hash(state)
|
761
|
-
|
762
|
-
payload[:cat_trip_id] = trip_id if trip_id
|
763
|
-
payload[:cat_referring_path_hash] = referring_path_hash if referring_path_hash
|
764
|
-
|
765
|
-
if path_hash
|
766
|
-
payload[:cat_path_hash] = path_hash
|
767
|
-
|
768
|
-
alternate_path_hashes = cat_path_hashes - [path_hash]
|
769
|
-
unless alternate_path_hashes.empty?
|
770
|
-
payload[:cat_alternate_path_hashes] = alternate_path_hashes
|
771
|
-
end
|
772
|
-
end
|
773
|
-
end
|
774
|
-
|
775
|
-
def append_synthetics_to(state, payload)
|
725
|
+
def append_synthetics_to(payload)
|
776
726
|
return unless is_synthetics_request?
|
777
727
|
|
778
728
|
payload[:synthetics_resource_id] = synthetics_resource_id
|
@@ -780,13 +730,6 @@ module NewRelic
|
|
780
730
|
payload[:synthetics_monitor_id] = synthetics_monitor_id
|
781
731
|
end
|
782
732
|
|
783
|
-
def append_referring_transaction_guid_to(state, payload)
|
784
|
-
referring_guid = NewRelic::Agent.instance.cross_app_monitor.client_referring_transaction_guid(state)
|
785
|
-
if referring_guid
|
786
|
-
payload[:referring_transaction_guid] = referring_guid
|
787
|
-
end
|
788
|
-
end
|
789
|
-
|
790
733
|
def merge_metrics
|
791
734
|
NewRelic::Agent.instance.stats_engine.merge_transaction_metrics!(@metrics, best_name)
|
792
735
|
end
|
@@ -834,12 +777,6 @@ module NewRelic
|
|
834
777
|
end
|
835
778
|
end
|
836
779
|
|
837
|
-
def record_client_application_metric state
|
838
|
-
if id = state.client_cross_app_id
|
839
|
-
NewRelic::Agent.record_metric "ClientApplication/#{id}/all", state.timings.app_time_in_seconds
|
840
|
-
end
|
841
|
-
end
|
842
|
-
|
843
780
|
APDEX_ALL_METRIC = 'ApdexAll'.freeze
|
844
781
|
|
845
782
|
APDEX_METRIC = 'Apdex'.freeze
|
@@ -862,28 +799,26 @@ module NewRelic
|
|
862
799
|
self.class.apdex_bucket(duration, had_error_affecting_apdex?, current_apdex_t)
|
863
800
|
end
|
864
801
|
|
865
|
-
def record_apdex
|
802
|
+
def record_apdex
|
866
803
|
return unless state.is_execution_traced?
|
867
804
|
|
868
805
|
freeze_name_and_execute_if_not_ignored do
|
869
|
-
total_duration = end_time - apdex_start
|
870
|
-
action_duration = end_time - start_time
|
871
|
-
|
872
806
|
if recording_web_transaction?
|
873
|
-
record_apdex_metrics(APDEX_METRIC, APDEX_TXN_METRIC_PREFIX,
|
874
|
-
total_duration, action_duration, apdex_t)
|
807
|
+
record_apdex_metrics(APDEX_METRIC, APDEX_TXN_METRIC_PREFIX, apdex_t)
|
875
808
|
else
|
876
|
-
record_apdex_metrics(APDEX_OTHER_METRIC,
|
877
|
-
|
809
|
+
record_apdex_metrics(APDEX_OTHER_METRIC,
|
810
|
+
APDEX_OTHER_TXN_METRIC_PREFIX,
|
811
|
+
transaction_specific_apdex_t)
|
878
812
|
end
|
879
813
|
end
|
880
814
|
end
|
881
815
|
|
882
|
-
def record_apdex_metrics(rollup_metric, transaction_prefix,
|
816
|
+
def record_apdex_metrics(rollup_metric, transaction_prefix, current_apdex_t)
|
883
817
|
return unless current_apdex_t
|
884
818
|
|
819
|
+
total_duration = end_time - apdex_start
|
885
820
|
apdex_bucket_global = apdex_bucket(total_duration, current_apdex_t)
|
886
|
-
apdex_bucket_txn = apdex_bucket(
|
821
|
+
apdex_bucket_txn = apdex_bucket(duration, current_apdex_t)
|
887
822
|
|
888
823
|
@metrics.record_unscoped(rollup_metric, apdex_bucket_global, current_apdex_t)
|
889
824
|
@metrics.record_unscoped(APDEX_ALL_METRIC, apdex_bucket_global, current_apdex_t)
|
@@ -983,15 +918,6 @@ module NewRelic
|
|
983
918
|
@ignore_trace
|
984
919
|
end
|
985
920
|
|
986
|
-
def add_message_cat_headers headers
|
987
|
-
state.is_cross_app_caller = true
|
988
|
-
CrossAppTracing.insert_message_headers headers,
|
989
|
-
guid,
|
990
|
-
cat_trip_id,
|
991
|
-
cat_path_hash,
|
992
|
-
raw_synthetics_header
|
993
|
-
end
|
994
|
-
|
995
921
|
private
|
996
922
|
|
997
923
|
def process_cpu
|
@@ -15,7 +15,7 @@ module NewRelic
|
|
15
15
|
UNKNOWN = 'unknown'.freeze
|
16
16
|
|
17
17
|
attr_reader :product, :operation, :collection, :sql_statement, :nosql_statement, :host, :port_path_or_id
|
18
|
-
attr_accessor :database_name
|
18
|
+
attr_accessor :database_name, :record_sql
|
19
19
|
|
20
20
|
|
21
21
|
def initialize product, operation, collection = nil, host = nil, port_path_or_id = nil, database_name = nil, start_time = nil
|
@@ -24,6 +24,7 @@ module NewRelic
|
|
24
24
|
@collection = collection
|
25
25
|
@sql_statement = nil
|
26
26
|
@nosql_statement = nil
|
27
|
+
@record_sql = true
|
27
28
|
set_instance_info host, port_path_or_id
|
28
29
|
@database_name = database_name ? database_name.to_s : nil
|
29
30
|
super Datastores::MetricHelper.scoped_metric_for(product, operation, collection),
|
@@ -135,7 +136,7 @@ module NewRelic
|
|
135
136
|
end
|
136
137
|
|
137
138
|
def record_sql?
|
138
|
-
transaction_state.is_sql_recorded?
|
139
|
+
transaction_state.is_sql_recorded? && @record_sql
|
139
140
|
end
|
140
141
|
|
141
142
|
def record_span_event
|