newrelic_rpm 3.7.2.195 → 3.7.3.199
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +25 -1
- data/Rakefile +7 -0
- data/lib/new_relic/agent/agent.rb +19 -13
- data/lib/new_relic/agent/configuration/default_source.rb +23 -0
- data/lib/new_relic/agent/cross_app_tracing.rb +2 -0
- data/lib/new_relic/agent/database.rb +123 -94
- data/lib/new_relic/agent/database/obfuscation_helpers.rb +37 -0
- data/lib/new_relic/agent/database/obfuscator.rb +65 -0
- data/lib/new_relic/agent/database/postgres_explain_obfuscator.rb +49 -0
- data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +2 -1
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +9 -8
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +1 -38
- data/lib/new_relic/agent/instrumentation/rubyprof.rb +26 -0
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +3 -2
- data/lib/new_relic/agent/pipe_channel_manager.rb +45 -12
- data/lib/new_relic/agent/pipe_service.rb +14 -8
- data/lib/new_relic/agent/request_sampler.rb +63 -6
- data/lib/new_relic/agent/sampler_collection.rb +5 -2
- data/lib/new_relic/agent/shim_agent.rb +1 -1
- data/lib/new_relic/agent/transaction.rb +41 -22
- data/lib/new_relic/agent/transaction_sample_builder.rb +0 -4
- data/lib/new_relic/agent/transaction_sampler.rb +2 -5
- data/lib/new_relic/agent/transaction_state.rb +43 -11
- data/lib/new_relic/agent/vm.rb +32 -0
- data/lib/new_relic/agent/vm/jruby_vm.rb +40 -0
- data/lib/new_relic/agent/vm/monotonic_gc_profiler.rb +36 -0
- data/lib/new_relic/agent/vm/mri_vm.rb +86 -0
- data/lib/new_relic/agent/vm/rubinius_vm.rb +40 -0
- data/lib/new_relic/agent/vm/snapshot.rb +16 -0
- data/lib/new_relic/control.rb +0 -6
- data/lib/new_relic/language_support.rb +20 -0
- data/lib/new_relic/latest_changes.rb +41 -12
- data/lib/new_relic/rack/developer_mode.rb +8 -1
- data/lib/new_relic/rack/transaction_reset.rb +1 -1
- data/lib/new_relic/transaction_sample.rb +0 -13
- data/lib/new_relic/version.rb +1 -1
- data/lib/tasks/install.rake +5 -0
- data/newrelic_rpm.gemspec +2 -1
- data/test/active_record_fixtures.rb +7 -9
- data/test/agent_helper.rb +11 -50
- data/test/environments/lib/environments/runner.rb +3 -5
- data/test/environments/rails40/Gemfile +12 -3
- data/test/environments/rails41/Gemfile +34 -0
- data/test/environments/rails41/Rakefile +11 -0
- data/test/environments/rails41/config/application.rb +18 -0
- data/test/environments/rails41/config/boot.rb +10 -0
- data/test/environments/rails41/config/database.yml +26 -0
- data/test/environments/rails41/config/environment.rb +6 -0
- data/test/environments/rails41/db/schema.rb +5 -0
- data/test/fixtures/cross_agent_tests/README.md +12 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/basic_where.colon_obfuscated.txt +3 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/basic_where.explain.txt +3 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/basic_where.obfuscated.txt +3 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/basic_where.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/current_date.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/current_date.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/current_date.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/current_date.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/date.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/date.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/date.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/date.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/embedded_newline.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/embedded_newline.explain.txt +3 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/embedded_newline.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/embedded_newline.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/embedded_quote.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/embedded_quote.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/embedded_quote.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/embedded_quote.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/floating_point.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/floating_point.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/floating_point.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/floating_point.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/function_with_strings.colon_obfuscated.txt +5 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/function_with_strings.explain.txt +5 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/function_with_strings.obfuscated.txt +5 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/function_with_strings.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/quote_in_table_name.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/quote_in_table_name.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/quote_in_table_name.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/quote_in_table_name.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/subplan.colon_obfuscated.txt +5 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/subplan.explain.txt +5 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/subplan.obfuscated.txt +5 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/subplan.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/where_with_integer.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/where_with_integer.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/where_with_integer.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/where_with_integer.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/where_with_regex_chars.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/where_with_regex_chars.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/where_with_regex_chars.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/where_with_regex_chars.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/where_with_substring.colon_obfuscated.txt +3 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/where_with_substring.explain.txt +3 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/where_with_substring.obfuscated.txt +3 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/where_with_substring.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case1.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case1.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case1.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case1.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case2.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case2.explain.txt +3 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case2.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case2.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case3.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case3.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case3.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case3.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case4.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case4.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case4.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case4.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case5.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case5.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case5.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case5.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case6.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case6.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case6.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case6.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case7.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case7.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case7.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case7.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case8.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case8.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case8.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case8.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case9.colon_obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case9.explain.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case9.obfuscated.txt +2 -0
- data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/with_escape_case9.query.txt +1 -0
- data/test/fixtures/cross_agent_tests/rules.json +165 -0
- data/test/fixtures/cross_agent_tests/rum_client_config.json +142 -0
- data/test/fixtures/cross_agent_tests/rum_cookie.json +17 -0
- data/test/fixtures/cross_agent_tests/rum_footer_insertion_location/close-body-in-comment.html +10 -0
- data/test/fixtures/cross_agent_tests/rum_footer_insertion_location/dynamic-iframe.html +19 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/basic.html +10 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/body_with_attributes.html +3 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/charset_tag.html +11 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/charset_tag_after_x_ua_tag.html +11 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/charset_tag_before_x_ua_tag.html +11 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/charset_tag_with_spaces.html +11 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/comments1.html +24 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/comments2.html +24 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/content_type_charset_tag.html +11 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/content_type_charset_tag_after_x_ua_tag.html +11 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/content_type_charset_tag_before_x_ua_tag.html +11 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/gt_in_quotes1.html +27 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/gt_in_quotes2.html +24 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/gt_in_quotes_mismatch.html +24 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/gt_in_single_quotes1.html +25 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/gt_in_single_quotes_mismatch.html +25 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/head_with_attributes.html +10 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/incomplete_non_meta_tags.html +10 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/no_header.html +7 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/no_html_and_no_header.html +3 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/no_start_header.html +9 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/script1.html +19 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/script2.html +17 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag.html +10 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_multiline.html +11 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_spaces_around_equals.html +10 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_with_others.html +11 -0
- data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_with_spaces.html +10 -0
- data/test/fixtures/cross_agent_tests/sql_parsing.json +55 -0
- data/test/fixtures/cross_agent_tests/url_clean.json +15 -0
- data/test/fixtures/cross_agent_tests/url_domain_extraction.json +35 -0
- data/test/flaky_proxy/README.md +91 -33
- data/test/flaky_proxy/lib/flaky_proxy.rb +1 -0
- data/test/flaky_proxy/lib/flaky_proxy/http_message.rb +2 -0
- data/test/flaky_proxy/lib/flaky_proxy/proxy.rb +19 -4
- data/test/flaky_proxy/lib/flaky_proxy/rule.rb +13 -16
- data/test/flaky_proxy/lib/flaky_proxy/rule_set.rb +10 -2
- data/test/flaky_proxy/lib/flaky_proxy/sequence.rb +14 -0
- data/test/helpers/file_searching.rb +1 -1
- data/test/intentional_fail.rb +1 -1
- data/test/multiverse/lib/multiverse/suite.rb +26 -3
- data/test/multiverse/suites/active_record/Envfile +1 -1
- data/test/multiverse/suites/active_record/ar_method_aliasing.rb +1 -1
- data/test/multiverse/suites/agent_only/audit_log_test.rb +1 -1
- data/test/multiverse/suites/agent_only/collector_exception_handling_test.rb +1 -1
- data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +1 -1
- data/test/multiverse/suites/agent_only/encoding_handling_test.rb +1 -1
- data/test/multiverse/suites/agent_only/harvest_timestamps_test.rb +1 -1
- data/test/multiverse/suites/agent_only/http_response_code_test.rb +1 -1
- data/test/multiverse/suites/agent_only/key_transactions_test.rb +1 -1
- data/test/multiverse/suites/agent_only/logging_test.rb +1 -1
- data/test/multiverse/suites/agent_only/marshaling_test.rb +1 -1
- data/test/multiverse/suites/agent_only/pipe_manager_test.rb +1 -1
- data/test/multiverse/suites/agent_only/rename_rule_test.rb +1 -1
- data/test/multiverse/suites/agent_only/rum_instrumentation_test.rb +1 -1
- data/test/multiverse/suites/agent_only/service_timeout_test.rb +1 -1
- data/test/multiverse/suites/agent_only/set_transaction_name_test.rb +1 -1
- data/test/multiverse/suites/agent_only/ssl_test.rb +1 -1
- data/test/multiverse/suites/agent_only/start_up_test.rb +1 -1
- data/test/multiverse/suites/agent_only/thread_profiling_test.rb +1 -1
- data/test/multiverse/suites/agent_only/xray_sessions_test.rb +1 -1
- data/test/multiverse/suites/bare/standalone_instrumentation_test.rb +1 -1
- data/test/multiverse/suites/config_file_loading/config_file_loading_test.rb +1 -1
- data/test/multiverse/suites/curb/curb_test.rb +1 -1
- data/test/multiverse/suites/datamapper/datamapper_test.rb +1 -1
- data/test/multiverse/suites/deferred_instrumentation/sinatra_test.rb +1 -1
- data/test/multiverse/suites/excon/excon_test.rb +1 -1
- data/test/multiverse/suites/httpclient/httpclient_test.rb +1 -1
- data/test/multiverse/suites/mongo/helpers/mongo_operation_tests.rb +7 -3
- data/test/multiverse/suites/mongo/mongo_instrumentation_test.rb +1 -1
- data/test/multiverse/suites/mongo/mongo_unsupported_version_test.rb +2 -2
- data/test/multiverse/suites/net_http/net_http_test.rb +1 -1
- data/test/multiverse/suites/padrino/Envfile +1 -1
- data/test/multiverse/suites/padrino/padrino_test.rb +1 -1
- data/test/multiverse/suites/rails/Envfile +10 -0
- data/test/multiverse/suites/rails/request_statistics_test.rb +59 -6
- data/test/multiverse/suites/rails/view_instrumentation_test.rb +1 -0
- data/test/multiverse/suites/resque/instrumentation_test.rb +1 -1
- data/test/multiverse/suites/sequel/sequel_instrumentation_test.rb +5 -18
- data/test/multiverse/suites/sequel/sequel_safety_test.rb +1 -1
- data/test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb +1 -1
- data/test/multiverse/suites/sinatra/ignoring_test.rb +1 -1
- data/test/multiverse/suites/sinatra/sinatra_classic_test.rb +1 -1
- data/test/multiverse/suites/sinatra/sinatra_error_tracing_test.rb +1 -1
- data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +1 -1
- data/test/multiverse/suites/sinatra/sinatra_modular_test.rb +1 -1
- data/test/multiverse/suites/sinatra/sinatra_routes_test.rb +1 -1
- data/test/multiverse/suites/typhoeus/typhoeus_test.rb +36 -2
- data/test/new_relic/FAKECHANGELOG +21 -0
- data/test/new_relic/agent/agent/connect_test.rb +1 -1
- data/test/new_relic/agent/agent/start_test.rb +1 -1
- data/test/new_relic/agent/agent/start_worker_thread_test.rb +1 -1
- data/test/new_relic/agent/agent_logger_test.rb +1 -1
- data/test/new_relic/agent/agent_test.rb +14 -8
- data/test/new_relic/agent/apdex_from_server_test.rb +1 -1
- data/test/new_relic/agent/audit_logger_test.rb +1 -1
- data/test/new_relic/agent/autostart_test.rb +1 -1
- data/test/new_relic/agent/browser_token_test.rb +1 -1
- data/test/new_relic/agent/busy_calculator_test.rb +1 -1
- data/test/new_relic/agent/commands/agent_command_router_test.rb +1 -1
- data/test/new_relic/agent/commands/agent_command_test.rb +1 -1
- data/test/new_relic/agent/commands/thread_profiler_session_test.rb +2 -2
- data/test/new_relic/agent/commands/xray_session_collection_test.rb +1 -1
- data/test/new_relic/agent/commands/xray_session_test.rb +1 -1
- data/test/new_relic/agent/configuration/default_source_test.rb +1 -1
- data/test/new_relic/agent/configuration/environment_source_test.rb +1 -1
- data/test/new_relic/agent/configuration/manager_test.rb +1 -1
- data/test/new_relic/agent/configuration/orphan_configuration_test.rb +1 -1
- data/test/new_relic/agent/configuration/server_source_test.rb +1 -1
- data/test/new_relic/agent/configuration/yaml_source_test.rb +1 -1
- data/test/new_relic/agent/cpu_sampler_test.rb +1 -1
- data/test/new_relic/agent/cross_app_monitor_test.rb +3 -3
- data/test/new_relic/agent/cross_app_tracing_test.rb +1 -1
- data/test/new_relic/agent/database/postgres_explain_obfuscator_test.rb +34 -0
- data/test/new_relic/agent/database_test.rb +192 -5
- data/test/new_relic/agent/datastores/mongo/metric_generator_test.rb +1 -1
- data/test/new_relic/agent/datastores/mongo/metric_translator_test.rb +11 -1
- data/test/new_relic/agent/datastores/mongo/obfuscator_test.rb +1 -1
- data/test/new_relic/agent/datastores/mongo/statement_formatter_test.rb +1 -1
- data/test/new_relic/agent/error_collector/notice_error_test.rb +1 -1
- data/test/new_relic/agent/error_collector_test.rb +1 -1
- data/test/new_relic/agent/event_listener_test.rb +1 -1
- data/test/new_relic/agent/harvester_test.rb +1 -1
- data/test/new_relic/agent/http_clients/uri_util_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/action_controller_subscriber_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/action_view_subscriber_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/active_record_helper_test.rb +4 -4
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +2 -2
- data/test/new_relic/agent/instrumentation/active_record_test.rb +385 -0
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/instrumentation_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/metric_frame_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/queue_time_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/rack_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/sinatra/transaction_namer_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/sinatra_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +1 -1
- data/test/new_relic/agent/javascript_instrumentor_test.rb +3 -3
- data/test/new_relic/agent/memcache_instrumentation_test.rb +1 -1
- data/test/new_relic/agent/memory_logger_test.rb +1 -1
- data/test/new_relic/agent/method_interrobang_test.rb +1 -1
- data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +1 -1
- data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +1 -1
- data/test/new_relic/agent/method_tracer_test.rb +1 -1
- data/test/new_relic/agent/method_visibility_test.rb +1 -1
- data/test/new_relic/agent/new_relic_service_test.rb +2 -2
- data/test/new_relic/agent/obfuscator_test.rb +1 -1
- data/test/new_relic/agent/pipe_channel_manager_test.rb +216 -143
- data/test/new_relic/agent/pipe_service_test.rb +26 -15
- data/test/new_relic/agent/request_sampler_test.rb +65 -18
- data/test/new_relic/agent/rpm_agent_test.rb +1 -1
- data/test/new_relic/agent/rules_engine_test.rb +1 -1
- data/test/new_relic/agent/sampled_buffer_test.rb +1 -1
- data/test/new_relic/agent/sampler_collection_test.rb +8 -1
- data/test/new_relic/agent/sampler_test.rb +1 -1
- data/test/new_relic/agent/shim_agent_test.rb +3 -3
- data/test/new_relic/agent/sql_sampler_test.rb +7 -6
- data/test/new_relic/agent/stats_engine/gc_profiler_test.rb +1 -1
- data/test/new_relic/agent/stats_engine/metric_stats_test.rb +1 -1
- data/test/new_relic/agent/stats_engine/samplers_test.rb +1 -1
- data/test/new_relic/agent/stats_engine_test.rb +1 -1
- data/test/new_relic/agent/stats_hash_test.rb +1 -1
- data/test/new_relic/agent/stats_test.rb +1 -1
- data/test/new_relic/agent/threading/agent_thread_test.rb +1 -1
- data/test/new_relic/agent/threading/backtrace_node_test.rb +1 -1
- data/test/new_relic/agent/threading/backtrace_service_test.rb +3 -3
- data/test/new_relic/agent/threading/thread_profile_test.rb +1 -1
- data/test/new_relic/agent/transaction/developer_mode_sample_buffer_test.rb +1 -1
- data/test/new_relic/agent/transaction/force_persist_sample_buffer_test.rb +1 -1
- data/test/new_relic/agent/transaction/pop_test.rb +1 -1
- data/test/new_relic/agent/transaction/slowest_sample_buffer_test.rb +1 -1
- data/test/new_relic/agent/transaction/xray_sample_buffer_test.rb +1 -1
- data/test/new_relic/agent/transaction_interrobang_test.rb +1 -1
- data/test/new_relic/agent/transaction_sample_builder_test.rb +1 -1
- data/test/new_relic/agent/transaction_sampler_test.rb +17 -17
- data/test/new_relic/agent/transaction_state_test.rb +61 -6
- data/test/new_relic/agent/transaction_test.rb +60 -3
- data/test/new_relic/agent/transaction_timings_test.rb +1 -1
- data/test/new_relic/agent/vm/monotonic_gc_profiler_test.rb +42 -0
- data/test/new_relic/agent/vm/mri_vm_test.rb +35 -0
- data/test/new_relic/agent/vm/snapshot_test.rb +8 -0
- data/test/new_relic/agent/vm_test.rb +48 -0
- data/test/new_relic/agent/worker_loop_test.rb +1 -1
- data/test/new_relic/agent_test.rb +1 -1
- data/test/new_relic/cli/deployments_test.rb +1 -1
- data/test/new_relic/coerce_test.rb +1 -1
- data/test/new_relic/collection_helper_test.rb +1 -1
- data/test/new_relic/control/class_methods_test.rb +1 -1
- data/test/new_relic/control/frameworks/rails_test.rb +1 -1
- data/test/new_relic/control_test.rb +1 -1
- data/test/new_relic/dependency_detection_test.rb +1 -1
- data/test/new_relic/dispatcher_test.rb +1 -1
- data/test/new_relic/environment_report_test.rb +1 -1
- data/test/new_relic/framework_test.rb +1 -1
- data/test/new_relic/http_client_test_cases.rb +1 -1
- data/test/new_relic/json_wrapper_test.rb +1 -1
- data/test/new_relic/language_support_test.rb +42 -1
- data/test/new_relic/latest_changes_test.rb +45 -0
- data/test/new_relic/license_test.rb +2 -2
- data/test/new_relic/load_test.rb +1 -1
- data/test/new_relic/local_environment_test.rb +1 -1
- data/test/new_relic/metric_data_test.rb +1 -1
- data/test/new_relic/metric_parser/metric_parser_test.rb +1 -1
- data/test/new_relic/metric_spec_test.rb +1 -1
- data/test/new_relic/multiverse_helpers.rb +0 -27
- data/test/new_relic/noticed_error_test.rb +1 -1
- data/test/new_relic/rack/agent_hooks_test.rb +1 -1
- data/test/new_relic/rack/all_test.rb +1 -1
- data/test/new_relic/rack/browser_monitoring_test.rb +2 -2
- data/test/new_relic/rack/deferred_instrumentation_test.rb +1 -1
- data/test/new_relic/rack/developer_mode_helper_test.rb +1 -1
- data/test/new_relic/rack/developer_mode_test.rb +2 -19
- data/test/new_relic/rack/error_collector_test.rb +1 -1
- data/test/new_relic/rack/transaction_reset_test.rb +1 -1
- data/test/new_relic/transaction_analysis/segment_summary_test.rb +1 -1
- data/test/new_relic/transaction_analysis_test.rb +1 -1
- data/test/new_relic/transaction_sample/composite_segment_test.rb +1 -1
- data/test/new_relic/transaction_sample/fake_segment_test.rb +1 -1
- data/test/new_relic/transaction_sample/segment_test.rb +2 -2
- data/test/new_relic/transaction_sample/summary_segment_test.rb +1 -1
- data/test/new_relic/transaction_sample_subtest_test.rb +1 -1
- data/test/new_relic/transaction_sample_test.rb +3 -3
- data/test/new_relic/version_number_test.rb +1 -1
- data/test/performance/lib/performance/instrumentation/stackprof.rb +33 -0
- data/test/performance/lib/performance/platform.rb +1 -0
- data/test/performance/suites/marshalling.rb +2 -1
- data/test/test_helper.rb +33 -3
- data/ui/views/newrelic/index.rhtml +2 -2
- metadata +169 -31
- metadata.gz.sig +0 -0
- data/lib/new_relic/control/profiling.rb +0 -29
- data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +0 -648
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
# New Relic Ruby Agent Release Notes #
|
2
2
|
|
3
|
+
## v3.7.3 ##
|
4
|
+
|
5
|
+
* Obfuscation for PostgreSQL explain plans
|
6
|
+
|
7
|
+
Fixes an agent bug with PostgreSQL where parameters from the original query
|
8
|
+
could appear in explain plans sent to New Relic servers, even when SQL
|
9
|
+
obfuscation was enabled. Parameters from the query are now masked in explain
|
10
|
+
plans prior to transmission when transaction_tracer.record_sql is set to
|
11
|
+
'obfuscated' (the default setting).
|
12
|
+
|
13
|
+
For more information, see:
|
14
|
+
https://docs.newrelic.com/docs/traces/security-for-postgresql-explain-plans
|
15
|
+
|
16
|
+
* More accurate categorization of SQL statements
|
17
|
+
|
18
|
+
Some SQL SELECT statements that were previously being mis-categorized as
|
19
|
+
'SQL - OTHER' will now correctly be tagged as 'SQL - SELECT'. This
|
20
|
+
particularly affected ActiveRecord users using PostgreSQL.
|
21
|
+
|
22
|
+
* More reliable Typhoeus instrumentation
|
23
|
+
|
24
|
+
Fixed an issue where an exception raised from a user-specified on_complete
|
25
|
+
block would cause our Typhoeus instrumentation to fail to record the request.
|
26
|
+
|
3
27
|
## v3.7.2 ##
|
4
28
|
|
5
29
|
* Mongo instrumentation improvements
|
@@ -25,7 +49,7 @@
|
|
25
49
|
|
26
50
|
* Improved Unicorn 4.8.0 compatibility
|
27
51
|
|
28
|
-
A rare issue that could lead to
|
52
|
+
A rare issue that could lead to spurious traced errors on app startup for
|
29
53
|
applications using Unicorn 4.8.0 has been fixed.
|
30
54
|
|
31
55
|
* meta_request gem compatibility
|
data/Rakefile
CHANGED
@@ -21,6 +21,7 @@ require 'new_relic/agent/cross_app_monitor'
|
|
21
21
|
require 'new_relic/agent/request_sampler'
|
22
22
|
require 'new_relic/agent/sampler_collection'
|
23
23
|
require 'new_relic/agent/javascript_instrumentor'
|
24
|
+
require 'new_relic/agent/vm/monotonic_gc_profiler'
|
24
25
|
require 'new_relic/environment_report'
|
25
26
|
|
26
27
|
module NewRelic
|
@@ -52,6 +53,7 @@ module NewRelic
|
|
52
53
|
@harvest_samplers = NewRelic::Agent::SamplerCollection.new(@events)
|
53
54
|
@javascript_instrumentor = NewRelic::Agent::JavascriptInstrumentor.new(@events)
|
54
55
|
@harvester = NewRelic::Agent::Harvester.new(@events)
|
56
|
+
@monotonic_gc_profiler = NewRelic::Agent::VM::MonotonicGCProfiler.new
|
55
57
|
|
56
58
|
@connect_state = :pending
|
57
59
|
@connect_attempts = 0
|
@@ -105,6 +107,8 @@ module NewRelic
|
|
105
107
|
# the latter during harvest.
|
106
108
|
attr_reader :transaction_rules
|
107
109
|
attr_reader :harvest_lock
|
110
|
+
# GC::Profiler.total_time is not monotonic so we wrap it.
|
111
|
+
attr_reader :monotonic_gc_profiler
|
108
112
|
|
109
113
|
# fakes out a transaction that did not happen in this process
|
110
114
|
# by creating apdex, summary metrics, and recording statistics
|
@@ -836,23 +840,25 @@ module NewRelic
|
|
836
840
|
end
|
837
841
|
include Connect
|
838
842
|
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
if transaction_traces && transaction_traces.respond_to?(:any?) &&
|
847
|
-
transaction_traces.any?
|
848
|
-
@transaction_sampler.merge!(transaction_traces)
|
843
|
+
def container_for_endpoint(endpoint)
|
844
|
+
case endpoint
|
845
|
+
when :metric_data then @stats_engine
|
846
|
+
when :transaction_sample_data then @transaction_sampler
|
847
|
+
when :error_data then @error_collector
|
848
|
+
when :analytic_event_data then @request_sampler
|
849
|
+
when :sql_trace_data then @sql_sampler
|
849
850
|
end
|
850
|
-
|
851
|
-
|
851
|
+
end
|
852
|
+
|
853
|
+
def merge_data_for_endpoint(endpoint, data)
|
854
|
+
if data && !data.empty?
|
855
|
+
container_for_endpoint(endpoint).merge!(data)
|
852
856
|
end
|
857
|
+
rescue => e
|
858
|
+
NewRelic::Agent.logger.error("Error while merging #{endpoint} data from child: ", e)
|
853
859
|
end
|
854
860
|
|
855
|
-
public :
|
861
|
+
public :merge_data_for_endpoint
|
856
862
|
|
857
863
|
# Connect to the server and validate the license. If successful,
|
858
864
|
# connected? returns true when finished. If not successful, you can
|
@@ -147,6 +147,17 @@ module NewRelic
|
|
147
147
|
Proc.new { NewRelic::Agent.config[:developer] }
|
148
148
|
end
|
149
149
|
|
150
|
+
def self.profiling_available
|
151
|
+
Proc.new {
|
152
|
+
begin
|
153
|
+
require 'ruby-prof'
|
154
|
+
true
|
155
|
+
rescue LoadError
|
156
|
+
false
|
157
|
+
end
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
150
161
|
def self.monitor_mode
|
151
162
|
Proc.new { NewRelic::Agent.config[:enabled] }
|
152
163
|
end
|
@@ -283,6 +294,18 @@ module NewRelic
|
|
283
294
|
:type => Boolean,
|
284
295
|
:description => 'Alternative method of enabling developer_mode.'
|
285
296
|
},
|
297
|
+
:'profiling.available' => {
|
298
|
+
:default => DefaultSource.profiling_available,
|
299
|
+
:public => false,
|
300
|
+
:type => Boolean,
|
301
|
+
:description => 'Determines if ruby-prof is available for developer mode profiling.'
|
302
|
+
},
|
303
|
+
:'profiling.enabled' => {
|
304
|
+
:default => false,
|
305
|
+
:public => false,
|
306
|
+
:type => Boolean,
|
307
|
+
:description => 'Determines at runtime whether developer mode should be profiling or not.'
|
308
|
+
},
|
286
309
|
:apdex_t => {
|
287
310
|
:default => 0.5,
|
288
311
|
:public => true,
|
@@ -153,6 +153,8 @@ module NewRelic
|
|
153
153
|
def inject_request_headers( request )
|
154
154
|
cross_app_id = NewRelic::Agent.config[:cross_process_id] or
|
155
155
|
raise NewRelic::Agent::CrossAppTracing::Error, "no cross app ID configured"
|
156
|
+
|
157
|
+
NewRelic::Agent::TransactionState.get.is_cross_app_caller = true
|
156
158
|
txn_guid = NewRelic::Agent::TransactionState.get.request_guid
|
157
159
|
txn_data = NewRelic::JSONWrapper.dump([ txn_guid, false ])
|
158
160
|
|
@@ -3,6 +3,9 @@
|
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
5
|
require 'singleton'
|
6
|
+
require 'new_relic/agent/database/obfuscation_helpers'
|
7
|
+
require 'new_relic/agent/database/obfuscator'
|
8
|
+
require 'new_relic/agent/database/postgres_explain_obfuscator'
|
6
9
|
|
7
10
|
module NewRelic
|
8
11
|
# columns for a mysql explain plan
|
@@ -78,6 +81,18 @@ module NewRelic
|
|
78
81
|
ConnectionManager.instance.close_connections
|
79
82
|
end
|
80
83
|
|
84
|
+
# This takes a connection config hash from ActiveRecord or Sequel and
|
85
|
+
# returns a string describing the associated database adapter
|
86
|
+
def adapter_from_config(config)
|
87
|
+
if config[:adapter]
|
88
|
+
return config[:adapter].to_s
|
89
|
+
elsif config[:uri] && config[:uri].to_s =~ /^jdbc:([^:]+):/
|
90
|
+
# This case is for Sequel with the jdbc-mysql, jdbc-postgres, or
|
91
|
+
# jdbc-sqlite3 gems.
|
92
|
+
return $1
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
81
96
|
# Perform this in the runtime environment of a managed
|
82
97
|
# application, to explain the sql statement executed within a
|
83
98
|
# segment of a transaction sample. Returns an array of
|
@@ -94,6 +109,8 @@ module NewRelic
|
|
94
109
|
return explain_plan || []
|
95
110
|
end
|
96
111
|
|
112
|
+
SUPPORTED_ADAPTERS_FOR_EXPLAIN = %w[postgres postgresql mysql2 mysql sqlite].freeze
|
113
|
+
|
97
114
|
def explain_statement(statement, config, &explainer)
|
98
115
|
return unless is_select?(statement)
|
99
116
|
|
@@ -107,40 +124,100 @@ module NewRelic
|
|
107
124
|
return
|
108
125
|
end
|
109
126
|
|
127
|
+
adapter = adapter_from_config(config)
|
128
|
+
if !SUPPORTED_ADAPTERS_FOR_EXPLAIN.include?(adapter)
|
129
|
+
NewRelic::Agent.logger.debug("Not collecting explain plan because an unknown connection adapter ('#{adapter}') was used.")
|
130
|
+
return
|
131
|
+
end
|
132
|
+
|
110
133
|
handle_exception_in_explain do
|
111
134
|
start = Time.now
|
112
135
|
plan = explainer.call(config, statement)
|
113
136
|
::NewRelic::Agent.record_metric("Supportability/Database/execute_explain_plan", Time.now - start)
|
114
|
-
return process_resultset(plan) if plan
|
137
|
+
return process_resultset(plan, adapter) if plan
|
115
138
|
end
|
116
139
|
end
|
117
140
|
|
118
|
-
def process_resultset(
|
119
|
-
|
120
|
-
|
121
|
-
|
141
|
+
def process_resultset(results, adapter)
|
142
|
+
case adapter.to_s
|
143
|
+
when 'postgres', 'postgresql'
|
144
|
+
process_explain_results_postgres(results)
|
145
|
+
when 'mysql2'
|
146
|
+
process_explain_results_mysql2(results)
|
147
|
+
when 'mysql'
|
148
|
+
process_explain_results_mysql(results)
|
149
|
+
when 'sqlite'
|
150
|
+
process_explain_results_sqlite(results)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
QUERY_PLAN = 'QUERY PLAN'.freeze
|
155
|
+
|
156
|
+
def process_explain_results_postgres(results)
|
157
|
+
if results.is_a?(String)
|
158
|
+
query_plan_string = results
|
159
|
+
else
|
160
|
+
lines = []
|
161
|
+
results.each { |row| lines << row[QUERY_PLAN] }
|
162
|
+
query_plan_string = lines.join("\n")
|
163
|
+
end
|
164
|
+
|
165
|
+
unless record_sql_method == :raw
|
166
|
+
query_plan_string = NewRelic::Agent::Database::PostgresExplainObfuscator.obfuscate(query_plan_string)
|
167
|
+
end
|
168
|
+
values = query_plan_string.split("\n").map { |line| [line] }
|
122
169
|
|
170
|
+
[[QUERY_PLAN], values]
|
171
|
+
end
|
172
|
+
|
173
|
+
# Sequel returns explain plans as just one big pre-formatted String
|
174
|
+
# In that case, we send a nil headers array, and the single string
|
175
|
+
# wrapped in an array for the values.
|
176
|
+
# Note that we don't use this method for Postgres explain plans, since
|
177
|
+
# they need to be passed through the explain plan obfuscator first.
|
178
|
+
def string_explain_plan_results(results)
|
179
|
+
[nil, [results]]
|
180
|
+
end
|
181
|
+
|
182
|
+
def process_explain_results_mysql(results)
|
183
|
+
return string_explain_plan_results(results) if results.is_a?(String)
|
123
184
|
headers = []
|
124
|
-
values
|
125
|
-
if
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
items.each do |row|
|
132
|
-
if row.kind_of?(Hash)
|
133
|
-
headers = row.keys
|
134
|
-
values << headers.map{|h| row[h] }
|
135
|
-
else
|
136
|
-
values << row
|
137
|
-
end
|
185
|
+
values = []
|
186
|
+
if results.is_a?(Array)
|
187
|
+
# We're probably using the jdbc-mysql gem for JRuby, which will give
|
188
|
+
# us an array of hashes.
|
189
|
+
headers = results.first.keys
|
190
|
+
results.each do |row|
|
191
|
+
values << headers.map { |h| row[h] }
|
138
192
|
end
|
139
193
|
else
|
140
|
-
|
194
|
+
# We're probably using the native mysql driver gem, which will give us
|
195
|
+
# a Mysql::Result object that responds to each_hash
|
196
|
+
results.each_hash do |row|
|
197
|
+
headers = row.keys
|
198
|
+
values << headers.map { |h| row[h] }
|
199
|
+
end
|
141
200
|
end
|
201
|
+
[headers, values]
|
202
|
+
end
|
203
|
+
|
204
|
+
def process_explain_results_mysql2(results)
|
205
|
+
return string_explain_plan_results(results) if results.is_a?(String)
|
206
|
+
headers = results.fields
|
207
|
+
values = []
|
208
|
+
results.each { |row| values << row }
|
209
|
+
[headers, values]
|
210
|
+
end
|
142
211
|
|
143
|
-
|
212
|
+
SQLITE_EXPLAIN_COLUMNS = %w[addr opcode p1 p2 p3 p4 p5 comment]
|
213
|
+
|
214
|
+
def process_explain_results_sqlite(results)
|
215
|
+
return string_explain_plan_results(results) if results.is_a?(String)
|
216
|
+
headers = SQLITE_EXPLAIN_COLUMNS
|
217
|
+
values = []
|
218
|
+
results.each do |row|
|
219
|
+
values << headers.map { |h| row[h] }
|
220
|
+
end
|
144
221
|
[headers, values]
|
145
222
|
end
|
146
223
|
|
@@ -157,11 +234,32 @@ module NewRelic
|
|
157
234
|
end
|
158
235
|
end
|
159
236
|
|
237
|
+
KNOWN_OPERATIONS = [
|
238
|
+
'alter',
|
239
|
+
'select',
|
240
|
+
'update',
|
241
|
+
'delete',
|
242
|
+
'insert',
|
243
|
+
'create',
|
244
|
+
'show',
|
245
|
+
'set',
|
246
|
+
'exec',
|
247
|
+
'execute',
|
248
|
+
'call'
|
249
|
+
]
|
250
|
+
|
251
|
+
SQL_COMMENT_REGEX = Regexp.new('/\*.*?\*/', Regexp::MULTILINE).freeze
|
252
|
+
|
253
|
+
def parse_operation_from_query(sql)
|
254
|
+
sql = sql.gsub(SQL_COMMENT_REGEX, '')
|
255
|
+
if sql =~ /(\w+)/
|
256
|
+
op = $1.downcase
|
257
|
+
return op if KNOWN_OPERATIONS.include?(op)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
160
261
|
def is_select?(statement)
|
161
|
-
|
162
|
-
# system-defined field separator character
|
163
|
-
first_word, rest_of_statement = statement.split($;, 2)
|
164
|
-
(first_word.upcase == 'SELECT')
|
262
|
+
parse_operation_from_query(statement) == 'select'
|
165
263
|
end
|
166
264
|
|
167
265
|
def parameterized?(statement)
|
@@ -204,75 +302,6 @@ module NewRelic
|
|
204
302
|
end
|
205
303
|
end
|
206
304
|
|
207
|
-
class Obfuscator
|
208
|
-
include Singleton
|
209
|
-
|
210
|
-
attr_reader :obfuscator
|
211
|
-
|
212
|
-
def initialize
|
213
|
-
reset
|
214
|
-
end
|
215
|
-
|
216
|
-
def reset
|
217
|
-
@obfuscator = method(:default_sql_obfuscator)
|
218
|
-
end
|
219
|
-
|
220
|
-
# Sets the sql obfuscator used to clean up sql when sending it
|
221
|
-
# to the server. Possible types are:
|
222
|
-
#
|
223
|
-
# :before => sets the block to run before the existing
|
224
|
-
# obfuscators
|
225
|
-
#
|
226
|
-
# :after => sets the block to run after the existing
|
227
|
-
# obfuscator(s)
|
228
|
-
#
|
229
|
-
# :replace => removes the current obfuscator and replaces it
|
230
|
-
# with the provided block
|
231
|
-
def set_sql_obfuscator(type, &block)
|
232
|
-
if type == :before
|
233
|
-
@obfuscator = NewRelic::ChainedCall.new(block, @obfuscator)
|
234
|
-
elsif type == :after
|
235
|
-
@obfuscator = NewRelic::ChainedCall.new(@obfuscator, block)
|
236
|
-
elsif type == :replace
|
237
|
-
@obfuscator = block
|
238
|
-
else
|
239
|
-
fail "unknown sql_obfuscator type #{type}"
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
def default_sql_obfuscator(sql)
|
244
|
-
if sql[-3,3] == '...'
|
245
|
-
return "Query too large (over 16k characters) to safely obfuscate"
|
246
|
-
end
|
247
|
-
|
248
|
-
stmt = sql.kind_of?(Statement) ? sql : Statement.new(sql)
|
249
|
-
adapter = stmt.adapter
|
250
|
-
obfuscated = remove_escaped_quotes(stmt)
|
251
|
-
obfuscated = obfuscate_single_quote_literals(obfuscated)
|
252
|
-
if !(adapter.to_s =~ /postgres/ || adapter.to_s =~ /sqlite/)
|
253
|
-
obfuscated = obfuscate_double_quote_literals(obfuscated)
|
254
|
-
end
|
255
|
-
obfuscated = obfuscate_numeric_literals(obfuscated)
|
256
|
-
obfuscated.to_s # return back to a regular String
|
257
|
-
end
|
258
|
-
|
259
|
-
def remove_escaped_quotes(sql)
|
260
|
-
sql.gsub(/\\"/, '').gsub(/\\'/, '')
|
261
|
-
end
|
262
|
-
|
263
|
-
def obfuscate_single_quote_literals(sql)
|
264
|
-
sql.gsub(/'(?:[^']|'')*'/, '?')
|
265
|
-
end
|
266
|
-
|
267
|
-
def obfuscate_double_quote_literals(sql)
|
268
|
-
sql.gsub(/"(?:[^"]|"")*"/, '?')
|
269
|
-
end
|
270
|
-
|
271
|
-
def obfuscate_numeric_literals(sql)
|
272
|
-
sql.gsub(/\b\d+\b/, "?")
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
305
|
class Statement < String
|
277
306
|
attr_accessor :adapter, :config, :explainer
|
278
307
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under New Relic's license terms.
|
3
|
+
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
|
+
|
5
|
+
module NewRelic
|
6
|
+
module Agent
|
7
|
+
module Database
|
8
|
+
module ObfuscationHelpers
|
9
|
+
NUMERICS = /\b\d+\b/
|
10
|
+
SINGLE_QUOTES = /'(?:[^']|'')*'/
|
11
|
+
DOUBLE_QUOTES = /"(?:[^"]|"")*"/
|
12
|
+
|
13
|
+
def remove_escaped_quotes(sql)
|
14
|
+
sql.gsub(/\\"/, '').gsub(/\\'/, '')
|
15
|
+
end
|
16
|
+
|
17
|
+
def obfuscate_single_quote_literals(sql)
|
18
|
+
sql.gsub(SINGLE_QUOTES, '?')
|
19
|
+
end
|
20
|
+
|
21
|
+
def obfuscate_double_quote_literals(sql)
|
22
|
+
sql.gsub(DOUBLE_QUOTES, '?')
|
23
|
+
end
|
24
|
+
|
25
|
+
def obfuscate_numeric_literals(sql)
|
26
|
+
sql.gsub(NUMERICS, "?")
|
27
|
+
end
|
28
|
+
|
29
|
+
def find_literals(sql)
|
30
|
+
literals = sql.scan(NUMERICS)
|
31
|
+
literals << sql.scan(SINGLE_QUOTES)
|
32
|
+
literals.flatten
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|