newrelic_rpm 6.0.0.351 → 6.2.0.354

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91ab526e3b85c3d323b557163c7213681e1783c0c6ac9f29bf53dad5dd421a92
4
- data.tar.gz: ba03925e985ecaf44b0b56375cb0c38532c2473cf87440c2b7f2c4fccea3d744
3
+ metadata.gz: 61ee707dd3738565b01b05857ed9ae7de00a6ab3e9cc0522ba5d651819c24634
4
+ data.tar.gz: e8b630ad8f1c69a51dae797a046f90bd8d87683dcc4a2fb97f2960dcf6f90b4b
5
5
  SHA512:
6
- metadata.gz: 811d5a9f971f18d5e66a2b0826d003603b5771b8378906ee1594ec95834593f31a668e8d8084cbd84db8f0e3d367d93620ed87b86e047c31d20b115cd4c8cfb6
7
- data.tar.gz: 115f4a4d0c6186546cdd6d698279e5d60b26a67d7749bd2959c44f0478f594621e78e4785a8b6508d78c986e5a19d6dcb5df145f9891eb323432141336e72845
6
+ metadata.gz: 9ee286b42523ceca71287a9463a6e6a66e825f27956fd460c72aacb640780a20db0e5c688951f2d0a4bb648a4d8bd5dad98220d1f5a98e9abcc51843bd71aa1e
7
+ data.tar.gz: 1a5070f668fd0b4f802ee71fe3909c123d0b38a53a1491ec07a496177cf9f392015c95ae62284b086a4fd27952fa0e62a7d720813de09449f5b4b8b8c4331a5e
data/.gitignore CHANGED
@@ -25,4 +25,5 @@ lib/new_relic/build.rb
25
25
  .bundle
26
26
  .yardoc
27
27
  artifacts/
28
+ test/performance/log/
28
29
  test/performance/script/log/
@@ -10,15 +10,16 @@ sudo: required
10
10
 
11
11
  before_install:
12
12
  # RUBY-2072 Prevent Travis setup failure before our test even starts
13
+ - jdk_switcher use oraclejdk8
13
14
  - sudo rm -f /etc/apt/sources.list.d/travis_ci_zeromq3.list
14
15
  - gem --version
15
16
  - ./test/script/before_install/update_rubygems.sh
16
- - gem uninstall bundler -a -x
17
+ - rvm @global do gem uninstall bundler --all --executables || true
17
18
  - gem install bundler -v=1.17.3
18
19
  - ./test/script/before_install/gemstash_mirror.sh
19
- - bundle _1.17.3_ --version
20
+ - bundle --version
20
21
 
21
- install: bundle _1.17.3_ install
22
+ install: bundle install
22
23
 
23
24
  addons:
24
25
  apt:
@@ -46,9 +47,9 @@ notifications:
46
47
 
47
48
  rvm:
48
49
  # Run slowest builds first to try and optimize overall cycle time.
49
- - jruby-9.1.13.0
50
- - 2.6.0
51
- - 2.5.0
50
+ - jruby-9.2.6.0
51
+ - 2.6.1
52
+ - 2.5.3
52
53
  - 2.4.2
53
54
  - 2.3.5
54
55
  - 2.2.8
@@ -66,11 +67,6 @@ env:
66
67
  - TESTOPTS="-v"
67
68
  - VERBOSE = 1
68
69
  matrix:
69
- # RUBY-1668 rails21, rails22, and rails23 are all excluded below
70
- - TYPE=UNIT ENVIRONMENT=rails21
71
- - TYPE=UNIT ENVIRONMENT=rails22
72
- - TYPE=UNIT ENVIRONMENT=rails23
73
-
74
70
  - TYPE=UNIT ENVIRONMENT=rails30
75
71
  - TYPE=UNIT ENVIRONMENT=rails31
76
72
  - TYPE=UNIT ENVIRONMENT=rails32
@@ -97,48 +93,30 @@ matrix:
97
93
  exclude:
98
94
  # Unsupported Rails/Ruby combinations
99
95
  # 2.6
100
- - rvm: 2.6.0
101
- env: TYPE=UNIT ENVIRONMENT=rails21
102
- - rvm: 2.6.0
103
- env: TYPE=UNIT ENVIRONMENT=rails22
104
- - rvm: 2.6.0
105
- env: TYPE=UNIT ENVIRONMENT=rails23
106
- - rvm: 2.6.0
96
+ - rvm: 2.6.1
107
97
  env: TYPE=UNIT ENVIRONMENT=rails30
108
- - rvm: 2.6.0
98
+ - rvm: 2.6.1
109
99
  env: TYPE=UNIT ENVIRONMENT=rails31
110
- - rvm: 2.6.0
100
+ - rvm: 2.6.1
111
101
  env: TYPE=UNIT ENVIRONMENT=rails32
112
- - rvm: 2.6.0
102
+ - rvm: 2.6.1
113
103
  env: TYPE=UNIT ENVIRONMENT=rails40
114
- - rvm: 2.6.0
104
+ - rvm: 2.6.1
115
105
  env: TYPE=UNIT ENVIRONMENT=rails41
116
106
 
117
107
  # 2.5
