newrelic_rpm 4.3.0.335 → 4.4.0.336

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
  SHA1:
3
- metadata.gz: 4c39aaf49c14d8f52c0ad1551e36d973c7ec9130
4
- data.tar.gz: dda64be5f11fe80294aaac0c4435442aabdd69f2
3
+ metadata.gz: b9d189b04c1171316153a227be91c6abad18f00a
4
+ data.tar.gz: 2b1c100c3778ba5fa95937d6d87bbe9949fb99a1
5
5
  SHA512:
6
- metadata.gz: 504238d5388bcc1857fe19282a581f5011597c9a21484c321a7696628a2f078b6c232e1f2a11c417440b07db9860892a6a1a6448d1b9c64c61e289096130f1b5
7
- data.tar.gz: 04b9adc55208fb75aa0437aadf72a7daf7c74730f55b0f3c9658dd38cafb7d5ca3170f80154036eebbe0d6eddacb1c468f54c28e1e0eaeca728698a226a08b02
6
+ metadata.gz: e77e92639fc53364aaf68627c4d41f1bc9e61ad6f2ce1978732d206a3b7eaf84ee72f06a934a92087179b3c534ea4803d7da5fe6d134416bd32b14f1e7532483
7
+ data.tar.gz: 566143ee90b3f3c027cb4201824766986d62c66cc78f2311da53861f23dcd272deb528dabceb36efd37db5fcc8e9f8b28f45d12f3729362feea58044dbe87b76
data/.yardopts CHANGED
@@ -7,6 +7,7 @@ lib/new_relic/agent/instrumentation/rack.rb
7
7
  lib/new_relic/agent/instrumentation/metric_frame.rb
8
8
  lib/new_relic/agent/stats_engine/metric_stats.rb
9
9
  lib/new_relic/agent/datastores.rb
10
+ lib/new_relic/agent/messaging.rb
10
11
  lib/new_relic/agent/sql_sampler.rb
11
12
  lib/new_relic/agent/transaction.rb
12
13
  lib/new_relic/agent/transaction_sampler.rb
@@ -1,5 +1,46 @@
1
1
  # New Relic Ruby Agent Release Notes #
2
2
 
3
+ ## v4.4.0 ##
4
+
5
+ * Include test helper for 3rd party use
6
+
7
+ In 4.2.0, all test files were excluded from being packaged in the gem. An
8
+ agent class method `NewRelic::Agent.require_test_helper` was used by 3rd
9
+ party gem authors to test extensions to the agent. The required file is now
10
+ included in the gem.
11
+
12
+ * Collect cloud metadata from Azure, GCP, PCF, and AWS cloud platform
13
+
14
+ The agent now collects additional metadata when running in AWS, GCP, Azure, and
15
+ PCF. This information is used to provide an enhanced experience when the agent
16
+ is deployed on those platforms.
17
+
18
+ * Install `at_exit` hook when running JRuby
19
+
20
+ The agent now installs an `at_exit` hook when running JRuby, which wasn't
21
+ done before because of constraints related to older JRuby versions that
22
+ are no longer supported.
23
+
24
+ * User/Utilization and System/Utilization metrics not recorded after Resque forks
25
+
26
+ The agent no longer records invalid User/Utilization and System/Utilization
27
+ metrics, which can lead to negative values, in forks of Resque processes.
28
+
29
+ * Add `identifier` field to agent connect settings
30
+
31
+ The agent now includes a unique identifier in its connect settings, ensuring
32
+ that when multiple agents connect to multiple different apps, data are reported
33
+ for each of the apps.
34
+
35
+ * Clear transaction state after forking now opt-in
36
+
37
+ The agent waits to connect until the first web request when it detects it's
38
+ running in a forking dispatcher. When clearing the transaction state in this
39
+ situation we lose the first frame of the transaction and the subsequent
40
+ trace becomes corrupted. We've made this feature opt-in and is turned off by
41
+ default. This behavior only affects the first transaction after a dispatcher
42
+ forks.
43
+
3
44
  ## v4.3.0 ##
4
45
 
5
46
  * Instrumentation for the Bunny AMQP Client
@@ -377,7 +377,6 @@ module NewRelic
377
377
  def should_install_exit_handler?
