newrelic_rpm 6.7.0.359 → 6.8.0.360
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +41 -6
- data/CHANGELOG.md +76 -0
- data/Guardfile +7 -1
- data/lib/new_relic/agent.rb +31 -0
- data/lib/new_relic/agent/agent.rb +7 -2
- data/lib/new_relic/agent/agent_logger.rb +4 -0
- data/lib/new_relic/agent/attribute_filter.rb +7 -7
- data/lib/new_relic/agent/attributes.rb +152 -0
- data/lib/new_relic/agent/autostart.rb +19 -14
- data/lib/new_relic/agent/configuration/default_source.rb +72 -5
- data/lib/new_relic/agent/configuration/yaml_source.rb +10 -5
- data/lib/new_relic/agent/connect/request_builder.rb +3 -11
- data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +2 -2
- data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +8 -8
- data/lib/new_relic/agent/distributed_trace_intrinsics.rb +90 -0
- data/lib/new_relic/agent/distributed_trace_metrics.rb +74 -0
- data/lib/new_relic/agent/distributed_trace_monitor.rb +2 -12
- data/lib/new_relic/agent/distributed_trace_payload.rb +9 -76
- data/lib/new_relic/agent/distributed_trace_transport_type.rb +43 -0
- data/lib/new_relic/agent/guid_generator.rb +28 -0
- data/lib/new_relic/agent/logging.rb +4 -0
- data/lib/new_relic/agent/new_relic_service.rb +7 -5
- data/lib/new_relic/agent/span_event_aggregator.rb +1 -0
- data/lib/new_relic/agent/span_event_primitive.rb +29 -7
- data/lib/new_relic/agent/sql_sampler.rb +1 -1
- data/lib/new_relic/agent/trace_context.rb +244 -0
- data/lib/new_relic/agent/trace_context_payload.rb +134 -0
- data/lib/new_relic/agent/trace_context_request_monitor.rb +42 -0
- data/lib/new_relic/agent/transaction.rb +26 -18
- data/lib/new_relic/agent/transaction/abstract_segment.rb +2 -2
- data/lib/new_relic/agent/transaction/distributed_tracing.rb +20 -101
- data/lib/new_relic/agent/transaction/external_request_segment.rb +18 -5
- data/lib/new_relic/agent/transaction/segment.rb +7 -1
- data/lib/new_relic/agent/transaction/trace_context.rb +159 -0
- data/lib/new_relic/agent/transaction/trace_node.rb +8 -3
- data/lib/new_relic/agent/transaction_error_primitive.rb +4 -11
- data/lib/new_relic/agent/transaction_event_primitive.rb +3 -11
- data/lib/new_relic/coerce.rb +29 -6
- data/lib/new_relic/control/instance_methods.rb +10 -1
- data/lib/new_relic/dependency_detection.rb +4 -4
- data/lib/new_relic/noticed_error.rb +8 -4
- data/lib/new_relic/version.rb +1 -1
- data/newrelic_rpm.gemspec +6 -4
- data/test/agent_helper.rb +88 -9
- data/true +0 -0
- metadata +50 -18
- data/lib/new_relic/agent/transaction/attributes.rb +0 -154
- data/lib/tasks/versions.html.erb +0 -28
- data/lib/tasks/versions.postface.html +0 -8
- data/lib/tasks/versions.preface.html +0 -9
- data/lib/tasks/versions.rake +0 -65
- data/lib/tasks/versions.txt.erb +0 -14
data/lib/new_relic/version.rb
CHANGED
data/newrelic_rpm.gemspec
CHANGED
@@ -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 = [ "
|
13
|
+
s.authors = [ "Chris Pine", "Rachel Klein", "Justin Foote", "Michael Lang" ]
|
14
14
|
s.date = Time.now.strftime('%Y-%m-%d')
|
15
15
|
s.licenses = ['New Relic']
|
16
16
|
s.description = <<-EOS
|
@@ -48,12 +48,14 @@ EOS
|
|
48
48
|
s.rubygems_version = Gem::VERSION
|
49
49
|
s.summary = "New Relic Ruby Agent"
|
50
50
|
|
51
|
-
s.add_development_dependency 'rake', '
|
51
|
+
s.add_development_dependency 'rake', '12.3.3'
|
52
52
|
s.add_development_dependency 'minitest', '~> 4.7.5'
|
53
|
-
s.add_development_dependency 'mocha', '~>
|
53
|
+
s.add_development_dependency 'mocha', '~> 1.9.0'
|
54
54
|
s.add_development_dependency 'yard'
|
55
55
|
s.add_development_dependency 'pry-nav', '~> 0.2.4'
|
56
56
|
s.add_development_dependency 'pry-stack_explorer', '~> 0.4.9'
|
57
|
+
s.add_development_dependency 'guard', '~> 2.16.0'
|
58
|
+
s.add_development_dependency 'guard-minitest', '~> 2.4.0'
|
57
59
|
s.add_development_dependency 'hometown', '~> 0.2.5'
|
58
|
-
s.add_development_dependency 'bundler'
|
60
|
+
s.add_development_dependency 'bundler'
|
59
61
|
end
|
data/test/agent_helper.rb
CHANGED
@@ -212,7 +212,7 @@ end
|
|
212
212
|
#
|
213
213
|
# If you want to *allow* unexpected metrics matching certain patterns, use
|
214
214
|
# the :ignore_filter option. This will allow you to specify a Regex that
|
215
|
-
#
|
215
|
+
# allowlists broad swathes of metric territory (e.g. 'Supportability/').
|
216
216
|
#
|
217
217
|
def assert_metrics_recorded_exclusive(expected, options={})
|
218
218
|
expected = _normalize_metric_expectations(expected)
|
@@ -345,6 +345,15 @@ def in_transaction(*args, &blk)
|
|
345
345
|
txn
|
346
346
|
end
|
347
347
|
|
348
|
+
# Convenience wrapper to stand up a transaction and provide a segment within
|
349
|
+
# that transaction to work with. The same arguements as provided to in_transaction
|
350
|
+
# may be supplied.
|
351
|
+
def with_segment *args, &blk
|
352
|
+
in_transaction *args do |txn|
|
353
|
+
yield txn.current_segment, txn
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
348
357
|
def stub_transaction_guid(guid)
|
349
358
|
NewRelic::Agent::Transaction.tl_current.instance_variable_set(:@guid, guid)
|
350
359
|
end
|
@@ -612,17 +621,87 @@ ensure
|
|
612
621
|
NewRelic::Agent.logger = orig_logger
|
613
622
|
end
|
614
623
|
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
624
|
+
# The EnvUpdater was introduced due to random fails in JRuby environment
|
625
|
+
# whereby attempting to set ENV[key] = some_value randomly failed.
|
626
|
+
# It is conjectured that this is thread related, but may also be
|
627
|
+
# a core bug in the JVM implementation of Ruby. Root cause was not
|
628
|
+
# discovered, but it was found that a combination of retrying and using
|
629
|
+
# mutex lock around the update operation was the only consistently working
|
630
|
+
# solution as the error continued to surface without the mutex and
|
631
|
+
# retry alone wasn't enough, either.
|
632
|
+
#
|
633
|
+
# JRUBY: oraclejdk8 + jruby-9.2.6.0
|
634
|
+
#
|
635
|
+
# NOTE: Singleton pattern to ensure one mutex lock for all threads
|
636
|
+
class EnvUpdater
|
637
|
+
MAX_RETRIES = 5
|
638
|
+
|
639
|
+
def initialize
|
640
|
+
@mutex = Mutex.new
|
620
641
|
end
|
621
|
-
|
642
|
+
|
643
|
+
# Will attempt the given block up to MAX_RETRIES before
|
644
|
+
# surfacing the exception down the chain.
|
645
|
+
def with_retry retry_limit=MAX_RETRIES
|
646
|
+
retries ||= 0
|
647
|
+
sleep(retries)
|
622
648
|
yield
|
623
|
-
|
624
|
-
|
649
|
+
rescue
|
650
|
+
(retries += 1) < retry_limit ? retry : raise
|
651
|
+
end
|
652
|
+
|
653
|
+
# Locks and updates the ENV
|
654
|
+
def safe_update env
|
655
|
+
with_retry do
|
656
|
+
@mutex.synchronize do
|
657
|
+
env.each{ |key, val| ENV[key] = val.to_s }
|
658
|
+
end
|
659
|
+
end
|
660
|
+
end
|
661
|
+
|
662
|
+
# Locks and restores the ENV
|
663
|
+
def safe_restore old_env
|
664
|
+
with_retry do
|
665
|
+
@mutex.synchronize do
|
666
|
+
old_env.each{ |key, val| val ? ENV[key] = val : ENV.delete(key) }
|
667
|
+
end
|
668
|
+
end
|
669
|
+
end
|
670
|
+
|
671
|
+
# Singleton pattern implemented via @@instance
|
672
|
+
def self.instance
|
673
|
+
@@instance ||= EnvUpdater.new
|
674
|
+
end
|
675
|
+
|
676
|
+
def self.safe_update env
|
677
|
+
instance.safe_update env
|
625
678
|
end
|
679
|
+
|
680
|
+
def self.safe_restore old_env
|
681
|
+
instance.safe_restore old_env
|
682
|
+
end
|
683
|
+
|
684
|
+
# Effectively saves current ENV settings for given env's key/values,
|
685
|
+
# runs given block, then restores ENV to original state before returning.
|
686
|
+
def self.inject env, &block
|
687
|
+
old_env = {}
|
688
|
+
env.each{ |key, val| old_env[key] = ENV[key] }
|
689
|
+
begin
|
690
|
+
safe_update(env)
|
691
|
+
yield
|
692
|
+
ensure
|
693
|
+
safe_restore(old_env)
|
694
|
+
end
|
695
|
+
end
|
696
|
+
|
697
|
+
# must call instance here to ensure only one @mutex for all threads.
|
698
|
+
instance
|
699
|
+
end
|
700
|
+
|
701
|
+
# Changes ENV settings to given and runs given block and restores ENV
|
702
|
+
# to original values before returning.
|
703
|
+
def with_environment(env, &block)
|
704
|
+
EnvUpdater.inject(env) { yield }
|
626
705
|
end
|
627
706
|
|
628
707
|
def with_argv(argv)
|
data/true
ADDED
File without changes
|
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.
|
4
|
+
version: 6.8.0.360
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Matthew Wear
|
8
7
|
- Chris Pine
|
9
8
|
- Rachel Klein
|
10
9
|
- Justin Foote
|
10
|
+
- Michael Lang
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2019-
|
14
|
+
date: 2019-12-19 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rake
|
@@ -19,14 +19,14 @@ dependencies:
|
|
19
19
|
requirements:
|
20
20
|
- - '='
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 12.3.3
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - '='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 12.3.3
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: minitest
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -47,14 +47,14 @@ dependencies:
|
|
47
47
|
requirements:
|
48
48
|
- - "~>"
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version:
|
50
|
+
version: 1.9.0
|
51
51
|
type: :development
|
52
52
|
prerelease: false
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
54
54
|
requirements:
|
55
55
|
- - "~>"
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version:
|
57
|
+
version: 1.9.0
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: yard
|
60
60
|
requirement: !ruby/object:Gem::Requirement
|
@@ -97,6 +97,34 @@ dependencies:
|
|
97
97
|
- - "~>"
|
98
98
|
- !ruby/object:Gem::Version
|
99
99
|
version: 0.4.9
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
name: guard
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - "~>"
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 2.16.0
|
107
|
+
type: :development
|
108
|
+
prerelease: false
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: 2.16.0
|
114
|
+
- !ruby/object:Gem::Dependency
|
115
|
+
name: guard-minitest
|
116
|
+
requirement: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - "~>"
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: 2.4.0
|
121
|
+
type: :development
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - "~>"
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: 2.4.0
|
100
128
|
- !ruby/object:Gem::Dependency
|
101
129
|
name: hometown
|
102
130
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,16 +143,16 @@ dependencies:
|
|
115
143
|
name: bundler
|
116
144
|
requirement: !ruby/object:Gem::Requirement
|
117
145
|
requirements:
|
118
|
-
- - "
|
146
|
+
- - ">="
|
119
147
|
- !ruby/object:Gem::Version
|
120
|
-
version: '
|
148
|
+
version: '0'
|
121
149
|
type: :development
|
122
150
|
prerelease: false
|
123
151
|
version_requirements: !ruby/object:Gem::Requirement
|
124
152
|
requirements:
|
125
|
-
- - "
|
153
|
+
- - ">="
|
126
154
|
- !ruby/object:Gem::Version
|
127
|
-
version: '
|
155
|
+
version: '0'
|
128
156
|
description: |
|
129
157
|
New Relic is a performance management system, developed by New Relic,
|
130
158
|
Inc (http://www.newrelic.com). New Relic provides you with deep
|
@@ -172,6 +200,7 @@ files:
|
|
172
200
|
- lib/new_relic/agent/agent_logger.rb
|
173
201
|
- lib/new_relic/agent/attribute_filter.rb
|
174
202
|
- lib/new_relic/agent/attribute_processing.rb
|
203
|
+
- lib/new_relic/agent/attributes.rb
|
175
204
|
- lib/new_relic/agent/audit_logger.rb
|
176
205
|
- lib/new_relic/agent/autostart.rb
|
177
206
|
- lib/new_relic/agent/chained_call.rb
|
@@ -210,8 +239,11 @@ files:
|
|
210
239
|
- lib/new_relic/agent/datastores/mongo/statement_formatter.rb
|
211
240
|
- lib/new_relic/agent/datastores/redis.rb
|
212
241
|
- lib/new_relic/agent/deprecator.rb
|
242
|
+
- lib/new_relic/agent/distributed_trace_intrinsics.rb
|
243
|
+
- lib/new_relic/agent/distributed_trace_metrics.rb
|
213
244
|
- lib/new_relic/agent/distributed_trace_monitor.rb
|
214
245
|
- lib/new_relic/agent/distributed_trace_payload.rb
|
246
|
+
- lib/new_relic/agent/distributed_trace_transport_type.rb
|
215
247
|
- lib/new_relic/agent/distributed_tracing.rb
|
216
248
|
- lib/new_relic/agent/encoding_normalizer.rb
|
217
249
|
- lib/new_relic/agent/error_collector.rb
|
@@ -222,6 +254,7 @@ files:
|
|
222
254
|
- lib/new_relic/agent/event_listener.rb
|
223
255
|
- lib/new_relic/agent/event_loop.rb
|
224
256
|
- lib/new_relic/agent/external.rb
|
257
|
+
- lib/new_relic/agent/guid_generator.rb
|
225
258
|
- lib/new_relic/agent/harvester.rb
|
226
259
|
- lib/new_relic/agent/heap.rb
|
227
260
|
- lib/new_relic/agent/hostname.rb
|
@@ -342,10 +375,12 @@ files:
|
|
342
375
|
- lib/new_relic/agent/threading/backtrace_service.rb
|
343
376
|
- lib/new_relic/agent/threading/thread_profile.rb
|
344
377
|
- lib/new_relic/agent/timestamp_sampled_buffer.rb
|
378
|
+
- lib/new_relic/agent/trace_context.rb
|
379
|
+
- lib/new_relic/agent/trace_context_payload.rb
|
380
|
+
- lib/new_relic/agent/trace_context_request_monitor.rb
|
345
381
|
- lib/new_relic/agent/tracer.rb
|
346
382
|
- lib/new_relic/agent/transaction.rb
|
347
383
|
- lib/new_relic/agent/transaction/abstract_segment.rb
|
348
|
-
- lib/new_relic/agent/transaction/attributes.rb
|
349
384
|
- lib/new_relic/agent/transaction/datastore_segment.rb
|
350
385
|
- lib/new_relic/agent/transaction/distributed_tracing.rb
|
351
386
|
- lib/new_relic/agent/transaction/external_request_segment.rb
|
@@ -356,6 +391,7 @@ files:
|
|
356
391
|
- lib/new_relic/agent/transaction/synthetics_sample_buffer.rb
|
357
392
|
- lib/new_relic/agent/transaction/trace.rb
|
358
393
|
- lib/new_relic/agent/transaction/trace_builder.rb
|
394
|
+
- lib/new_relic/agent/transaction/trace_context.rb
|
359
395
|
- lib/new_relic/agent/transaction/trace_node.rb
|
360
396
|
- lib/new_relic/agent/transaction/tracing.rb
|
361
397
|
- lib/new_relic/agent/transaction/transaction_sample_buffer.rb
|
@@ -430,15 +466,11 @@ files:
|
|
430
466
|
- lib/tasks/multiverse.rb
|
431
467
|
- lib/tasks/newrelic.rb
|
432
468
|
- lib/tasks/tests.rake
|
433
|
-
- lib/tasks/versions.html.erb
|
434
|
-
- lib/tasks/versions.postface.html
|
435
|
-
- lib/tasks/versions.preface.html
|
436
|
-
- lib/tasks/versions.rake
|
437
|
-
- lib/tasks/versions.txt.erb
|
438
469
|
- newrelic.yml
|
439
470
|
- newrelic_rpm.gemspec
|
440
471
|
- recipes/newrelic.rb
|
441
472
|
- test/agent_helper.rb
|
473
|
+
- 'true'
|
442
474
|
homepage: https://github.com/newrelic/rpm
|
443
475
|
licenses:
|
444
476
|
- New Relic
|
@@ -462,7 +494,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
462
494
|
- !ruby/object:Gem::Version
|
463
495
|
version: 1.3.1
|
464
496
|
requirements: []
|
465
|
-
rubygems_version: 3.0.
|
497
|
+
rubygems_version: 3.0.6
|
466
498
|
signing_key:
|
467
499
|
specification_version: 4
|
468
500
|
summary: New Relic Ruby Agent
|
@@ -1,154 +0,0 @@
|
|
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/attribute_processing'
|
6
|
-
|
7
|
-
module NewRelic
|
8
|
-
module Agent
|
9
|
-
class Transaction
|
10
|
-
class Attributes
|
11
|
-
KEY_LIMIT = 255
|
12
|
-
VALUE_LIMIT = 255
|
13
|
-
COUNT_LIMIT = 64
|
14
|
-
|
15
|
-
EMPTY_HASH = {}.freeze
|
16
|
-
|
17
|
-
def initialize(filter)
|
18
|
-
@filter = filter
|
19
|
-
|
20
|
-
@custom_attributes = {}
|
21
|
-
@agent_attributes = {}
|
22
|
-
@intrinsic_attributes = {}
|
23
|
-
|
24
|
-
@custom_destinations = {}
|
25
|
-
@agent_destinations = {}
|
26
|
-
@already_warned_count_limit = nil
|
27
|
-
end
|
28
|
-
|
29
|
-
def add_agent_attribute(key, value, default_destinations)
|
30
|
-
destinations = @filter.apply(key, default_destinations)
|
31
|
-
return if destinations == AttributeFilter::DST_NONE
|
32
|
-
|
33
|
-
@agent_destinations[key] = destinations
|
34
|
-
add(@agent_attributes, key, value)
|
35
|
-
end
|
36
|
-
|
37
|
-
def add_agent_attribute_with_key_check(key, value, default_destinations)
|
38
|
-
if exceeds_bytesize_limit? key, KEY_LIMIT
|
39
|
-
NewRelic::Agent.logger.debug("Agent attribute #{key} was dropped for exceeding key length limit #{KEY_LIMIT}")
|
40
|
-
return
|
41
|
-
end
|
42
|
-
|
43
|
-
add_agent_attribute(key, value, default_destinations)
|
44
|
-
end
|
45
|
-
|
46
|
-
def add_intrinsic_attribute(key, value)
|
47
|
-
add(@intrinsic_attributes, key, value)
|
48
|
-
end
|
49
|
-
|
50
|
-
def merge_untrusted_agent_attributes(attributes, prefix, default_destinations)
|
51
|
-
return if @filter.high_security?
|
52
|
-
return if !@filter.might_allow_prefix?(prefix)
|
53
|
-
|
54
|
-
AttributeProcessing.flatten_and_coerce(attributes, prefix) do |k, v|
|
55
|
-
add_agent_attribute_with_key_check(k, v, AttributeFilter::DST_NONE)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def merge_custom_attributes(other)
|
60
|
-
return unless Agent.config[:'custom_attributes.enabled']
|
61
|
-
return if other.empty?
|
62
|
-
AttributeProcessing.flatten_and_coerce(other) do |k, v|
|
63
|
-
add_custom_attribute(k, v)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def custom_attributes_for(destination)
|
68
|
-
for_destination(@custom_attributes, @custom_destinations, destination)
|
69
|
-
end
|
70
|
-
|
71
|
-
def agent_attributes_for(destination)
|
72
|
-
for_destination(@agent_attributes, @agent_destinations, destination)
|
73
|
-
end
|
74
|
-
|
75
|
-
def intrinsic_attributes_for(destination)
|
76
|
-
if destination == NewRelic::Agent::AttributeFilter::DST_TRANSACTION_TRACER ||
|
77
|
-
destination == NewRelic::Agent::AttributeFilter::DST_ERROR_COLLECTOR
|
78
|
-
@intrinsic_attributes
|
79
|
-
else
|
80
|
-
EMPTY_HASH
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
def add_custom_attribute(key, value)
|
87
|
-
if @custom_attributes.size >= COUNT_LIMIT
|
88
|
-
unless @already_warned_count_limit
|
89
|
-
NewRelic::Agent.logger.warn("Custom attributes count exceeded limit of #{COUNT_LIMIT}. Any additional custom attributes during this transaction will be dropped.")
|
90
|
-
@already_warned_count_limit = true
|
91
|
-
end
|
92
|
-
return
|
93
|
-
end
|
94
|
-
|
95
|
-
if @filter.high_security?
|
96
|
-
NewRelic::Agent.logger.debug("Unable to add custom attribute #{key} while in high security mode.")
|
97
|
-
return
|
98
|
-
end
|
99
|
-
|
100
|
-
if exceeds_bytesize_limit?(key, KEY_LIMIT)
|
101
|
-
NewRelic::Agent.logger.warn("Custom attribute key '#{key}' was longer than limit of #{KEY_LIMIT} bytes. This attribute will be dropped.")
|
102
|
-
return
|
103
|
-
end
|
104
|
-
|
105
|
-
destinations = @filter.apply(key, AttributeFilter::DST_ALL)
|
106
|
-
return if destinations == AttributeFilter::DST_NONE
|
107
|
-
|
108
|
-
@custom_destinations[key] = destinations
|
109
|
-
add(@custom_attributes, key, value)
|
110
|
-
end
|
111
|
-
|
112
|
-
def add(attributes, key, value)
|
113
|
-
return if value.nil?
|
114
|
-
|
115
|
-
if exceeds_bytesize_limit?(value, VALUE_LIMIT)
|
116
|
-
value = slice(value)
|
117
|
-
end
|
118
|
-
|
119
|
-
attributes[key] = value
|
120
|
-
end
|
121
|
-
|
122
|
-
def for_destination(attributes, calculated_destinations, destination)
|
123
|
-
# Avoid allocating anything if there are no attrs at all
|
124
|
-
return EMPTY_HASH if attributes.empty?
|
125
|
-
|
126
|
-
attributes.inject({}) do |memo, (key, value)|
|
127
|
-
if @filter.allows?(calculated_destinations[key], destination)
|
128
|
-
memo[key] = value
|
129
|
-
end
|
130
|
-
memo
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def exceeds_bytesize_limit?(value, limit)
|
135
|
-
if value.respond_to?(:bytesize)
|
136
|
-
value.bytesize > limit
|
137
|
-
elsif value.is_a?(Symbol)
|
138
|
-
value.to_s.bytesize > limit
|
139
|
-
else
|
140
|
-
false
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
# Take one byte past our limit. Why? This lets us unconditionally chop!
|
145
|
-
# the end. It'll either remove the one-character-too-many we have, or
|
146
|
-
# peel off the partial, mangled character left by the byteslice.
|
147
|
-
def slice(incoming)
|
148
|
-
result = incoming.to_s.byteslice(0, VALUE_LIMIT + 1)
|
149
|
-
result.chop!
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|