118
- - rvm: 2.5.0
119
- env: TYPE=UNIT ENVIRONMENT=rails21
120
- - rvm: 2.5.0
121
- env: TYPE=UNIT ENVIRONMENT=rails22
122
- - rvm: 2.5.0
123
- env: TYPE=UNIT ENVIRONMENT=rails23
124
- - rvm: 2.5.0
108
+ - rvm: 2.5.3
125
109
  env: TYPE=UNIT ENVIRONMENT=rails30
126
- - rvm: 2.5.0
110
+ - rvm: 2.5.3
127
111
  env: TYPE=UNIT ENVIRONMENT=rails31
128
- - rvm: 2.5.0
112
+ - rvm: 2.5.3
129
113
  env: TYPE=UNIT ENVIRONMENT=rails32
130
- - rvm: 2.5.0
114
+ - rvm: 2.5.3
131
115
  env: TYPE=UNIT ENVIRONMENT=rails40
132
- - rvm: 2.5.0
116
+ - rvm: 2.5.3
133
117
  env: TYPE=UNIT ENVIRONMENT=rails41
134
118
 
135
119
  # 2.4
136
- - rvm: 2.4.2
137
- env: TYPE=UNIT ENVIRONMENT=rails21
138
- - rvm: 2.4.2
139
- env: TYPE=UNIT ENVIRONMENT=rails22
140
- - rvm: 2.4.2
141
- env: TYPE=UNIT ENVIRONMENT=rails23
142
120
  - rvm: 2.4.2
143
121
  env: TYPE=UNIT ENVIRONMENT=rails30
144
122
  - rvm: 2.4.2
@@ -150,78 +128,26 @@ matrix:
150
128
  - rvm: 2.4.2
151
129
  env: TYPE=UNIT ENVIRONMENT=rails41
152
130
 
153
- # 2.3
154
- - rvm: 2.3.5
155
- env: TYPE=UNIT ENVIRONMENT=rails21
156
- - rvm: 2.3.5
157
- env: TYPE=UNIT ENVIRONMENT=rails22
158
- - rvm: 2.3.5
159
- env: TYPE=UNIT ENVIRONMENT=rails23
160
-
161
- # 2.2
162
- - rvm: 2.2.8
163
- env: TYPE=UNIT ENVIRONMENT=rails21
164
- - rvm: 2.2.8
165
- env: TYPE=UNIT ENVIRONMENT=rails22
166
- - rvm: 2.2.8
167
- env: TYPE=UNIT ENVIRONMENT=rails23
168
-
169
131
  # 2.1
170
- - rvm: 2.1.10
171
- env: TYPE=UNIT ENVIRONMENT=rails21
172
- - rvm: 2.1.10
173
- env: TYPE=UNIT ENVIRONMENT=rails22
174
- - rvm: 2.1.10
175
- env: TYPE=UNIT ENVIRONMENT=rails23
176
132
  - rvm: 2.1.10
177
133
  env: TYPE=UNIT ENVIRONMENT=rails50
178
134
  - rvm: 2.1.10
179
135
  env: TYPE=UNIT ENVIRONMENT=rails51
180
136
 
181
137
  # 2.0
182
- - rvm: 2.0.0-p648
183
- env: TYPE=UNIT ENVIRONMENT=rails21
184
- - rvm: 2.0.0-p648
185
- env: TYPE=UNIT ENVIRONMENT=rails22
186
- - rvm: 2.0.0-p648
187
- env: TYPE=UNIT ENVIRONMENT=rails23
188
138
  - rvm: 2.0.0-p648
189
139
  env: TYPE=UNIT ENVIRONMENT=rails50
190
140
  - rvm: 2.0.0-p648
191
141
  env: TYPE=UNIT ENVIRONMENT=rails51
192
142
 
193
- # jruby 9.0
194
- - rvm: jruby-9.1.13.0
195
- env: TYPE=UNIT ENVIRONMENT=rails21
196
- - rvm: jruby-9.1.13.0
197
- env: TYPE=UNIT ENVIRONMENT=rails22
198
- - rvm: jruby-9.1.13.0
199
- env: TYPE=UNIT ENVIRONMENT=rails23
200
- - rvm: jruby-9.1.13.0
143
+ # jruby 9.2.6.0 (Compatible with MRI 2.5)
144
+ - rvm: jruby-9.2.6.0
201
145
  env: TYPE=UNIT ENVIRONMENT=rails30
202
- - rvm: jruby-9.1.13.0
146
+ - rvm: jruby-9.2.6.0
203
147
  env: TYPE=UNIT ENVIRONMENT=rails31
204
- - rvm: jruby-9.1.13.0
148
+ - rvm: jruby-9.2.6.0
205
149
  env: TYPE=UNIT ENVIRONMENT=rails32
206
-
207
- # Travis (and only Travis) has been throwing difficult-to-reproduce
208
- # errors in various JRuby tests. These appeared after a build image
209
- # update, and they seem to be unrelated to any agent code changes.
210
- # So, we'll allow these specific test runs to fail while we track
211
- # the issue (RUBY-1869).
212
- #
213
- allow_failures:
214
- - rvm: jruby-9.1.13.0
150
+ - rvm: jruby-9.2.6.0
215
151
  env: TYPE=UNIT ENVIRONMENT=rails40
216
- - rvm: jruby-9.1.13.0
152
+ - rvm: jruby-9.2.6.0
217
153
  env: TYPE=UNIT ENVIRONMENT=rails41
