newrelic_rpm 2.14.1 → 3.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of newrelic_rpm might be problematic. Click here for more details.

Files changed (123) hide show
  1. data/CHANGELOG +8 -0
  2. data/README.rdoc +2 -0
  3. data/install.rb +2 -2
  4. data/lib/new_relic/agent.rb +34 -1
  5. data/lib/new_relic/agent/agent.rb +34 -25
  6. data/lib/new_relic/agent/browser_monitoring.rb +111 -0
  7. data/lib/new_relic/agent/error_collector.rb +4 -4
  8. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +3 -3
  9. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +5 -7
  10. data/lib/new_relic/agent/instrumentation/data_mapper.rb +8 -8
  11. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +1 -1
  12. data/lib/new_relic/agent/instrumentation/memcache.rb +1 -1
  13. data/lib/new_relic/agent/instrumentation/merb/controller.rb +1 -1
  14. data/lib/new_relic/agent/instrumentation/merb/errors.rb +1 -1
  15. data/lib/new_relic/agent/instrumentation/metric_frame.rb +1 -0
  16. data/lib/new_relic/agent/instrumentation/queue_time.rb +26 -26
  17. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +1 -1
  18. data/lib/new_relic/agent/instrumentation/rails/errors.rb +1 -1
  19. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +2 -2
  20. data/lib/new_relic/agent/instrumentation/sinatra.rb +1 -1
  21. data/lib/new_relic/agent/method_tracer.rb +15 -15
  22. data/lib/new_relic/agent/shim_agent.rb +2 -0
  23. data/lib/new_relic/agent/stats_engine/metric_stats.rb +3 -3
  24. data/lib/new_relic/agent/stats_engine/samplers.rb +2 -2
  25. data/lib/new_relic/agent/stats_engine/transactions.rb +2 -1
  26. data/lib/new_relic/agent/transaction_sample_builder.rb +101 -0
  27. data/lib/new_relic/agent/transaction_sampler.rb +299 -251
  28. data/lib/new_relic/control.rb +2 -2
  29. data/lib/new_relic/control/class_methods.rb +0 -5
  30. data/lib/new_relic/control/configuration.rb +4 -3
  31. data/lib/new_relic/control/frameworks/rails.rb +9 -12
  32. data/lib/new_relic/control/instance_methods.rb +2 -2
  33. data/lib/new_relic/control/instrumentation.rb +1 -1
  34. data/lib/new_relic/control/server_methods.rb +2 -2
  35. data/lib/new_relic/delayed_job_injection.rb +1 -1
  36. data/lib/new_relic/local_environment.rb +7 -7
  37. data/lib/new_relic/rack/browser_monitoring.rb +61 -0
  38. data/lib/new_relic/stats.rb +6 -6
  39. data/lib/new_relic/version.rb +4 -4
  40. data/newrelic.yml +19 -0
  41. data/newrelic_rpm.gemspec +9 -4
  42. data/test/active_record_fixtures.rb +5 -5
  43. data/test/config/test_control.rb +3 -3
  44. data/test/new_relic/agent/agent/connect_test.rb +27 -6
  45. data/test/new_relic/agent/agent/start_test.rb +13 -13
  46. data/test/new_relic/agent/agent/start_worker_thread_test.rb +8 -8
  47. data/test/new_relic/agent/agent_test.rb +85 -0
  48. data/test/new_relic/agent/agent_test_controller.rb +9 -9
  49. data/test/new_relic/agent/agent_test_controller_test.rb +37 -37
  50. data/test/new_relic/agent/browser_monitoring_test.rb +124 -0
  51. data/test/new_relic/agent/busy_calculator_test.rb +7 -7
  52. data/test/new_relic/agent/error_collector/notice_error_test.rb +9 -9
  53. data/test/new_relic/agent/error_collector_test.rb +54 -54
  54. data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +69 -69
  55. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +36 -0
  56. data/test/new_relic/agent/instrumentation/metric_frame_test.rb +3 -3
  57. data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +11 -11
  58. data/test/new_relic/agent/instrumentation/queue_time_test.rb +38 -35
  59. data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +18 -18
  60. data/test/new_relic/agent/memcache_instrumentation_test.rb +12 -12
  61. data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +1 -1
  62. data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +16 -15
  63. data/test/new_relic/agent/method_tracer_test.rb +60 -60
  64. data/test/new_relic/agent/mock_scope_listener.rb +8 -8
  65. data/test/new_relic/agent/rpm_agent_test.rb +26 -26
  66. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +17 -17
  67. data/test/new_relic/agent/stats_engine/samplers_test.rb +4 -4
  68. data/test/new_relic/agent/stats_engine/stats_engine_test.rb +51 -51
  69. data/test/new_relic/agent/transaction_sample_builder_test.rb +36 -36
  70. data/test/new_relic/agent/transaction_sampler_test.rb +727 -178
  71. data/test/new_relic/agent/worker_loop_test.rb +4 -4
  72. data/test/new_relic/collection_helper_test.rb +15 -15
  73. data/test/new_relic/command/deployments_test.rb +5 -5
  74. data/test/new_relic/control_test.rb +25 -25
  75. data/test/new_relic/local_environment_test.rb +11 -11
  76. data/test/new_relic/metric_spec_test.rb +21 -21
  77. data/test/new_relic/rack/episodes_test.rb +35 -35
  78. data/test/new_relic/stats_test.rb +61 -43
  79. data/test/new_relic/transaction_sample_subtest_test.rb +15 -15
  80. data/test/new_relic/transaction_sample_test.rb +25 -25
  81. data/test/new_relic/version_number_test.rb +11 -11
  82. data/test/test_contexts.rb +7 -7
  83. data/test/test_helper.rb +6 -6
  84. data/ui/helpers/developer_mode_helper.rb +67 -67
  85. data/ui/helpers/google_pie_chart.rb +4 -4
  86. data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +4 -4
  87. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/action_mailer.rb +3 -3
  88. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/active_merchant.rb +7 -7
  89. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/active_record.rb +1 -1
  90. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/apdex.rb +9 -9
  91. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/background_transaction.rb +1 -1
  92. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/client.rb +8 -8
  93. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/controller.rb +9 -9
  94. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/controller_cpu.rb +4 -4
  95. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/controller_ext.rb +2 -2
  96. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/database.rb +8 -8
  97. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/database_pool.rb +3 -3
  98. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/dot_net.rb +6 -6
  99. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/dot_net_parser.rb +3 -3
  100. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/external.rb +2 -2
  101. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/frontend.rb +6 -6
  102. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/gc.rb +2 -2
  103. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/hibernate_session.rb +1 -1
  104. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/java.rb +4 -4
  105. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/java_parser.rb +3 -3
  106. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/jsp.rb +4 -4
  107. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/jsp_tag.rb +1 -1
  108. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/mem_cache.rb +1 -1
  109. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/metric_parser.rb +21 -21
  110. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/orm.rb +2 -2
  111. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/other_transaction.rb +6 -6
  112. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet.rb +2 -2
  113. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet_context_listener.rb +1 -1
  114. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet_filter.rb +1 -1
  115. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/solr.rb +3 -3
  116. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/solr_request_handler.rb +1 -1
  117. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/spring.rb +8 -8
  118. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/struts_action.rb +3 -3
  119. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/struts_result.rb +3 -3
  120. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/view.rb +5 -5
  121. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/web_transaction.rb +20 -20
  122. metadata +15 -9
  123. data/lib/new_relic/agent/instrumentation/sequel.rb +0 -109
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ v3.0.0
2
+ * Support for Real User Monitoring
3
+ * Back end work on internals to improve reliability
4
+ * added a 'log_file_name' and 'log_file_path' configuration variable to allow
5
+ setting the path and name of the agent log file
6
+ * Improve reliability of statistics calculations
7
+ * Remove some previously deprecated methods
8
+
1
9
  v2.14.1
