newrelic_rpm 6.2.0.354 → 6.7.0.359

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +27 -5
  3. data/CHANGELOG.md +157 -6
  4. data/lib/new_relic/agent.rb +49 -0
  5. data/lib/new_relic/agent/agent.rb +110 -146
  6. data/lib/new_relic/agent/commands/agent_command_router.rb +2 -21
  7. data/lib/new_relic/agent/configuration/default_source.rb +103 -41
  8. data/lib/new_relic/agent/configuration/environment_source.rb +4 -2
  9. data/lib/new_relic/agent/configuration/event_harvest_config.rb +45 -0
  10. data/lib/new_relic/agent/configuration/high_security_source.rb +1 -0
  11. data/lib/new_relic/agent/configuration/manager.rb +13 -9
  12. data/lib/new_relic/agent/configuration/server_source.rb +35 -1
  13. data/lib/new_relic/agent/connect/request_builder.rb +69 -0
  14. data/lib/new_relic/agent/connect/response_handler.rb +61 -0
  15. data/lib/new_relic/agent/cross_app_monitor.rb +1 -1
  16. data/lib/new_relic/agent/error_collector.rb +2 -2
  17. data/lib/new_relic/agent/error_event_aggregator.rb +2 -1
  18. data/lib/new_relic/agent/error_trace_aggregator.rb +1 -0
  19. data/lib/new_relic/agent/event_aggregator.rb +26 -32
  20. data/lib/new_relic/agent/hostname.rb +1 -1
  21. data/lib/new_relic/agent/inbound_request_monitor.rb +2 -2
  22. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +24 -42
  23. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +46 -74
  24. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +70 -53
  25. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +168 -0
  26. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +40 -47
  27. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +4 -4
  28. data/lib/new_relic/agent/instrumentation/grape.rb +2 -3
  29. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +76 -0
  30. data/lib/new_relic/agent/instrumentation/{rails5 → rails_notifications}/action_cable.rb +5 -6
  31. data/lib/new_relic/agent/instrumentation/{rails5 → rails_notifications}/action_controller.rb +3 -3
  32. data/lib/new_relic/agent/instrumentation/{rails4 → rails_notifications}/action_view.rb +3 -3
  33. data/lib/new_relic/agent/javascript_instrumentor.rb +1 -1
  34. data/lib/new_relic/agent/logging.rb +125 -0
  35. data/lib/new_relic/agent/new_relic_service.rb +0 -4
  36. data/lib/new_relic/agent/parameter_filtering.rb +18 -5
  37. data/lib/new_relic/agent/priority_sampled_buffer.rb +2 -0
  38. data/lib/new_relic/agent/span_event_aggregator.rb +2 -5
  39. data/lib/new_relic/agent/threading/backtrace_service.rb +3 -3
  40. data/lib/new_relic/agent/threading/thread_profile.rb +9 -23
  41. data/lib/new_relic/agent/tracer.rb +32 -0
  42. data/lib/new_relic/agent/transaction.rb +0 -2
  43. data/lib/new_relic/agent/transaction/trace.rb +3 -8
  44. data/lib/new_relic/agent/transaction/trace_builder.rb +0 -1
  45. data/lib/new_relic/agent/transaction_event_recorder.rb +3 -3
  46. data/lib/new_relic/agent/transaction_sampler.rb +1 -5
  47. data/lib/new_relic/cli/commands/deployments.rb +1 -1
  48. data/lib/new_relic/control/class_methods.rb +7 -1
  49. data/lib/new_relic/control/frameworks/{rails5.rb → rails_notifications.rb} +1 -1
  50. data/lib/new_relic/rack/browser_monitoring.rb +10 -8
  51. data/lib/new_relic/version.rb +1 -1
  52. data/lib/tasks/config.rake +1 -2
  53. data/newrelic_rpm.gemspec +7 -0
  54. data/test/agent_helper.rb +18 -5
  55. metadata +17 -16
  56. data/lib/new_relic/agent/commands/xray_session.rb +0 -55
  57. data/lib/new_relic/agent/commands/xray_session_collection.rb +0 -161
  58. data/lib/new_relic/agent/instrumentation/active_record_4.rb +0 -42
  59. data/lib/new_relic/agent/instrumentation/active_record_5.rb +0 -41
  60. data/lib/new_relic/agent/instrumentation/evented_subscriber.rb +0 -104
  61. data/lib/new_relic/agent/instrumentation/rails4/action_controller.rb +0 -32
  62. data/lib/new_relic/agent/instrumentation/rails5/action_view.rb +0 -27
  63. data/lib/new_relic/agent/transaction/xray_sample_buffer.rb +0 -64
  64. data/lib/new_relic/control/frameworks/rails6.rb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61ee707dd3738565b01b05857ed9ae7de00a6ab3e9cc0522ba5d651819c24634
4
- data.tar.gz: e8b630ad8f1c69a51dae797a046f90bd8d87683dcc4a2fb97f2960dcf6f90b4b
3
+ metadata.gz: e0981d305747247f1ac56c96ff7268cfd8b9bd7d419e8b800f2daf9193ae1dee
4
+ data.tar.gz: 9b4ca44ed6641fe4ea5f71296d8042f3ed5024a9d8d1dc3230241f02cab529fd
5
5
  SHA512:
6
- metadata.gz: 9ee286b42523ceca71287a9463a6e6a66e825f27956fd460c72aacb640780a20db0e5c688951f2d0a4bb648a4d8bd5dad98220d1f5a98e9abcc51843bd71aa1e
7
- data.tar.gz: 1a5070f668fd0b4f802ee71fe3909c123d0b38a53a1491ec07a496177cf9f392015c95ae62284b086a4fd27952fa0e62a7d720813de09449f5b4b8b8c4331a5e
6
+ metadata.gz: 8596846993859508c5acf8fc54155572332a75258f1970b01b9d89974ec7a4f935d5f728f2826bbac8190e49f368e51d961b6754f2742248a228458fa225763d
7
+ data.tar.gz: b07bc5d7dbd98faec43a76514ac6314f5f9c8667941db20b68ac4f13fddbf69656c7b75d1d3b02f4c1d46873aecf528bd5062c96f4895bf2a4234bd48da5999d
@@ -6,7 +6,10 @@ services:
6
6
 
7
7
  language: ruby
8
8
 
9
+ dist: precise
9
10
  sudo: required
11
+ jdk:
12
+ - oraclejdk8
10
13
 
11
14
  before_install:
12
15
  # RUBY-2072 Prevent Travis setup failure before our test even starts
@@ -15,6 +18,7 @@ before_install:
15
18
  - gem --version
16
19
  - ./test/script/before_install/update_rubygems.sh
17
20
  - rvm @global do gem uninstall bundler --all --executables || true
21
+ - gem uninstall bundler --all --executables || true
18
22
  - gem install bundler -v=1.17.3
19
23
  - ./test/script/before_install/gemstash_mirror.sh
20
24
  - bundle --version
@@ -40,11 +44,6 @@ branches:
40
44
  - dev
41
45
  - release
42
46
 
43
- notifications:
44
- webhooks: http://notifitron.herokuapp.com/
45
- on_success: always
46
- on_failure: always
47
-
48
47
  rvm:
49
48
  # Run slowest builds first to try and optimize overall cycle time.
50
49
  - jruby-9.2.6.0
@@ -56,6 +55,9 @@ rvm:
56
55
  - 2.1.10
57
56
  - 2.0.0-p648
58
57
 
58
+ jdk:
59
+ - oraclejdk8
60
+
59
61
  env:
60
62
  global:
61
63
  - BUNDLE_PATH=/home/travis/bundle
@@ -75,6 +77,7 @@ env:
75
77
  - TYPE=UNIT ENVIRONMENT=rails42
76
78
  - TYPE=UNIT ENVIRONMENT=rails50
77
79
  - TYPE=UNIT ENVIRONMENT=rails51
80
+ - TYPE=UNIT ENVIRONMENT=rails60
78
81
  - TYPE=UNIT ENVIRONMENT=norails
79
82
  - TYPE=FUNCTIONAL GROUP=agent
80
83
  - TYPE=FUNCTIONAL GROUP=api
@@ -89,6 +92,9 @@ env:
89
92
  - TYPE=NULLVERSE
90
93
 
91
94
  matrix:
95
+ allow_failures:
96
+ - rvm: jruby-9.2.6.0
97
+ env: TYPE=FUNCTIONAL GROUP=agent
92
98
  fast_finish: true
93
99
  exclude:
94
100
  # Unsupported Rails/Ruby combinations
@@ -127,18 +133,32 @@ matrix:
127
133
  env: TYPE=UNIT ENVIRONMENT=rails40
128
134
  - rvm: 2.4.2
129
135
  env: TYPE=UNIT ENVIRONMENT=rails41
136
+ - rvm: 2.4.2
137
+ env: TYPE=UNIT ENVIRONMENT=rails60
138
+
139
+ # 2.3
140
+ - rvm: 2.3.5
141
+ env: TYPE=UNIT ENVIRONMENT=rails60
142
+
143
+ # 2.2
144
+ - rvm: 2.2.8
145
+ env: TYPE=UNIT ENVIRONMENT=rails60
130
146
 
131
147
  # 2.1
132
148
  - rvm: 2.1.10
133
149
  env: TYPE=UNIT ENVIRONMENT=rails50
134
150
  - rvm: 2.1.10
135
151
  env: TYPE=UNIT ENVIRONMENT=rails51
152
+ - rvm: 2.1.10
153
+ env: TYPE=UNIT ENVIRONMENT=rails60
136
154
 
137
155
  # 2.0
138
156
  - rvm: 2.0.0-p648
139
157
  env: TYPE=UNIT ENVIRONMENT=rails50
140
158
  - rvm: 2.0.0-p648
141
159
  env: TYPE=UNIT ENVIRONMENT=rails51
160
+ - rvm: 2.0.0-p648
161
+ env: TYPE=UNIT ENVIRONMENT=rails60
142
162
 
143
163
  # jruby 9.2.6.0 (Compatible with MRI 2.5)
144
164
  - rvm: jruby-9.2.6.0
@@ -151,3 +171,5 @@ matrix:
151
171
  env: TYPE=UNIT ENVIRONMENT=rails40
152
172
  - rvm: jruby-9.2.6.0
153
173
  env: TYPE=UNIT ENVIRONMENT=rails41
174
+ - rvm: jruby-9.2.6.0
175
+ env: TYPE=UNIT ENVIRONMENT=rails60
@@ -1,19 +1,170 @@
1
1
  # New Relic Ruby Agent Release Notes #
2
2
 