218
- - rvm: jruby-9.1.13.0
219
- env: TYPE=UNIT ENVIRONMENT=rails42
220
- - rvm: jruby-9.1.13.0
221
- env: TYPE=UNIT ENVIRONMENT=rails50
222
- - rvm: jruby-9.1.13.0
223
- env: TYPE=UNIT ENVIRONMENT=rails51
224
- - rvm: jruby-9.1.13.0
225
- env: TYPE=UNIT ENVIRONMENT=norails
226
- - rvm: jruby-9.1.13.0
227
- env: TYPE=FUNCTIONAL GROUP=background_2
@@ -1,5 +1,38 @@
1
1
  # New Relic Ruby Agent Release Notes #
2
2
 
3
+ ## v6.2.0
4
+
5
+ * Bugfix for superfluous `Empty JSON response` error messages
6
+
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.
9
+
10
+ * Bugfix for `Unable to calculate elapsed transaction time` warning messages
11
+
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
14
+ 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
17
+ correctly recorded.
18
+
19
+ ## v6.1.0
20
+
21
+ * Performance monitoring on Kubernetes
22
+
23
+ This release adds Transaction event attributes that provide
24
+ context between your Kubernetes cluster and services. For details
25
+ on the benefits, see this [blog
26
+ post](https://blog.newrelic.com/engineering/monitoring-application-performance-in-kubernetes/).
27
+
28
+ * Bugfix for Bunny instrumentation when popping empty queues
29
+
30
+ When a customer calls `Bunny::Queue#pop` on an empty queue, Bunny
31
+ returns a `nil` value. Previous Ruby Agent versions raised a
32
+ `NoMethodError` when trying to process this result. Now, the
33
+ agent correctly skips processing for `nil` values. Thanks to
34
+ Matt Campbell for the contribution.
35
+
3
36
  ## v6.0.0
4
37
 
5
38
  * Tracer API for flexible custom instrumentation
@@ -76,7 +76,11 @@ module NewRelic
76
76
  class ForceDisconnectException < StandardError; end
77
77
 
78
78
  # An exception that forces an agent to restart.
79
- class ForceRestartException < StandardError; end
79
+ class ForceRestartException < StandardError
80
+ def message
81
+ "#{super}, restarting."
82
+ end
83
+ end
80
84
 
81
85
  # Used to blow out of a periodic task without logging a an error, such as for routine
82
86
  # failures.
@@ -624,7 +624,7 @@ module NewRelic
624
624
  # is the worker thread that gathers data and talks to the
625
625
  # server.
626
626
  def handle_force_disconnect(error)
627
- ::NewRelic::Agent.logger.warn "New Relic forced this agent to disconnect (#{error.message})"
627
+ ::NewRelic::Agent.logger.warn "Agent received a ForceDisconnectException from the server, disconnecting. (#{error.message})"
628
628
  disconnect
629
629
  end
630
630
 
@@ -632,7 +632,7 @@ module NewRelic
632
632
  # it and disconnecting the agent, since we are now in an
633
633
  # unknown state.
634
634
  def handle_other_error(error)
635
- ::NewRelic::Agent.logger.error "Unhandled error in worker thread, disconnecting this agent process:"
635
+ ::NewRelic::Agent.logger.error "Unhandled error in worker thread, disconnecting."
636
636
  # These errors are fatal (that is, they will prevent the agent from
637
637
  # reporting entirely), so we really want backtraces when they happen
638
638
  ::NewRelic::Agent.logger.log_exception(:error, error)
@@ -1119,6 +1119,8 @@ module NewRelic
1119
1119
  @agent_command_router.check_for_and_handle_agent_commands
1120
1120
  rescue ForceRestartException, ForceDisconnectException
1121
1121
  raise
1122
+ rescue UnrecoverableServerException => e
1123
+ NewRelic::Agent.logger.warn("get_agent_commands message was rejected by remote service, discarding. Error: ", e)
1122
1124
  rescue ServerConnectionException => e
1123
1125
  log_remote_unavailable(:get_agent_commands, e)
1124
1126
  rescue => e
@@ -1694,6 +1694,13 @@ module NewRelic
1694
1694
  :allowed_from_server => false,
1695
1695
  :description => 'If <code>true</code>, the agent automatically detects that it is running in Docker.'
1696
1696
  },
1697
+ :'utilization.detect_kubernetes' => {
1698
+ :default => true,
1699
+ :public => true,
1700
+ :type => Boolean,
1701
+ :allowed_from_server => false,
1702
+ :description => 'If <code>true</code>, the agent automatically detects that it is running in Kubernetes.'
1703
+ },
1697
1704
  :'utilization.billing_hostname' => {
1698
1705
  :default => nil,
1699
1706
  :allow_nil => true,
@@ -103,7 +103,8 @@ module NewRelic
103
103
  'error_collector.enabled' => 'collect_errors',
104
104
  'analytics_events.enabled' => 'collect_analytics_events',
105
105
  'custom_insights_events.enabled' => 'collect_custom_events',
106
- 'error_collector.capture_events' => 'collect_error_events'
106
+ 'error_collector.capture_events' => 'collect_error_events',
107
+ 'span_events.enabled' => 'collect_span_events'
107
108
  }
108
109
  gated_features.each do |config_key, gate_key|
109
110
  if connect_reply.has_key?(gate_key)
@@ -168,7 +168,12 @@ module NewRelic
168
168
  @caller_transport_type = PARENT_TRANSPORT_TYPE_UNKNOWN