2
10
  * Avoid overriding methods named 'log' when including the MethodTracer module
3
11
  * Ensure that all load paths for 'new_relic/agent' go through 'new_relic/control' first
@@ -1,5 +1,7 @@
1
1
  = New Relic RPM
2
2
 
3
+
4
+
3
5
  New Relic RPM is a Ruby performance management system, developed by
4
6
  New Relic, Inc (http://www.newrelic.com). RPM provides you with deep
5
7
  information about the performance of your Ruby on Rails or Merb
data/install.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  if __FILE__ == $0 || $0 =~ /script\/plugin/
2
2
  $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
3
- require 'new_relic/command'
3
+ require 'new_relic/command'
4
4
  begin
5
5
  NewRelic::Command::Install.new(:quiet => true, :app_name => 'My Application').run
6
6
  rescue NewRelic::Command::CommandFailure => e
7
7
  $stderr.puts e.message
8
8
  end
9
- end
9
+ end
@@ -71,9 +71,10 @@ module NewRelic
71
71
  require 'new_relic/noticed_error'
72
72
  require 'new_relic/histogram'
73
73
  require 'new_relic/timer_lib'
74
-
74
+
75
75
  require 'new_relic/agent'
76
76
  require 'new_relic/agent/chained_call'
77
+ require 'new_relic/agent/browser_monitoring'
77
78
  require 'new_relic/agent/agent'
78
79
  require 'new_relic/agent/shim_agent'
79
80
  require 'new_relic/agent/method_tracer'
@@ -291,6 +292,14 @@ module NewRelic
291
292
  def is_execution_traced?
292
293
  Thread.current[:newrelic_untraced].nil? || Thread.current[:newrelic_untraced].last != false
293
294
  end
295
+
296
+ def is_transaction_traced?
297
+ Thread::current[:record_tt] != false
298
+ end
299
+
300
+ def is_sql_recorded?
301
+ Thread::current[:record_sql] != false
302
+ end
294
303
 
295
304
  # Set a filter to be applied to errors that RPM will track. The
296
305
  # block should evalute to the exception to track (which could be
@@ -379,5 +388,29 @@ module NewRelic
379
388
  def record_transaction(response_sec, options = {})
380
389
  agent.record_transaction(response_sec, options)
381
390
  end
391
+
392
+ # PRE-RELEASE
393
+ # Returns a Javascript string which should be injected into the very top of the response body
394
+ #
395
+ def browser_timing_header
396
+ agent.browser_timing_header
397
+ end
398
+
399
+ # PRE-RELEASE
400
+ # Returns a Javascript string which should be injected into the very bottom of the response body
401
+ #
402
+ def browser_timing_footer
403
+ agent.browser_timing_footer
404
+ end
405
+
406
+ # FOR BACKWARD COMPATIBILITY (REMOVE BEFORE GA)
407
+ def browser_instrumentation_header(options={})
408
+ agent.browser_timing_header
409
+ end
410
+
411
+ # FOR BACKWARD COMPATIBILITY (REMOVE BEFORE GA)
412
+ def browser_instrumentation_footer(options={})
413
+ agent.browser_timing_footer
414
+ end
382
415
  end
383
416
  end
@@ -62,6 +62,7 @@ module NewRelic
62
62
  attr_reader :histogram
63
63
  attr_reader :metric_ids
64
64
  attr_reader :url_rules
65
+ attr_reader :beacon_configuration
65
66
 
66
67
  def record_transaction(duration_seconds, options={})
67
68
  is_error = options['is_error'] || options['error_message'] || options['exception']
@@ -198,7 +199,12 @@ module NewRelic
198
199
  # Push flag indicating whether we should be tracing in this
199
200
  # thread.
200
201
  def push_trace_execution_flag(should_trace=false)
201
- (Thread.current[:newrelic_untraced] ||= []) << should_trace
202
+ value = Thread.current[:newrelic_untraced]
203
+ if (value.nil?)
204
+ Thread.current[:newrelic_untraced] = []
205
+ end
206
+
207
+ Thread.current[:newrelic_untraced] << should_trace
202
208
  end
203
209
 
204
210
  # Pop the current trace execution status. Restore trace execution status
@@ -222,7 +228,7 @@ module NewRelic
222
228
  def log
223
229
  NewRelic::Agent.logger
224
230
  end
225
-
231
+
226
232
  # Herein lies the corpse of the former 'start' method. May
227
233
  # it's unmatched flog score rest in pieces.
228
234
  module Start
@@ -236,13 +242,13 @@ module NewRelic
236
242
  def disabled?
237
243
  !control.agent_enabled?
238
244
  end
239
-
245
+
240
246
  def log_dispatcher
241
247
  dispatcher_name = control.dispatcher.to_s
242
248
  return if log_if(dispatcher_name.empty?, :info, "No dispatcher detected.")
243
249
  log.info "Dispatcher: #{dispatcher_name}"
244
250
  end
245
-
251
+
246
252
  def log_app_names
247
253
  log.info "Application: #{control.app_names.join(", ")}"
248
254
  end
@@ -252,7 +258,7 @@ module NewRelic
252
258
  end
253
259
 
254
260
  def apdex_f_threshold?
255
- sampler_config.fetch('transaction_threshold', '') =~ /apdex_f/i
261
+ sampler_config.fetch('transaction_threshold', '') =~ /apdex_f/i
256
262
  end
257
263
 
258
264
  def set_sql_recording!
@@ -269,7 +275,7 @@ module NewRelic
269
275
  else
270
276
  @record_sql = :obfuscated
271
277
  end
272
-
278
+
273
279
  log_sql_transmission_warning?
274
280
  end
275
281
 
@@ -280,7 +286,7 @@ module NewRelic
280
286
  def sampler_config
281
287
  control.fetch('transaction_tracer', {})
282
288
  end
283
-
289
+
284
290
  # this entire method should be done on the transaction
285
291
  # sampler object, rather than here. We should pass in the
286
292
  # sampler config.
@@ -290,7 +296,7 @@ module NewRelic
290
296
  @explain_threshold = sampler_config.fetch('explain_threshold', 0.5).to_f
291
297
  @explain_enabled = sampler_config.fetch('explain_enabled', true)
292
298
  set_sql_recording!
293
-
299
+
294
300
  # default to 2.0, string 'apdex_f' will turn into your
295
301
  # apdex * 4
296
302
  @slowest_transaction_threshold = sampler_config.fetch('transaction_threshold', 2.0).to_f
@@ -302,23 +308,23 @@ module NewRelic
302
308
  end
303
309
 
304
310
  def using_rubinius?
305
- RUBY_VERSION =~ /rubinius/i
311
+ RUBY_VERSION =~ /rubinius/i
306
312
  end
307
-
313
+
308
314
  def using_jruby?
309
- defined?(JRuby)
315
+ defined?(JRuby)
310
316
  end
311
-
317
+
312
318
  def using_sinatra?
313
319
  defined?(Sinatra::Application)
314
320
  end
315
-
321
+
316
322
  # we should not set an at_exit block if people are using
317
323
  # these as they don't do standard at_exit behavior per MRI/YARV
318
324
  def weird_ruby?
319
325
  using_rubinius? || using_jruby? || using_sinatra?
320
326
  end
321
-
327
+
322
328
  def install_exit_handler
323
329
  if control.send_data_on_exit && !weird_ruby?
324
330
  # Our shutdown handler needs to run after other shutdown handlers
@@ -334,7 +340,7 @@ module NewRelic
334
340
  def log_version_and_pid
335
341
  log.info "New Relic RPM Agent #{NewRelic::VERSION::STRING} Initialized: pid = #{$$}"
336
342
  end
337
-
343
+
338
344
  def log_if(boolean, level, message)
339
345
  self.log.send(level, message) if boolean
340
346
  boolean
@@ -344,7 +350,7 @@ module NewRelic
344
350
  self.log.send(level, message) unless boolean
345
351
  boolean
346
352
  end
347
-
353
+
348
354
  def monitoring?
349
355
  log_unless(control.monitor_mode?, :warn, "Agent configured not to send data in this environment - edit newrelic.yml to change this")
350
356
  end
@@ -356,7 +362,7 @@ module NewRelic
356
362
  def has_correct_license_key?
357
363
  has_license_key? && correct_license_length
358
364
  end
359
-
365
+
360
366
  def correct_license_length
361
367
  key = control.license_key
362
368
  log_unless((key.length == 40), :error, "Invalid license key: #{key}")
@@ -365,7 +371,7 @@ module NewRelic
365
371
  def using_forking_dispatcher?
366
372
  log_if([:passenger, :unicorn].include?(control.dispatcher), :info, "Connecting workers after forking.")
367
373
  end
368
-
374
+
369
375
  def check_config_and_start_agent
370
376
  return unless monitoring? && has_correct_license_key?
371
377
  return if using_forking_dispatcher?
@@ -473,7 +479,7 @@ module NewRelic
473
479
  rescue Exception => e
474
480
  handle_other_error(e)
475
481
  end
476
-
482
+
477
483
  def deferred_work!(connection_options)
478
484
  catch_errors do
479
485
  NewRelic::Agent.disable_all_tracing do
@@ -494,7 +500,7 @@ module NewRelic
494
500
  end
495
501
  end
496
502
  include StartWorkerThread
497
-
503
+
498
504
  # Try to launch the worker thread and connect to the server.
499
505
  #
500
506
  # See #connect for a description of connection_options.
@@ -509,7 +515,7 @@ module NewRelic
509
515
  def control
510
516
  NewRelic::Control.instance
511
517
  end
512
-
518
+
513
519
  module Connect
514
520
  attr_accessor :connect_retry_period
515
521
  attr_accessor :connect_attempts
@@ -558,7 +564,7 @@ module NewRelic
558
564
  log.info "Visit NewRelic.com to obtain a valid license key, or to upgrade your account."
559
565
  disconnect
560
566
  end
561
-
567
+
562
568
  def log_seed_token
563
569
  if control.validate_seed
564
570
  log.debug "Connecting with validation seed/token: #{control.validate_seed}/#{control.validate_token}"
@@ -602,13 +608,14 @@ module NewRelic
602
608
  end
603
609
  log.debug "Errors will #{enabled ? '' : 'not '}be sent to the RPM service."
604
610
  end
605
-
611
+
606
612
  def enable_random_samples!(sample_rate)
613
+ sample_rate = 10 unless sample_rate.to_i > 0# a sane default for random sampling
607
614
  @transaction_sampler.random_sampling = true
608
615
  @transaction_sampler.sampling_rate = sample_rate
609
616
  log.info "Transaction sampling enabled, rate = #{@transaction_sampler.sampling_rate}"
610
617
  end
611
-
618
+
612
619
 
613
620
  def configure_transaction_tracer!(server_enabled, sample_rate)
614
621
  # Ask the server for permission to send transaction samples.
@@ -633,13 +640,14 @@ module NewRelic
633
640
 
634
641
  def query_server_for_configuration
635
642
  set_collector_host!
636
-
643
+
637
644
  finish_setup(connect_to_server)
638
645
  end
639
646
  def finish_setup(config_data)
640
647
  @agent_id = config_data['agent_run_id']
641
648
  @report_period = config_data['data_report_period']
642
649
  @url_rules = config_data['url_rules']
650
+ @beacon_configuration = BeaconConfiguration.new(config_data)
643
651
 
644
652
  log_connection!(config_data)
645
653
  configure_transaction_tracer!(config_data['collect_traces'], config_data['sample_rate'])
@@ -938,6 +946,7 @@ module NewRelic
938
946
 
939
947
  extend ClassMethods
940
948
  include InstanceMethods
949
+ include BrowserMonitoring
941
950
  end
942
951
  end
943
952
  end
@@ -0,0 +1,111 @@
1
+ require 'base64'
2
+
3
+ module NewRelic
4
+ module Agent
5
+ class BeaconConfiguration
6
+ attr_reader :browser_timing_header
7
+ attr_reader :application_id
8
+ attr_reader :browser_monitoring_key
9
+ attr_reader :beacon
10
+ attr_reader :rum_enabled
11
+ attr_reader :license_bytes
12
+
13
+ def initialize(connect_data)
14
+ @browser_monitoring_key = connect_data['browser_key']
15
+ @application_id = connect_data['application_id']
16
+ @beacon = connect_data['beacon']
17
+ @rum_enabled = connect_data['rum.enabled']
18
+ @rum_enabled = true if @rum_enabled.nil?
19
+ @browser_timing_header = build_browser_timing_header(connect_data)
20
+ end
21
+
22
+ def license_bytes
23
+ if @license_bytes.nil?
24
+ @license_bytes = []
25
+ NewRelic::Control.instance.license_key.each_byte {|byte| @license_bytes << byte}
26
+ else
27
+ @license_bytes
28
+ end
29
+ end
30
+
31
+ def build_browser_timing_header(connect_data)
32
+ return "" if !@rum_enabled
33
+ return "" if @browser_monitoring_key.nil?
34
+
35
+ episodes_url = connect_data['episodes_url']
36
+ load_episodes_file = connect_data['rum.load_episodes_file']
37
+ load_episodes_file = true if load_episodes_file.nil?
38
+
39
+ load_js = load_episodes_file ? "(function(){var d=document;var e=d.createElement(\"script\");e.type=\"text/javascript\";e.async=true;e.src=\"#{episodes_url}\";var s=d.getElementsByTagName(\"script\")[0];s.parentNode.insertBefore(e,s);})()" : ""
40
+
41
+ value = "<script>var NREUMQ=[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);#{load_js}</script>"
42
+ if value.respond_to?(:html_safe)
43
+ value.html_safe
44
+ else
45
+ value
46
+ end
47
+ end
48
+ end
49
+
50
+ module BrowserMonitoring
51
+
52
+ def browser_timing_header
53
+ return "" if NewRelic::Agent.instance.beacon_configuration.nil?
54
+
55
+ return "" if !NewRelic::Agent.is_transaction_traced? || !NewRelic::Agent.is_execution_traced?
56
+
57
+ NewRelic::Agent.instance.beacon_configuration.browser_timing_header
58
+ end
59
+
60
+ def browser_timing_footer
61
+ config = NewRelic::Agent.instance.beacon_configuration
62
+ return "" if config.nil? || !config.rum_enabled
63
+
64
+ license_key = config.browser_monitoring_key
65
+ return "" if license_key.nil?
66
+
67
+ return "" if !NewRelic::Agent.is_transaction_traced? || !NewRelic::Agent.is_execution_traced?
68
+
69
+ application_id = config.application_id
70
+ beacon = config.beacon
71
+
72
+ transaction_name = Thread.current[:newrelic_most_recent_transaction] || "<unknown>"
73
+ start_time = Thread.current[:newrelic_start_time]
74
+ queue_time = (Thread.current[:newrelic_queue_time].to_f * 1000.0).round
75
+
76
+ value = ''
77
+ if start_time
78
+
79
+ obf = obfuscate(transaction_name)
80
+ app_time = ((Time.now - start_time).to_f * 1000.0).round
81
+
82
+ queue_time = 0.0 if queue_time < 0
83
+ app_time = 0.0 if app_time < 0
84
+
85
+ value = <<-eos
86
+ <script type="text/javascript" charset="utf-8">NREUMQ.push(["nrf2","#{beacon}","#{license_key}",#{application_id},"#{obf}",#{queue_time},#{app_time}])</script>
87
+ eos
88
+ end
89
+ if value.respond_to?(:html_safe)
90
+ value.html_safe
91
+ else
92
+ value
93
+ end
94
+ end
95
+
96
+ private
97
+
98
+ def obfuscate(text)
99
+ obfuscated = ""
100
+ key_bytes = NewRelic::Agent.instance.beacon_configuration.license_bytes
101
+ index = 0
102
+ text.each_byte{|byte|
103
+ obfuscated.concat((byte ^ key_bytes[index % 13].to_i))
104
+ index+=1
105
+ }
106
+
107
+ [obfuscated].pack("m0").chomp
108
+ end
109
+ end
110
+ end
111
+ end
@@ -97,7 +97,7 @@ module NewRelic
97
97
  end
98
98
 
99
99
  def custom_params_from_opts(options)
100
- # If anything else is left over, treat it like a custom param:
100
+ # If anything else is left over, treat it like a custom param:
101
101
  fetch_from_options(options, :custom_params, {}).merge(options)
102
102
  end
103
103
 
@@ -109,14 +109,14 @@ module NewRelic
109
109
  nil
110
110
  end
111
111
  end
112
-
112
+
113
113
  def normalized_request_and_custom_params(options)
114
114
  {
115
115
  :request_params => normalize_params(request_params_from_opts(options)),
116
116
  :custom_params => normalize_params(custom_params_from_opts(options))
117
117
  }
118
118
  end
119
-
119
+
120
120
  def error_params_from_options(options)
121
121
  uri_ref_and_root(options).merge(normalized_request_and_custom_params(options))
122
122
  end
@@ -148,7 +148,7 @@ module NewRelic
148
148
  log.warn("The error reporting queue has reached #{MAX_ERROR_QUEUE_LENGTH}. The error detail for this and subsequent errors will not be transmitted to RPM until the queued errors have been sent: #{exception}") if over_limit
149
149
  over_limit
150
150
  end
151
-
151
+
152
152
 
153
153
  def add_to_error_queue(noticed_error, exception)
154
154
  @lock.synchronize do