378
378
  (
379
379
  Agent.config[:send_data_on_exit] &&
380
- !NewRelic::LanguageSupport.jruby? &&
381
380
  !sinatra_classic_app?
382
381
  )
383
382
  end
@@ -543,7 +542,9 @@ module NewRelic
543
542
  @transaction_event_recorder.drop_buffered_data
544
543
  @custom_event_aggregator.reset!
545
544
  @sql_sampler.reset!
546
- TransactionState.tl_clear
545
+ if Agent.config[:clear_transaction_state_after_fork]
546
+ TransactionState.tl_clear
547
+ end
547
548
  end
548
549
 
549
550
  # Clear out state for any objects that we know lock from our parents
@@ -803,7 +804,8 @@ module NewRelic
803
804
  :environment => @environment_report,
804
805
  :settings => Agent.config.to_collector_hash,
805
806
  :high_security => Agent.config[:high_security],
806
- :utilization => UtilizationData.new.to_collector_hash
807
+ :utilization => UtilizationData.new.to_collector_hash,
808
+ :identifier => "ruby:#{local_host}:#{Agent.config.app_names.sort.join(',')}"
807
809
  }
808
810
  end
809
811
 
@@ -1561,8 +1561,33 @@ module NewRelic
1561
1561
  :public => true,
1562
1562
  :type => Boolean,
1563
1563
  :allowed_from_server => false,
1564
+ :dynamic_name => true,
1564
1565
  :description => 'If <code>true</code>, the agent automatically detects that it is running in an AWS environment.'
1565
1566
  },
1567
+ :'utilization.detect_azure' => {
1568
+ :default => true,
1569
+ :public => true,
1570
+ :type => Boolean,
1571
+ :allowed_from_server => false,
1572
+ :dynamic_name => true,
1573
+ :description => 'If <code>true</code>, the agent automatically detects that it is running in an Azure environment.'
1574
+ },
1575
+ :'utilization.detect_gcp' => {
1576
+ :default => true,
1577
+ :public => true,
1578
+ :type => Boolean,
1579
+ :allowed_from_server => false,
1580
+ :dynamic_name => true,
1581
+ :description => 'If <code>true</code>, the agent automatically detects that it is running in an Google Cloud Platform environment.'
1582
+ },
1583
+ :'utilization.detect_pcf' => {
1584
+ :default => true,
1585
+ :public => true,
1586
+ :type => Boolean,
1587
+ :allowed_from_server => false,
1588
+ :dynamic_name => true,
1589
+ :description => 'If <code>true</code>, the agent automatically detects that it is running in a Pivotal Cloud Foundry environment.'
1590
+ },
1566
1591
  :'utilization.detect_docker' => {
1567
1592
  :default => true,
1568
1593
  :public => true,
@@ -1607,6 +1632,13 @@ module NewRelic
1607
1632
  :type => Boolean,
1608
1633
  :allowed_from_server => false,
1609
1634
  :description => 'If <code>false</code>, the agent will not add <code>database_name</code> parameter to transaction or slow sql traces.'
1635
+ },
1636
+ :'clear_transaction_state_after_fork' => {
1637
+ :default => false,
1638
+ :public => true,
1639
+ :type => Boolean,
1640
+ :allowed_from_server => false,
1641
+ :description => 'If <code>true</code>, the agent will clear <code>TransactionState</code> in <code>Agent.drop_buffered_data</code>.'
1610
1642
  }
1611
1643
  }.freeze
1612
1644
  end
@@ -50,7 +50,8 @@ module NewRelic
50
50
  def poll
51
51
  now = Time.now
52
52
  t = Process.times
53
- if @last_time
53
+
54
+ if @last_time && t.utime != 0.0 && t.stime != 0.0
54
55
  elapsed = now - @last_time
55
56
  return if elapsed < 1 # Causing some kind of math underflow
56
57
 
@@ -62,10 +63,10 @@ module NewRelic
62
63
 
63
64
  # Calculate the true utilization by taking cpu times and dividing by
64
65
  # elapsed time X processor_count.
65
-
66
66
  record_user_util(usertime / (elapsed * @processor_count))
67
67
  record_system_util(systemtime / (elapsed * @processor_count))