169
169
  end
170
170
 
171
- def to_json
171
+ # Represent this payload as a raw JSON string.
172
+ #
173
+ # @return [String] Payload translated to JSON
174
+ #
175
+ # @api public
176
+ def text
172
177
  result = {
173
178
  VERSION_KEY => version
174
179
  }
@@ -198,16 +203,7 @@ module NewRelic
198
203
  #
199
204
  # @api public
200
205
  def http_safe
201
- Base64.strict_encode64 to_json
202
- end
203
-
204
- # Represent this payload as a raw JSON string.
205
- #
206
- # @return [String] Payload translated to JSON
207
- #
208
- # @api public
209
- def text
210
- to_json
206
+ Base64.strict_encode64 text
211
207
  end
212
208
 
213
209
  def assign_intrinsics transaction, transaction_payload
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+ require 'socket'
4
5
 
5
6
  module NewRelic
6
7
  module Agent
@@ -16,6 +17,13 @@ module NewRelic
16
17
  end
17
18
  end
18
19
 
20
+ def self.get_fqdn
21
+ %x[hostname -f].chomp!
22
+ rescue => e
23
+ NewRelic::Agent.logger.debug "Unable to determine fqdn #{e}"
24
+ nil
25
+ end
26
+
19
27
  def self.heroku_dyno_name_prefix(dyno_name)
20
28
  get_dyno_prefixes.find do |dyno_prefix|
21
29
  dyno_name.start_with?(dyno_prefix + ".")
@@ -31,7 +31,7 @@ module NewRelic
31
31
  # we don't expect this to be called more than once, but we're being
32
32
  # defensive.
33
33
  return if defined?(cached?)
34
- if ::ActiveRecord::VERSION::STRING >= "5.1.0"
34
+ if defined?(::ActiveRecord) && ::ActiveRecord::VERSION::STRING >= "5.1.0"
35
35
  def cached?(payload)
36
36
  payload.fetch(:cached, false)
37
37
  end
@@ -57,19 +57,23 @@ DependencyDetection.defer do
57
57
  def pop(opts = {:manual_ack => false}, &block)
58
58
  t0 = Time.now
59
59
  msg = pop_without_new_relic opts, &block
60
+ delivery_info, message_properties, _payload = msg
60
61
 
61
62
  begin
62
- exchange_name = NewRelic::Agent::Instrumentation::Bunny.exchange_name(msg.first.exchange)
63
-
64
- segment = NewRelic::Agent::Messaging.start_amqp_consume_segment(
65
- library: NewRelic::Agent::Instrumentation::Bunny::LIBRARY,
66
- destination_name: exchange_name,
67
- delivery_info: msg[0],
68
- message_properties: msg[1],
69
- exchange_type: channel.exchanges[msg.first.exchange].type,
70
- queue_name: name,
71
- start_time: t0
72
- )
63
+ if delivery_info
64
+ exchange_name = NewRelic::Agent::Instrumentation::Bunny.exchange_name(delivery_info.exchange)
65
+ exchange_type = NewRelic::Agent::Instrumentation::Bunny.exchange_type(delivery_info, channel)
66
+
67
+ segment = NewRelic::Agent::Messaging.start_amqp_consume_segment(
68
+ library: NewRelic::Agent::Instrumentation::Bunny::LIBRARY,
69
+ destination_name: exchange_name,
70
+ delivery_info: delivery_info,
71
+ message_properties: message_properties,
72
+ exchange_type: exchange_type,
73
+ queue_name: name,
74
+ start_time: t0
75
+ )
76
+ end
73
77
 
74
78
  rescue => e
75
79
  NewRelic::Agent.logger.error "Error starting message broker segment in Bunny::Queue#pop", e
@@ -112,13 +112,9 @@ DependencyDetection.defer do
112
112
  alias_method :add_without_newrelic, :add
113
113
  alias_method :add, :add_with_newrelic
114
114
 
115
-
116
115
  # Trace as an External/Multiple call if the first request isn't serial.
117
116
  def perform_with_newrelic(&blk)
118
- return perform_without_newrelic if
119
- self.requests.first &&
120
- self.requests.first.respond_to?(:_nr_serial) &&
121
- self.requests.first._nr_serial
117
+ return perform_without_newrelic if first_request_is_serial?
122
118
 
123
119
  trace_execution_scoped("External/Multiple/Curb::Multi/perform") do
124
120
  perform_without_newrelic(&blk)
@@ -198,6 +194,23 @@ DependencyDetection.defer do
198
194
  request._nr_instrumented = false
199
195
  end
200
196
 
197
+ private
198
+
199
+ def first_request_is_serial?
200
+ return false unless (first = self.requests.first)
201
+
202
+ # Before curb 0.9.8, requests was an array of Curl::Easy
203
+ # instances. Starting with 0.9.8, it's a Hash where the
204
+ # values are Curl::Easy instances.
205
+ #
206
+ # So, requests.first will either be an_obj or [a_key, an_obj].
207
+ # We need to handle either case.
208
+ #
209
+ first = first[-1] if first.is_a?(Array)
210
+
211
+ first.respond_to?(:_nr_serial) && first._nr_serial
212
+ end
213
+
201
214
  end # class Curl::Multi
202
215
 
203
216
  end
