newrelic_rpm 3.11.2.286 → 3.12.0.288
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -2
- data/.yardopts +2 -0
- data/CHANGELOG +39 -4
- data/README.md +4 -2
- data/lib/new_relic/agent.rb +229 -214
- data/lib/new_relic/agent/agent.rb +23 -12
- data/lib/new_relic/agent/attribute_filter.rb +242 -0
- data/lib/new_relic/agent/attribute_processing.rb +62 -0
- data/lib/new_relic/agent/commands/xray_session_collection.rb +4 -1
- data/lib/new_relic/agent/configuration/default_source.rb +284 -30
- data/lib/new_relic/agent/configuration/high_security_source.rb +0 -8
- data/lib/new_relic/agent/configuration/manager.rb +1 -1
- data/lib/new_relic/agent/configuration/server_source.rb +86 -31
- data/lib/new_relic/agent/configuration/yaml_source.rb +1 -1
- data/lib/new_relic/agent/cross_app_monitor.rb +8 -13
- data/lib/new_relic/agent/cross_app_tracing.rb +15 -15
- data/lib/new_relic/agent/custom_event_aggregator.rb +6 -2
- data/lib/new_relic/agent/database.rb +15 -2
- data/lib/new_relic/agent/datastores.rb +52 -38
- data/lib/new_relic/agent/datastores/metric_helper.rb +2 -1
- data/lib/new_relic/agent/encoding_normalizer.rb +82 -0
- data/lib/new_relic/agent/error_collector.rb +125 -169
- data/lib/new_relic/agent/hash_extensions.rb +26 -0
- data/lib/new_relic/agent/http_clients/excon_wrappers.rb +13 -11
- data/lib/new_relic/agent/http_clients/uri_util.rb +9 -0
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +1 -3
- data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +12 -5
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +6 -7
- data/lib/new_relic/agent/instrumentation/curb.rb +6 -6
- data/lib/new_relic/agent/instrumentation/excon/middleware.rb +4 -4
- data/lib/new_relic/agent/instrumentation/grape.rb +4 -3
- data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +6 -3
- data/lib/new_relic/agent/instrumentation/rails/errors.rb +9 -3
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +6 -1
- data/lib/new_relic/agent/instrumentation/rails3/errors.rb +9 -7
- data/lib/new_relic/agent/instrumentation/rails4/errors.rb +8 -6
- data/lib/new_relic/agent/instrumentation/resque.rb +2 -3
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +3 -3
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +2 -2
- data/lib/new_relic/agent/javascript_instrumentor.rb +24 -16
- data/lib/new_relic/agent/parameter_filtering.rb +8 -1
- data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +2 -2
- data/lib/new_relic/agent/sql_sampler.rb +1 -0
- data/lib/new_relic/agent/stats.rb +0 -4
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +5 -3
- data/lib/new_relic/agent/stats_engine/stats_hash.rb +4 -0
- data/lib/new_relic/agent/supported_versions.rb +2 -2
- data/lib/new_relic/agent/traced_method_stack.rb +3 -3
- data/lib/new_relic/agent/transaction.rb +141 -118
- data/lib/new_relic/agent/transaction/attributes.rb +161 -0
- data/lib/new_relic/agent/transaction/developer_mode_sample_buffer.rb +4 -4
- data/lib/new_relic/agent/transaction/trace.rb +150 -0
- data/lib/new_relic/agent/transaction/trace_node.rb +190 -0
- data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +2 -2
- data/lib/new_relic/agent/transaction_event_aggregator.rb +23 -7
- data/lib/new_relic/agent/transaction_sample_builder.rb +37 -62
- data/lib/new_relic/agent/transaction_sampler.rb +29 -66
- data/lib/new_relic/cli/commands/install.rb +2 -2
- data/lib/new_relic/coerce.rb +15 -28
- data/lib/new_relic/json_wrapper.rb +14 -73
- data/lib/new_relic/noticed_error.rb +81 -5
- data/lib/new_relic/rack/browser_monitoring.rb +14 -19
- data/lib/new_relic/rack/developer_mode.rb +68 -14
- data/lib/new_relic/rack/developer_mode/segment_summary.rb +56 -0
- data/lib/new_relic/version.rb +2 -2
- data/newrelic.yml +19 -196
- data/test/agent_helper.rb +42 -36
- data/test/config/newrelic.yml +0 -1
- data/test/environments/rails40/Gemfile +1 -1
- data/test/environments/rails41/Gemfile +1 -1
- data/test/environments/rails42/Gemfile +1 -1
- data/test/fixtures/cross_agent_tests/attribute_configuration.json +35 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/README.md +19 -12
- data/test/fixtures/cross_agent_tests/sql_obfuscation/sql_obfuscation.json +365 -0
- data/test/multiverse/lib/multiverse/suite.rb +5 -1
- data/test/multiverse/suites/active_record/active_record_test.rb +8 -8
- data/test/multiverse/suites/agent_only/agent_attributes_test.rb +145 -0
- data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +8 -0
- data/test/multiverse/suites/agent_only/custom_queue_time_test.rb +5 -1
- data/test/multiverse/suites/agent_only/encoding_handling_test.rb +6 -6
- data/test/multiverse/suites/agent_only/marshaling_test.rb +1 -1
- data/test/multiverse/suites/agent_only/set_transaction_name_test.rb +2 -3
- data/test/multiverse/suites/agent_only/synthetics_test.rb +3 -3
- data/test/multiverse/suites/agent_only/testing_app.rb +4 -0
- data/test/multiverse/suites/agent_only/thread_profiling_test.rb +1 -1
- data/test/multiverse/suites/agent_only/utilization_data_collection_test.rb +9 -7
- data/test/multiverse/suites/curb/Envfile +5 -6
- data/test/multiverse/suites/curb/curb_test.rb +4 -5
- data/test/multiverse/suites/datamapper/datamapper_test.rb +2 -2
- data/test/multiverse/suites/excon/Envfile +11 -4
- data/test/multiverse/suites/excon/excon_test.rb +5 -5
- data/test/multiverse/suites/grape/config/newrelic.yml +1 -0
- data/test/multiverse/suites/grape/grape_test.rb +76 -12
- data/test/multiverse/suites/grape/grape_test_api.rb +16 -0
- data/test/multiverse/suites/high_security/config/newrelic.yml +43 -3
- data/test/multiverse/suites/high_security/high_security_test.rb +165 -9
- data/test/multiverse/suites/httpclient/Envfile +5 -1
- data/test/multiverse/suites/httpclient/httpclient_test.rb +2 -2
- data/test/multiverse/suites/memcached/Envfile +1 -1
- data/test/multiverse/suites/mongo/Envfile +8 -1
- data/test/multiverse/suites/mongo/helpers/mongo_operation_tests.rb +29 -29
- data/test/multiverse/suites/mongo/mongo_unsupported_version_test.rb +43 -8
- data/test/multiverse/suites/rack/rack_parameter_filtering_test.rb +13 -3
- data/test/multiverse/suites/rails/Envfile +3 -3
- data/test/multiverse/suites/rails/error_tracing_test.rb +52 -31
- data/test/multiverse/suites/rails/gc_instrumentation_test.rb +1 -1
- data/test/multiverse/suites/rails/ignore_test.rb +1 -1
- data/test/multiverse/suites/rails/parameter_capture_test.rb +108 -40
- data/test/multiverse/suites/rails/request_statistics_test.rb +10 -4
- data/test/multiverse/suites/rails/view_instrumentation_test.rb +24 -24
- data/test/multiverse/suites/resque/instrumentation_test.rb +46 -12
- data/test/multiverse/suites/sequel/sequel_extension_test.rb +8 -8
- data/test/multiverse/suites/sequel/sequel_helpers.rb +11 -11
- data/test/multiverse/suites/sequel/sequel_plugin_test.rb +11 -11
- data/test/multiverse/suites/sidekiq/Envfile +1 -4
- data/test/multiverse/suites/sidekiq/after_suite.rb +9 -0
- data/test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb +49 -16
- data/test/multiverse/suites/sidekiq/test_worker.rb +1 -2
- data/test/multiverse/suites/sinatra/Envfile +1 -1
- data/test/multiverse/suites/sinatra/config/newrelic.yml +1 -0
- data/test/multiverse/suites/sinatra/sinatra_classic_test.rb +0 -4
- data/test/multiverse/suites/sinatra/sinatra_modular_test.rb +0 -4
- data/test/multiverse/suites/sinatra/sinatra_parameter_capture_test.rb +65 -0
- data/test/multiverse/suites/sinatra/sinatra_test_cases.rb +0 -11
- data/test/multiverse/suites/typhoeus/Envfile +8 -2
- data/test/multiverse/suites/typhoeus/typhoeus_test.rb +4 -4
- data/test/new_relic/agent/agent/connect_test.rb +13 -9
- data/test/new_relic/agent/agent_test.rb +34 -24
- data/test/new_relic/agent/attribute_filter_test.rb +218 -0
- data/test/new_relic/agent/attribute_processing_test.rb +160 -0
- data/test/new_relic/agent/configuration/default_source_test.rb +88 -0
- data/test/new_relic/agent/configuration/manager_test.rb +3 -4
- data/test/new_relic/agent/configuration/orphan_configuration_test.rb +3 -1
- data/test/new_relic/agent/configuration/server_source_test.rb +39 -0
- data/test/new_relic/agent/cross_app_monitor_test.rb +6 -30
- data/test/new_relic/agent/cross_app_tracing_test.rb +12 -12
- data/test/new_relic/agent/database/sql_obfuscation_test.rb +39 -65
- data/test/new_relic/agent/datastores/metric_helper_test.rb +36 -0
- data/test/new_relic/agent/encoding_normalizer_test.rb +66 -0
- data/test/new_relic/agent/error_collector_test.rb +181 -34
- data/test/new_relic/agent/hash_extensions_test.rb +34 -0
- data/test/new_relic/agent/instrumentation/action_controller_subscriber_test.rb +20 -23
- data/test/new_relic/agent/instrumentation/action_view_subscriber_test.rb +12 -12
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +5 -5
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +4 -4
- data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +21 -11
- data/test/new_relic/agent/javascript_instrumentor_test.rb +69 -45
- data/test/new_relic/agent/pipe_service_test.rb +2 -2
- data/test/new_relic/agent/stats_engine/gc_profiler_test.rb +1 -1
- data/test/new_relic/agent/stats_engine/metric_stats_test.rb +8 -7
- data/test/new_relic/agent/stats_engine/stats_hash_test.rb +2 -2
- data/test/new_relic/agent/threading/backtrace_node_test.rb +2 -2
- data/test/new_relic/agent/transaction/attributes_test.rb +276 -0
- data/test/new_relic/agent/transaction/developer_mode_sample_buffer_test.rb +10 -10
- data/test/new_relic/agent/transaction/trace_node_test.rb +361 -0
- data/test/new_relic/agent/transaction/trace_test.rb +394 -0
- data/test/new_relic/agent/transaction/xray_sample_buffer_test.rb +1 -1
- data/test/new_relic/agent/transaction_event_aggregator_test.rb +127 -57
- data/test/new_relic/agent/transaction_sample_builder_test.rb +70 -78
- data/test/new_relic/agent/transaction_sampler_test.rb +76 -185
- data/test/new_relic/agent/transaction_test.rb +283 -135
- data/test/new_relic/agent_test.rb +27 -12
- data/test/new_relic/cli/commands/install_test.rb +27 -0
- data/test/new_relic/coerce_test.rb +0 -59
- data/test/new_relic/data_container_tests.rb +5 -5
- data/test/new_relic/fake_collector.rb +27 -9
- data/test/new_relic/filtering_test_app.rb +2 -1
- data/test/new_relic/http_client_test_cases.rb +16 -16
- data/test/new_relic/json_wrapper_test.rb +0 -54
- data/test/new_relic/marshalling_test_cases.rb +1 -0
- data/test/new_relic/multiverse_helpers.rb +144 -0
- data/test/new_relic/noticed_error_test.rb +112 -9
- data/test/new_relic/rack/browser_monitoring_test.rb +12 -7
- data/test/new_relic/{transaction_analysis → rack/developer_mode}/segment_summary_test.rb +5 -4
- data/test/new_relic/rack/developer_mode_test.rb +17 -3
- data/test/new_relic/rack/error_collector_test.rb +1 -1
- data/test/performance/lib/performance/instrumentation/stackprof.rb +1 -1
- data/test/performance/script/runner +2 -2
- data/test/performance/suites/active_record.rb +3 -3
- data/test/performance/suites/agent_attributes.rb +62 -0
- data/test/performance/suites/rack_middleware.rb +78 -28
- data/test/performance/suites/transaction_tracing.rb +35 -0
- data/test/test_helper.rb +9 -1
- data/ui/helpers/developer_mode_helper.rb +16 -23
- data/ui/views/newrelic/_sample.rhtml +3 -3
- data/ui/views/newrelic/_segment.rhtml +1 -1
- data/ui/views/newrelic/_show_sample_summary.rhtml +1 -1
- data/ui/views/newrelic/show_sample.rhtml +5 -4
- metadata +23 -80
- data/lib/new_relic/agent/transaction/force_persist_sample_buffer.rb +0 -25
- data/lib/new_relic/transaction_analysis.rb +0 -80
- data/lib/new_relic/transaction_analysis/segment_summary.rb +0 -53
- data/lib/new_relic/transaction_sample.rb +0 -207
- data/lib/new_relic/transaction_sample/composite_segment.rb +0 -31
- data/lib/new_relic/transaction_sample/fake_segment.rb +0 -13
- data/lib/new_relic/transaction_sample/segment.rb +0 -197
- data/lib/new_relic/transaction_sample/summary_segment.rb +0 -25
- data/lib/new_relic/url_rule.rb +0 -18
- data/test/fixtures/cross_agent_tests/sql_obfuscation/back_quoted_identifiers.mysql.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/back_quoted_identifiers.mysql.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/comment_delimiters_in_strings.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/comment_delimiters_in_strings.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/double_quoted_identifiers.postgres.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/double_quoted_identifiers.postgres.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_line_comment_in_string.obfuscated +0 -2
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_line_comment_in_string.sql +0 -2
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_query_comment_cstyle.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_query_comment_cstyle.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_query_comment_doubledash.obfuscated +0 -2
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_query_comment_doubledash.sql +0 -2
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_query_comment_hash.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_query_comment_hash.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/escape_string_constants.postgres.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/escape_string_constants.postgres.sql +0 -4
- data/test/fixtures/cross_agent_tests/sql_obfuscation/malformed/unterminated_double_quoted_string.mysql.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/malformed/unterminated_single_quoted_string.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/multiple_literal_types.mysql.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/multiple_literal_types.mysql.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/numbers_in_identifiers.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/numbers_in_identifiers.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/numeric_literals.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/numeric_literals.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/pathological/README.md +0 -4
- data/test/fixtures/cross_agent_tests/sql_obfuscation/pathological/end_of_line_comments_with_quotes.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/pathological/end_of_line_comments_with_quotes.sql +0 -2
- data/test/fixtures/cross_agent_tests/sql_obfuscation/pathological/mixed_comments_and_quotes.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/pathological/mixed_comments_and_quotes.sql +0 -2
- data/test/fixtures/cross_agent_tests/sql_obfuscation/pathological/mixed_quotes_comments_and_newlines.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/pathological/mixed_quotes_comments_and_newlines.sql +0 -4
- data/test/fixtures/cross_agent_tests/sql_obfuscation/pathological/mixed_quotes_end_of_line_comments.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/pathological/mixed_quotes_end_of_line_comments.sql +0 -3
- data/test/fixtures/cross_agent_tests/sql_obfuscation/pathological/quote_delimiters_in_comments.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/pathological/quote_delimiters_in_comments.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_double_quoted.mysql.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_double_quoted.mysql.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_single_quoted.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_single_quoted.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_backslash_and_twin_single_quotes.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_backslash_and_twin_single_quotes.sql +0 -4
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_embedded_double_quote.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_embedded_double_quote.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_embedded_newline.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_embedded_newline.sql +0 -2
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_embedded_single_quote.mysql.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_embedded_single_quote.mysql.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_escaped_quotes.mysql.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_escaped_quotes.mysql.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_backslash.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_backslash.sql +0 -4
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_escaped_backslash.mysql.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_escaped_backslash.mysql.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_escaped_backslash_single_quoted.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_escaped_backslash_single_quoted.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_escaped_quote.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_escaped_quote.sql +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_twin_single_quotes.obfuscated +0 -1
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_twin_single_quotes.sql +0 -1
- data/test/new_relic/agent/error_collector/notice_error_test.rb +0 -261
- data/test/new_relic/agent/transaction/force_persist_sample_buffer_test.rb +0 -52
- data/test/new_relic/transaction_analysis_test.rb +0 -125
- data/test/new_relic/transaction_sample/composite_segment_test.rb +0 -38
- data/test/new_relic/transaction_sample/fake_segment_test.rb +0 -18
- data/test/new_relic/transaction_sample/segment_test.rb +0 -361
- data/test/new_relic/transaction_sample/summary_segment_test.rb +0 -34
- data/test/new_relic/transaction_sample_subtest_test.rb +0 -41
- data/test/new_relic/transaction_sample_test.rb +0 -361
@@ -86,8 +86,8 @@ module NewRelic
|
|
86
86
|
end
|
87
87
|
|
88
88
|
# When pushing a scope different sample buffers potentially want to
|
89
|
-
# know about what's happening to annotate the incoming
|
90
|
-
def
|
89
|
+
# know about what's happening to annotate the incoming nodes
|
90
|
+
def visit_node(*)
|
91
91
|
# no-op
|
92
92
|
end
|
93
93
|
|
@@ -32,6 +32,9 @@ class NewRelic::Agent::TransactionEventAggregator
|
|
32
32
|
SYNTHETICS_JOB_ID_KEY = "nr.syntheticsJobId".freeze
|
33
33
|
SYNTHETICS_MONITOR_ID_KEY = "nr.syntheticsMonitorId".freeze
|
34
34
|
|
35
|
+
# To avoid allocations when we have empty custom or agent attributes
|
36
|
+
EMPTY_HASH = {}.freeze
|
37
|
+
|
35
38
|
def initialize( event_listener )
|
36
39
|
super()
|
37
40
|
|
@@ -143,10 +146,12 @@ class NewRelic::Agent::TransactionEventAggregator
|
|
143
146
|
def on_transaction_finished(payload)
|
144
147
|
return unless @enabled
|
145
148
|
|
149
|
+
attributes = payload[:attributes]
|
146
150
|
main_event = create_main_event(payload)
|
147
|
-
|
151
|
+
custom_attributes = create_custom_attributes(attributes)
|
152
|
+
agent_attributes = create_agent_attributes(attributes)
|
148
153
|
|
149
|
-
self.synchronize { append_event([main_event,
|
154
|
+
self.synchronize { append_event([main_event, custom_attributes, agent_attributes]) }
|
150
155
|
notify_full if !@notified_full && @samples.full?
|
151
156
|
end
|
152
157
|
|
@@ -246,12 +251,23 @@ class NewRelic::Agent::TransactionEventAggregator
|
|
246
251
|
end
|
247
252
|
end
|
248
253
|
|
249
|
-
def
|
250
|
-
|
251
|
-
|
252
|
-
|
254
|
+
def create_custom_attributes(attributes)
|
255
|
+
if attributes
|
256
|
+
custom_attributes = attributes.custom_attributes_for(NewRelic::Agent::AttributeFilter::DST_TRANSACTION_EVENTS)
|
257
|
+
custom_attributes = custom_attributes
|
258
|
+
custom_attributes.freeze
|
259
|
+
else
|
260
|
+
EMPTY_HASH
|
253
261
|
end
|
254
|
-
custom_params
|
255
262
|
end
|
256
263
|
|
264
|
+
def create_agent_attributes(attributes)
|
265
|
+
if attributes
|
266
|
+
agent_attributes = attributes.agent_attributes_for(NewRelic::Agent::AttributeFilter::DST_TRANSACTION_EVENTS)
|
267
|
+
agent_attributes = agent_attributes
|
268
|
+
agent_attributes.freeze
|
269
|
+
else
|
270
|
+
EMPTY_HASH
|
271
|
+
end
|
272
|
+
end
|
257
273
|
end
|
@@ -3,9 +3,10 @@
|
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
5
|
require 'new_relic/collection_helper'
|
6
|
-
require 'new_relic/transaction_sample'
|
7
6
|
require 'new_relic/control'
|
8
7
|
require 'new_relic/agent/transaction'
|
8
|
+
require 'new_relic/agent/transaction/trace'
|
9
|
+
|
9
10
|
module NewRelic
|
10
11
|
module Agent
|
11
12
|
# a builder is created with every sampled transaction, to dynamically
|
@@ -15,25 +16,25 @@ module NewRelic
|
|
15
16
|
# @api private
|
16
17
|
class TransactionSampleBuilder
|
17
18
|
|
18
|
-
# Once we hit the TT
|
19
|
+
# Once we hit the TT node limit, we use this class to hold our place in
|
19
20
|
# the tree so that we can still get accurate names and times on the
|
20
|
-
#
|
21
|
-
# depth counter that's incremented on each
|
21
|
+
# nodes we've already created. The placeholder node keeps a
|
22
|
+
# depth counter that's incremented on each node entry, and decremented
|
22
23
|
# on exit, until it reaches zero, when we throw the placeholder away.
|
23
|
-
# There should only ever be zero or one placeholder
|
24
|
+
# There should only ever be zero or one placeholder node at a time.
|
24
25
|
#
|
25
26
|
# @api private
|
26
|
-
class
|
27
|
-
attr_reader :
|
27
|
+
class PlaceholderNode
|
28
|
+
attr_reader :parent_node
|
28
29
|
attr_accessor :depth
|
29
30
|
|
30
|
-
def initialize(
|
31
|
-
@
|
31
|
+
def initialize(parent_node)
|
32
|
+
@parent_node = parent_node
|
32
33
|
@depth = 1
|
33
34
|
end
|
34
35
|
|
35
36
|
# No-op - some clients expect to be able to use these to read/write
|
36
|
-
# params on TT
|
37
|
+
# params on TT nodes.
|
37
38
|
def [](key); end
|
38
39
|
def []=(key, value); end
|
39
40
|
|
@@ -42,14 +43,14 @@ module NewRelic
|
|
42
43
|
def params=; end
|
43
44
|
end
|
44
45
|
|
45
|
-
attr_reader :
|
46
|
+
attr_reader :current_node, :sample
|
46
47
|
|
47
48
|
include NewRelic::CollectionHelper
|
48
49
|
|
49
50
|
def initialize(time=Time.now)
|
50
|
-
@sample = NewRelic::
|
51
|
+
@sample = NewRelic::Agent::Transaction::Trace.new(time.to_f)
|
51
52
|
@sample_start = time.to_f
|
52
|
-
@
|
53
|
+
@current_node = @sample.root_node
|
53
54
|
end
|
54
55
|
|
55
56
|
def sample_id
|
@@ -64,58 +65,53 @@ module NewRelic
|
|
64
65
|
@ignore = true
|
65
66
|
end
|
66
67
|
|
67
|
-
def
|
68
|
+
def node_limit
|
68
69
|
Agent.config[:'transaction_tracer.limit_segments']
|
69
70
|
end
|
70
71
|
|
71
72
|
def trace_entry(time)
|
72
|
-
if @sample.
|
73
|
-
|
74
|
-
@
|
75
|
-
@
|
76
|
-
if @sample.
|
77
|
-
::NewRelic::Agent.logger.debug("
|
73
|
+
if @sample.count_nodes < node_limit
|
74
|
+
node = @sample.create_node(time.to_f - @sample_start)
|
75
|
+
@current_node.add_called_node(node)
|
76
|
+
@current_node = node
|
77
|
+
if @sample.count_nodes == node_limit()
|
78
|
+
::NewRelic::Agent.logger.debug("Node limit of #{node_limit} reached, ceasing collection.")
|
78
79
|
end
|
79
80
|
else
|
80
|
-
if @
|
81
|
-
@
|
81
|
+
if @current_node.is_a?(PlaceholderNode)
|
82
|
+
@current_node.depth += 1
|
82
83
|
else
|
83
|
-
@
|
84
|
+
@current_node = PlaceholderNode.new(@current_node)
|
84
85
|
end
|
85
86
|
end
|
86
|
-
@
|
87
|
+
@current_node
|
87
88
|
end
|
88
89
|
|
89
90
|
def trace_exit(metric_name, time)
|
90
|
-
if @
|
91
|
-
@
|
92
|
-
if @
|
93
|
-
@
|
91
|
+
if @current_node.is_a?(PlaceholderNode)
|
92
|
+
@current_node.depth -= 1
|
93
|
+
if @current_node.depth == 0
|
94
|
+
@current_node = @current_node.parent_node
|
94
95
|
end
|
95
96
|
else
|
96
|
-
@
|
97
|
-
@
|
98
|
-
@
|
97
|
+
@current_node.metric_name = metric_name
|
98
|
+
@current_node.end_trace(time.to_f - @sample_start)
|
99
|
+
@current_node = @current_node.parent_node
|
99
100
|
end
|
100
101
|
end
|
101
102
|
|
102
|
-
def finish_trace(time=Time.now.to_f
|
103
|
+
def finish_trace(time=Time.now.to_f)
|
103
104
|
# Should never get called twice, but in a rare case that we can't
|
104
105
|
# reproduce in house it does. log forensics and return gracefully
|
105
106
|
if @sample.finished
|
106
107
|
::NewRelic::Agent.logger.error "Unexpected double-finish_trace of Transaction Trace Object: \n#{@sample.to_s}"
|
107
108
|
return
|
108
109
|
end
|
109
|
-
@sample.
|
110
|
-
@sample.params[:custom_params] ||= {}
|
111
|
-
@sample.params[:custom_params].merge!(normalize_params(custom_params))
|
110
|
+
@sample.root_node.end_trace(time.to_f - @sample_start)
|
112
111
|
|
113
|
-
# If we ever implement saving of TTs based on the record_tt flag on the
|
114
|
-
# calling and called applications, we should change this flag's value.
|
115
|
-
@sample.force_persist = false
|
116
112
|
@sample.threshold = transaction_trace_threshold
|
117
113
|
@sample.finished = true
|
118
|
-
@
|
114
|
+
@current_node = nil
|
119
115
|
end
|
120
116
|
|
121
117
|
TT_THRESHOLD_KEY = :'transaction_tracer.transaction_threshold'
|
@@ -132,37 +128,16 @@ module NewRelic
|
|
132
128
|
|
133
129
|
def scope_depth
|
134
130
|
depth = -1 # have to account for the root
|
135
|
-
current = @
|
131
|
+
current = @current_node
|
136
132
|
|
137
133
|
while(current)
|
138
134
|
depth += 1
|
139
|
-
current = current.
|
135
|
+
current = current.parent_node
|
140
136
|
end
|
141
137
|
|
142
138
|
depth
|
143
139
|
end
|
144
140
|
|
145
|
-
def set_transaction_uri(uri)
|
146
|
-
@sample.params[:uri] ||= uri
|
147
|
-
end
|
148
|
-
|
149
|
-
def set_request_params(params)
|
150
|
-
if Agent.config[:capture_params]
|
151
|
-
params = normalize_params(params)
|
152
|
-
@sample.params[:request_params].merge!(params)
|
153
|
-
@sample.params[:request_params].delete :controller
|
154
|
-
@sample.params[:request_params].delete :action
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def set_transaction_name(name)
|
159
|
-
@sample.transaction_name = name
|
160
|
-
end
|
161
|
-
|
162
|
-
def set_transaction_cpu_time(cpu_time)
|
163
|
-
@sample.set_custom_param(:cpu_time, cpu_time)
|
164
|
-
end
|
165
|
-
|
166
141
|
def sample
|
167
142
|
@sample
|
168
143
|
end
|
@@ -6,7 +6,6 @@ require 'new_relic/agent'
|
|
6
6
|
require 'new_relic/control'
|
7
7
|
require 'new_relic/agent/transaction_sample_builder'
|
8
8
|
require 'new_relic/agent/transaction/developer_mode_sample_buffer'
|
9
|
-
require 'new_relic/agent/transaction/force_persist_sample_buffer'
|
10
9
|
require 'new_relic/agent/transaction/slowest_sample_buffer'
|
11
10
|
require 'new_relic/agent/transaction/synthetics_sample_buffer'
|
12
11
|
require 'new_relic/agent/transaction/xray_sample_buffer'
|
@@ -43,7 +42,6 @@ module NewRelic
|
|
43
42
|
@sample_buffers << @xray_sample_buffer
|
44
43
|
@sample_buffers << NewRelic::Agent::Transaction::SlowestSampleBuffer.new
|
45
44
|
@sample_buffers << NewRelic::Agent::Transaction::SyntheticsSampleBuffer.new
|
46
|
-
@sample_buffers << NewRelic::Agent::Transaction::ForcePersistSampleBuffer.new
|
47
45
|
|
48
46
|
# This lock is used to synchronize access to the @last_sample
|
49
47
|
# and related variables. It can become necessary on JRuby or
|
@@ -70,28 +68,27 @@ module NewRelic
|
|
70
68
|
Agent.config[:'transaction_tracer.enabled'] || Agent.config[:developer_mode]
|
71
69
|
end
|
72
70
|
|
73
|
-
def on_start_transaction(state, start_time
|
71
|
+
def on_start_transaction(state, start_time)
|
74
72
|
if enabled?
|
75
73
|
start_builder(state, start_time.to_f)
|
76
74
|
builder = state.transaction_sample_builder
|
77
|
-
builder.set_transaction_uri(uri) if builder
|
78
75
|
end
|
79
76
|
end
|
80
77
|
|
81
|
-
# This delegates to the builder to create a new open transaction
|
78
|
+
# This delegates to the builder to create a new open transaction node
|
82
79
|
# for the frame, beginning at the optionally specified time.
|
83
80
|
#
|
84
81
|
# Note that in developer mode, this captures a stacktrace for
|
85
|
-
# the beginning of each
|
82
|
+
# the beginning of each node, which can be fairly slow
|
86
83
|
def notice_push_frame(state, time=Time.now)
|
87
84
|
builder = state.transaction_sample_builder
|
88
85
|
return unless builder
|
89
86
|
|
90
|
-
|
87
|
+
node = builder.trace_entry(time.to_f)
|
91
88
|
if @dev_mode_sample_buffer
|
92
|
-
@dev_mode_sample_buffer.
|
89
|
+
@dev_mode_sample_buffer.visit_node(node)
|
93
90
|
end
|
94
|
-
|
91
|
+
node
|
95
92
|
end
|
96
93
|
|
97
94
|
# Informs the transaction sample builder about the end of a traced frame
|
@@ -102,14 +99,6 @@ module NewRelic
|
|
102
99
|
builder.trace_exit(frame, time.to_f)
|
103
100
|
end
|
104
101
|
|
105
|
-
def custom_parameters_from_transaction(txn)
|
106
|
-
if Agent.config[:'transaction_tracer.capture_attributes']
|
107
|
-
txn.custom_parameters
|
108
|
-
else
|
109
|
-
{}
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
102
|
# This is called when we are done with the transaction. We've
|
114
103
|
# unwound the stack to the top level. It also clears the
|
115
104
|
# transaction sample builder so that it won't continue to have
|
@@ -117,33 +106,20 @@ module NewRelic
|
|
117
106
|
#
|
118
107
|
# It sets various instance variables to the finished sample,
|
119
108
|
# depending on which settings are active. See `store_sample`
|
120
|
-
def on_finishing_transaction(state, txn, time=Time.now
|
109
|
+
def on_finishing_transaction(state, txn, time=Time.now)
|
121
110
|
last_builder = state.transaction_sample_builder
|
122
111
|
return unless last_builder && enabled?
|
123
112
|
|
124
113
|
state.transaction_sample_builder = nil
|
125
|
-
return if
|
114
|
+
return if txn.ignore_trace?
|
126
115
|
|
127
|
-
last_builder.
|
128
|
-
last_builder.set_transaction_name(txn.best_name)
|
129
|
-
last_builder.finish_trace(time.to_f, custom_parameters_from_transaction(txn))
|
116
|
+
last_builder.finish_trace(time.to_f)
|
130
117
|
|
131
118
|
last_sample = last_builder.sample
|
119
|
+
last_sample.transaction_name = txn.best_name
|
120
|
+
last_sample.uri = txn.request_path
|
132
121
|
last_sample.guid = txn.guid
|
133
|
-
last_sample.
|
134
|
-
|
135
|
-
if state.is_cross_app?
|
136
|
-
last_sample.set_custom_param(:'nr.trip_id', txn.cat_trip_id(state))
|
137
|
-
last_sample.set_custom_param(:'nr.path_hash', txn.cat_path_hash(state))
|
138
|
-
end
|
139
|
-
|
140
|
-
if txn.is_synthetics_request?
|
141
|
-
last_sample.set_custom_param(:'nr.synthetics_resource_id', txn.synthetics_resource_id)
|
142
|
-
last_sample.set_custom_param(:'nr.synthetics_job_id', txn.synthetics_job_id)
|
143
|
-
last_sample.set_custom_param(:'nr.synthetics_monitor_id', txn.synthetics_monitor_id)
|
144
|
-
|
145
|
-
last_sample.synthetics_resource_id = txn.synthetics_resource_id
|
146
|
-
end
|
122
|
+
last_sample.attributes = txn.attributes
|
147
123
|
|
148
124
|
@samples_lock.synchronize do
|
149
125
|
@last_sample = last_sample
|
@@ -158,42 +134,27 @@ module NewRelic
|
|
158
134
|
end
|
159
135
|
end
|
160
136
|
|
161
|
-
# Tells the builder to ignore a transaction, if we are currently
|
162
|
-
# creating one. Only causes the sample to be ignored upon end of
|
163
|
-
# the transaction, and does not change the metrics gathered
|
164
|
-
# outside of the sampler
|
165
|
-
def ignore_transaction(state)
|
166
|
-
builder = state.transaction_sample_builder
|
167
|
-
builder.ignore_transaction if builder
|
168
|
-
end
|
169
|
-
|
170
|
-
# Sets the CPU time used by a transaction, delegates to the builder
|
171
|
-
def notice_transaction_cpu_time(state, cpu_time)
|
172
|
-
builder = state.transaction_sample_builder
|
173
|
-
builder.set_transaction_cpu_time(cpu_time) if builder
|
174
|
-
end
|
175
|
-
|
176
137
|
MAX_DATA_LENGTH = 16384
|
177
138
|
# This method is used to record metadata into the currently
|
178
|
-
# active
|
139
|
+
# active node like a sql query, memcache key, or Net::HTTP uri
|
179
140
|
#
|
180
141
|
# duration is seconds, float value.
|
181
142
|
def notice_extra_data(builder, message, duration, key)
|
182
143
|
return unless builder
|
183
|
-
|
184
|
-
if
|
144
|
+
node = builder.current_node
|
145
|
+
if node
|
185
146
|
if key == :sql
|
186
|
-
sql =
|
147
|
+
sql = node[:sql]
|
187
148
|
if(sql && !sql.empty?)
|
188
149
|
sql = self.class.truncate_message(sql << "\n#{message}") if sql.length <= MAX_DATA_LENGTH
|
189
150
|
else
|
190
151
|
# message is expected to have been pre-truncated by notice_sql
|
191
|
-
|
152
|
+
node[:sql] = message
|
192
153
|
end
|
193
154
|
else
|
194
|
-
|
155
|
+
node[key] = self.class.truncate_message(message)
|
195
156
|
end
|
196
|
-
append_backtrace(
|
157
|
+
append_backtrace(node, duration)
|
197
158
|
end
|
198
159
|
end
|
199
160
|
|
@@ -211,15 +172,15 @@ module NewRelic
|
|
211
172
|
end
|
212
173
|
end
|
213
174
|
|
214
|
-
# Appends a backtrace to a
|
175
|
+
# Appends a backtrace to a node if that node took longer
|
215
176
|
# than the specified duration
|
216
|
-
def append_backtrace(
|
177
|
+
def append_backtrace(node, duration)
|
217
178
|
if duration >= Agent.config[:'transaction_tracer.stack_trace_threshold']
|
218
|
-
|
179
|
+
node[:backtrace] = caller.join("\n")
|
219
180
|
end
|
220
181
|
end
|
221
182
|
|
222
|
-
# Attaches an SQL query on the current transaction trace
|
183
|
+
# Attaches an SQL query on the current transaction trace node.
|
223
184
|
#
|
224
185
|
# This method should be used only by gem authors wishing to extend
|
225
186
|
# the Ruby agent to instrument new database interfaces - it should
|
@@ -232,6 +193,7 @@ module NewRelic
|
|
232
193
|
# not pass this parameter.
|
233
194
|
#
|
234
195
|
# @api public
|
196
|
+
# @deprecated Use {Datastores.notice_sql} instead.
|
235
197
|
#
|
236
198
|
def notice_sql(sql, config, duration, state=nil, &explainer) #THREAD_LOCAL_ACCESS sometimes
|
237
199
|
# some statements (particularly INSERTS with large BLOBS
|
@@ -256,7 +218,7 @@ module NewRelic
|
|
256
218
|
end
|
257
219
|
|
258
220
|
# Attaches an additional non-SQL query parameter to the current
|
259
|
-
# transaction trace
|
221
|
+
# transaction trace node.
|
260
222
|
#
|
261
223
|
# This may be used for recording a query against a key-value store like
|
262
224
|
# memcached or redis.
|
@@ -269,6 +231,7 @@ module NewRelic
|
|
269
231
|
# @param duration [Float] number of seconds the query took to execute
|
270
232
|
#
|
271
233
|
# @api public
|
234
|
+
# @deprecated Use {Datastores.notice_statement} instead.
|
272
235
|
#
|
273
236
|
def notice_nosql(key, duration) #THREAD_LOCAL_ACCESS
|
274
237
|
builder = tl_builder
|
@@ -280,11 +243,11 @@ module NewRelic
|
|
280
243
|
notice_extra_data(builder, statement, duration, :statement)
|
281
244
|
end
|
282
245
|
|
283
|
-
# Set parameters on the current
|
284
|
-
def
|
246
|
+
# Set parameters on the current node.
|
247
|
+
def add_node_parameters(params) #THREAD_LOCAL_ACCESS
|
285
248
|
builder = tl_builder
|
286
249
|
return unless builder
|
287
|
-
params.each { |k,v| builder.
|
250
|
+
params.each { |k,v| builder.current_node[k] = v }
|
288
251
|
end
|
289
252
|
|
290
253
|
# Gather transaction traces that we'd like to transmit to the server.
|