newrelic_rpm 3.6.5.130 → 3.6.6.147
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 +27 -3
- data/Gemfile +1 -14
- data/Rakefile +15 -5
- data/config.dot +1 -1
- data/lib/new_relic/agent/agent.rb +15 -0
- data/lib/new_relic/agent/agent_logger.rb +19 -14
- data/lib/new_relic/agent/configuration/defaults.rb +4 -3
- data/lib/new_relic/agent/configuration/environment_source.rb +6 -4
- data/lib/new_relic/agent/configuration/manager.rb +7 -2
- data/lib/new_relic/agent/configuration/mask_defaults.rb +1 -2
- data/lib/new_relic/agent/cross_app_monitor.rb +5 -4
- data/lib/new_relic/agent/cross_app_tracing.rb +0 -1
- data/lib/new_relic/agent/error_collector.rb +30 -1
- data/lib/new_relic/agent/http_clients/curb_wrappers.rb +67 -0
- data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +59 -0
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +12 -0
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +3 -3
- data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +3 -3
- data/lib/new_relic/agent/instrumentation/authlogic.rb +3 -3
- data/lib/new_relic/agent/instrumentation/curb.rb +179 -0
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +3 -3
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +35 -26
- data/lib/new_relic/agent/instrumentation/httpclient.rb +46 -0
- data/lib/new_relic/agent/instrumentation/merb/controller.rb +3 -3
- data/lib/new_relic/agent/instrumentation/puma.rb +23 -0
- data/lib/new_relic/agent/instrumentation/rack.rb +40 -0
- data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +4 -4
- data/lib/new_relic/agent/instrumentation/rails/errors.rb +0 -1
- data/lib/new_relic/agent/instrumentation/sequel.rb +0 -1
- data/lib/new_relic/agent/instrumentation/sunspot.rb +1 -1
- data/lib/new_relic/agent/internal_agent_error.rb +18 -0
- data/lib/new_relic/agent/new_relic_service.rb +2 -8
- data/lib/new_relic/agent/request_sampler.rb +4 -6
- data/lib/new_relic/agent/samplers/cpu_sampler.rb +0 -1
- data/lib/new_relic/agent/stats.rb +9 -0
- data/lib/new_relic/agent/stats_engine/stats_hash.rb +44 -6
- data/lib/new_relic/agent/system_info.rb +1 -1
- data/lib/new_relic/agent/thread_profiler.rb +6 -6
- data/lib/new_relic/agent/transaction.rb +1 -1
- data/lib/new_relic/agent/transaction_info.rb +0 -1
- data/lib/new_relic/agent/transaction_sample_builder.rb +6 -5
- data/lib/new_relic/agent/transaction_sampler.rb +1 -1
- data/lib/new_relic/commands/deployments.rb +6 -0
- data/lib/new_relic/commands/install.rb +2 -2
- data/lib/new_relic/control/frameworks/rails.rb +1 -2
- data/lib/new_relic/control/instrumentation.rb +2 -2
- data/lib/new_relic/control/server_methods.rb +1 -2
- data/lib/new_relic/delayed_job_injection.rb +0 -40
- data/lib/new_relic/helper.rb +0 -1
- data/lib/new_relic/latest_changes.rb +1 -1
- data/lib/new_relic/local_environment.rb +9 -4
- data/lib/new_relic/metric_spec.rb +19 -3
- data/lib/new_relic/noticed_error.rb +2 -1
- data/lib/new_relic/rack/agent_hooks.rb +0 -1
- data/lib/new_relic/rack/developer_mode.rb +1 -1
- data/lib/new_relic/rack/error_collector.rb +42 -21
- data/lib/new_relic/recipes.rb +0 -1
- data/lib/new_relic/transaction_analysis.rb +0 -1
- data/lib/new_relic/transaction_sample/segment.rb +4 -4
- data/lib/new_relic/version.rb +1 -1
- data/lib/sequel/extensions/newrelic_instrumentation.rb +6 -7
- data/lib/sequel/plugins/newrelic_instrumentation.rb +0 -1
- data/lib/tasks/install.rake +2 -2
- data/newrelic_rpm.gemspec +11 -1
- data/test/active_record_fixtures.rb +2 -2
- data/test/agent_helper.rb +46 -3
- data/test/config/newrelic.yml +2 -2
- data/test/multiverse/.gitignore +2 -0
- data/test/multiverse/lib/multiverse/envfile.rb +6 -9
- data/test/multiverse/lib/multiverse/environment.rb +0 -1
- data/test/multiverse/lib/multiverse/output_collector.rb +43 -11
- data/test/multiverse/lib/multiverse/runner.rb +37 -5
- data/test/multiverse/lib/multiverse/suite.rb +149 -67
- data/test/multiverse/script/run_one +4 -2
- data/test/multiverse/script/runner +1 -5
- data/test/multiverse/suites/active_record/Envfile +3 -2
- data/test/multiverse/suites/active_record/ar_method_aliasing.rb +13 -12
- data/test/multiverse/suites/active_record/config/newrelic.yml +0 -3
- data/test/multiverse/suites/agent_only/audit_log_test.rb +30 -34
- data/test/multiverse/suites/agent_only/before_suite.rb +7 -0
- data/test/multiverse/suites/agent_only/config/newrelic.yml +1 -7
- data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +12 -20
- data/test/multiverse/suites/agent_only/http_response_code_test.rb +16 -34
- data/test/multiverse/suites/agent_only/key_transactions_test.rb +18 -28
- data/test/multiverse/suites/agent_only/logging_test.rb +25 -49
- data/test/multiverse/suites/agent_only/marshaling_test.rb +30 -38
- data/test/multiverse/suites/agent_only/pipe_manager_test.rb +12 -6
- data/test/multiverse/suites/agent_only/rename_rule_test.rb +30 -38
- data/test/multiverse/suites/agent_only/rum_instrumentation_test.rb +16 -18
- data/test/multiverse/suites/agent_only/service_timeout_test.rb +6 -7
- data/test/multiverse/suites/agent_only/set_transaction_name_test.rb +26 -32
- data/test/multiverse/suites/agent_only/ssl_test.rb +10 -14
- data/test/multiverse/suites/agent_only/start_up_test.rb +1 -1
- data/test/multiverse/suites/agent_only/testing_app.rb +2 -0
- data/test/multiverse/suites/agent_only/thread_profiling_test.rb +23 -24
- data/test/multiverse/suites/config_file_loading/Envfile +6 -2
- data/test/multiverse/suites/config_file_loading/config_file_loading_test.rb +8 -4
- data/test/multiverse/suites/curb/Envfile +19 -0
- data/test/multiverse/suites/curb/config/newrelic.yml +19 -0
- data/test/multiverse/suites/curb/curb_test.rb +195 -0
- data/test/multiverse/suites/datamapper/Envfile +2 -0
- data/test/multiverse/suites/datamapper/config/newrelic.yml +0 -2
- data/test/multiverse/suites/datamapper/datamapper_test.rb +6 -10
- data/test/multiverse/suites/deferred_instrumentation/Envfile +19 -0
- data/test/multiverse/suites/deferred_instrumentation/config/newrelic.yml +22 -0
- data/test/multiverse/suites/deferred_instrumentation/sinatra_test.rb +103 -0
- data/test/multiverse/suites/excon/config/newrelic.yml +0 -2
- data/test/multiverse/suites/excon/excon_test.rb +3 -3
- data/test/multiverse/suites/httpclient/Envfile +15 -0
- data/test/multiverse/suites/httpclient/config/newrelic.yml +19 -0
- data/test/multiverse/suites/httpclient/httpclient_test.rb +70 -0
- data/test/multiverse/suites/net_http/config/newrelic.yml +0 -2
- data/test/multiverse/suites/net_http/net_http_test.rb +9 -4
- data/test/multiverse/suites/padrino/Envfile +2 -0
- data/test/multiverse/suites/padrino/config/newrelic.yml +0 -3
- data/test/multiverse/suites/padrino/padrino_test.rb +5 -4
- data/test/multiverse/suites/rails/Envfile +3 -0
- data/test/multiverse/suites/rails/app.rb +1 -0
- data/test/multiverse/suites/rails/bad_instrumentation_test.rb +31 -0
- data/test/multiverse/suites/rails/config/newrelic.yml +2 -3
- data/test/multiverse/suites/rails/error_tracing_test.rb +32 -41
- data/test/multiverse/suites/rails/gc_instrumentation_test.rb +6 -16
- data/test/multiverse/suites/rails/queue_time_test.rb +4 -20
- data/test/multiverse/suites/rails/request_statistics_test.rb +7 -32
- data/test/multiverse/suites/rails/view_instrumentation_test.rb +6 -10
- data/test/multiverse/suites/resque/config/newrelic.yml +1 -3
- data/test/multiverse/suites/resque/instrumentation_test.rb +10 -7
- data/test/multiverse/suites/sequel/Envfile +8 -0
- data/test/multiverse/suites/sequel/config/newrelic.yml +0 -3
- data/test/multiverse/suites/sequel/sequel_test.rb +1 -2
- data/test/multiverse/suites/sidekiq/Envfile +0 -12
- data/test/multiverse/suites/sidekiq/config/newrelic.yml +1 -3
- data/test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb +44 -100
- data/test/multiverse/suites/sinatra/config/newrelic.yml +0 -3
- data/test/multiverse/suites/sinatra/ignoring_test.rb +8 -5
- data/test/multiverse/suites/sinatra/sinatra_classic_test.rb +8 -1
- data/test/multiverse/suites/sinatra/sinatra_error_tracing_test.rb +9 -12
- data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +9 -8
- data/test/multiverse/suites/sinatra/sinatra_modular_test.rb +1 -1
- data/test/multiverse/suites/sinatra/sinatra_routes_test.rb +6 -5
- data/test/multiverse/suites/sinatra/sinatra_test_cases.rb +10 -13
- data/test/multiverse/suites/typhoeus/config/newrelic.yml +0 -2
- data/test/multiverse/suites/typhoeus/typhoeus_test.rb +7 -4
- data/test/multiverse/test/suite_examples/one/a/a_test.rb +0 -1
- data/test/multiverse/test/suite_examples/one/a/config/newrelic.yml +0 -1
- data/test/multiverse/test/suite_examples/one/b/b_test.rb +0 -1
- data/test/multiverse/test/suite_examples/one/b/config/newrelic.yml +0 -1
- data/test/new_relic/agent/agent/connect_test.rb +1 -1
- data/test/new_relic/agent/agent/start_test.rb +0 -1
- data/test/new_relic/agent/agent/start_worker_thread_test.rb +0 -1
- data/test/new_relic/agent/agent_logger_test.rb +37 -3
- data/test/new_relic/agent/agent_test.rb +23 -1
- data/test/new_relic/agent/browser_monitoring_test.rb +0 -1
- data/test/new_relic/agent/busy_calculator_test.rb +2 -2
- data/test/new_relic/agent/configuration/environment_source_test.rb +22 -0
- data/test/new_relic/agent/error_collector/notice_error_test.rb +1 -1
- data/test/new_relic/agent/error_collector_test.rb +95 -13
- data/test/new_relic/agent/event_listener_test.rb +0 -1
- data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +23 -0
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +4 -2
- data/test/new_relic/agent/instrumentation/instrumentation_test.rb +0 -1
- data/test/new_relic/agent/instrumentation/queue_time_test.rb +16 -11
- data/test/new_relic/agent/instrumentation/rack_test.rb +0 -1
- data/test/new_relic/agent/memcache_instrumentation_test.rb +7 -7
- data/test/{multiverse/suites/agent_only/test_trace_method_with_punctuation.rb → new_relic/agent/method_interrobang_test.rb} +3 -5
- data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +1 -2
- data/test/{multiverse/suites/agent_only → new_relic/agent}/method_visibility_test.rb +17 -29
- data/test/new_relic/agent/new_relic_service_test.rb +1 -1
- data/test/new_relic/agent/pipe_service_test.rb +1 -1
- data/test/new_relic/agent/request_sampler_test.rb +10 -10
- data/test/new_relic/agent/rpm_agent_test.rb +1 -2
- data/test/new_relic/agent/stats_hash_test.rb +83 -5
- data/test/new_relic/agent/stats_test.rb +0 -1
- data/test/new_relic/agent/thread_profiler_test.rb +7 -7
- data/test/new_relic/agent/threaded_test.rb +1 -2
- data/test/new_relic/agent/transaction/pop_test.rb +0 -1
- data/test/{multiverse/suites/agent_only/test_trace_transaction_with_punctuation.rb → new_relic/agent/transaction_interrobang_test.rb} +2 -4
- data/test/new_relic/agent/transaction_sample_builder_test.rb +13 -0
- data/test/new_relic/agent/transaction_test.rb +7 -5
- data/test/new_relic/agent/worker_loop_test.rb +0 -1
- data/test/new_relic/agent_test.rb +0 -27
- data/test/new_relic/collection_helper_test.rb +17 -17
- data/test/new_relic/control/class_methods_test.rb +1 -1
- data/test/new_relic/control_test.rb +6 -6
- data/test/new_relic/dependency_detection_test.rb +28 -0
- data/test/new_relic/evil_server.rb +0 -1
- data/test/new_relic/fake_collector.rb +20 -2
- data/test/new_relic/fake_server.rb +0 -12
- data/test/new_relic/http_client_test_cases.rb +20 -24
- data/test/new_relic/metric_spec_test.rb +18 -0
- data/test/new_relic/multiverse_helpers.rb +164 -0
- data/test/new_relic/rack/agent_hooks_test.rb +0 -1
- data/test/new_relic/rack/all_test.rb +0 -1
- data/test/new_relic/rack/deferred_instrumentation_test.rb +35 -0
- data/test/new_relic/rack/developer_mode_helper_test.rb +8 -9
- data/test/new_relic/rack/developer_mode_test.rb +0 -2
- data/test/new_relic/rack/error_collector_test.rb +52 -8
- data/test/new_relic/transaction_sample/composite_segment_test.rb +0 -1
- data/test/new_relic/transaction_sample/fake_segment_test.rb +0 -1
- data/test/new_relic/transaction_sample/segment_test.rb +0 -1
- data/test/new_relic/transaction_sample/summary_segment_test.rb +0 -1
- data/test/performance/README.md +162 -0
- data/test/performance/lib/performance.rb +28 -0
- data/test/performance/lib/performance/console_reporter.rb +51 -0
- data/test/performance/lib/performance/hako_client.rb +31 -0
- data/test/performance/lib/performance/hako_reporter.rb +26 -0
- data/test/performance/lib/performance/instrumentation/cpu_usage.rb +26 -0
- data/test/performance/lib/performance/instrumentation/gc_stats.rb +53 -0
- data/test/performance/lib/performance/instrumentation/perf_tools.rb +30 -0
- data/test/performance/lib/performance/instrumentor.rb +110 -0
- data/test/performance/lib/performance/json_reporter.rb +15 -0
- data/test/performance/lib/performance/result.rb +80 -0
- data/test/performance/lib/performance/runner.rb +207 -0
- data/test/performance/lib/performance/test_case.rb +65 -0
- data/test/performance/lib/performance/timer.rb +38 -0
- data/test/performance/script/mega-runner +37 -0
- data/test/performance/script/runner +81 -0
- data/test/performance/suites/startup.rb +12 -0
- data/test/performance/suites/transaction_tracing.rb +66 -0
- data/test/script/ci_agent-tests_runner.sh +4 -4
- data/test/script/ci_multiverse_runner.sh +3 -3
- data/test/test_helper.rb +0 -11
- data/ui/helpers/developer_mode_helper.rb +1 -1
- data/ui/views/layouts/newrelic_default.rhtml +1 -1
- data/ui/views/newrelic/_segment.rhtml +2 -2
- data/ui/views/newrelic/_segment_limit_message.rhtml +1 -1
- data/ui/views/newrelic/_show_sample_detail.rhtml +1 -1
- data/ui/views/newrelic/_show_sample_sql.rhtml +4 -4
- data/ui/views/newrelic/_stack_trace.rhtml +2 -2
- data/ui/views/newrelic/file/javascript/transaction_sample.js +3 -3
- data/ui/views/newrelic/file/stylesheets/style.css +13 -13
- data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +18 -4
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/metric_parser.rb +0 -1
- metadata +186 -17
- metadata.gz.sig +0 -0
- data/test/multiverse/suites/active_record/encoding_test.rb +0 -30
- data/test/multiverse/suites/agent_only/no_dns_resolv.rb +0 -21
- data/test/multiverse/suites/sidekiq/app.rb +0 -25
- data/test/new_relic/delayed_job_injection_test.rb +0 -25
@@ -0,0 +1,28 @@
|
|
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 'logger'
|
6
|
+
|
7
|
+
$: << File.expand_path(File.dirname(__FILE__))
|
8
|
+
|
9
|
+
require 'performance/result'
|
10
|
+
require 'performance/runner'
|
11
|
+
require 'performance/test_case'
|
12
|
+
require 'performance/timer'
|
13
|
+
require 'performance/instrumentor'
|
14
|
+
require 'performance/console_reporter'
|
15
|
+
require 'performance/json_reporter'
|
16
|
+
require 'performance/hako_client'
|
17
|
+
require 'performance/hako_reporter'
|
18
|
+
|
19
|
+
module Performance
|
20
|
+
def self.logger
|
21
|
+
log_path = ENV['LOG'] || $stderr
|
22
|
+
@logger ||= Logger.new(log_path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.log_path=(path)
|
26
|
+
@logger = Logger.new(path)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,51 @@
|
|
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 Performance
|
6
|
+
class ConsoleReporter
|
7
|
+
def initialize(results, elapsed, options={})
|
8
|
+
@results = results
|
9
|
+
@elapsed = elapsed
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def report
|
14
|
+
failures = @results.select { |result| result.failure? }
|
15
|
+
successes = @results - failures
|
16
|
+
puts "#{@results.size} tests, #{failures.size} failures, #{@elapsed} s total"
|
17
|
+
report_successful_results(successes) if successes.any?
|
18
|
+
report_failed_results(failures) if failures.any?
|
19
|
+
end
|
20
|
+
|
21
|
+
def report_successful_results(results)
|
22
|
+
puts ''
|
23
|
+
results.each do |result|
|
24
|
+
puts "#{result.identifier}: #{result.elapsed} s"
|
25
|
+
unless @options[:brief]
|
26
|
+
result.measurements.each do |key, value|
|
27
|
+
puts " #{key}: #{value}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
unless result.artifacts.empty?
|
31
|
+
puts " artifacts:"
|
32
|
+
result.artifacts.each do |artifact|
|
33
|
+
puts " #{artifact}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
puts '' if !@options[:brief] || !result.artifacts.empty?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def report_failed_results(results)
|
41
|
+
puts ''
|
42
|
+
results.each do |failure|
|
43
|
+
puts "FAILED: #{failure.identifier}"
|
44
|
+
e = failure.exception
|
45
|
+
puts "#{e['class']}: #{e['message']}"
|
46
|
+
puts failure.exception['backtrace'].map { |l| " #{l}" }.join("\n")
|
47
|
+
end
|
48
|
+
puts ''
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,31 @@
|
|
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 'json'
|
6
|
+
require 'net/http'
|
7
|
+
require 'uri'
|
8
|
+
|
9
|
+
module Performance
|
10
|
+
class HakoClient
|
11
|
+
BASE_URI = 'http://hako.pdx.vm.datanerd.us'
|
12
|
+
|
13
|
+
def initialize(token)
|
14
|
+
@token = token
|
15
|
+
end
|
16
|
+
|
17
|
+
def submit(result)
|
18
|
+
body = JSON.dump('result' => result.to_h)
|
19
|
+
|
20
|
+
uri = URI(BASE_URI + "/api/results")
|
21
|
+
req = Net::HTTP::Post.new(uri.to_s)
|
22
|
+
req.body = body
|
23
|
+
req.content_type = 'application/json'
|
24
|
+
req['Authorization'] = "Token token=\"#{@token}\""
|
25
|
+
|
26
|
+
Net::HTTP.start(uri.host, uri.port) do |conn|
|
27
|
+
conn.request(req)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
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 Performance
|
6
|
+
class HakoReporter
|
7
|
+
def initialize(results, elapsed, options={})
|
8
|
+
@results = results
|
9
|
+
@token = ENV['HAKO_TOKEN'] || options[:hako_token]
|
10
|
+
end
|
11
|
+
|
12
|
+
def report
|
13
|
+
Performance.logger.info("Uploading #{@results.size} results to Hako")
|
14
|
+
client = HakoClient.new(@token)
|
15
|
+
@results.each do |result|
|
16
|
+
rsp = client.submit(result)
|
17
|
+
case rsp
|
18
|
+
when Net::HTTPSuccess
|
19
|
+
Performance.logger.debug("Successfully posted result to Hako")
|
20
|
+
else
|
21
|
+
Performance.logger.error("Failed to post results to Hako: #{rsp.inspect}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
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 Performance
|
6
|
+
module Instrumentation
|
7
|
+
class CpuUsage < Instrumentor
|
8
|
+
on_by_default
|
9
|
+
|
10
|
+
def before(*)
|
11
|
+
@times_before = Process.times
|
12
|
+
end
|
13
|
+
|
14
|
+
def after(*)
|
15
|
+
@times_after = Process.times
|
16
|
+
end
|
17
|
+
|
18
|
+
def results
|
19
|
+
{
|
20
|
+
:cpu_time_user => @times_after.utime - @times_before.utime,
|
21
|
+
:cpu_time_system => @times_after.stime - @times_before.stime
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,53 @@
|
|
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 Performance
|
6
|
+
module Instrumentation
|
7
|
+
class MRIGCStats < Instrumentor
|
8
|
+
platforms :mri_193, :mri_20
|
9
|
+
on_by_default
|
10
|
+
|
11
|
+
def before(*)
|
12
|
+
@stats_before = GC.stat
|
13
|
+
end
|
14
|
+
|
15
|
+
def after(*)
|
16
|
+
@stats_after = GC.stat
|
17
|
+
end
|
18
|
+
|
19
|
+
def results
|
20
|
+
res = {
|
21
|
+
:gc_runs => @stats_after[:count] - @stats_before[:count],
|
22
|
+
:live_objects => @stats_after[:heap_live_num] - @stats_before[:heap_live_num]
|
23
|
+
}
|
24
|
+
if RUBY_VERSION >= "2.0.0"
|
25
|
+
res[:allocations] = @stats_after[:total_allocated_object] - @stats_before[:total_allocated_object]
|
26
|
+
end
|
27
|
+
res
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class REEGCStats < Instrumentor
|
32
|
+
platforms :ree
|
33
|
+
on_by_default
|
34
|
+
|
35
|
+
def before(*)
|
36
|
+
@allocations_before = ObjectSpace.allocated_objects
|
37
|
+
@live_objects_before = ObjectSpace.live_objects
|
38
|
+
end
|
39
|
+
|
40
|
+
def after(*)
|
41
|
+
@allocations_after = ObjectSpace.allocated_objects
|
42
|
+
@live_objects_after = ObjectSpace.live_objects
|
43
|
+
end
|
44
|
+
|
45
|
+
def results
|
46
|
+
{
|
47
|
+
:allocations => @allocations_after - @allocations_before,
|
48
|
+
:live_objects => @live_objects_after - @live_objects_before,
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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 Performance
|
6
|
+
module Instrumentation
|
7
|
+
class PerfToolsProfile < Instrumentor
|
8
|
+
platforms :mri_19, :mri_20
|
9
|
+
|
10
|
+
def self.setup
|
11
|
+
require 'tmpdir'
|
12
|
+
require 'perftools'
|
13
|
+
end
|
14
|
+
|
15
|
+
def before(test, test_name)
|
16
|
+
@profile_dir = Dir.mktmpdir('profile')
|
17
|
+
@profile_path = File.join(@profile_dir, "profile")
|
18
|
+
PerfTools::CpuProfiler.start(@profile_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def after(test, test_name)
|
22
|
+
PerfTools::CpuProfiler.stop
|
23
|
+
output_profile_path = artifact_path(test, test_name, "dot")
|
24
|
+
system("pprof.rb --dot #{@profile_path} >#{output_profile_path}")
|
25
|
+
@artifacts << output_profile_path
|
26
|
+
FileUtils.remove_entry_secure(@profile_dir)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,110 @@
|
|
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 Performance
|
6
|
+
module Instrumentation
|
7
|
+
def self.current_platform_matches?(p)
|
8
|
+
is_jruby = defined?(JRUBY_VERSION)
|
9
|
+
is_ree = defined?(RUBY_DESCRIPTION) && RUBY_DESCRIPTION =~ /MBARI/
|
10
|
+
case p
|
11
|
+
when :jruby then is_jruby
|
12
|
+
when :mri then !is_jruby
|
13
|
+
when :ree then !is_jruby && is_ree
|
14
|
+
when :mri_18 then !is_jruby && RUBY_VERSION =~ /^1\.8\./
|
15
|
+
when :mri_19 then !is_jruby && RUBY_VERSION =~ /^1\.9\./
|
16
|
+
when :mri_193 then !is_jruby && RUBY_VERSION =~ /^1\.9\.3/
|
17
|
+
when :mri_20 then !is_jruby && RUBY_VERSION =~ /^2\.0\./
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.load_instrumentors
|
22
|
+
dir = File.expand_path(File.join(File.dirname(__FILE__), 'instrumentation'))
|
23
|
+
Dir.glob(File.join(dir, "*.rb")).each do |filename|
|
24
|
+
require filename
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.default_instrumentors
|
29
|
+
Instrumentor.subclasses.select do |cls|
|
30
|
+
cls.on_by_default? && cls.supported?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.instrumentor_class_by_name(name)
|
35
|
+
begin
|
36
|
+
cls = self.const_get(name)
|
37
|
+
if cls.supported?
|
38
|
+
cls
|
39
|
+
else
|
40
|
+
Performance.logger.warn("Instrumentor '#{name}' is unsupported on this platform")
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
rescue NameError => e
|
44
|
+
Performance.logger.error("Failed to load instrumentor '#{name}': #{e.inspect}")
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class Instrumentor
|
50
|
+
def self.inherited(cls)
|
51
|
+
@subclasses ||= []
|
52
|
+
@subclasses << cls
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.subclasses
|
56
|
+
@subclasses || []
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.platforms(*args)
|
60
|
+
@supported_platforms = args
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.supported?
|
64
|
+
(
|
65
|
+
@supported_platforms.nil? ||
|
66
|
+
@supported_platforms.any? { |p| Instrumentation.current_platform_matches?(p) }
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.on_by_default
|
71
|
+
@on_by_default = true
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.on_by_default?
|
75
|
+
@on_by_default
|
76
|
+
end
|
77
|
+
|
78
|
+
attr_reader :artifacts
|
79
|
+
|
80
|
+
def initialize(artifacts_dir)
|
81
|
+
@artifacts_dir = artifacts_dir
|
82
|
+
reset
|
83
|
+
end
|
84
|
+
|
85
|
+
def reset
|
86
|
+
@artifacts = []
|
87
|
+
end
|
88
|
+
|
89
|
+
def pretty_name
|
90
|
+
self.class.name.split("::").last
|
91
|
+
end
|
92
|
+
|
93
|
+
def artifacts_dir_for(test_case, test_name)
|
94
|
+
path = File.join(@artifacts_dir, test_case.class.name, test_name)
|
95
|
+
FileUtils.mkdir_p(path)
|
96
|
+
path
|
97
|
+
end
|
98
|
+
|
99
|
+
def artifact_path(test_case, test_name, extension)
|
100
|
+
File.join(artifacts_dir_for(test_case, test_name), "#{pretty_name}.#{extension}")
|
101
|
+
end
|
102
|
+
|
103
|
+
def before(*); end
|
104
|
+
def after(*); end
|
105
|
+
def results; {}; end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
Performance::Instrumentation.load_instrumentors
|
@@ -0,0 +1,15 @@
|
|
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 Performance
|
6
|
+
class JSONReporter
|
7
|
+
def initialize(results, elapsed, options={})
|
8
|
+
@results = results
|
9
|
+
end
|
10
|
+
|
11
|
+
def report
|
12
|
+
puts JSON.dump(@results.map { |result| result.to_h })
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,80 @@
|
|
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 Performance
|
6
|
+
class Result
|
7
|
+
attr_reader :test_name, :measurements, :tags, :timer, :artifacts
|
8
|
+
attr_accessor :exception
|
9
|
+
|
10
|
+
def initialize(test_case, test_name)
|
11
|
+
@test_case = test_case
|
12
|
+
@test_name = test_name
|
13
|
+
@measurements = {}
|
14
|
+
@tags = {}
|
15
|
+
@timer = Timer.new
|
16
|
+
@artifacts = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def exception=(e)
|
20
|
+
if e.is_a?(Exception)
|
21
|
+
@exception = {
|
22
|
+
'class' => e.class.name,
|
23
|
+
'message' => e.message,
|
24
|
+
'backtrace' => e.backtrace
|
25
|
+
}
|
26
|
+
else
|
27
|
+
@exception = e
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def elapsed=(elapsed)
|
32
|
+
@elapsed = elapsed
|
33
|
+
end
|
34
|
+
|
35
|
+
def elapsed
|
36
|
+
@elapsed || @timer.elapsed
|
37
|
+
end
|
38
|
+
|
39
|
+
def failure?
|
40
|
+
elapsed.nil? || !@exception.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
def suite_name
|
44
|
+
@test_case.is_a?(String) ? @test_case : @test_case.name
|
45
|
+
end
|
46
|
+
|
47
|
+
def identifier
|
48
|
+
"#{suite_name}##{@test_name}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def measurements_hash
|
52
|
+
@measurements.merge(:elapsed => elapsed)
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_h
|
56
|
+
{
|
57
|
+
"suite" => suite_name,
|
58
|
+
"name" => @test_name,
|
59
|
+
"measurements" => measurements_hash,
|
60
|
+
"tags" => @tags,
|
61
|
+
"exception" => @exception,
|
62
|
+
"artifacts" => @artifacts
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.from_hash(hash)
|
67
|
+
elapsed = hash['measurements'].delete('elapsed')
|
68
|
+
result = self.new(hash['suite'], hash['name'])
|
69
|
+
result.measurements.merge! hash['measurements']
|
70
|
+
result.tags.merge! hash['tags']
|
71
|
+
result.exception = hash['exception']
|
72
|
+
result.elapsed = elapsed
|
73
|
+
result
|
74
|
+
end
|
75
|
+
|
76
|
+
def inspect
|
77
|
+
"<Performance::Result #{identifier}: #{elapsed} s, results=#{@results.inspect}>"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|