@@ -16,7 +16,7 @@ module NewRelic
16
16
  # Specifies the version of the agent's communication protocol with
17
17
  # the NewRelic hosted site.
18
18
 
19
- PROTOCOL_VERSION = 16
19
+ PROTOCOL_VERSION = 17
20
20
 
21
21
  # 1f147a42: v10 (tag 3.5.3.17)
22
22
  # cf0d1ff1: v9 (tag 3.5.0)
@@ -43,6 +43,7 @@ module NewRelic
43
43
  @in_session = nil
44
44
  @agent_id = nil
45
45
  @shared_tcp_connection = nil
46
+ @request_headers_map = nil
46
47
  reset_remote_method_uris
47
48
 
48
49
  @audit_logger = ::NewRelic::Agent::AuditLogger.new
@@ -69,6 +70,7 @@ module NewRelic
69
70
  end
70
71
 
71
72
  def connect(settings={})
73
+ @request_headers_map = nil
72
74
  security_policies = nil
73
75
  if response = preconnect
74
76
  if host = response['redirect_host']
@@ -80,6 +82,7 @@ module NewRelic
80
82
  end
81
83
  end
82
84
  response = invoke_remote(:connect, [settings])
85
+ @request_headers_map = response['request_headers_map']
83
86
  self.agent_id = response['agent_run_id']
84
87
  response.merge!(security_policies) if security_policies
85
88
  response
@@ -404,7 +407,7 @@ module NewRelic
404
407
  def invoke_remote(method, payload = [], options = {})
405
408
  start_ts = Time.now
406
409
 
407
- data, size, serialize_finish_ts = nil
410
+ data, size, serialize_finish_ts, request_send_ts, response_check_ts = nil
408
411
  begin
409
412
  data = @marshaller.dump(payload, options)
410
413
  rescue StandardError, SystemStackError => e
@@ -419,13 +422,16 @@ module NewRelic
419
422
  full_uri = "#{@collector}#{uri}"
420
423
 
421
424
  @audit_logger.log_request(full_uri, payload, @marshaller)
425
+ request_send_ts = Time.now
422
426
  response = send_request(:data => data,
423
427
  :uri => uri,
424
428
  :encoding => encoding,
425
- :collector => @collector)
429
+ :collector => @collector,
430
+ :endpoint => method)
431
+ response_check_ts = Time.now
426
432
  @marshaller.load(decompress_response(response))
427
433
  ensure
428
- record_timing_supportability_metrics(method, start_ts, serialize_finish_ts)
434
+ record_timing_supportability_metrics(method, start_ts, serialize_finish_ts, request_send_ts, response_check_ts)
429
435
  if size
430
436
  record_size_supportability_metrics(method, size, options[:item_count])
431
437
  end
@@ -440,11 +446,12 @@ module NewRelic
440
446
  raise error
441
447
  end
442
448
 
443
- def record_timing_supportability_metrics(method, start_ts, serialize_finish_ts)
449
+ def record_timing_supportability_metrics(method, start_ts, serialize_finish_ts, request_send_ts, response_check_ts)
444
450
  serialize_time = serialize_finish_ts && (serialize_finish_ts - start_ts)
445
- duration = (Time.now - start_ts).to_f
446
- NewRelic::Agent.record_metric("Supportability/invoke_remote", duration)
447
- NewRelic::Agent.record_metric("Supportability/invoke_remote/#{method.to_s}", duration)
451
+ request_duration = response_check_ts && (response_check_ts - request_send_ts).to_f
452
+ if request_duration
453
+ NewRelic::Agent.record_metric("Supportability/Agent/Collector/#{method.to_s}/Duration", request_duration)
454
+ end
448
455
  if serialize_time
449
456
  NewRelic::Agent.record_metric("Supportability/invoke_remote_serialize", serialize_time)
450
457
  NewRelic::Agent.record_metric("Supportability/invoke_remote_serialize/#{method.to_s}", serialize_time)
@@ -489,10 +496,16 @@ module NewRelic
489
496
  # contact
490
497
  # - :data => the data to send as the body of the request
491
498
  def send_request(opts)
499
+ headers = {
500
+ 'Content-Encoding' => opts[:encoding],
501
+ 'Host' => opts[:collector].name
502
+ }
503
+ headers.merge!(@request_headers_map) if @request_headers_map
504
+
492
505
  if Agent.config[:put_for_data_send]
493
- request = Net::HTTP::Put.new(opts[:uri], 'CONTENT-ENCODING' => opts[:encoding], 'HOST' => opts[:collector].name)
506
+ request = Net::HTTP::Put.new(opts[:uri], headers)
494
507
  else
495
- request = Net::HTTP::Post.new(opts[:uri], 'CONTENT-ENCODING' => opts[:encoding], 'HOST' => opts[:collector].name)
508
+ request = Net::HTTP::Post.new(opts[:uri], headers)
496
509
  end
497
510
  request['user-agent'] = user_agent
498
511
  request.content_type = "application/octet-stream"
@@ -501,6 +514,7 @@ module NewRelic
501
514
  response = nil
502
515
  attempts = 0
503
516
  max_attempts = 2
517
+ endpoint = opts[:endpoint]
504
518
 
505
519
  begin
506
520
  attempts += 1
@@ -522,20 +536,43 @@ module NewRelic
522
536
  log_response(response)
523
537
 
524
538
  case response