3
+ ## v6.7.0
4
+
5
+ * **Trace and Entity Metadata API**
6
+
7
+ Several new API methods have been added to the agent:
8
+ * [`Agent#linking_metadata`](https://www.rubydoc.info/github/newrelic/rpm/NewRelic/Agent#linking_metadata-instance_method)
9
+ * [`Tracer#trace_id`](https://www.rubydoc.info/github/newrelic/rpm/NewRelic/Agent/Tracer#trace_id-class_method)
10
+ * [`Tracer#span_id`](https://www.rubydoc.info/github/newrelic/rpm/NewRelic/Agent/Tracer#span_id-class_method)
11
+ * [`Tracer#sampled?`](https://www.rubydoc.info/github/newrelic/rpm/NewRelic/Agent/Tracer#sampled?-class_method)
12
+
13
+ These API methods allow you to access information that can be used to link data of your choosing to a trace or entity.
14
+
15
+ * **Logs in Context**
16
+
17
+ This version of the agent includes a logger, which can be used in place of `::Logger`
18
+ from the standard library, or `ActiveSupport::Logger` from Rails. This logger
19
+ leverages the new trace and entity metadata API to decorate log statements with entity
20
+ and trace metadata, so they can be correlated together in the New Relic UI.
21
+
22
+ For more information on how to use logs in context, see https://docs.newrelic.com/docs/enable-logs-context-ruby
23
+
24
+ * **Project metadata in Gemspec**
25
+
26
+ Project metadata has been added to the gemspec file. This means our Rubygems page will allow users to more easily
27
+ access the agent's source code, raise issues, and read the changelog.
28
+
29
+ Thanks to Orien Madgwick for the contribution!
30
+
31
+ ## v6.6.0
32
+
33
+ * **Bugfix for ActionCable Instrumentation**
34
+
35
+ Previous versions of the agent sometimes caused application crashes with some versions
36
+ of ActionCable. The application would exit quickly after startup with the error:
37
+ `uninitialized constant ActionCable::Engine`.
38
+
39
+ Version 6.6.0 of the agent no longer crashes in this way.
40
+
41
+
42
+ * **Handling of disabling Error Collection**
43
+
44
+ When the agent first starts, it begins collecting Error Events and Traces before
45
+ fetching configuration from New Relic. In previous versions of the agent, those
46
+ events or traces would be sent to New Relic, even if _Error Collection_ is disabled in
47
+ the application's server-side configuration.
48
+
49
+ Version 6.6.0 of the agent drops all collected Error Events and Traces if the
50
+ configuration from the server disables _Error Collection_.
51
+
52
+ ## v6.5.0
53
+
54
+ * **Change to default setting for ActiveRecord connection resolution**
55
+
56
+ Due to incompatibilities between the faster ActiveRecord connection resolution
57
+ released in v6.3.0 of the agent and other gems which patch ActiveRecord,
58
+ `backport_fast_active_record_connection_lookup` will now be set to `false` by default.
59
+ Because it results in a significant performance improvement, we recommend customers
60
+ whose environments include ActiveRecord change this setting to `true`
61
+ _unless_ they are using other gems which measure ActiveRecord performance, which may
62
+ lose functionality when combined with this setting. If unsure whether to enable
63
+ `backport_fast_active_record_connection_lookup`, we recommend enabling it in a
64
+ development environment to make sure other gems which patch ActiveRecord are still
65
+ working as expected.
66
+
67
+ * **Bugfix for ActiveStorage instrumentation error**
68
+
69
+ Version 6.4.0 of the agent introduced a bug that interfered with ActiveStorage
70
+ callbacks, resulting in the agent being unable to instrument ActiveStorage operations.
71
+ ActiveStorage segments are now correctly recorded.
72
+
73
+ * **Bugfix for ActiveRecord 4.1 and 4.2 exception logging**
74
+
75
+ Version 6.3.0 of the agent introduced a bug that prevented ActiveRecord versions 4.1
76
+ and 4.2 from logging exceptions that occurred within a database transaction. This
77
+ version of the agent restores the exception logging functionality from previous agent
78
+ versions.
79
+ Thanks to Oleksiy Kovyrin for the contribution!
80
+
81
+ ## v6.4.0
82
+
83
+ * **Custom Metadata Collection**
84
+
85
+ The agent now collects environment variables prefixed by `NEW_RELIC_METADATA_`. These
86
+ may be added to transaction events to provide context between your Kubernetes cluster
87
+ and your services. For details on the behavior, see
88
+ [this blog post](https://blog.newrelic.com/engineering/monitoring-application-performance-in-kubernetes/).
89
+
90
+ * **Bugfix for faster ActiveRecord connection resolution**
91
+
92
+ Version 6.3.0 of the agent backported the faster ActiveRecord connection resolution
93
+ from Rails 6.0 to previous versions, but the implementation caused certain other gems
94
+ which measured ActiveRecord performance to stop working. This version of the agent
95
+ changes the implementation of this performance improvement so no such conflicts occur.
96
+
97
+ * **Bugfix for Grape instrumentation error**
98
+
99
+ Previous versions of the agent would fail to install Grape instrumentation in Grape
100
+ versions 1.2.0 and up if the API being instrumented subclassed `Grape::API::Instance`
101
+ rather than `Grape::API`. A warning would also print to the newrelic_agent log:
102
+ ```
103
+ WARN : Error in Grape instrumentation
104
+ WARN : NoMethodError: undefined method `name' for nil:NilClass
105
+ ```
106
+
107
+ This version of the agent successfully installs instrumentation for subclasses
108
+ of `Grape::API::Instance`, and these log messages should no longer appear.
109
+
110
+ * **Bugfix for streaming responses**
111
+
112
+ Previous versions of the agent would attempt to insert JavaScript instrumentation into
113
+ any streaming response that did not make use of `ActionController::Live`. This resulted
114
+ in an empty, non-streamed response being sent to the client.
115
+
116
+ This version of the agent will not attempt to insert JavaScript instrumentation into
117
+ a response which includes the header `Transfer-Encoding=chunked`, which indicates a
118
+ streaming response.
119
+
120
+ This should exclude JavaScript instrumentation for all streamed responses. To include
121
+ this instrumentation manually, see
122
+ [Manually instrument via agent API](https://docs.newrelic.com/docs/agents/ruby-agent/features/new-relic-browser-ruby-agent#manual_instrumentation)
123
+ in our documentation.
124
+
125
+ ## v6.3.0
126
+
127
+ * **Official Rails 6.0 support**
128
+
129
+ This version of the agent has been verified against the Rails 6.0.0 release.
130
+
131
+ As ActiveRecord 4, 5, and 6 use the same New Relic instrumentation, the
132
+ `disable_active_record_4` and `disable_active_record_5` settings in NewRelic.yml are being
133
+ deprecated in favor of the new `disable_active_record_notifications`. This new
134
+ setting will affect the instrumentation of ActiveRecord 4, 5, and 6. The deprecated settings
135
+ will be removed in a future release.
136
+
137
+ * **Bugfix for `newrelic deployments` script**
138
+
139
+ For applications housed in the EU, the `newrelic deployments` script included with previous
140
+ versions of the agent would fail with the following message: `Deployment not recorded:
141
+ Application does not exist.` This is because the script would attempt to send the deployment
142
+ notification to the US region. The deployment script now sends deployments to the correct region.
143
+
144
+ * **Faster ActiveRecord connection resolution**
145
+
146
+ This version of the agent uses the faster ActiveRecord connection resolution that Rails 6.0 uses, even on previous versions of Rails.
147
+ Thanks to Callum Jones for the contribution!
148
+
149
+ * **Support non-ascii characters in hostnames**
150
+
151
+ Previous versions of the agent would frequently log warnings like: `log writing failed. "\xE2" from ASCII-8BIT to UTF-8` if the hostname contained a non-ascii character. This version of the agent will no longer log these warnings.
152
+ Thanks to Rafael Petry for the contribution!
153
+
3
154
  ## v6.2.0
4
155
 
5
156
  * Bugfix for superfluous `Empty JSON response` error messages
6
157
 
7
- Version 6.1.0 of the agent frequently logged error messages about an empty
8
- JSON response, when no error had occurred. These logs no longer appear.
158
+ Version 6.1.0 of the agent frequently logged error messages about an empty
159
+ JSON response, when no error had occurred. These logs no longer appear.
9
160
 
10
161
  * Bugfix for `Unable to calculate elapsed transaction time` warning messages
11
162
 
12
- Ruby Agent versions 5.4 through 6.1, when running in jruby without
13
- ObjectSpace enabled, would occasionally log a warning indicating that the
163
+ Ruby Agent versions 5.4 through 6.1, when running in jruby without
164
+ ObjectSpace enabled, would occasionally log a warning indicating that the
14
165
  agent was unable to calculate the elapsed transaction time. When this log
15
- statement appeared, the affected transactions would not be included in the
16
- data displayed on the capacity analysis page. These transactions are now
166
+ statement appeared, the affected transactions would not be included in the
167
+ data displayed on the capacity analysis page. These transactions are now
17
168
  correctly recorded.
18
169
 
19
170
  ## v6.1.0
@@ -55,6 +55,7 @@ module NewRelic
55
55
  require 'new_relic/agent/system_info'
56
56
  require 'new_relic/agent/external'
57
57
  require 'new_relic/agent/deprecator'
58
+ require 'new_relic/agent/logging'
58
59
 
59
60
  require 'new_relic/agent/instrumentation/controller_instrumentation'
60
61
 
@@ -660,6 +661,54 @@ module NewRelic
660
661
  NewRelic::Agent.logger.debug "Ignoring exception during %p event notification" % [event_type]
661
662
  end
662
663
 
664
+ # @!group Trace and Entity metadata
665
+
666
+ TRACE_ID_KEY = 'trace.id'.freeze
667
+ SPAN_ID_KEY = 'span.id'.freeze
668
+ ENTITY_NAME_KEY = 'entity.name'.freeze
669
+ ENTITY_TYPE_KEY = 'entity.type'.freeze
670
+ ENTITY_GUID_KEY = 'entity.guid'.freeze
671
+ HOSTNAME_KEY = 'hostname'.freeze
672
+
673
+ ENTITY_TYPE = 'SERVICE'.freeze
674
+
675
+ # Returns a new hash containing trace and entity metadata that can be used
676
+ # to relate data to a trace or to an entity in APM.
677
+ #
678
+ # This hash includes:
679
+ # * trace.id - The current trace id, if there is a current trace id. This
680
+ # value may be omitted.
681
+ # * span.id - The current span id, if there is a current span. This
682
+ # value may be omitted.
683
+ # * entity.name - The name of the current application. This is read from
684
+ # the +app_name+ key in your config. If there are multiple application
685
+ # names, the first one is used.
686
+ # * entity.type - The entity type is hardcoded to the string +'SERVICE'+.
687
+ # * entity.guid - The guid of the current entity.
688
+ # * hostname - The fully qualified hostname.
689
+ #
690
+ # @api public
691
+ def linking_metadata
692
+ metadata = Hash.new
693
+ metadata[ENTITY_NAME_KEY] = config[:app_name][0]
694
+ metadata[ENTITY_TYPE_KEY] = ENTITY_TYPE
695
+ metadata[HOSTNAME_KEY] = Hostname.get
696
+
697
+ if entity_guid = config[:entity_guid]
698
+ metadata[ENTITY_GUID_KEY] = entity_guid
699
+ end
700
+
701
+ if trace_id = Tracer.current_trace_id
702
+ metadata[TRACE_ID_KEY] = trace_id
703
+ end
704
+ if span_id = Tracer.current_span_id
705
+ metadata[SPAN_ID_KEY] = span_id
706
+ end
707
+ metadata
708
+ end
709
+
710
+ #@!endgroup
711
+
663
712
  # @!group Manual browser monitoring configuration
664
713
 
665
714
  # This method returns a string suitable for inclusion in a page - known as
@@ -30,6 +30,8 @@ require 'new_relic/agent/utilization_data'
30
30
  require 'new_relic/environment_report'
31
31
  require 'new_relic/agent/attribute_filter'
32
32
  require 'new_relic/agent/adaptive_sampler'
33
+ require 'new_relic/agent/connect/request_builder'
34
+ require 'new_relic/agent/connect/response_handler'
33
35
 
34
36
  module NewRelic
35
37
  module Agent
@@ -57,7 +59,7 @@ module NewRelic
57
59
  @cross_app_monitor = NewRelic::Agent::CrossAppMonitor.new(@events)
58
60
  @distributed_trace_monitor = NewRelic::Agent::DistributedTraceMonitor.new(@events)
59
61
  @synthetics_monitor = NewRelic::Agent::SyntheticsMonitor.new(@events)
60
- @error_collector = NewRelic::Agent::ErrorCollector.new
62
+ @error_collector = NewRelic::Agent::ErrorCollector.new @events
61
63
  @transaction_rules = NewRelic::Agent::RulesEngine.new
62
64
  @harvest_samplers = NewRelic::Agent::SamplerCollection.new(@events)
63
65
  @monotonic_gc_profiler = NewRelic::Agent::VM::MonotonicGCProfiler.new
@@ -68,13 +70,12 @@ module NewRelic
68
70
  @harvester = NewRelic::Agent::Harvester.new(@events)
69
71
  @after_fork_lock = Mutex.new
70
72
 
71
- @transaction_event_recorder = NewRelic::Agent::TransactionEventRecorder.new
72
- @custom_event_aggregator = NewRelic::Agent::CustomEventAggregator.new
73
- @span_event_aggregator = NewRelic::Agent::SpanEventAggregator.new
73
+ @transaction_event_recorder = NewRelic::Agent::TransactionEventRecorder.new @events
74
+ @custom_event_aggregator = NewRelic::Agent::CustomEventAggregator.new @events
75
+ @span_event_aggregator = NewRelic::Agent::SpanEventAggregator.new @events
74
76
 
75
77
  @connect_state = :pending
76
78
  @connect_attempts = 0
77
- @environment_report = nil
78
79
  @waited_on_connect = nil
79
80
  @connected_pid = nil
80
81
 
@@ -87,7 +88,7 @@ module NewRelic
87
88
  def setup_attribute_filter
88
89
  refresh_attribute_filter
89
90
 
90
- @events.subscribe(:finished_configuring) do
91
+ @events.subscribe(:initial_configuration_complete) do
91
92
  refresh_attribute_filter
92
93
  end
93
94
  end
@@ -136,7 +137,7 @@ module NewRelic
136
137
  # Transaction and metric renaming rules as provided by the
137
138
  # collector on connect. The former are applied during txns,
138
139
  # the latter during harvest.
139
- attr_reader :transaction_rules
140
+ attr_accessor :transaction_rules
140
141
  # Responsbile for restarting the harvest thread
141
142
  attr_reader :harvester
142
143
  # GC::Profiler.total_time is not monotonic so we wrap it.
@@ -155,6 +156,10 @@ module NewRelic
155
156
  @transaction_event_recorder.synthetics_event_aggregator
156
157
  end
157
158
 
159
+ def agent_id=(agent_id)
160
+ @service.agent_id = agent_id
161
+ end
162
+
158
163
  # This method should be called in a forked process after a fork.
159
164
  # It assumes the parent process initialized the agent, but does
160
165
  # not assume the agent started.
@@ -327,7 +332,7 @@ module NewRelic
327
332
  end
328
333
 
329
334
  def log_app_name
330
- ::NewRelic::Agent.logger.info "Application: #{Agent.config.app_names.join(", ")}"
335
+ ::NewRelic::Agent.logger.info "Application: #{Agent.config[:app_name].join(", ")}"
331
336
  end
332
337
 
333
338
  def log_ignore_url_regexes
@@ -340,7 +345,7 @@ module NewRelic
340
345
 
341
346
  # Logs the configured application names
342
347
  def app_name_configured?
343
- names = Agent.config.app_names
348
+ names = Agent.config[:app_name]
344
349
  return names.respond_to?(:any?) && names.any?
345
350
  end
346
351
 
@@ -476,7 +481,6 @@ module NewRelic
476
481
  @harvester.mark_started
477
482
 
478
483
  unless in_resque_child_process?
479
- generate_environment_report
480
484
  install_exit_handler
481
485
  @harvest_samplers.load_samplers unless Agent.config[:disable_samplers]
482
486
  end
@@ -527,7 +531,7 @@ module NewRelic
527
531
  check_config_and_start_agent
528
532
  log_version_and_pid
529
533
 
530
- events.subscribe(:finished_configuring) do
534
+ events.subscribe(:initial_configuration_complete) do
531
535
  log_ignore_url_regexes
532
536
  end
533
537
  end
@@ -557,7 +561,10 @@ module NewRelic
557
561
  def flush_pipe_data
558
562
  if connected? && @service.is_a?(::NewRelic::Agent::PipeService)
559
563
  transmit_data
560
- transmit_event_data
564
+ transmit_analytic_event_data
565
+ transmit_custom_event_data
566
+ transmit_error_event_data
567
+ transmit_span_event_data
561
568
  end
562
569
  end
563
570
 
@@ -571,40 +578,48 @@ module NewRelic
571
578
  EventLoop.new
572
579
  end
573
580
 
574
- # Never allow any data type to be reported more frequently than once
575
- # per second.
576
- MIN_ALLOWED_REPORT_PERIOD = 1.0
581
+ LOG_ONCE_KEYS_RESET_PERIOD = 60.0
577
582
 
578
- def report_period_for(method)
579
- config_key = "data_report_periods.#{method}".to_sym
580
- period = Agent.config[config_key]
581
- if !period
582
- period = Agent.config[:data_report_period]
583
- ::NewRelic::Agent.logger.warn("Could not find configured period for #{method}, falling back to data_report_period (#{period} s)")
584
- end
585
- if period < MIN_ALLOWED_REPORT_PERIOD
586
- ::NewRelic::Agent.logger.warn("Configured #{config_key} was #{period}, but minimum allowed is #{MIN_ALLOWED_REPORT_PERIOD}, using #{MIN_ALLOWED_REPORT_PERIOD}.")
587
- period = MIN_ALLOWED_REPORT_PERIOD
588
- end
589
- period
583
+ # Certain event types may sometimes need to be on the same interval as metrics,
584
+ # so we will check config assigned in EventHarvestConfig to determine the interval
585
+ # on which to report them
586
+ def interval_for event_type
587
+ interval = Agent.config[:"event_report_period.#{event_type}"]
588
+ :"#{interval}_second_harvest"
590
589
  end
591
590
 
592
- LOG_ONCE_KEYS_RESET_PERIOD = 60.0
591
+ ANALYTIC_EVENT_DATA = "analytic_event_data".freeze
592
+ CUSTOM_EVENT_DATA = "custom_event_data".freeze
593
+ ERROR_EVENT_DATA = "error_event_data".freeze
594
+ SPAN_EVENT_DATA = "span_event_data".freeze
593
595
 
594
596
  def create_and_run_event_loop
597
+ data_harvest = :"#{Agent.config[:data_report_period]}_second_harvest"
598
+ event_harvest = :"#{Agent.config[:event_report_period]}_second_harvest"
599
+
595
600
  @event_loop = create_event_loop
596
- @event_loop.on(:report_data) do
601
+ @event_loop.on(data_harvest) do
597
602
  transmit_data
598
603
  end
599
- @event_loop.on(:report_event_data) do
600
- transmit_event_data
604
+
605
+ @event_loop.on(interval_for ANALYTIC_EVENT_DATA) do
606
+ transmit_analytic_event_data
607
+ end
608
+ @event_loop.on(interval_for CUSTOM_EVENT_DATA) do
609
+ transmit_custom_event_data
610
+ end
611
+ @event_loop.on(interval_for ERROR_EVENT_DATA) do
612
+ transmit_error_event_data
613
+ end
614
+ @event_loop.on(interval_for SPAN_EVENT_DATA) do
615
+ transmit_span_event_data
601
616
  end
602
617
  @event_loop.on(:reset_log_once_keys) do
603
618
  ::NewRelic::Agent.logger.clear_already_logged
604
619
  end
605
- @event_loop.fire_every(Agent.config[:data_report_period], :report_data)
606
- @event_loop.fire_every(report_period_for(:analytic_event_data), :report_event_data)
607
- @event_loop.fire_every(LOG_ONCE_KEYS_RESET_PERIOD, :reset_log_once_keys)
620
+ @event_loop.fire_every(Agent.config[:data_report_period], data_harvest)
621
+ @event_loop.fire_every(Agent.config[:event_report_period], event_harvest)
622
+ @event_loop.fire_every(LOG_ONCE_KEYS_RESET_PERIOD, :reset_log_once_keys)
608
623
 
609
624
  @event_loop.run
610
625
  end
@@ -768,10 +783,6 @@ module NewRelic
768
783
  shutdown
769
784
  end
770
785
 
771
- def generate_environment_report
772
- @environment_report = environment_for_connect
773
- end
774
-
775
786
  # Checks whether we should send environment info, and if so,
776
787
  # returns the snapshot from the local environment.
777
788
  # Generating the EnvironmentReport has the potential to trigger
@@ -781,93 +792,49 @@ module NewRelic
781
792
  Agent.config[:send_environment_info] ? Array(EnvironmentReport.new) : []
782
793
  end
783
794
 
784
- # We've seen objects in the environment report (Rails.env in
785
- # particular) that can't seralize to JSON. Cope with that here and
786
- # clear out so downstream code doesn't have to check again.
787
- def sanitize_environment_report
788
- if !@service.valid_to_marshal?(@environment_report)
789
- @environment_report = []
790
- end
795
+ # Constructs and memoizes an event_harvest_config hash to be used in
796
+ # the payload sent during connect (and reconnect)
797
+ def event_harvest_config
798
+ @event_harvest_config ||= Configuration::EventHarvestConfig.from_config(Agent.config)
791
799
  end
792
800
 
793
- # Initializes the hash of settings that we send to the
794
- # server. Returns a literal hash containing the options
795
- def connect_settings
796
- sanitize_environment_report
797
-
798
- {
799
- :pid => $$,
800
- :host => local_host,
801
- :display_host => Agent.config[:'process_host.display_name'],
802
- :app_name => Agent.config.app_names,
803
- :language => 'ruby',
804
- :labels => Agent.config.parsed_labels,
805
- :agent_version => NewRelic::VERSION::STRING,
806
- :environment => @environment_report,
807
- :settings => Agent.config.to_collector_hash,
808
- :high_security => Agent.config[:high_security],
809
- :utilization => UtilizationData.new.to_collector_hash,
810
- :identifier => "ruby:#{local_host}:#{Agent.config.app_names.sort.join(',')}"
811
- }
812
- end
813
-
814
- # Returns connect data passed back from the server
801
+ # Builds the payload to send to the connect service,
802
+ # connects, then configures the agent using the response from
803
+ # the connect service
815
804
  def connect_to_server
816
- @service.connect(connect_settings)
817
- end
805
+ request_builder = ::NewRelic::Agent::Connect::RequestBuilder.new \
806
+ @service,
807
+ Agent.config,
808
+ event_harvest_config
809
+ connect_response = @service.connect request_builder.connect_payload
818
810
 
819
- # apdex_f is always 4 times the apdex_t
820
- def apdex_f
821
- (4 * Agent.config[:apdex_t]).to_f
822
- end
811
+ response_handler = ::NewRelic::Agent::Connect::ResponseHandler.new(self, Agent.config)
812
+ response_handler.configure_agent(connect_response)
823
813
 
824
- # Sets the collector host and connects to the server, then
825
- # invokes the final configuration with the returned data
826
- def query_server_for_configuration
827
- finish_setup(connect_to_server)
814
+ log_connection connect_response if connect_response
815
+ connect_response
828
816
  end
829
817
 
830
- # Takes a hash of configuration data returned from the
831
- # server and uses it to set local variables and to
832
- # initialize various parts of the agent that are configured
833
- # separately.
834
- #
835
- # Can accommodate most arbitrary data - anything extra is
836
- # ignored unless we say to do something with it here.
837
- def finish_setup(config_data)
838
- return if config_data == nil
839
-
840
- @service.agent_id = config_data['agent_run_id']
841
-
842
- security_policies = config_data.delete('security_policies')
843
-
844
- add_server_side_config(config_data)
845
- add_security_policy_config(security_policies) if security_policies
846
-
847
- log_connection!(config_data)
848
- @transaction_rules = RulesEngine.create_transaction_rules(config_data)
849
- @stats_engine.metric_rules = RulesEngine.create_metric_rules(config_data)
850
-
851
- # If you're adding something else here to respond to the server-side config,
852
- # use Agent.instance.events.subscribe(:finished_configuring) callback instead!
818
+ # Logs when we connect to the server, for debugging purposes
819
+ # - makes sure we know if an agent has not connected
820
+ def log_connection(config_data)
821
+ ::NewRelic::Agent.logger.debug "Connected to NewRelic Service at #{@service.collector.name}"
822
+ ::NewRelic::Agent.logger.debug "Agent Run = #{@service.agent_id}."
823
+ ::NewRelic::Agent.logger.debug "Connection data = #{config_data.inspect}"
824
+ if config_data['messages'] && config_data['messages'].any?
825
+ log_collector_messages(config_data['messages'])
826
+ end
853
827
  end
854
828
 
855
- def add_server_side_config(config_data)
856
- if config_data['agent_config']
857
- ::NewRelic::Agent.logger.debug "Using config from server"
829
+ def log_collector_messages(messages)
830
+ messages.each do |message|
831
+ ::NewRelic::Agent.logger.send(message['level'].downcase, message['message'])
858
832
  end
859
-
860
- ::NewRelic::Agent.logger.debug "Server provided config: #{config_data.inspect}"
861
- server_config = NewRelic::Agent::Configuration::ServerSource.new(config_data, Agent.config)
862
- Agent.config.replace_or_add_config(server_config)
863
833
  end
864
834
 
865
- def add_security_policy_config(security_policies)
866
- ::NewRelic::Agent.logger.info 'Installing security policies'
867
- security_policy_source = NewRelic::Agent::Configuration::SecurityPolicySource.new(security_policies)
868
- Agent.config.replace_or_add_config(security_policy_source)
869
- # drop data collected before applying security policies
870
- drop_buffered_data
835
+ # apdex_f is always 4 times the apdex_t
836
+ def apdex_f
837
+ (4 * Agent.config[:apdex_t]).to_f
871
838
  end
872
839
 
873
840
  class WaitOnConnectTimeout < StandardError
@@ -899,22 +866,6 @@ module NewRelic
899
866
  end
900
867
  end
901
868
 
902
- # Logs when we connect to the server, for debugging purposes
903
- # - makes sure we know if an agent has not connected
904
- def log_connection!(config_data)
905
- ::NewRelic::Agent.logger.debug "Connected to NewRelic Service at #{@service.collector.name}"
906
- ::NewRelic::Agent.logger.debug "Agent Run = #{@service.agent_id}."
907
- ::NewRelic::Agent.logger.debug "Connection data = #{config_data.inspect}"
908
- if config_data['messages'] && config_data['messages'].any?
909
- log_collector_messages(config_data['messages'])
910
- end
911
- end
912
-
913
- def log_collector_messages(messages)
914
- messages.each do |message|
915
- ::NewRelic::Agent.logger.send(message['level'].downcase, message['message'])
916
- end
917
- end
918
869
  end
919
870
  include Connect
920
871
 
@@ -974,7 +925,7 @@ module NewRelic
974
925
  return unless should_connect?(opts[:force_reconnect])
975
926
 
976
927
  ::NewRelic::Agent.logger.debug "Connecting Process to New Relic: #$0"
977
- query_server_for_configuration
928
+ connect_to_server
978
929
  @connected_pid = $$
979
930
  @connect_state = :connected
980
931
  signal_connected
@@ -998,15 +949,6 @@ module NewRelic
998
949
  raise
999
950
  end
1000
951
 
1001
- # Who am I? Well, this method can tell you your hostname.
1002
- def determine_host
1003
- NewRelic::Agent::Hostname.get
1004
- end
1005
-
1006
- def local_host
1007
- @local_host ||= determine_host
1008
- end
1009
-
1010
952
  # Delegates to the control class to determine the root
1011
953
  # directory of this project
1012
954
  def determine_home_directory
@@ -1106,14 +1048,20 @@ module NewRelic
1106
1048
  def harvest_and_send_analytic_event_data
1107
1049
  harvest_and_send_from_container(transaction_event_aggregator, :analytic_event_data)
1108
1050
  harvest_and_send_from_container(synthetics_event_aggregator, :analytic_event_data)
1109
- harvest_and_send_from_container(@custom_event_aggregator, :custom_event_data)
1110
- harvest_and_send_from_container(span_event_aggregator, :span_event_data)
1051
+ end
1052
+
1053
+ def harvest_and_send_custom_event_data
1054
+ harvest_and_send_from_container(@custom_event_aggregator, :custom_event_data)
1111
1055
  end
1112
1056
 
1113
1057
  def harvest_and_send_error_event_data
1114
1058
  harvest_and_send_from_container @error_collector.error_event_aggregator, :error_event_data
1115
1059
  end
1116
1060
 
1061
+ def harvest_and_send_span_event_data
1062
+ harvest_and_send_from_container(span_event_aggregator, :span_event_data)
1063
+ end
1064
+
1117
1065
  def check_for_and_handle_agent_commands
1118
1066
  begin
1119
1067
  @agent_command_router.check_for_and_handle_agent_commands
@@ -1134,18 +1082,30 @@ module NewRelic
1134
1082
  NewRelic::Agent.record_metric("Supportability/remote_unavailable/#{endpoint.to_s}", 0.0)
1135
1083
  end
1136
1084
 
1137
- def transmit_event_data
1138
- transmit_single_data_type(:harvest_and_send_analytic_event_data, "TransactionEvent")
1085
+ TRANSACTION_EVENT = "TransactionEvent".freeze
1086
+ def transmit_analytic_event_data
1087
+ transmit_single_data_type(:harvest_and_send_analytic_event_data, TRANSACTION_EVENT)
1088
+ end
1089
+
1090
+ CUSTOM_EVENT = "CustomEvent".freeze
1091
+ def transmit_custom_event_data
1092
+ transmit_single_data_type(:harvest_and_send_custom_event_data, CUSTOM_EVENT)
1093
+ end
1094
+
1095
+ ERROR_EVENT = "ErrorEvent".freeze
1096
+ def transmit_error_event_data
1097
+ transmit_single_data_type(:harvest_and_send_error_event_data, ERROR_EVENT)
1139
1098
  end
1140
1099
 
1100
+ SPAN_EVENT = "SpanEvent".freeze
1141
1101
  def transmit_span_event_data
1142
- transmit_single_data_type(:harvest_and_send_span_event_data, "SpanEvent")
1102
+ transmit_single_data_type(:harvest_and_send_span_event_data, SPAN_EVENT)
1143
1103
  end
1144
1104
 
1145
1105
  def transmit_single_data_type(harvest_method, supportability_name)
1146
1106
  now = Time.now
1147
1107
 
1148
- msg = "Sending #{harvest_method.to_s.gsub("harvest_and_send_", "")} to New Relic Service"
1108
+ msg = "Sending #{supportability_name} data to New Relic Service"
1149
1109
  ::NewRelic::Agent.logger.debug msg
1150
1110
 
1151
1111
  @service.session do # use http keep-alive
@@ -1167,6 +1127,7 @@ module NewRelic
1167
1127
  harvest_and_send_transaction_traces
1168
1128
  harvest_and_send_slowest_sql
1169
1129
  harvest_and_send_timeslice_data
1130
+ harvest_and_send_span_event_data
1170
1131
 
1171
1132
  check_for_and_handle_agent_commands
1172
1133
  harvest_and_send_for_agent_commands
@@ -1191,7 +1152,10 @@ module NewRelic
1191
1152
 
1192
1153
  @events.notify(:before_shutdown)
1193
1154
  transmit_data
1194
- transmit_event_data
1155
+ transmit_analytic_event_data
1156
+ transmit_custom_event_data
1157
+ transmit_error_event_data
1158
+ transmit_span_event_data
1195
1159
 
1196
1160
  if @connected_pid == $$ && !@service.kind_of?(NewRelic::Agent::NewRelicService)
1197
1161
  ::NewRelic::Agent.logger.debug "Sending New Relic service agent run shutdown message"