68
68
  end
69
+
69
70
  @last_utime = t.utime
70
71
  @last_stime = t.stime
71
72
  @last_time = now
@@ -251,6 +251,40 @@ module NewRelic
251
251
  nil
252
252
  end
253
253
  end
254
+
255
+ def self.boot_id
256
+ return nil unless linux?
257
+ if bid = proc_try_read('/proc/sys/kernel/random/boot_id')
258
+ bid.chomp!
259
+
260
+ if bid.ascii_only?
261
+ if bid.empty?
262
+ ::NewRelic::Agent.logger.debug("boot_id not found in /proc/sys/kernel/random/boot_id")
263
+ ::NewRelic::Agent.increment_metric "Supportability/utilization/boot_id/error"
264
+ nil
265
+
266
+ elsif bid.bytesize == 36
267
+ bid
268
+
269
+ else
270
+ ::NewRelic::Agent.logger.debug("Found boot_id with invalid length: #{bid}")
271
+ ::NewRelic::Agent.increment_metric "Supportability/utilization/boot_id/error"
272
+ bid[0,128]
273
+
274
+ end
275
+ else
276
+ ::NewRelic::Agent.logger.debug("Found boot_id with non-ASCII characters: #{bid}")
277
+ ::NewRelic::Agent.increment_metric "Supportability/utilization/boot_id/error"
278
+ nil
279
+
280
+ end
281
+ else
282
+ ::NewRelic::Agent.logger.debug("boot_id not found in /proc/sys/kernel/random/boot_id")
283
+ ::NewRelic::Agent.increment_metric "Supportability/utilization/boot_id/error"
284
+ nil
285
+
286
+ end
287
+ end
254
288
  end
255
289
  end
256
290
  end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ require 'new_relic/agent/utilization/vendor'