525
- when Net::HTTPSuccess
539
+ when Net::HTTPSuccess,
540
+ Net::HTTPAccepted
526
541
  true # do nothing
527
- when Net::HTTPUnauthorized
528
- raise LicenseException, 'Invalid license key, please visit support.newrelic.com'
529
- when Net::HTTPServiceUnavailable
530
- raise ServerConnectionException, "Service unavailable (#{response.code}): #{response.message}"
531
- when Net::HTTPGatewayTimeOut
532
- raise ServerConnectionException, "Gateway timeout (#{response.code}): #{response.message}"
533
- when Net::HTTPRequestEntityTooLarge
534
- raise UnrecoverableServerException, '413 Request Entity Too Large'
535
- when Net::HTTPUnsupportedMediaType
536
- raise UnrecoverableServerException, '415 Unsupported Media Type'
542
+ when Net::HTTPRequestTimeOut,
543
+ Net::HTTPTooManyRequests,
544
+ Net::HTTPInternalServerError,
545
+ Net::HTTPServiceUnavailable
546
+ record_endpoint_attempts_supportability_metrics(endpoint)
547
+ raise ServerConnectionException, "#{response.code}: #{response.message}"
548
+ when Net::HTTPBadRequest,
549
+ Net::HTTPForbidden,
550
+ Net::HTTPNotFound,
551
+ Net::HTTPMethodNotAllowed,
552
+ Net::HTTPProxyAuthenticationRequired,
553
+ Net::HTTPLengthRequired,
554
+ Net::HTTPRequestEntityTooLarge,
555
+ Net::HTTPRequestURITooLong,
556
+ Net::HTTPUnsupportedMediaType,
557
+ Net::HTTPExpectationFailed,
558
+ Net::HTTPUnsupportedMediaType,
559
+ Net::HTTPRequestHeaderFieldsTooLarge
560
+ record_endpoint_attempts_supportability_metrics(endpoint)
561
+ record_error_response_supportability_metrics(response.code)
562
+ raise UnrecoverableServerException, "#{response.code}: #{response.message}"
563
+ when Net::HTTPConflict,
564
+ Net::HTTPUnauthorized
565
+ record_endpoint_attempts_supportability_metrics(endpoint)
566
+ record_error_response_supportability_metrics(response.code)
567
+ raise ForceRestartException, "#{response.code}: #{response.message}"
568
+ when Net::HTTPGone
569
+ record_endpoint_attempts_supportability_metrics(endpoint)
570
+ record_error_response_supportability_metrics(response.code)
571
+ raise ForceDisconnectException, "#{response.code}: #{response.message}"
537
572
  else
538
- raise ServerConnectionException, "Unexpected response from server (#{response.code}): #{response.message}"
573
+ record_endpoint_attempts_supportability_metrics(endpoint)
574
+ record_error_response_supportability_metrics(response.code)
575
+ raise UnrecoverableServerException, "#{response.code}: #{response.message}"
539
576
  end
540
577
  response
541
578
  end
@@ -544,6 +581,16 @@ module NewRelic
544
581
  ::NewRelic::Agent.logger.debug "Received response, status: #{response.code}, encoding: '#{response['content-encoding']}'"
545
582
  end
546
583
 
584
+ # Per protocol 17, this metric should be recorded for all error response codes
585
+ # that cause data to be discarded.
586
+ def record_error_response_supportability_metrics(response_code)
587
+ ::NewRelic::Agent.increment_metric("Supportability/Agent/Collector/HTTPError/#{response_code}")
588
+ end
589
+
590
+ def record_endpoint_attempts_supportability_metrics(endpoint)
591
+ ::NewRelic::Agent.increment_metric("Supportability/Agent/Collector/#{endpoint}/Attempts")
592
+ end
593
+
547
594
  # Decompresses the response from the server, if it is gzip
548
595
  # encoded, otherwise returns it verbatim
549
596
  def decompress_response(response)
@@ -566,9 +613,6 @@ module NewRelic
566
613
  zlib_version << "zlib/#{Zlib.zlib_version}" if defined?(::Zlib) && Zlib.respond_to?(:zlib_version)
567
614
  "NewRelic-RubyAgent/#{NewRelic::VERSION::STRING} #{ruby_description}#{zlib_version}"
568
615
  end
569
-
570
- # Used to wrap errors reported to agent by the collector
571
- class CollectorError < StandardError; end
572
616
  end
573
617
  end
574
618
  end
@@ -39,7 +39,6 @@ module NewRelic
39
39
 
40
40
  def load(data)
41
41
  if data.nil? || data.empty?
42
- ::NewRelic::Agent.logger.error "Empty JSON response from collector: '#{data.inspect}'"
43
42
  return nil
44
43
  end
45
44
 
@@ -6,24 +6,6 @@ module NewRelic
6
6
  module Agent
7
7
  class NewRelicService
8
8
  class Marshaller
9
- def parsed_error(error)
10
- error_type = error['error_type']
11
- error_message = error['message']
12
-
13
- exception = case error_type
14
- when 'NewRelic::Agent::LicenseException'
15
- LicenseException.new(error_message)
16
- when 'NewRelic::Agent::ForceRestartException'
17
- ForceRestartException.new(error_message)
18
- when 'NewRelic::Agent::ForceDisconnectException'
19
- ForceDisconnectException.new(error_message)
20
- else
21
- CollectorError.new("#{error['error_type']}: #{error['message']}")
22
- end
23
-
24
- exception
25
- end
26
-
27
9
  def prepare(data, options={})
