newrelic_rpm 3.7.1.188 → 3.7.2.190.beta
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +3 -2
- data/CHANGELOG +1 -1
- data/Guardfile +3 -3
- data/README.md +1 -1
- data/Rakefile +0 -2
- data/init.rb +2 -5
- data/lib/new_relic/agent.rb +3 -0
- data/lib/new_relic/agent/agent.rb +2 -0
- data/lib/new_relic/agent/configuration/default_source.rb +32 -14
- data/lib/new_relic/agent/configuration/environment_source.rb +1 -0
- data/lib/new_relic/agent/cross_app_monitor.rb +2 -2
- data/lib/new_relic/agent/cross_app_tracing.rb +2 -2
- data/lib/new_relic/agent/error_collector.rb +1 -1
- data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +4 -1
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +10 -8
- data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +11 -6
- data/lib/new_relic/agent/javascript_instrumentor.rb +27 -36
- data/lib/new_relic/agent/method_tracer.rb +20 -2
- data/lib/new_relic/agent/new_relic_service.rb +35 -27
- data/lib/new_relic/agent/request_sampler.rb +20 -13
- data/lib/new_relic/agent/sampler_collection.rb +4 -0
- data/lib/new_relic/agent/stats_engine/stats_hash.rb +4 -4
- data/lib/new_relic/agent/system_info.rb +25 -15
- data/lib/new_relic/agent/transaction.rb +23 -4
- data/lib/new_relic/agent/transaction_sampler.rb +1 -1
- data/lib/new_relic/cli/install.rb +1 -1
- data/lib/new_relic/control.rb +1 -0
- data/lib/new_relic/helper.rb +1 -29
- data/lib/new_relic/json_wrapper.rb +92 -0
- data/lib/new_relic/language_support.rb +4 -0
- data/lib/new_relic/rack/agent_hooks.rb +4 -0
- data/lib/new_relic/rack/browser_monitoring.rb +4 -0
- data/lib/new_relic/rack/developer_mode.rb +4 -1
- data/lib/new_relic/rack/error_collector.rb +5 -0
- data/lib/new_relic/rack/transaction_reset.rb +20 -0
- data/lib/new_relic/version.rb +1 -1
- data/lib/tasks/install.rake +0 -1
- data/newrelic_rpm.gemspec +1 -1
- data/test/agent_helper.rb +7 -8
- data/test/environments/norails/Gemfile +2 -1
- data/test/environments/rails21/Gemfile +2 -2
- data/test/environments/rails21/config/environment.rb +1 -3
- data/test/environments/rails21/config/environments/development.rb +0 -6
- data/test/environments/rails22/Gemfile +2 -2
- data/test/environments/rails22/config/environment.rb +0 -2
- data/test/environments/rails22/config/environments/development.rb +0 -6
- data/test/environments/rails23/Gemfile +2 -3
- data/test/environments/rails23/config/environment.rb +0 -9
- data/test/environments/rails23/config/environments/development.rb +0 -5
- data/test/environments/rails30/Gemfile +2 -2
- data/test/environments/rails31/Gemfile +2 -2
- data/test/environments/rails32/Gemfile +2 -1
- data/test/environments/rails40/Gemfile +2 -1
- data/test/intentional_fail.rb +1 -2
- data/test/multiverse/lib/multiverse/envfile.rb +1 -5
- data/test/multiverse/lib/multiverse/suite.rb +10 -27
- data/test/multiverse/suites/active_record/ar_method_aliasing.rb +49 -67
- data/test/multiverse/suites/agent_only/encoding_handling_test.rb +128 -0
- data/test/multiverse/suites/agent_only/marshaling_test.rb +7 -9
- data/test/multiverse/suites/agent_only/script/loading.rb +20 -0
- data/test/multiverse/suites/agent_only/start_up_test.rb +7 -0
- data/test/multiverse/suites/bare/Envfile +3 -0
- data/test/multiverse/suites/bare/standalone_instrumentation_test.rb +43 -0
- data/test/multiverse/suites/rails/Envfile +0 -2
- data/test/multiverse/suites/rails/app/views/views/_a_partial.html.erb +1 -0
- data/test/multiverse/suites/rails/app/views/views/index.html.erb +1 -1
- data/test/multiverse/suites/rails/error_tracing_test.rb +1 -1
- data/test/multiverse/suites/rails/request_statistics_test.rb +9 -4
- data/test/multiverse/suites/rails/view_instrumentation_test.rb +111 -106
- data/test/multiverse/suites/typhoeus/Envfile +1 -1
- data/test/multiverse/suites/typhoeus/typhoeus_test.rb +16 -2
- data/test/multiverse/test/multiverse_test.rb +2 -2
- 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 +3 -7
- data/test/new_relic/agent/agent_test.rb +33 -57
- data/test/new_relic/agent/apdex_from_server_test.rb +1 -1
- data/test/new_relic/agent/audit_logger_test.rb +5 -8
- 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 +2 -4
- data/test/new_relic/agent/commands/agent_command_router_test.rb +5 -5
- data/test/new_relic/agent/commands/agent_command_test.rb +1 -1
- data/test/new_relic/agent/commands/thread_profiler_session_test.rb +6 -6
- data/test/new_relic/agent/commands/xray_session_collection_test.rb +10 -10
- data/test/new_relic/agent/commands/xray_session_test.rb +1 -1
- data/test/new_relic/agent/configuration/default_source_test.rb +4 -4
- data/test/new_relic/agent/configuration/environment_source_test.rb +14 -2
- data/test/new_relic/agent/configuration/manager_test.rb +3 -3
- 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 +2 -2
- 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 +5 -4
- data/test/new_relic/agent/database_test.rb +1 -1
- data/test/new_relic/agent/datastores/mongo/metric_generator_test.rb +1 -1
- data/test/new_relic/agent/datastores/mongo/metric_translator_test.rb +1 -1
- data/test/new_relic/agent/datastores/mongo/obfuscator_test.rb +1 -1
- data/test/new_relic/agent/datastores/mongo/statement_formatter_test.rb +2 -2
- data/test/new_relic/agent/error_collector/notice_error_test.rb +1 -1
- data/test/new_relic/agent/error_collector_test.rb +5 -3
- 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 +1 -1
- data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +495 -495
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +2 -2
- 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 +4 -6
- 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 +7 -7
- data/test/new_relic/agent/javascript_instrumentor_test.rb +47 -55
- 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 +2 -3
- data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +4 -4
- 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 +6 -7
- data/test/new_relic/agent/method_visibility_test.rb +1 -1
- data/test/new_relic/agent/new_relic_service_test.rb +129 -19
- data/test/new_relic/agent/obfuscator_test.rb +1 -1
- data/test/new_relic/agent/pipe_channel_manager_test.rb +143 -145
- data/test/new_relic/agent/pipe_service_test.rb +2 -4
- data/test/new_relic/agent/request_sampler_test.rb +23 -19
- data/test/new_relic/agent/rpm_agent_test.rb +3 -3
- 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 +3 -3
- data/test/new_relic/agent/sampler_test.rb +1 -1
- data/test/new_relic/agent/shim_agent_test.rb +1 -1
- data/test/new_relic/agent/sql_sampler_test.rb +4 -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 +5 -5
- data/test/new_relic/agent/stats_engine/samplers_test.rb +2 -2
- data/test/new_relic/agent/stats_engine_test.rb +3 -3
- data/test/new_relic/agent/stats_hash_test.rb +2 -2
- data/test/new_relic/agent/stats_test.rb +1 -1
- data/test/new_relic/agent/threading/agent_thread_test.rb +2 -4
- data/test/new_relic/agent/threading/backtrace_node_test.rb +1 -1
- data/test/new_relic/agent/threading/backtrace_service_test.rb +5 -5
- 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 +2 -3
- data/test/new_relic/agent/transaction_sample_builder_test.rb +16 -14
- data/test/new_relic/agent/transaction_sampler_test.rb +16 -21
- data/test/new_relic/agent/transaction_state_test.rb +1 -1
- data/test/new_relic/agent/transaction_test.rb +61 -1
- data/test/new_relic/agent/transaction_timings_test.rb +1 -1
- data/test/new_relic/agent/worker_loop_test.rb +1 -1
- data/test/new_relic/agent_test.rb +2 -3
- data/test/new_relic/cli/deployments_test.rb +3 -3
- 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 +2 -2
- data/test/new_relic/control/frameworks/rails_test.rb +1 -1
- data/test/new_relic/control_test.rb +9 -4
- 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 +4 -6
- data/test/new_relic/fake_collector.rb +1 -158
- data/test/new_relic/framework_test.rb +2 -1
- data/test/new_relic/http_client_test_cases.rb +2 -3
- data/test/new_relic/json_wrapper_test.rb +77 -0
- data/test/new_relic/language_support_test.rb +1 -1
- data/test/new_relic/license_test.rb +2 -2
- data/test/new_relic/load_test.rb +2 -8
- 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 +26 -30
- 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 +4 -2
- data/test/new_relic/rack/deferred_instrumentation_test.rb +3 -5
- data/test/new_relic/rack/developer_mode_helper_test.rb +1 -1
- data/test/new_relic/rack/developer_mode_test.rb +1 -1
- data/test/new_relic/rack/error_collector_test.rb +8 -8
- data/test/new_relic/rack/transaction_reset_test.rb +35 -0
- data/test/new_relic/transaction_analysis/segment_summary_test.rb +2 -2
- 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 +2 -4
- data/test/new_relic/transaction_sample/segment_test.rb +3 -7
- 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 +4 -6
- data/test/new_relic/version_number_test.rb +1 -1
- data/test/performance/lib/performance/instrumentation/gc_stats.rb +1 -1
- data/test/performance/lib/performance/json_reporter.rb +1 -1
- data/test/performance/suites/marshalling.rb +76 -0
- data/test/test_helper.rb +6 -39
- metadata +19 -12
- metadata.gz.sig +0 -0
- data/test/new_relic/helper_test.rb +0 -32
@@ -159,7 +159,6 @@ module NewRelic
|
|
159
159
|
|
160
160
|
# Send fine-grained analytic data to the collector.
|
161
161
|
def analytic_event_data(data)
|
162
|
-
data = data.map { |hash| [hash] }
|
163
162
|
invoke_remote(:analytic_event_data, @agent_id, data)
|
164
163
|
end
|
165
164
|
|
@@ -279,15 +278,15 @@ module NewRelic
|
|
279
278
|
# enough to be worth compressing, and handles any errors the
|
280
279
|
# server may return
|
281
280
|
def invoke_remote(method, *args)
|
282
|
-
|
281
|
+
start_ts = Time.now
|
283
282
|
|
284
|
-
data, size = nil
|
283
|
+
data, size, serialize_finish_ts = nil
|
285
284
|
begin
|
286
285
|
data = @marshaller.dump(args)
|
287
|
-
rescue
|
288
|
-
|
289
|
-
retry
|
286
|
+
rescue => e
|
287
|
+
handle_serialization_error(method, e)
|
290
288
|
end
|
289
|
+
serialize_finish_ts = Time.now
|
291
290
|
|
292
291
|
data, encoding = compress_request_if_needed(data)
|
293
292
|
size = data.size
|
@@ -301,20 +300,31 @@ module NewRelic
|
|
301
300
|
:encoding => encoding,
|
302
301
|
:collector => @collector)
|
303
302
|
@marshaller.load(decompress_response(response))
|
304
|
-
rescue NewRelic::Agent::ForceRestartException => e
|
305
|
-
::NewRelic::Agent.logger.debug e.message
|
306
|
-
raise
|
307
303
|
ensure
|
308
|
-
record_supportability_metrics(method,
|
304
|
+
record_supportability_metrics(method, start_ts, serialize_finish_ts, size)
|
305
|
+
end
|
306
|
+
|
307
|
+
def handle_serialization_error(method, e)
|
308
|
+
NewRelic::Agent.increment_metric("Supportability/serialization_failure")
|
309
|
+
NewRelic::Agent.increment_metric("Supportability/serialization_failure/#{method}")
|
310
|
+
msg = "Failed to serialize #{method} data using #{@marshaller.class.to_s}: #{e.inspect}"
|
311
|
+
error = SerializationError.new(msg)
|
312
|
+
error.set_backtrace(e.backtrace)
|
313
|
+
raise error
|
309
314
|
end
|
310
315
|
|
311
|
-
def record_supportability_metrics(method,
|
312
|
-
|
313
|
-
|
314
|
-
NewRelic::Agent.record_metric(
|
316
|
+
def record_supportability_metrics(method, start_ts, serialize_finish_ts, size)
|
317
|
+
serialize_time = serialize_finish_ts && (serialize_finish_ts - start_ts)
|
318
|
+
duration = (Time.now - start_ts).to_f
|
319
|
+
NewRelic::Agent.record_metric("Supportability/invoke_remote", duration)
|
320
|
+
NewRelic::Agent.record_metric("Supportability/invoke_remote/#{method.to_s}", duration)
|
321
|
+
if serialize_time
|
322
|
+
NewRelic::Agent.record_metric("Supportability/invoke_remote_serialize", serialize_time)
|
323
|
+
NewRelic::Agent.record_metric("Supportability/invoke_remote_serialize/#{method.to_s}", serialize_time)
|
324
|
+
end
|
315
325
|
if size
|
316
|
-
NewRelic::Agent.record_metric(
|
317
|
-
NewRelic::Agent.record_metric(
|
326
|
+
NewRelic::Agent.record_metric("Supportability/invoke_remote_size", size)
|
327
|
+
NewRelic::Agent.record_metric("Supportability/invoke_remote_size/#{method.to_s}", size)
|
318
328
|
end
|
319
329
|
end
|
320
330
|
|
@@ -353,7 +363,7 @@ module NewRelic
|
|
353
363
|
when Net::HTTPSuccess
|
354
364
|
true # fall through
|
355
365
|
when Net::HTTPUnauthorized
|
356
|
-
raise LicenseException, 'Invalid license key, please
|
366
|
+
raise LicenseException, 'Invalid license key, please visit support.newrelic.com'
|
357
367
|
when Net::HTTPServiceUnavailable
|
358
368
|
raise ServerConnectionException, "Service unavailable (#{response.code}): #{response.message}"
|
359
369
|
when Net::HTTPGatewayTimeOut
|
@@ -416,7 +426,9 @@ module NewRelic
|
|
416
426
|
|
417
427
|
module Base64CompressedJSON
|
418
428
|
def self.encode(data)
|
419
|
-
|
429
|
+
json = ::NewRelic::JSONWrapper.dump(data,
|
430
|
+
:normalize => Agent.config[:normalize_json_string_encodings])
|
431
|
+
Base64.encode64(Compressed.encode(json))
|
420
432
|
end
|
421
433
|
end
|
422
434
|
end
|
@@ -424,9 +436,6 @@ module NewRelic
|
|
424
436
|
# Used to wrap errors reported to agent by the collector
|
425
437
|
class CollectorError < StandardError; end
|
426
438
|
|
427
|
-
# Used to wrap any problem with the JSON marshaller
|
428
|
-
class JsonError < StandardError; end
|
429
|
-
|
430
439
|
class Marshaller
|
431
440
|
def parsed_error(error)
|
432
441
|
error_class = error['error_type'].split('::') \
|
@@ -511,14 +520,13 @@ module NewRelic
|
|
511
520
|
end
|
512
521
|
|
513
522
|
def dump(ruby, opts={})
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
raise JsonError.new(e)
|
523
|
+
prepared = prepare(ruby, opts)
|
524
|
+
NewRelic::JSONWrapper.dump(prepared,
|
525
|
+
:normalize => Agent.config[:normalize_json_string_encodings])
|
518
526
|
end
|
519
527
|
|
520
528
|
def load(data)
|
521
|
-
return_value(
|
529
|
+
return_value(NewRelic::JSONWrapper.load(data)) if data && data != ''
|
522
530
|
rescue => e
|
523
531
|
::NewRelic::Agent.logger.debug "#{e.class.name} : #{e.message} encountered loading collector response: #{data}"
|
524
532
|
raise
|
@@ -533,7 +541,7 @@ module NewRelic
|
|
533
541
|
end
|
534
542
|
|
535
543
|
def self.is_supported?
|
536
|
-
NewRelic::
|
544
|
+
NewRelic::JSONWrapper.usable_for_collector_serialization?
|
537
545
|
end
|
538
546
|
|
539
547
|
def self.human_readable?
|
@@ -12,9 +12,6 @@ class NewRelic::Agent::RequestSampler
|
|
12
12
|
include NewRelic::Coerce,
|
13
13
|
MonitorMixin
|
14
14
|
|
15
|
-
# The namespace and keys of config values
|
16
|
-
ENABLED_KEY = :'analytics_events.enabled'
|
17
|
-
|
18
15
|
# The type field of the sample
|
19
16
|
SAMPLE_TYPE = 'Transaction'
|
20
17
|
|
@@ -102,7 +99,7 @@ class NewRelic::Agent::RequestSampler
|
|
102
99
|
self.reset!
|
103
100
|
end
|
104
101
|
|
105
|
-
NewRelic::Agent.config.register_callback(
|
102
|
+
NewRelic::Agent.config.register_callback(:'analytics_events.enabled') do |enabled|
|
106
103
|
NewRelic::Agent.logger.info "%sabling the Request Sampler." % [ enabled ? 'En' : 'Dis' ]
|
107
104
|
@enabled = enabled
|
108
105
|
end
|
@@ -117,20 +114,30 @@ class NewRelic::Agent::RequestSampler
|
|
117
114
|
def on_transaction_finished(payload)
|
118
115
|
return unless @enabled
|
119
116
|
return unless NewRelic::Agent::Transaction.transaction_type_is_web?(payload[:type])
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
117
|
+
|
118
|
+
main_event = create_main_event(payload)
|
119
|
+
custom_params = create_custom_parameters(payload)
|
120
|
+
|
121
|
+
is_full = self.synchronize { @samples.append([main_event, custom_params]) }
|
122
|
+
notify_full if is_full && !@notified_full
|
123
|
+
end
|
124
|
+
|
125
|
+
def create_main_event(payload)
|
126
|
+
sample = payload[:overview_metrics] || {}
|
127
127
|
sample.merge!({
|
128
128
|
TIMESTAMP_KEY => float(payload[:start_timestamp]),
|
129
129
|
NAME_KEY => string(payload[:name]),
|
130
130
|
DURATION_KEY => float(payload[:duration]),
|
131
131
|
TYPE_KEY => SAMPLE_TYPE,
|
132
132
|
})
|
133
|
-
is_full = self.synchronize { @samples.append(sample) }
|
134
|
-
notify_full if is_full && !@notified_full
|
135
133
|
end
|
134
|
+
|
135
|
+
def create_custom_parameters(payload)
|
136
|
+
custom_params = {}
|
137
|
+
if ::NewRelic::Agent.config[:'analytics_events.capture_attributes']
|
138
|
+
custom_params.merge!(event_params(payload[:custom_params] || {}))
|
139
|
+
end
|
140
|
+
custom_params
|
141
|
+
end
|
142
|
+
|
136
143
|
end
|
@@ -38,9 +38,9 @@ module NewRelic
|
|
38
38
|
Hash[self] == Hash[other]
|
39
39
|
end
|
40
40
|
|
41
|
-
class
|
42
|
-
def initialize(hash, metric_spec)
|
43
|
-
super("
|
41
|
+
class StatsHashLookupError < NewRelic::Agent::InternalAgentError
|
42
|
+
def initialize(original_error, hash, metric_spec)
|
43
|
+
super("Lookup error in StatsHash: #{original_error.class}: #{original_error.message}. Falling back adding #{metric_spec.inspect}")
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -53,7 +53,7 @@ module NewRelic
|
|
53
53
|
# This only happen in the case of a corrupted default_proc
|
54
54
|
# Side-step it manually, notice the issue, and carry on....
|
55
55
|
NewRelic::Agent.instance.error_collector. \
|
56
|
-
notice_agent_error(
|
56
|
+
notice_agent_error(StatsHashLookupError.new(e, self, metric_spec))
|
57
57
|
|
58
58
|
stats = NewRelic::Agent::Stats.new
|
59
59
|
self[metric_spec] = stats
|
@@ -21,20 +21,8 @@ module NewRelic
|
|
21
21
|
when /darwin/, /freebsd/
|
22
22
|
`sysctl -n hw.ncpu`.to_i
|
23
23
|
when /linux/
|
24
|
-
cpuinfo = ''
|
25
|
-
|
26
|
-
File.open(proc_file) do |f|
|
27
|
-
loop do
|
28
|
-
begin
|
29
|
-
cpuinfo << f.read_nonblock(4096).strip
|
30
|
-
rescue EOFError
|
31
|
-
break
|
32
|
-
rescue Errno::EWOULDBLOCK, Errno::EAGAIN
|
33
|
-
cpuinfo = ''
|
34
|
-
break # don't select file handle, just give up
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
24
|
+
cpuinfo = proc_try_read('/proc/cpuinfo')
|
25
|
+
return unless cpuinfo
|
38
26
|
processors = cpuinfo.split("\n").select {|line| line =~ /^processor\s*:/ }.size
|
39
27
|
processors == 0 ? nil : processors
|
40
28
|
end
|
@@ -47,7 +35,29 @@ module NewRelic
|
|
47
35
|
end
|
48
36
|
|
49
37
|
def self.os_version
|
50
|
-
|
38
|
+
proc_try_read('/proc/version')
|
39
|
+
end
|
40
|
+
|
41
|
+
# A File.read against /(proc|sysfs)/* can hang with some older Linuxes.
|
42
|
+
# See https://bugzilla.redhat.com/show_bug.cgi?id=604887, RUBY-736, and
|
43
|
+
# https://github.com/opscode/ohai/commit/518d56a6cb7d021b47ed3d691ecf7fba7f74a6a7
|
44
|
+
# for details on why we do it this way.
|
45
|
+
def self.proc_try_read(path)
|
46
|
+
return nil unless File.exist?(path)
|
47
|
+
content = ''
|
48
|
+
File.open(path) do |f|
|
49
|
+
loop do
|
50
|
+
begin
|
51
|
+
content << f.read_nonblock(4096)
|
52
|
+
rescue EOFError
|
53
|
+
break
|
54
|
+
rescue Errno::EWOULDBLOCK, Errno::EAGAIN
|
55
|
+
content = nil
|
56
|
+
break # don't select file handle, just give up
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
content
|
51
61
|
end
|
52
62
|
end
|
53
63
|
end
|
@@ -262,16 +262,35 @@ module NewRelic
|
|
262
262
|
# Anything left over is treated as custom params
|
263
263
|
|
264
264
|
def self.notice_error(e, options={})
|
265
|
+
options = extract_request_options(options)
|
266
|
+
if current
|
267
|
+
current.notice_error(e, options)
|
268
|
+
else
|
269
|
+
options = extract_finished_transaction_options(options)
|
270
|
+
agent.error_collector.notice_error(e, options)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def self.extract_request_options(options)
|
265
275
|
request = options.delete(:request)
|
266
276
|
if request
|
267
277
|
options[:referer] = referer_from_request(request)
|
268
278
|
options[:uri] = uri_from_request(request)
|
269
279
|
end
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
280
|
+
options
|
281
|
+
end
|
282
|
+
|
283
|
+
# If we aren't currently in a transaction, but found the remains of one
|
284
|
+
# just finished in the TransactionState, use those custom params!
|
285
|
+
def self.extract_finished_transaction_options(options)
|
286
|
+
finished_txn = NewRelic::Agent::TransactionState.get.transaction
|
287
|
+
if finished_txn
|
288
|
+
custom_params = options.fetch(:custom_params, {})
|
289
|
+
custom_params.merge!(finished_txn.custom_parameters)
|
290
|
+
options = options.merge(:custom_params => custom_params)
|
291
|
+
options[:metric] = finished_txn.name
|
274
292
|
end
|
293
|
+
options
|
275
294
|
end
|
276
295
|
|
277
296
|
# Do not call this. Invoke the class method instead.
|
data/lib/new_relic/control.rb
CHANGED
data/lib/new_relic/helper.rb
CHANGED
@@ -10,7 +10,7 @@ module NewRelic
|
|
10
10
|
|
11
11
|
# confirm a string is correctly encoded (in >= 1.9)
|
12
12
|
# If not force the encoding to ASCII-8BIT (binary)
|
13
|
-
if
|
13
|
+
if NewRelic::LanguageSupport.supports_string_encodings?
|
14
14
|
def correctly_encoded(string)
|
15
15
|
return string unless string.is_a? String
|
16
16
|
# The .dup here is intentional, since force_encoding mutates the target,
|
@@ -51,32 +51,4 @@ module NewRelic
|
|
51
51
|
milliseconds / 1000.0
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
55
|
-
# Load the JSON library from the standard library.
|
56
|
-
def self::load_stdlib_json
|
57
|
-
return false unless NewRelic::LanguageSupport.stdlib_json_usable?
|
58
|
-
|
59
|
-
require 'json'
|
60
|
-
define_method( :json_dump, &::JSON.method(:dump) )
|
61
|
-
define_method( :json_load, &::JSON.method(:parse) )
|
62
|
-
|
63
|
-
return true
|
64
|
-
rescue LoadError
|
65
|
-
NewRelic::Agent.logger.debug "%p while loading JSON library: %s" % [ err, err.message ] if
|
66
|
-
defined?( NewRelic::Agent ) && NewRelic::Agent.respond_to?( :logger )
|
67
|
-
return false
|
68
|
-
end
|
69
|
-
|
70
|
-
|
71
|
-
# Load the fallback JSON library
|
72
|
-
def self::load_okjson
|
73
|
-
require 'new_relic/okjson'
|
74
|
-
define_method( :json_dump, &::NewRelic::OkJson.method(:encode) )
|
75
|
-
define_method( :json_load, &::NewRelic::OkJson.method(:decode) )
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
load_stdlib_json or load_okjson
|
80
|
-
module_function :json_dump, :json_load
|
81
|
-
|
82
54
|
end
|
@@ -0,0 +1,92 @@
|
|
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
|
+
class JSONWrapper
|
7
|
+
def self.load_stdlib_json
|
8
|
+
return false unless NewRelic::LanguageSupport.stdlib_json_usable?
|
9
|
+
|
10
|
+
begin
|
11
|
+
require 'json'
|
12
|
+
@load_method = ::JSON.method(:load)
|
13
|
+
@dump_method = ::JSON.method(:dump)
|
14
|
+
@backend_name = :json
|
15
|
+
return true
|
16
|
+
rescue
|
17
|
+
NewRelic::Agent.logger.debug "%p while loading JSON library: %s" % [ err, err.message ] if
|
18
|
+
defined?( NewRelic::Agent ) && NewRelic::Agent.respond_to?( :logger )
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.load_okjson
|
23
|
+
require 'new_relic/okjson'
|
24
|
+
@load_method = ::NewRelic::OkJson.method(:decode)
|
25
|
+
@dump_method = ::NewRelic::OkJson.method(:encode)
|
26
|
+
@backend_name = :okjson
|
27
|
+
end
|
28
|
+
|
29
|
+
load_stdlib_json or load_okjson
|
30
|
+
|
31
|
+
def self.usable_for_collector_serialization?
|
32
|
+
@backend_name == :json
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.normalize_string(s)
|
36
|
+
encoding = s.encoding
|
37
|
+
if (encoding == Encoding::UTF_8 || encoding == Encoding::ISO_8859_1) && s.valid_encoding?
|
38
|
+
return s
|
39
|
+
end
|
40
|
+
|
41
|
+
# If the encoding is not valid, or it's ASCII-8BIT, we know conversion to
|
42
|
+
# UTF-8 is likely to fail, so treat it as ISO-8859-1 (byte-preserving).
|
43
|
+
normalized = s.dup
|
44
|
+
if encoding == Encoding::ASCII_8BIT || !s.valid_encoding?
|
45
|
+
normalized.force_encoding(Encoding::ISO_8859_1)
|
46
|
+
else
|
47
|
+
# Encoding is valid and non-binary, so it might be cleanly convertible
|
48
|
+
# to UTF-8. Give it a try and fall back to ISO-8859-1 if it fails.
|
49
|
+
begin
|
50
|
+
normalized.encode!(Encoding::UTF_8)
|
51
|
+
rescue
|
52
|
+
normalized.force_encoding(Encoding::ISO_8859_1)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
normalized
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.normalize(object)
|
59
|
+
case object
|
60
|
+
when String
|
61
|
+
normalize_string(object)
|
62
|
+
when Array
|
63
|
+
return object if object.empty?
|
64
|
+
result = object.map { |x| normalize(x) }
|
65
|
+
result
|
66
|
+
when Hash
|
67
|
+
return object if object.empty?
|
68
|
+
hash = {}
|
69
|
+
object.each_pair do |k, v|
|
70
|
+
k = normalize_string(k) if k.is_a?(String)
|
71
|
+
hash[k] = normalize(v)
|
72
|
+
end
|
73
|
+
hash
|
74
|
+
else
|
75
|
+
object
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.supports_normalization?
|
80
|
+
NewRelic::LanguageSupport.supports_string_encodings?
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.dump(object, options={})
|
84
|
+
object = normalize(object) if options[:normalize]
|
85
|
+
@dump_method.call(object)
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.load(string)
|
89
|
+
@load_method.call(string)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|