6
+
7
+ module NewRelic
8
+ module Agent
9
+ module Utilization
10
+ class AWS < Vendor
11
+ vendor_name "aws"
12
+ endpoint "http://169.254.169.254/2016-09-02/dynamic/instance-identity/document"
13
+ keys ["instanceId", "instanceType", "availabilityZone"]
14
+ key_transforms :to_sym
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ module NewRelic
6
+ module Agent
7
+ module Utilization
8
+ class Azure < Vendor
9
+ vendor_name "azure"
10
+ endpoint "http://169.254.169.254/metadata/instance/compute?api-version=2017-03-01"
11
+ headers "Metadata" => "true"
12
+ keys ["vmId", "name", "vmSize", "location"]
13
+ key_transforms :to_sym
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ require 'new_relic/agent/utilization/vendor'
6
+
7
+ module NewRelic
8
+ module Agent
9
+ module Utilization
10
+ class GCP < Vendor
11
+ vendor_name "gcp"
12
+ endpoint "http://metadata.google.internal/computeMetadata/v1/instance/?recursive=true"
13
+ headers "Metadata-Flavor" => "Google"
14
+ keys ["id", "machineType", "name", "zone"]
15
+ key_transforms :to_sym
16
+
17
+ MACH_TYPE = 'machineType'.freeze
18
+ ZONE = 'zone'.freeze
19
+
20
+ def prepare_response response
21
+ body = JSON.parse response.body
22
+ body[MACH_TYPE] = trim_leading body[MACH_TYPE]
23
+ body[ZONE] = trim_leading body[ZONE]
24
+ body
25
+ end
26
+
27
+ SLASH = '/'.freeze
28
+
29
+ def trim_leading value
30
+ value.split(SLASH).last
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ require 'new_relic/agent/utilization/vendor'
6
+
7
+ module NewRelic
8
+ module Agent
9
+ module Utilization
10
+ class PCF < Vendor
11
+ vendor_name "pcf"
12
+ keys ["CF_INSTANCE_GUID", "CF_INSTANCE_IP", "MEMORY_LIMIT"]
13
+ key_transforms [:downcase, :to_sym]
14
+
15
+ def detect
16
+ begin
17
+ return false unless pcf_keys_present?
18
+ process_response ENV
19
+ rescue
20
+ NewRelic::Agent.logger.error "Error occurred detecting: #{vendor_name}", e
21
+ record_supportability_metric
22
+ false
23
+ end
24
+ end
25
+
26
+ def pcf_keys_present?
27
+ !(ENV.keys & keys).empty?
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,144 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ require 'net/http'
6
+
7
+ module NewRelic
8
+ module Agent
9
+ module Utilization
10
+ class Vendor
11
+ class << self
12
+ def vendor_name vendor_name = nil
13
+ vendor_name ? @vendor_name = vendor_name.freeze : @vendor_name
14
+ end
15
+
16
+ def endpoint endpoint = nil
17
+ endpoint ? @endpoint = URI(endpoint) : @endpoint
18
+ end
19
+
20
+ def headers headers = nil
21
+ headers ? @headers = headers.freeze : @headers
22
+ end
23
+
24
+ def keys keys = nil
25
+ keys ? @keys = keys.freeze : @keys
26
+ end
27
+
28
+ def key_transforms key_transforms = nil
29
+ key_transforms ? @key_transforms = Array(key_transforms).freeze : @key_transforms
30
+ end
31
+ end
32
+
33
+ attr_reader :metadata
34
+
35
+ def initialize
36
+ @metadata = {}
37
+ end
38
+
39
+ [:vendor_name, :endpoint, :headers, :keys, :key_transforms].each do |method_name|
40
+ define_method(method_name) { self.class.send(method_name) }
41
+ end
42
+
43
+ SUCCESS = '200'.freeze
44
+
45
+ def detect
46
+ response = request_metadata
47
+ return false unless response
48
+
49
+ begin
50
+ if response.code == SUCCESS
51
+ process_response prepare_response(response)
52
+ else
53
+ false
54
+ end
55
+ rescue => e
56
+ NewRelic::Agent.logger.error "Error occurred detecting: #{vendor_name}", e
57
+ record_supportability_metric
58
+ false
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def request_metadata
65
+ Timeout.timeout 1 do
66
+ response = nil
67
+ Net::HTTP.start endpoint.host, endpoint.port do |http|
68
+ req = Net::HTTP::Get.new endpoint, headers
69
+ response = http.request req
70
+ end
71
+ response
72
+ end
73
+ rescue
74
+ NewRelic::Agent.logger.debug "#{vendor_name} environment not detected"
75
+ end
76
+
77
+ def prepare_response response
78
+ JSON.parse response.body
79
+ end
80
+
81
+ def process_response response
82
+ keys.each do |key|
83
+ normalized = normalize response[key]
84
+ if normalized
85
+ @metadata[transform_key(key)] = normalized
86
+ else
87
+ @metadata.clear
88
+ record_supportability_metric
89
+ return false
90
+ end
91
+ end
92
+ true
93
+ end
94
+
95
+ def normalize value
96
+ return if value.nil?
97
+
98
+ value = value.to_s
99
+ value = value.dup if value.frozen?
100
+
101
+ value.force_encoding Encoding::UTF_8
102
+ value.strip!
103
+
104
+ return unless valid_length? value
105
+ return unless valid_chars? value
106
+
107
+ value
108
+ end
109
+
110
+ def valid_length? value
111
+ if value.bytesize <= 255
112
+ true
113
+ else
114
+ NewRelic::Agent.logger.warn "Found invalid length value while detecting: #{vendor_name}"
115
+ false
116
+ end
117
+ end
118
+
119
+ VALID_CHARS = /^[0-9a-zA-Z_ .\/-]$/
120
+
121
+ def valid_chars? value
122
+ value.each_char do |ch|
123
+ next if ch =~ VALID_CHARS
124
+ code_point = ch[0].ord # this works in Ruby 1.8.7 - 2.1.2
125
+ next if code_point >= 0x80
126
+
127
+ NewRelic::Agent.logger.warn "Found invalid character while detecting: #{vendor_name}"
128
+ return false # it's in neither set of valid characters
129
+ end
130
+ true
131
+ end
132
+
133
+ def transform_key key
134
+ return key unless key_transforms
135
+ key_transforms.inject(key) { |memo, transform| memo.send(transform) }
136
+ end
137
+
138
+ def record_supportability_metric
139
+ NewRelic::Agent.increment_metric "Supportability/utilization/#{vendor_name}/error"
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end