28
10
  encoder = options[:encoder] || default_encoder
29
11
  if data.respond_to?(:to_collector_array)
@@ -46,15 +28,12 @@ module NewRelic
46
28
  protected
47
29
 
48
30
  def return_value(data)
49
- if data.respond_to?(:has_key?)
50
- if data.has_key?('exception')
51
- raise parsed_error(data['exception'])
52
- elsif data.has_key?('return_value')
53
- return data['return_value']
54
- end
31
+ if data.respond_to?(:has_key?) && data.has_key?('return_value')
32
+ data['return_value']
33
+ else
34
+ ::NewRelic::Agent.logger.debug("Unexpected response from collector: #{data}")
35
+ nil
55
36
  end
56
- ::NewRelic::Agent.logger.debug("Unexpected response from collector: #{data}")
57
- nil
58
37
  end
59
38
  end
60
39
  end
@@ -8,6 +8,7 @@
8
8
  # the requested information is unavailable.
9
9
 
10
10
  require 'rbconfig'
11
+ require 'socket'
11
12
 
12
13
  module NewRelic
13
14
  module Agent
@@ -30,6 +31,10 @@ module NewRelic
30
31
 
31
32
  @processor_info = nil
32
33
 
34
+ def self.ip_addresses
35
+ Socket.ip_address_list.map(&:ip_address)
36
+ end
37
+
33
38
  def self.clear_processor_info
34
39
  @processor_info = nil
35
40
  end
@@ -2,8 +2,6 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
 
5
- require 'objspace'
6
-
7
5
  # This module powers the Busy calculation for the Capacity report in
8
6
  # APM (https://rpm.newrelic.com/accounts/.../applications/.../optimize/capacity_analysis).
9
7
  #
@@ -102,12 +100,27 @@ module NewRelic
102
100
  end
103
101
 
104
102
  def thread_is_alive?(thread_id)
105
- thread = ObjectSpace._id2ref(thread_id)
103
+ thread = thread_by_id thread_id
106
104
  thread && thread.alive?
107
105
  rescue StandardError
108
106
  false
109
107
  end
110
108
 
109
+ # ObjectSpace is faster on MRI, but disabled by default on JRuby for
110
+ # perfomance reasons. We have two implmentations of `thread_by_id`
111
+ # based on ruby implementation.
112
+ if RUBY_ENGINE == 'jruby'
113
+ def thread_by_id thread_id
114
+ Thread.list.detect { |t| t.object_id == thread_id }
115
+ end
116
+ else
117
+ require 'objspace'
118
+
119
+ def thread_by_id thread_id
120
+ ObjectSpace._id2ref(thread_id)
121
+ end
122
+ end
123
+
111
124
  def set_transaction_start_time(timestamp, thread_id = current_thread)
112
125
  @stats[thread_id].transaction_started_at = timestamp
113
126
  end
@@ -131,7 +144,9 @@ module NewRelic
131
144
  end
132
145
 
133
146
  def log_missing_elapsed_transaction_time
134
- transaction_name = Tracer.current_transaction.best_name
147
+ transaction_name = Tracer.current_transaction &&
148
+ Tracer.current_transaction.best_name ||
149
+ "unknown"
135
150
  NewRelic::Agent.logger.warn("Unable to calculate elapsed transaction time for #{transaction_name}")
136
151
  end
137
152
  end
@@ -7,10 +7,11 @@ require 'new_relic/agent/utilization/gcp'
7
7
  require 'new_relic/agent/utilization/azure'
8
8
  require 'new_relic/agent/utilization/pcf'
9
9
 
10
+
10
11
  module NewRelic
11
12
  module Agent
12
13
  class UtilizationData
13
- METADATA_VERSION = 3
14
+ METADATA_VERSION = 5
14
15
 
