newrelic_rpm 3.9.1.236 → 3.9.2.239
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +2 -4
- data/CHANGELOG +96 -2
- data/lib/new_relic/agent.rb +47 -4
- data/lib/new_relic/agent/agent.rb +51 -26
- data/lib/new_relic/agent/agent_logger.rb +4 -0
- data/lib/new_relic/agent/configuration.rb +2 -32
- data/lib/new_relic/agent/configuration/default_source.rb +153 -118
- data/lib/new_relic/agent/configuration/dotted_hash.rb +52 -0
- data/lib/new_relic/agent/configuration/environment_source.rb +1 -1
- data/lib/new_relic/agent/configuration/manager.rb +101 -2
- data/lib/new_relic/agent/configuration/manual_source.rb +17 -0
- data/lib/new_relic/agent/configuration/server_source.rb +12 -4
- data/lib/new_relic/agent/configuration/yaml_source.rb +46 -22
- data/lib/new_relic/agent/cross_app_monitor.rb +1 -1
- data/lib/new_relic/agent/cross_app_tracing.rb +1 -1
- data/lib/new_relic/agent/database/obfuscation_helpers.rb +55 -14
- data/lib/new_relic/agent/database/obfuscator.rb +22 -7
- data/lib/new_relic/agent/database/postgres_explain_obfuscator.rb +6 -8
- data/lib/new_relic/agent/error_collector.rb +24 -16
- data/lib/new_relic/agent/event_loop.rb +189 -0
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +8 -17
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +17 -16
- data/lib/new_relic/agent/instrumentation/ignore_actions.rb +41 -0
- data/lib/new_relic/agent/instrumentation/merb/controller.rb +0 -11
- data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +0 -8
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +1 -9
- data/lib/new_relic/agent/instrumentation/rails4/action_controller.rb +0 -18
- data/lib/new_relic/agent/instrumentation/rubyprof.rb +1 -1
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +1 -1
- data/lib/new_relic/agent/instrumentation/sinatra.rb +12 -1
- data/lib/new_relic/agent/instrumentation/sinatra/transaction_namer.rb +1 -1
- data/lib/new_relic/agent/method_tracer.rb +33 -39
- data/lib/new_relic/agent/new_relic_service.rb +35 -156
- data/lib/new_relic/agent/new_relic_service/encoders.rb +34 -0
- data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +50 -0
- data/lib/new_relic/agent/new_relic_service/marshaller.rb +52 -0
- data/lib/new_relic/agent/new_relic_service/pruby_marshaller.rb +52 -0
- data/lib/new_relic/agent/threading/backtrace_node.rb +1 -1
- data/lib/new_relic/agent/traced_method_stack.rb +16 -2
- data/lib/new_relic/agent/transaction.rb +0 -4
- data/lib/new_relic/collection_helper.rb +2 -2
- data/lib/new_relic/control/frameworks/rails.rb +3 -0
- data/lib/new_relic/control/instrumentation.rb +6 -2
- data/lib/new_relic/json_wrapper.rb +47 -25
- data/lib/new_relic/language_support.rb +0 -4
- data/lib/new_relic/latest_changes.rb +2 -2
- data/lib/new_relic/rack/developer_mode.rb +4 -3
- data/lib/new_relic/recipes/capistrano3.rb +2 -2
- data/lib/new_relic/recipes/capistrano_legacy.rb +1 -1
- data/lib/new_relic/timer_lib.rb +1 -1
- data/lib/new_relic/version.rb +2 -2
- data/lib/tasks/config.html.erb +28 -0
- data/lib/tasks/config.rake +134 -0
- data/lib/tasks/config.text.erb +7 -0
- data/lib/tasks/install.rake +0 -63
- data/newrelic.yml +7 -0
- data/test/active_record_fixtures.rb +4 -4
- data/test/agent_helper.rb +58 -18
- data/test/environments/lib/environments/runner.rb +1 -1
- data/test/environments/rails21/Gemfile +1 -1
- data/test/environments/rails21/config/boot.rb +1 -1
- data/test/environments/rails22/Gemfile +1 -1
- data/test/environments/rails22/config/boot.rb +1 -1
- data/test/environments/rails23/config/boot.rb +2 -2
- data/test/environments/rails30/Gemfile +1 -1
- data/test/environments/rails31/Gemfile +1 -1
- data/test/environments/rails32/Gemfile +1 -1
- data/test/environments/rails40/Gemfile +1 -1
- data/test/environments/rails41/Gemfile +1 -1
- data/test/fixtures/cross_agent_tests/labels.json +104 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/README.md +23 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/back_quoted_identifiers.mysql.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/back_quoted_identifiers.mysql.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/comment_delimiters_in_strings.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/comment_delimiters_in_strings.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/double_quoted_identifiers.postgres.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/double_quoted_identifiers.postgres.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_line_comment_in_string.obfuscated +2 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_line_comment_in_string.sql +2 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_line_comments_with_quotes.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_line_comments_with_quotes.sql +2 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_query_comment_cstyle.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_query_comment_cstyle.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_query_comment_doubledash.obfuscated +2 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_query_comment_doubledash.sql +2 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_query_comment_hash.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/end_of_query_comment_hash.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/escape_string_constants.postgres.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/escape_string_constants.postgres.sql +4 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/malformed/unterminated_double_quoted_string.mysql.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/malformed/unterminated_single_quoted_string.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/mixed_comments_and_quotes.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/mixed_comments_and_quotes.sql +2 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/mixed_quotes_comments_and_newlines.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/mixed_quotes_comments_and_newlines.sql +4 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/mixed_quotes_end_of_line_comments.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/mixed_quotes_end_of_line_comments.sql +3 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/multiple_literal_types.mysql.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/multiple_literal_types.mysql.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/numbers_in_identifiers.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/numbers_in_identifiers.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/numeric_literals.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/numeric_literals.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/quote_delimiters_in_comments.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/quote_delimiters_in_comments.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_double_quoted.mysql.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_double_quoted.mysql.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_single_quoted.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_single_quoted.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_backslash_and_twin_single_quotes.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_backslash_and_twin_single_quotes.sql +4 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_embedded_double_quote.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_embedded_double_quote.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_embedded_newline.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_embedded_newline.sql +2 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_embedded_single_quote.mysql.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_embedded_single_quote.mysql.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_escaped_quotes.mysql.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_escaped_quotes.mysql.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_backslash.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_backslash.sql +4 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_escaped_backslash.mysql.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_escaped_backslash.mysql.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_escaped_backslash_single_quoted.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_escaped_backslash_single_quoted.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_escaped_quote.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_trailing_escaped_quote.sql +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_twin_single_quotes.obfuscated +1 -0
- data/test/fixtures/cross_agent_tests/sql_obfuscation/string_with_twin_single_quotes.sql +1 -0
- data/test/multiverse/lib/multiverse/output_collector.rb +1 -1
- data/test/multiverse/lib/multiverse/runner.rb +1 -1
- data/test/multiverse/lib/multiverse/suite.rb +19 -4
- data/test/multiverse/suites/agent_only/audit_log_test.rb +1 -38
- data/test/multiverse/suites/agent_only/collector_exception_handling_test.rb +25 -35
- data/test/multiverse/suites/agent_only/config/newrelic.yml +2 -0
- data/test/multiverse/suites/agent_only/encoding_handling_test.rb +1 -0
- data/test/multiverse/suites/agent_only/harvest_timestamps_test.rb +1 -1
- data/test/multiverse/suites/agent_only/keepalive_test.rb +29 -0
- data/test/multiverse/suites/agent_only/labels_test.rb +89 -0
- data/test/multiverse/suites/agent_only/marshaling_test.rb +1 -3
- data/test/multiverse/suites/agent_only/service_timeout_test.rb +1 -1
- data/test/multiverse/suites/agent_only/start_up_test.rb +9 -1
- data/test/multiverse/suites/capistrano/config/deploy.rb +6 -2
- data/test/multiverse/suites/capistrano/deployment_test.rb +12 -4
- data/test/multiverse/suites/config_file_loading/config_file_loading_test.rb +29 -1
- data/test/multiverse/suites/curb/Envfile +6 -2
- data/test/multiverse/suites/datamapper/Envfile +0 -4
- data/test/multiverse/suites/deferred_instrumentation/Envfile +0 -4
- data/test/multiverse/suites/deferred_instrumentation/sinatra_test.rb +1 -1
- data/test/multiverse/suites/excon/Envfile +5 -4
- data/test/multiverse/suites/excon/excon_test.rb +1 -1
- data/test/multiverse/suites/httpclient/Envfile +0 -4
- data/test/multiverse/suites/marshalling/Envfile +12 -0
- data/test/multiverse/suites/marshalling/config/newrelic.yml +20 -0
- data/test/multiverse/suites/marshalling/marshalling_test.rb +60 -0
- data/test/multiverse/suites/mongo/helpers/mongo_operation_tests.rb +1 -1
- data/test/multiverse/suites/mongo/helpers/mongo_replica_set.rb +1 -1
- data/test/multiverse/suites/mongo/helpers/mongo_server.rb +4 -4
- data/test/multiverse/suites/padrino/Envfile +0 -5
- data/test/multiverse/suites/padrino/padrino_test.rb +1 -1
- data/test/multiverse/suites/rack/rack_auto_instrumentation_test.rb +1 -1
- data/test/multiverse/suites/rails/gc_instrumentation_test.rb +2 -1
- data/test/multiverse/suites/rails/ignore_test.rb +22 -0
- data/test/multiverse/suites/rails/rails2_app/config/boot.rb +2 -2
- data/test/multiverse/suites/rails/rails2_app/config/routes.rb +1 -0
- data/test/multiverse/suites/resque/Envfile +0 -4
- data/test/multiverse/suites/sequel/Envfile +0 -5
- data/test/multiverse/suites/sinatra/sinatra_classic_test.rb +1 -1
- data/test/multiverse/suites/sinatra/sinatra_modular_test.rb +1 -1
- data/test/multiverse/suites/sinatra/sinatra_test_cases.rb +22 -0
- data/test/multiverse/suites/typhoeus/Envfile +1 -4
- data/test/new_relic/agent/agent/start_worker_thread_test.rb +1 -13
- data/test/new_relic/agent/agent_logger_test.rb +11 -0
- data/test/new_relic/agent/agent_test.rb +43 -20
- data/test/new_relic/agent/audit_logger_test.rb +7 -3
- data/test/new_relic/agent/commands/thread_profiler_session_test.rb +0 -1
- data/test/new_relic/agent/commands/xray_session_collection_test.rb +1 -1
- data/test/new_relic/agent/configuration/dotted_hash_test.rb +53 -0
- data/test/new_relic/agent/configuration/manager_test.rb +99 -6
- data/test/new_relic/agent/configuration/manual_source_test.rb +18 -0
- data/test/new_relic/agent/configuration/orphan_configuration_test.rb +1 -1
- data/test/new_relic/agent/configuration/yaml_source_test.rb +8 -4
- data/test/new_relic/agent/database/sql_obfuscation_test.rb +76 -0
- data/test/new_relic/agent/database_test.rb +2 -38
- data/test/new_relic/agent/error_collector/notice_error_test.rb +21 -3
- data/test/new_relic/agent/error_collector_test.rb +15 -2
- data/test/new_relic/agent/event_loop_test.rb +202 -0
- data/test/new_relic/agent/instrumentation/active_record_helper_test.rb +4 -0
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +283 -182
- data/test/new_relic/agent/method_tracer_test.rb +1 -2
- data/test/new_relic/agent/new_relic_service_test.rb +83 -27
- data/test/new_relic/agent/pipe_channel_manager_test.rb +6 -6
- data/test/new_relic/agent/rpm_agent_test.rb +1 -8
- data/test/new_relic/agent/sql_sampler_test.rb +10 -8
- data/test/new_relic/agent/threading/backtrace_service_test.rb +1 -1
- data/test/new_relic/agent/traced_method_stack_test.rb +45 -13
- data/test/new_relic/agent/transaction_sample_builder_test.rb +1 -2
- data/test/new_relic/agent/transaction_test.rb +3 -3
- data/test/new_relic/agent_test.rb +47 -8
- data/test/new_relic/collection_helper_test.rb +5 -5
- data/test/new_relic/control/instrumentation_test.rb +56 -0
- data/test/new_relic/control_test.rb +4 -3
- data/test/new_relic/fake_collector.rb +7 -2
- data/test/new_relic/http_client_test_cases.rb +4 -4
- data/test/new_relic/latest_changes_test.rb +3 -3
- data/test/new_relic/transaction_sample/segment_test.rb +0 -1
- data/test/new_relic/transaction_sample_test.rb +19 -2
- data/test/performance/lib/performance/runner.rb +4 -4
- data/test/performance/suites/marshalling.rb +46 -30
- data/test/performance/suites/sql_obfuscation.rb +30 -0
- data/test/test_helper.rb +1 -1
- data/ui/helpers/developer_mode_helper.rb +2 -2
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/java.rb +1 -1
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/view.rb +1 -1
- metadata +84 -3
- metadata.gz.sig +0 -0
- data/test/environments/rails23/config/environments/development.rb +0 -11
@@ -0,0 +1,34 @@
|
|
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
|
+
require 'base64'
|
6
|
+
require 'zlib'
|
7
|
+
|
8
|
+
module NewRelic
|
9
|
+
module Agent
|
10
|
+
class NewRelicService
|
11
|
+
module Encoders
|
12
|
+
module Identity
|
13
|
+
def self.encode(data)
|
14
|
+
data
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Compressed
|
19
|
+
def self.encode(data)
|
20
|
+
Zlib::Deflate.deflate(data, Zlib::DEFAULT_COMPRESSION)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module Base64CompressedJSON
|
25
|
+
def self.encode(data)
|
26
|
+
json = ::NewRelic::JSONWrapper.dump(data,
|
27
|
+
:normalize => Agent.config[:normalize_json_string_encodings])
|
28
|
+
Base64.encode64(Compressed.encode(json))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,50 @@
|
|
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
|
+
require 'new_relic/agent/new_relic_service/marshaller'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
class NewRelicService
|
10
|
+
# Marshal collector protocol with JSON when available
|
11
|
+
class JsonMarshaller < Marshaller
|
12
|
+
def initialize
|
13
|
+
::NewRelic::Agent.logger.debug "Using JSON marshaller (#{NewRelic::JSONWrapper.backend_name})"
|
14
|
+
unless self.class.is_supported?
|
15
|
+
::NewRelic::Agent.logger.warn "The JSON marshaller in use (#{NewRelic::JSONWrapper.backend_name}) is not recommended. Ensure the 'json' gem is available in your application for better performance."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def dump(ruby, opts={})
|
20
|
+
prepared = prepare(ruby, opts)
|
21
|
+
NewRelic::JSONWrapper.dump(prepared,
|
22
|
+
:normalize => Agent.config[:normalize_json_string_encodings])
|
23
|
+
end
|
24
|
+
|
25
|
+
def load(data)
|
26
|
+
return_value(NewRelic::JSONWrapper.load(data)) if data && data != ''
|
27
|
+
rescue => e
|
28
|
+
::NewRelic::Agent.logger.debug "#{e.class.name} : #{e.message} encountered loading collector response: #{data}"
|
29
|
+
raise
|
30
|
+
end
|
31
|
+
|
32
|
+
def default_encoder
|
33
|
+
Encoders::Base64CompressedJSON
|
34
|
+
end
|
35
|
+
|
36
|
+
def format
|
37
|
+
'json'
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.is_supported?
|
41
|
+
NewRelic::JSONWrapper.usable_for_collector_serialization?
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.human_readable?
|
45
|
+
true # for some definitions of 'human'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,52 @@
|
|
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
|
+
class NewRelicService
|
8
|
+
class Marshaller
|
9
|
+
def parsed_error(error)
|
10
|
+
error_class = error['error_type'].split('::') \
|
11
|
+
.inject(Module) {|mod,const| mod.const_get(const) }
|
12
|
+
error_class.new(error['message'])
|
13
|
+
rescue NameError
|
14
|
+
CollectorError.new("#{error['error_type']}: #{error['message']}")
|
15
|
+
end
|
16
|
+
|
17
|
+
def prepare(data, options={})
|
18
|
+
encoder = options[:encoder] || default_encoder
|
19
|
+
if data.respond_to?(:to_collector_array)
|
20
|
+
data.to_collector_array(encoder)
|
21
|
+
elsif data.kind_of?(Array)
|
22
|
+
data.map { |element| prepare(element, options) }
|
23
|
+
else
|
24
|
+
data
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def default_encoder
|
29
|
+
Encoders::Identity
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.human_readable?
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def return_value(data)
|
39
|
+
if data.respond_to?(:has_key?)
|
40
|
+
if data.has_key?('exception')
|
41
|
+
raise parsed_error(data['exception'])
|
42
|
+
elsif data.has_key?('return_value')
|
43
|
+
return data['return_value']
|
44
|
+
end
|
45
|
+
end
|
46
|
+
::NewRelic::Agent.logger.debug("Unexpected response from collector: #{data}")
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,52 @@
|
|
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
|
+
require 'new_relic/agent/new_relic_service/marshaller'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
class NewRelicService
|
10
|
+
# Primitive Ruby Object Notation which complies JSON format data strutures
|
11
|
+
class PrubyMarshaller < Marshaller
|
12
|
+
def initialize
|
13
|
+
::NewRelic::Agent.logger.debug 'Using Pruby marshaller'
|
14
|
+
warn_for_pruby_deprecation
|
15
|
+
end
|
16
|
+
|
17
|
+
def warn_for_pruby_deprecation
|
18
|
+
if RUBY_VERSION < "1.9" && !defined?(::JSON)
|
19
|
+
NewRelic::Agent.logger.warn("Upcoming versions of the Ruby agent running on Ruby 1.8.7 will require the 'json' gem. To avoid interuption in reporting, please update your Gemfile. See http://docs.newrelic.com/docs/ruby/ruby-1.8.7-support for more information.")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def dump(ruby, opts={})
|
24
|
+
NewRelic::LanguageSupport.with_cautious_gc do
|
25
|
+
Marshal.dump(prepare(ruby, opts))
|
26
|
+
end
|
27
|
+
rescue => e
|
28
|
+
::NewRelic::Agent.logger.debug("#{e.class.name} : #{e.message} when marshalling #{ruby.inspect}")
|
29
|
+
raise
|
30
|
+
end
|
31
|
+
|
32
|
+
def load(data)
|
33
|
+
return unless data && data != ''
|
34
|
+
NewRelic::LanguageSupport.with_cautious_gc do
|
35
|
+
return_value(Marshal.load(data))
|
36
|
+
end
|
37
|
+
rescue
|
38
|
+
::NewRelic::Agent.logger.debug "Error encountered loading collector response: #{data}"
|
39
|
+
raise
|
40
|
+
end
|
41
|
+
|
42
|
+
def format
|
43
|
+
'pruby'
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.is_supported?
|
47
|
+
true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -105,7 +105,7 @@ module NewRelic
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def dump_string(indent=0)
|
108
|
-
file, method,
|
108
|
+
@file, @method, @line_no = parse_backtrace_frame(@raw_line)
|
109
109
|
result = "#{" " * indent}#<BacktraceNode:#{object_id} [#{@runnable_count}] #{@file}:#{@line_no} in #{@method}>"
|
110
110
|
child_results = @children.map { |c| c.dump_string(indent+2) }.join("\n")
|
111
111
|
result << "\n" unless child_results.empty?
|
@@ -45,8 +45,7 @@ module NewRelic
|
|
45
45
|
#
|
46
46
|
# +name+ will be applied to the generated transaction trace segment.
|
47
47
|
def pop_frame(state, expected_frame, name, time, deduct_call_time_from_parent=true)
|
48
|
-
frame =
|
49
|
-
fail "unbalanced pop from blame stack, got #{frame ? frame.tag : 'nil'}, expected #{expected_frame ? expected_frame.tag : 'nil'}" if frame != expected_frame
|
48
|
+
frame = fetch_matching_frame(expected_frame)
|
50
49
|
|
51
50
|
note_children_time(frame, time, deduct_call_time_from_parent)
|
52
51
|
|
@@ -55,6 +54,21 @@ module NewRelic
|
|
55
54
|
frame
|
56
55
|
end
|
57
56
|
|
57
|
+
def fetch_matching_frame(expected_frame)
|
58
|
+
while frame = @stack.pop
|
59
|
+
if frame == expected_frame
|
60
|
+
return frame
|
61
|
+
else
|
62
|
+
NewRelic::Agent.logger.info("Unexpected frame in traced method stack: #{frame.inspect} expected to be #{expected_frame.inspect}")
|
63
|
+
NewRelic::Agent.logger.debug do
|
64
|
+
["Backtrace for unexpected frame: ", caller.join("\n")]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
raise "Frame not found in blame stack: #{expected_frame.inspect}"
|
70
|
+
end
|
71
|
+
|
58
72
|
def note_children_time(frame, time, deduct_call_time_from_parent)
|
59
73
|
if !@stack.empty?
|
60
74
|
if deduct_call_time_from_parent
|
@@ -317,10 +317,6 @@ module NewRelic
|
|
317
317
|
@frozen_name ? true : false
|
318
318
|
end
|
319
319
|
|
320
|
-
def ignored?
|
321
|
-
@ignore_this_transaction
|
322
|
-
end
|
323
|
-
|
324
320
|
# Indicate that we are entering a measured controller action or task.
|
325
321
|
# Make sure you unwind every push with a pop call.
|
326
322
|
def start(state)
|
@@ -40,7 +40,7 @@ module NewRelic
|
|
40
40
|
if backtrace && !Agent.config[:disable_backtrace_cleanup]
|
41
41
|
# this is for 1.9.1, where strings no longer have Enumerable
|
42
42
|
backtrace = backtrace.split("\n") if String === backtrace
|
43
|
-
backtrace = backtrace.map
|
43
|
+
backtrace = backtrace.map(&:to_s)
|
44
44
|
backtrace = backtrace.reject do |line|
|
45
45
|
line.include?(NewRelic::Control.newrelic_root) or
|
46
46
|
line =~ /^newrelic_rpm\s/
|
@@ -55,7 +55,7 @@ module NewRelic
|
|
55
55
|
|
56
56
|
# Convert any kind of object to a short string.
|
57
57
|
def flatten(object)
|
58
|
-
|
58
|
+
case object
|
59
59
|
when nil then ''
|
60
60
|
when object.instance_of?(String) then object
|
61
61
|
when String then String.new(object) # convert string subclasses to strings
|
@@ -98,6 +98,9 @@ module NewRelic
|
|
98
98
|
require 'new_relic/rack/developer_mode'
|
99
99
|
rails_config.middleware.use NewRelic::Rack::DeveloperMode
|
100
100
|
::NewRelic::Agent.logger.info("New Relic Agent Developer Mode enabled.")
|
101
|
+
if env == "production"
|
102
|
+
::NewRelic::Agent.logger.warn("***New Relic Developer Mode is not intended to be enabled in production environments! We highly recommend setting developer_mode: false for the production environment in your newrelic.yml.")
|
103
|
+
end
|
101
104
|
rescue => e
|
102
105
|
::NewRelic::Agent.logger.warn("Error installing New Relic Developer Mode", e)
|
103
106
|
end
|
@@ -27,8 +27,12 @@ module NewRelic
|
|
27
27
|
# if the agent is not running.
|
28
28
|
def install_shim
|
29
29
|
# Once we install instrumentation, you can't undo that by installing the shim.
|
30
|
-
|
31
|
-
|
30
|
+
if @instrumented
|
31
|
+
NewRelic::Agent.logger.error "Cannot install the Agent shim after instrumentation has already been installed!"
|
32
|
+
NewRelic::Agent.logger.error caller.join("\n")
|
33
|
+
else
|
34
|
+
NewRelic::Agent.agent = NewRelic::Agent::ShimAgent.instance
|
35
|
+
end
|
32
36
|
end
|
33
37
|
|
34
38
|
# Add instrumentation. Don't call this directly. Use NewRelic::Agent#add_instrumentation.
|
@@ -4,16 +4,14 @@
|
|
4
4
|
|
5
5
|
module NewRelic
|
6
6
|
class JSONWrapper
|
7
|
-
def self.
|
8
|
-
return false unless NewRelic::LanguageSupport.stdlib_json_usable?
|
9
|
-
|
7
|
+
def self.load_native_json
|
10
8
|
begin
|
11
|
-
require 'json'
|
9
|
+
require 'json' unless defined?(::JSON)
|
12
10
|
@load_method = ::JSON.method(:load)
|
13
11
|
@dump_method = ::JSON.method(:dump)
|
14
12
|
@backend_name = :json
|
15
13
|
return true
|
16
|
-
rescue
|
14
|
+
rescue StandardError, ScriptError
|
17
15
|
NewRelic::Agent.logger.debug "%p while loading JSON library: %s" % [ err, err.message ] if
|
18
16
|
defined?( NewRelic::Agent ) && NewRelic::Agent.respond_to?( :logger )
|
19
17
|
end
|
@@ -26,38 +24,62 @@ module NewRelic
|
|
26
24
|
@backend_name = :okjson
|
27
25
|
end
|
28
26
|
|
29
|
-
|
27
|
+
load_native_json or load_okjson
|
30
28
|
|
31
29
|
def self.usable_for_collector_serialization?
|
32
30
|
@backend_name == :json
|
33
31
|
end
|
34
32
|
|
33
|
+
def self.backend_name
|
34
|
+
@backend_name
|
35
|
+
end
|
36
|
+
|
35
37
|
def self.normalize_string(s)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
return s unless supports_normalization?
|
38
|
+
choose_normalizer unless @normalizer
|
39
|
+
@normalizer.normalize(s)
|
40
|
+
end
|
40
41
|
|
41
|
-
|
42
|
-
if
|
43
|
-
|
42
|
+
def self.choose_normalizer
|
43
|
+
if NewRelic::LanguageSupport.supports_string_encodings?
|
44
|
+
@normalizer = EncodingNormalizer
|
45
|
+
else
|
46
|
+
@normalizer = IconvNormalizer
|
44
47
|
end
|
48
|
+
end
|
45
49
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
#
|
54
|
-
|
55
|
-
|
56
|
-
|
50
|
+
class EncodingNormalizer
|
51
|
+
def self.normalize(s)
|
52
|
+
encoding = s.encoding
|
53
|
+
if (encoding == Encoding::UTF_8 || encoding == Encoding::ISO_8859_1) && s.valid_encoding?
|
54
|
+
return s
|
55
|
+
end
|
56
|
+
|
57
|
+
# If the encoding is not valid, or it's ASCII-8BIT, we know conversion to
|
58
|
+
# UTF-8 is likely to fail, so treat it as ISO-8859-1 (byte-preserving).
|
59
|
+
normalized = s.dup
|
60
|
+
if encoding == Encoding::ASCII_8BIT || !s.valid_encoding?
|
57
61
|
normalized.force_encoding(Encoding::ISO_8859_1)
|
62
|
+
else
|
63
|
+
# Encoding is valid and non-binary, so it might be cleanly convertible
|
64
|
+
# to UTF-8. Give it a try and fall back to ISO-8859-1 if it fails.
|
65
|
+
begin
|
66
|
+
normalized.encode!(Encoding::UTF_8)
|
67
|
+
rescue
|
68
|
+
normalized.force_encoding(Encoding::ISO_8859_1)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
normalized
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class IconvNormalizer
|
76
|
+
def self.normalize(s)
|
77
|
+
if @iconv.nil?
|
78
|
+
require 'iconv'
|
79
|
+
@iconv = Iconv.new('utf-8', 'iso-8859-1')
|
58
80
|
end
|
81
|
+
@iconv.iconv(s)
|
59
82
|
end
|
60
|
-
normalized
|
61
83
|
end
|
62
84
|
|
63
85
|
def self.normalize(object)
|
@@ -30,8 +30,8 @@ EOS
|
|
30
30
|
|
31
31
|
current_item = nil
|
32
32
|
latest.each do |line|
|
33
|
-
if line.match
|
34
|
-
if line.match
|
33
|
+
if line.match(/^\s*\*.*/)
|
34
|
+
if line.match(/\(#{patch_level}\)/)
|
35
35
|
# Found a patch level item, so start tracking the lines!
|
36
36
|
current_item = line
|
37
37
|
else
|
@@ -105,7 +105,7 @@ module NewRelic
|
|
105
105
|
@obfuscated_sql = @segment.obfuscated_sql
|
106
106
|
end
|
107
107
|
|
108
|
-
|
108
|
+
_headers, explanations = @segment.explain_sql
|
109
109
|
if explanations
|
110
110
|
@explanation = explanations
|
111
111
|
if !@explanation.blank?
|
@@ -138,12 +138,13 @@ module NewRelic
|
|
138
138
|
if view.is_a? Hash
|
139
139
|
layout = false
|
140
140
|
if view[:object]
|
141
|
+
# object *is* used here, as it is capture in the binding below
|
141
142
|
object = view[:object]
|
142
143
|
end
|
143
144
|
|
144
145
|
if view[:collection]
|
145
|
-
return view[:collection].map do |
|
146
|
-
render({:partial => view[:partial], :object =>
|
146
|
+
return view[:collection].map do |obj|
|
147
|
+
render({:partial => view[:partial], :object => obj})
|
147
148
|
end.join(' ')
|
148
149
|
end
|
149
150
|
|