15
16
  VENDORS = {
16
17
  Utilization::AWS => :'utilization.detect_aws',
@@ -23,6 +24,14 @@ module NewRelic
23
24
  NewRelic::Agent::Hostname.get
24
25
  end
25
26
 
27
+ def fqdn
28
+ NewRelic::Agent::Hostname.get_fqdn
29
+ end
30
+
31
+ def ip_addresses
32
+ ::NewRelic::Agent::SystemInfo.ip_addresses
33
+ end
34
+
26
35
  def container_id
27
36
  ::NewRelic::Agent::SystemInfo.docker_container_id
28
37
  end
@@ -69,6 +78,9 @@ module NewRelic
69
78
  append_docker_info(result)
70
79
  append_configured_values(result)
71
80
  append_boot_id(result)
81
+ append_ip_address(result)
82
+ append_full_hostname(result)
83
+ append_kubernetes_info(result)
72
84
 
73
85
  result
74
86
  end
@@ -105,6 +117,29 @@ module NewRelic
105
117
  end
106
118
  end
107
119
 
120
+ def append_ip_address(collector_hash)
121
+ ips = ip_addresses
122
+ collector_hash[:ip_address] = ips unless ips.empty?
123
+ end
124
+
125
+ KUBERNETES_SERVICE_HOST = 'KUBERNETES_SERVICE_HOST'.freeze
126
+
127
+ def append_kubernetes_info(collector_hash)
128
+ return unless Agent.config[:'utilization.detect_kubernetes']
129
+ if host = ENV[KUBERNETES_SERVICE_HOST]
130
+ collector_hash[:vendors] ||= {}
131
+ collector_hash[:vendors][:kubernetes] = {
132
+ kubernetes_service_host: host
133
+ }
134
+ end
135
+ end
136
+
137
+ def append_full_hostname(collector_hash)
138
+ full_hostname = fqdn
139
+ return if full_hostname.nil? || full_hostname.empty?
140
+ collector_hash[:full_hostname] = full_hostname
141
+ end
142
+
108
143
  def config_hash
109
144
  config_hash = {}
110
145
 
@@ -11,7 +11,7 @@ module NewRelic
11
11
  end
12
12
 
13
13
  MAJOR = 6
14
- MINOR = 0
14
+ MINOR = 2
15
15
  TINY = 0
16
16
 
17
17
  begin
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.version = NewRelic::VERSION::STRING
11
11
  s.required_ruby_version = '>= 2.0.0'
12
12
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
13
- s.authors = [ "Matthew Wear", "Chris Pine", "Erin Dees", "Rachel Klein" ]
13
+ s.authors = [ "Matthew Wear", "Chris Pine", "Rachel Klein", "Justin Foote" ]
14
14
  s.date = Time.now.strftime('%Y-%m-%d')
15
15
  s.licenses = ['New Relic']
16
16
  s.description = <<-EOS
@@ -45,15 +45,8 @@ EOS
45
45
  s.add_development_dependency 'minitest', '~> 4.7.5'
46
46
  s.add_development_dependency 'mocha', '~> 0.13.0'
47
47
  s.add_development_dependency 'yard'
48
- s.add_development_dependency 'rails', '~> 3.2.13'
49
- s.add_development_dependency 'json', '>= 2.0.2' if RUBY_VERSION >= '2.4.0' # possible bundler issue?
50
48
  s.add_development_dependency 'pry-nav', '~> 0.2.4'
51
49
  s.add_development_dependency 'pry-stack_explorer', '~> 0.4.9'
52
50
  s.add_development_dependency 'hometown', '~> 0.2.5'
53
-
54
- if RUBY_PLATFORM == 'java'
55
- s.add_development_dependency 'activerecord-jdbcsqlite3-adapter'
56
- else
57
- s.add_development_dependency 'sqlite3'
58
- end
51
+ s.add_development_dependency 'bundler', '< 2.0'
59
52
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newrelic_rpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0.351
4
+ version: 6.2.0.354
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Wear
8
8
  - Chris Pine
9
- - Erin Dees
10
9
  - Rachel Klein
10
+ - Justin Foote
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2019-01-23 00:00:00.000000000 Z
14
+ date: 2019-03-12 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rake
@@ -69,34 +69,6 @@ dependencies:
69
69
  - - ">="
70
70
  - !ruby/object:Gem::Version
71
71
  version: '0'
72
- - !ruby/object:Gem::Dependency
73
- name: rails
74
- requirement: !ruby/object:Gem::Requirement
75
- requirements:
76
- - - "~>"
77
- - !ruby/object:Gem::Version
78
- version: 3.2.13
79
- type: :development
80
- prerelease: false
81
- version_requirements: !ruby/object:Gem::Requirement
82
- requirements:
83
- - - "~>"
84
- - !ruby/object:Gem::Version
85
- version: 3.2.13
86
- - !ruby/object:Gem::Dependency
87
- name: json
88
- requirement: !ruby/object:Gem::Requirement
89
- requirements:
90
- - - ">="
91
- - !ruby/object:Gem::Version
92
- version: 2.0.2
93
- type: :development
94
- prerelease: false
95
- version_requirements: !ruby/object:Gem::Requirement
96
- requirements:
97
- - - ">="
98
- - !ruby/object:Gem::Version
99
- version: 2.0.2
100
72
  - !ruby/object:Gem::Dependency
101
73
  name: pry-nav
102
74
  requirement: !ruby/object:Gem::Requirement
@@ -140,19 +112,19 @@ dependencies:
140
112
  - !ruby/object:Gem::Version
141
113
  version: 0.2.5
142
114
  - !ruby/object:Gem::Dependency
143
- name: sqlite3
115
+ name: bundler
144
116
  requirement: !ruby/object:Gem::Requirement
145
117
  requirements:
146
- - - ">="
118
+ - - "<"
147
119
  - !ruby/object:Gem::Version
148
- version: '0'
120
+ version: '2.0'
149
121
  type: :development
150
122
  prerelease: false
151
123
  version_requirements: !ruby/object:Gem::Requirement
152
124
  requirements:
153
- - - ">="
125
+ - - "<"
154
126
  - !ruby/object:Gem::Version
155
- version: '0'
127
+ version: '2.0'
156
128
  description: |
157
129
  New Relic is a performance management system, developed by New Relic,
158
130
  Inc (http://www.newrelic.com). New Relic provides you with deep
@@ -489,8 +461,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
489
461
  - !ruby/object:Gem::Version
490
462
  version: 1.3.1
491
463
  requirements: []
492
- rubyforge_project:
493
- rubygems_version: 2.7.7
464
+ rubygems_version: 3.0.3
494
465
  signing_key:
495
466
  specification_version: 4
496
467
  summary: New Relic Ruby Agent