newrelic_rpm 5.1.0.344 → 5.2.0.345
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/lib/new_relic/agent/agent.rb +23 -9
- data/lib/new_relic/agent/configuration/default_source.rb +7 -0
- data/lib/new_relic/agent/configuration/manager.rb +40 -33
- data/lib/new_relic/agent/configuration/security_policy_source.rb +224 -0
- data/lib/new_relic/agent/custom_event_aggregator.rb +16 -5
- data/lib/new_relic/agent/datastores.rb +7 -4
- data/lib/new_relic/agent/error_collector.rb +1 -1
- data/lib/new_relic/agent/error_event_aggregator.rb +6 -2
- data/lib/new_relic/agent/event_aggregator.rb +3 -3
- data/lib/new_relic/agent/new_relic_service.rb +24 -4
- data/lib/new_relic/agent/new_relic_service/security_policy_settings.rb +61 -0
- data/lib/new_relic/agent/priority_sampled_buffer.rb +24 -2
- data/lib/new_relic/agent/synthetics_event_aggregator.rb +5 -12
- data/lib/new_relic/agent/timestamp_sampled_buffer.rb +19 -0
- data/lib/new_relic/agent/transaction_error_primitive.rb +2 -0
- data/lib/new_relic/agent/transaction_event_aggregator.rb +1 -13
- data/lib/new_relic/agent/transaction_event_recorder.rb +3 -3
- data/lib/new_relic/control/instance_methods.rb +19 -2
- data/lib/new_relic/version.rb +1 -1
- metadata +6 -6
- data/lib/new_relic/agent/sampled_buffer.rb +0 -68
- data/lib/new_relic/agent/sized_buffer.rb +0 -23
- data/lib/new_relic/agent/synthetics_event_buffer.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6f27f55d62839f2426dcc139af19e97f815c70783944d4c67363a7d54a5e208
|
4
|
+
data.tar.gz: 6543b4fa585ab70291df98c295818ccb74eb4d2ab00a9ac3f5093c7b89656d4d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 658044904957344ad87805e072168e9f366453733f0b9e42051230c2999be7170bfe5cac64c402e0ced3483e1f3d5ce091622c01d2ecb685e4354b41e6a11a38
|
7
|
+
data.tar.gz: ec9e153d940103faddd85fca6b00191e9214770aa5c7b5d1318fff41e3ff6d69f9720d2300847571ed1ba92b7d9c468fce5afc8dc6cfa711807405384d6cc94e
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# New Relic Ruby Agent Release Notes #
|
2
2
|
|
3
|
+
## v5.2.0 ##
|
4
|
+
|
5
|
+
* Use priority sampling for errors and custom events
|
6
|
+
|
7
|
+
Priority sampling replaces the older reservoir event sampling method.
|
8
|
+
With this change, the agent will maintain randomness across a given
|
9
|
+
time period while improving coordination among transactions, errors,
|
10
|
+
and custom events.
|
11
|
+
|
12
|
+
* Bugfix for wrapping datastore operations
|
13
|
+
|
14
|
+
The agent will now complete the process of wrapping datastore
|
15
|
+
operations even if an error occurs during execution of a callback.
|
16
|
+
|
3
17
|
## v5.1.0 ##
|
4
18
|
|
5
19
|
* Rails 5.2 support
|
@@ -8,7 +8,6 @@ require 'net/http'
|
|
8
8
|
require 'logger'
|
9
9
|
require 'zlib'
|
10
10
|
require 'stringio'
|
11
|
-
require 'new_relic/agent/sampled_buffer'
|
12
11
|
require 'new_relic/agent/autostart'
|
13
12
|
require 'new_relic/agent/harvester'
|
14
13
|
require 'new_relic/agent/hostname'
|
@@ -21,7 +20,6 @@ require 'new_relic/agent/event_listener'
|
|
21
20
|
require 'new_relic/agent/cross_app_monitor'
|
22
21
|
require 'new_relic/agent/distributed_trace_monitor'
|
23
22
|
require 'new_relic/agent/synthetics_monitor'
|
24
|
-
require 'new_relic/agent/synthetics_event_buffer'
|
25
23
|
require 'new_relic/agent/transaction_event_recorder'
|
26
24
|
require 'new_relic/agent/custom_event_aggregator'
|
27
25
|
require 'new_relic/agent/sampler_collection'
|
@@ -183,7 +181,8 @@ module NewRelic
|
|
183
181
|
return if !needs_restart ||
|
184
182
|
!Agent.config[:agent_enabled] ||
|
185
183
|
!Agent.config[:monitor_mode] ||
|
186
|
-
disconnected?
|
184
|
+
disconnected? ||
|
185
|
+
!control.security_settings_valid?
|
187
186
|
|
188
187
|
::NewRelic::Agent.logger.debug "Starting the worker thread in #{Process.pid} (parent #{Process.ppid}) after forking."
|
189
188
|
|
@@ -844,6 +843,20 @@ module NewRelic
|
|
844
843
|
|
845
844
|
@service.agent_id = config_data['agent_run_id']
|
846
845
|
|
846
|
+
security_policies = config_data.delete('security_policies')
|
847
|
+
|
848
|
+
add_server_side_config(config_data)
|
849
|
+
add_security_policy_config(security_policies) if security_policies
|
850
|
+
|
851
|
+
log_connection!(config_data)
|
852
|
+
@transaction_rules = RulesEngine.create_transaction_rules(config_data)
|
853
|
+
@stats_engine.metric_rules = RulesEngine.create_metric_rules(config_data)
|
854
|
+
|
855
|
+
# If you're adding something else here to respond to the server-side config,
|
856
|
+
# use Agent.instance.events.subscribe(:finished_configuring) callback instead!
|
857
|
+
end
|
858
|
+
|
859
|
+
def add_server_side_config(config_data)
|
847
860
|
if config_data['agent_config']
|
848
861
|
::NewRelic::Agent.logger.debug "Using config from server"
|
849
862
|
end
|
@@ -851,13 +864,14 @@ module NewRelic
|
|
851
864
|
::NewRelic::Agent.logger.debug "Server provided config: #{config_data.inspect}"
|
852
865
|
server_config = NewRelic::Agent::Configuration::ServerSource.new(config_data, Agent.config)
|
853
866
|
Agent.config.replace_or_add_config(server_config)
|
854
|
-
|
855
|
-
|
856
|
-
@transaction_rules = RulesEngine.create_transaction_rules(config_data)
|
857
|
-
@stats_engine.metric_rules = RulesEngine.create_metric_rules(config_data)
|
867
|
+
end
|
858
868
|
|
859
|
-
|
860
|
-
|
869
|
+
def add_security_policy_config(security_policies)
|
870
|
+
::NewRelic::Agent.logger.info 'Installing security policies'
|
871
|
+
security_policy_source = NewRelic::Agent::Configuration::SecurityPolicySource.new(security_policies)
|
872
|
+
Agent.config.replace_or_add_config(security_policy_source)
|
873
|
+
# drop data collected before applying security policies
|
874
|
+
drop_buffered_data
|
861
875
|
end
|
862
876
|
|
863
877
|
class WaitOnConnectTimeout < StandardError
|
@@ -313,6 +313,13 @@ module NewRelic
|
|
313
313
|
:allowed_from_server => false,
|
314
314
|
:description => 'If <code>true</code>, enables <a href="https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security">high security mode</a>. Ensure you understand the implications of high security mode before enabling this setting.'
|
315
315
|
},
|
316
|
+
:security_policies_token => {
|
317
|
+
:default => '',
|
318
|
+
:public => true,
|
319
|
+
:type => String,
|
320
|
+
:allowed_from_server => false,
|
321
|
+
:description => 'Applies Language Agent Security Policy settings.'
|
322
|
+
},
|
316
323
|
:proxy_host => {
|
317
324
|
:default => nil,
|
318
325
|
:allow_nil => true,
|
@@ -9,6 +9,7 @@ require 'new_relic/agent/configuration/default_source'
|
|
9
9
|
require 'new_relic/agent/configuration/server_source'
|
10
10
|
require 'new_relic/agent/configuration/environment_source'
|
11
11
|
require 'new_relic/agent/configuration/high_security_source'
|
12
|
+
require 'new_relic/agent/configuration/security_policy_source'
|
12
13
|
|
13
14
|
module NewRelic
|
14
15
|
module Agent
|
@@ -44,12 +45,13 @@ module NewRelic
|
|
44
45
|
|
45
46
|
def remove_config_type(sym)
|
46
47
|
source = case sym
|
47
|
-
when :
|
48
|
-
when :
|
49
|
-
when :
|
50
|
-
when :
|
51
|
-
when :
|
52
|
-
when :
|
48
|
+
when :security_policy then @security_policy_source
|
49
|
+
when :high_security then @high_security_source
|
50
|
+
when :environment then @environment_source
|
51
|
+
when :server then @server_source
|
52
|
+
when :manual then @manual_source
|
53
|
+
when :yaml then @yaml_source
|
54
|
+
when :default then @default_source
|
53
55
|
end
|
54
56
|
|
55
57
|
remove_config(source)
|
@@ -57,12 +59,13 @@ module NewRelic
|
|
57
59
|
|
58
60
|
def remove_config(source)
|
59
61
|
case source
|
60
|
-
when
|
61
|
-
when
|
62
|
-
when
|
63
|
-
when
|
64
|
-
when
|
65
|
-
when
|
62
|
+
when SecurityPolicySource then @security_policy_source = nil
|
63
|
+
when HighSecuritySource then @high_security_source = nil
|
64
|
+
when EnvironmentSource then @environment_source = nil
|
65
|
+
when ServerSource then @server_source = nil
|
66
|
+
when ManualSource then @manual_source = nil
|
67
|
+
when YamlSource then @yaml_source = nil
|
68
|
+
when DefaultSource then @default_source = nil
|
66
69
|
else
|
67
70
|
@configs_for_testing.delete_if {|src,lvl| src == source}
|
68
71
|
end
|
@@ -78,12 +81,13 @@ module NewRelic
|
|
78
81
|
|
79
82
|
invoke_callbacks(:add, source)
|
80
83
|
case source
|
81
|
-
when
|
82
|
-
when
|
83
|
-
when
|
84
|
-
when
|
85
|
-
when
|
86
|
-
when
|
84
|
+
when SecurityPolicySource then @security_policy_source = source
|
85
|
+
when HighSecuritySource then @high_security_source = source
|
86
|
+
when EnvironmentSource then @environment_source = source
|
87
|
+
when ServerSource then @server_source = source
|
88
|
+
when ManualSource then @manual_source = source
|
89
|
+
when YamlSource then @yaml_source = source
|
90
|
+
when DefaultSource then @default_source = source
|
87
91
|
else
|
88
92
|
NewRelic::Agent.logger.warn("Invalid config format; config will be ignored: #{source}")
|
89
93
|
end
|
@@ -323,14 +327,15 @@ module NewRelic
|
|
323
327
|
|
324
328
|
# Generally only useful during initial construction and tests
|
325
329
|
def reset_to_defaults
|
326
|
-
@
|
327
|
-
@
|
328
|
-
@
|
329
|
-
@
|
330
|
-
@
|
331
|
-
@
|
330
|
+
@security_policy_source = nil
|
331
|
+
@high_security_source = nil
|
332
|
+
@environment_source = EnvironmentSource.new
|
333
|
+
@server_source = nil
|
334
|
+
@manual_source = nil
|
335
|
+
@yaml_source = nil
|
336
|
+
@default_source = DefaultSource.new
|
332
337
|
|
333
|
-
@configs_for_testing
|
338
|
+
@configs_for_testing = []
|
334
339
|
|
335
340
|
reset_cache
|
336
341
|
end
|
@@ -350,13 +355,14 @@ module NewRelic
|
|
350
355
|
end
|
351
356
|
|
352
357
|
def delete_all_configs_for_testing
|
353
|
-
@
|
354
|
-
@
|
355
|
-
@
|
356
|
-
@
|
357
|
-
@
|
358
|
-
@
|
359
|
-
@
|
358
|
+
@security_policy_source = nil
|
359
|
+
@high_security_source = nil
|
360
|
+
@environment_source = nil
|
361
|
+
@server_source = nil
|
362
|
+
@manual_source = nil
|
363
|
+
@yaml_source = nil
|
364
|
+
@default_source = nil
|
365
|
+
@configs_for_testing = []
|
360
366
|
end
|
361
367
|
|
362
368
|
def num_configs_for_testing
|
@@ -370,7 +376,8 @@ module NewRelic
|
|
370
376
|
private
|
371
377
|
|
372
378
|
def config_stack
|
373
|
-
stack = [@
|
379
|
+
stack = [@security_policy_source,
|
380
|
+
@high_security_source,
|
374
381
|
@environment_source,
|
375
382
|
@server_source,
|
376
383
|
@manual_source,
|
@@ -0,0 +1,224 @@
|
|
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/configuration/dotted_hash'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
module Configuration
|
10
|
+
class SecurityPolicySource < DottedHash
|
11
|
+
class << self
|
12
|
+
def enabled?(option)
|
13
|
+
Agent.config[option]
|
14
|
+
end
|
15
|
+
|
16
|
+
def record_sql_enabled?(option)
|
17
|
+
Agent.config[option] == 'obfuscated' ||
|
18
|
+
Agent.config[option] == 'raw' ||
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def not_empty?(option)
|
23
|
+
!Agent.config[option].empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
def change_setting(policies, option, new_value)
|
27
|
+
current_value = Agent.config[option]
|
28
|
+
unless current_value == new_value
|
29
|
+
NewRelic::Agent.logger.info \
|
30
|
+
"Setting changed: {#{option}: from #{current_value} " \
|
31
|
+
"to #{new_value}}. Source: SecurityPolicySource"
|
32
|
+
end
|
33
|
+
policies[option] = new_value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# The keys of the security settings map are the names of security
|
38
|
+
# policies received from the server. They map to multiple configuration
|
39
|
+
# options in the local config. There is a hash of metadata that
|
40
|
+
# corresponds to each configuration option with the following keys:
|
41
|
+
#
|
42
|
+
# option: the configuration option name
|
43
|
+
# supported: true if the agent has one or more corresponding
|
44
|
+
# configuration options
|
45
|
+
# enabled_fn: a callable that takes the configuration option and returns
|
46
|
+
# true if the option is enabled, false otherwise
|
47
|
+
# disabled_value: the value of the configuration option when it is
|
48
|
+
# disabled
|
49
|
+
# permitted_fn: a callable, that will be executed if an option is
|
50
|
+
# permitted by the security policy and is also enabled by the config
|
51
|
+
|
52
|
+
SECURITY_SETTINGS_MAP = {
|
53
|
+
"record_sql" => [
|
54
|
+
{
|
55
|
+
option: :'transaction_tracer.record_sql',
|
56
|
+
supported: true,
|
57
|
+
enabled_fn: method(:record_sql_enabled?),
|
58
|
+
disabled_value: 'off',
|
59
|
+
permitted_fn: proc { |policies|
|
60
|
+
change_setting(policies, :'transaction_tracer.record_sql', 'obfuscated')
|
61
|
+
}
|
62
|
+
},
|
63
|
+
{
|
64
|
+
option: :'slow_sql.record_sql',
|
65
|
+
supported: true,
|
66
|
+
enabled_fn: method(:record_sql_enabled?),
|
67
|
+
disabled_value: 'off',
|
68
|
+
permitted_fn: proc { |policies|
|
69
|
+
change_setting(policies, :'slow_sql.record_sql', 'obfuscated')
|
70
|
+
}
|
71
|
+
},
|
72
|
+
{
|
73
|
+
option: :'mongo.capture_queries',
|
74
|
+
supported: true,
|
75
|
+
enabled_fn: method(:enabled?),
|
76
|
+
disabled_value: false,
|
77
|
+
permitted_fn: proc{ |policies|
|
78
|
+
change_setting(policies, :'mongo.obfuscate_queries', true)
|
79
|
+
}
|
80
|
+
},
|
81
|
+
{
|
82
|
+
option: :'transaction_tracer.record_redis_arguments',
|
83
|
+
supported: true,
|
84
|
+
enabled_fn: method(:enabled?),
|
85
|
+
disabled_value: false,
|
86
|
+
permitted_fn: nil
|
87
|
+
}
|
88
|
+
],
|
89
|
+
"attributes_include" => [
|
90
|
+
{
|
91
|
+
option: :'attributes.include',
|
92
|
+
supported: true,
|
93
|
+
enabled_fn: method(:not_empty?),
|
94
|
+
disabled_value: [],
|
95
|
+
permitted_fn: nil
|
96
|
+
},
|
97
|
+
{
|
98
|
+
option: :'transaction_tracer.attributes.include',
|
99
|
+
supported: true,
|
100
|
+
enabled_fn: method(:not_empty?),
|
101
|
+
disabled_value: [],
|
102
|
+
permitted_fn: nil
|
103
|
+
},
|
104
|
+
{
|
105
|
+
option: :'transaction_events.attributes.include',
|
106
|
+
supported: true,
|
107
|
+
enabled_fn: method(:not_empty?),
|
108
|
+
disabled_value: [],
|
109
|
+
permitted_fn: nil
|
110
|
+
},
|
111
|
+
{
|
112
|
+
option: :'error_collector.attributes.include',
|
113
|
+
supported: true,
|
114
|
+
enabled_fn: method(:not_empty?),
|
115
|
+
disabled_value: [],
|
116
|
+
permitted_fn: nil
|
117
|
+
},
|
118
|
+
{
|
119
|
+
option: :'browser_monitoring.attributes.include',
|
120
|
+
supported: true,
|
121
|
+
enabled_fn: method(:not_empty?),
|
122
|
+
disabled_value: [],
|
123
|
+
permitted_fn: nil
|
124
|
+
}
|
125
|
+
],
|
126
|
+
"allow_raw_exception_messages" => [
|
127
|
+
{
|
128
|
+
option: :'strip_exception_messages.enabled',
|
129
|
+
supported: true,
|
130
|
+
enabled_fn: method(:enabled?),
|
131
|
+
disabled_value: false,
|
132
|
+
permitted_fn: nil
|
133
|
+
}
|
134
|
+
],
|
135
|
+
"custom_events" => [
|
136
|
+
{
|
137
|
+
option: :'custom_insights_events.enabled',
|
138
|
+
supported: true,
|
139
|
+
enabled_fn: method(:enabled?),
|
140
|
+
disabled_value: false,
|
141
|
+
permitted_fn: nil
|
142
|
+
}
|
143
|
+
],
|
144
|
+
"custom_parameters" => [
|
145
|
+
{
|
146
|
+
option: :'custom_attributes.enabled',
|
147
|
+
supported: true,
|
148
|
+
enabled_fn: method(:enabled?),
|
149
|
+
disabled_value: false,
|
150
|
+
permitted_fn: nil
|
151
|
+
}
|
152
|
+
],
|
153
|
+
"custom_instrumentation_editor" => [
|
154
|
+
{
|
155
|
+
option: nil,
|
156
|
+
supported: false,
|
157
|
+
enabled_fn: nil,
|
158
|
+
disabled_value: nil,
|
159
|
+
permitted_fn: nil
|
160
|
+
}
|
161
|
+
],
|
162
|
+
"message_parameters" => [
|
163
|
+
{
|
164
|
+
option: :'message_tracer.segment_parameters.enabled',
|
165
|
+
supported: true,
|
166
|
+
enabled_fn: method(:enabled?),
|
167
|
+
disabled_value: false,
|
168
|
+
permitted_fn: nil
|
169
|
+
}
|
170
|
+
],
|
171
|
+
"job_arguments" => [
|
172
|
+
{
|
173
|
+
option: :'resque.capture_params',
|
174
|
+
supported: true,
|
175
|
+
enabled_fn: method(:enabled?),
|
176
|
+
disabled_value: false,
|
177
|
+
permitted_fn: nil
|
178
|
+
},
|
179
|
+
{
|
180
|
+
option: :'sidekiq.capture_params',
|
181
|
+
supported: true,
|
182
|
+
enabled_fn: method(:enabled?),
|
183
|
+
disabled_value: false,
|
184
|
+
permitted_fn: nil
|
185
|
+
}
|
186
|
+
]
|
187
|
+
}
|
188
|
+
|
189
|
+
def initialize(security_policies)
|
190
|
+
super(build_overrides(security_policies))
|
191
|
+
end
|
192
|
+
|
193
|
+
ENABLED = "enabled".freeze
|
194
|
+
COLON_COLON = "::".freeze
|
195
|
+
|
196
|
+
def build_overrides(security_policies)
|
197
|
+
security_policies.inject({}) do |settings, (policy_name, policy_settings)|
|
198
|
+
SECURITY_SETTINGS_MAP[policy_name].each do |policy|
|
199
|
+
next unless policy[:supported]
|
200
|
+
if policy_settings[ENABLED]
|
201
|
+
if policy[:enabled_fn].call(policy[:option])
|
202
|
+
if permitted_fn = policy[:permitted_fn]
|
203
|
+
permitted_fn.call(settings)
|
204
|
+
end
|
205
|
+
else
|
206
|
+
config_source = Agent.config.source(policy[:option]).class.name.split(COLON_COLON).last
|
207
|
+
NewRelic::Agent.logger.info \
|
208
|
+
"Setting applied: {#{policy[:option]}: #{policy[:disabled_value]}}. " \
|
209
|
+
"Source: #{config_source}"
|
210
|
+
end
|
211
|
+
else
|
212
|
+
settings[policy[:option]] = policy[:disabled_value]
|
213
|
+
NewRelic::Agent.logger.info \
|
214
|
+
"Setting applied: {#{policy[:option]}: #{policy[:disabled_value]}}. " \
|
215
|
+
"Source: SecurityPolicySource"
|
216
|
+
end
|
217
|
+
end
|
218
|
+
settings
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
@@ -12,6 +12,7 @@ module NewRelic
|
|
12
12
|
|
13
13
|
TYPE = 'type'.freeze
|
14
14
|
TIMESTAMP = 'timestamp'.freeze
|
15
|
+
PRIORITY = 'priority'.freeze
|
15
16
|
EVENT_TYPE_REGEX = /^[a-zA-Z0-9:_ ]+$/.freeze
|
16
17
|
|
17
18
|
named :CustomEventAggregator
|
@@ -23,25 +24,35 @@ module NewRelic
|
|
23
24
|
raise ArgumentError, "Expected Hash but got #{attributes.class}"
|
24
25
|
end
|
25
26
|
|
27
|
+
return unless enabled?
|
28
|
+
|
26
29
|
type = @type_strings[type]
|
27
30
|
unless type =~ EVENT_TYPE_REGEX
|
28
31
|
note_dropped_event(type)
|
29
32
|
return false
|
30
33
|
end
|
31
34
|
|
32
|
-
|
33
|
-
{ TYPE => type, TIMESTAMP => Time.now.to_i },
|
34
|
-
AttributeProcessing.flatten_and_coerce(attributes)
|
35
|
-
]
|
35
|
+
priority = attributes[:priority] || rand
|
36
36
|
|
37
37
|
stored = @lock.synchronize do
|
38
|
-
@buffer.append(
|
38
|
+
@buffer.append(priority: priority) do
|
39
|
+
create_event(type, priority, attributes)
|
40
|
+
end
|
39
41
|
end
|
40
42
|
stored
|
41
43
|
end
|
42
44
|
|
43
45
|
private
|
44
46
|
|
47
|
+
def create_event(type, priority, attributes)
|
48
|
+
[
|
49
|
+
{ TYPE => type, TIMESTAMP => Time.now.to_i,
|
50
|
+
PRIORITY => priority
|
51
|
+
},
|
52
|
+
AttributeProcessing.flatten_and_coerce(attributes)
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
45
56
|
def after_initialize
|
46
57
|
@type_strings = Hash.new { |hash, key| hash[key] = key.to_s.freeze }
|
47
58
|
end
|
@@ -121,11 +121,14 @@ module NewRelic
|
|
121
121
|
begin
|
122
122
|
result = yield
|
123
123
|
ensure
|
124
|
-
|
125
|
-
|
126
|
-
|
124
|
+
begin
|
125
|
+
if callback
|
126
|
+
elapsed_time = (Time.now - segment.start_time).to_f
|
127
|
+
callback.call(result, segment.name, elapsed_time)
|
128
|
+
end
|
129
|
+
ensure
|
130
|
+
segment.finish if segment
|
127
131
|
end
|
128
|
-
segment.finish if segment
|
129
132
|
end
|
130
133
|
end
|
131
134
|
|
@@ -209,7 +209,7 @@ module NewRelic
|
|
209
209
|
noticed_error = create_noticed_error(exception, options)
|
210
210
|
error_trace_aggregator.add_to_error_queue(noticed_error)
|
211
211
|
payload = state.current_transaction ? state.current_transaction.payload : nil
|
212
|
-
error_event_aggregator.
|
212
|
+
error_event_aggregator.record(noticed_error, payload)
|
213
213
|
exception
|
214
214
|
rescue => e
|
215
215
|
::NewRelic::Agent.logger.warn("Failure when capturing error '#{exception}':", e)
|
@@ -5,6 +5,7 @@
|
|
5
5
|
|
6
6
|
require 'new_relic/agent/event_aggregator'
|
7
7
|
require 'new_relic/agent/transaction_error_primitive'
|
8
|
+
require 'new_relic/agent/priority_sampled_buffer'
|
8
9
|
|
9
10
|
module NewRelic
|
10
11
|
module Agent
|
@@ -13,12 +14,15 @@ module NewRelic
|
|
13
14
|
named :ErrorEventAggregator
|
14
15
|
capacity_key :'error_collector.max_event_samples_stored'
|
15
16
|
enabled_key :'error_collector.capture_events'
|
17
|
+
buffer_class PrioritySampledBuffer
|
16
18
|
|
17
|
-
def
|
19
|
+
def record noticed_error, transaction_payload = nil
|
18
20
|
return unless enabled?
|
19
21
|
|
22
|
+
priority = (transaction_payload && transaction_payload[:priority]) || rand
|
23
|
+
|
20
24
|
@lock.synchronize do
|
21
|
-
@buffer.append do
|
25
|
+
@buffer.append(priority: priority) do
|
22
26
|
create_event(noticed_error, transaction_payload)
|
23
27
|
end
|
24
28
|
notify_if_full
|
@@ -2,7 +2,7 @@
|
|
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 'new_relic/agent/
|
5
|
+
require 'new_relic/agent/priority_sampled_buffer'
|
6
6
|
|
7
7
|
module NewRelic
|
8
8
|
module Agent
|
@@ -24,7 +24,7 @@ module NewRelic
|
|
24
24
|
if klass
|
25
25
|
@buffer_class = klass
|
26
26
|
else
|
27
|
-
@buffer_class ||=
|
27
|
+
@buffer_class ||= PrioritySampledBuffer
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -79,7 +79,7 @@ module NewRelic
|
|
79
79
|
@buffer.decrement_lifetime_counts_by samples.count
|
80
80
|
end
|
81
81
|
|
82
|
-
samples.each { |s| @buffer.append s }
|
82
|
+
samples.each { |s| @buffer.append event: s }
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -8,6 +8,7 @@ require 'new_relic/agent/audit_logger'
|
|
8
8
|
require 'new_relic/agent/new_relic_service/encoders'
|
9
9
|
require 'new_relic/agent/new_relic_service/marshaller'
|
10
10
|
require 'new_relic/agent/new_relic_service/json_marshaller'
|
11
|
+
require 'new_relic/agent/new_relic_service/security_policy_settings'
|
11
12
|
|
12
13
|
module NewRelic
|
13
14
|
module Agent
|
@@ -15,7 +16,7 @@ module NewRelic
|
|
15
16
|
# Specifies the version of the agent's communication protocol with
|
16
17
|
# the NewRelic hosted site.
|
17
18
|
|
18
|
-
PROTOCOL_VERSION =
|
19
|
+
PROTOCOL_VERSION = 16
|
19
20
|
|
20
21
|
# 1f147a42: v10 (tag 3.5.3.17)
|
21
22
|
# cf0d1ff1: v9 (tag 3.5.0)
|
@@ -68,16 +69,35 @@ module NewRelic
|
|
68
69
|
end
|
69
70
|
|
70
71
|
def connect(settings={})
|
71
|
-
|
72
|
-
|
72
|
+
security_policies = nil
|
73
|
+
if response = preconnect
|
74
|
+
if host = response['redirect_host']
|
75
|
+
@collector = NewRelic::Control.instance.server_from_host(host)
|
76
|
+
end
|
77
|
+
if policies = response['security_policies']
|
78
|
+
security_policies = SecurityPolicySettings.preliminary_settings(policies)
|
79
|
+
settings.merge!(security_policies)
|
80
|
+
end
|
73
81
|
end
|
74
82
|
response = invoke_remote(:connect, [settings])
|
75
83
|
self.agent_id = response['agent_run_id']
|
84
|
+
response.merge!(security_policies) if security_policies
|
76
85
|
response
|
77
86
|
end
|
78
87
|
|
79
88
|
def preconnect
|
80
|
-
|
89
|
+
token = Agent.config[:security_policies_token]
|
90
|
+
|
91
|
+
if token && !token.empty?
|
92
|
+
response = invoke_remote(:preconnect, [{'security_policies_token' => token}])
|
93
|
+
|
94
|
+
validator = SecurityPolicySettings::Validator.new(response)
|
95
|
+
validator.validate_matching_agent_config!
|
96
|
+
|
97
|
+
response
|
98
|
+
else
|
99
|
+
invoke_remote(:preconnect, [])
|
100
|
+
end
|
81
101
|
end
|
82
102
|
|
83
103
|
def shutdown(time)
|
@@ -0,0 +1,61 @@
|
|
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
|
+
class NewRelicService
|
8
|
+
module SecurityPolicySettings
|
9
|
+
EXPECTED_SECURITY_POLICIES = %w(
|
10
|
+
record_sql
|
11
|
+
attributes_include
|
12
|
+
allow_raw_exception_messages
|
13
|
+
custom_events
|
14
|
+
custom_parameters
|
15
|
+
custom_instrumentation_editor
|
16
|
+
message_parameters
|
17
|
+
job_arguments).map(&:freeze)
|
18
|
+
|
19
|
+
def self.preliminary_settings(security_policies)
|
20
|
+
enabled_key = 'enabled'.freeze
|
21
|
+
settings = EXPECTED_SECURITY_POLICIES.inject({}) do |memo, policy_name|
|
22
|
+
memo[policy_name] = {enabled_key => security_policies[policy_name][enabled_key]}
|
23
|
+
memo
|
24
|
+
end
|
25
|
+
{'security_policies' => settings}
|
26
|
+
end
|
27
|
+
|
28
|
+
class Validator
|
29
|
+
def initialize(preconnect_response)
|
30
|
+
@preconnect_policies = preconnect_response['security_policies'] || {}
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate_matching_agent_config!
|
34
|
+
agent_keys = EXPECTED_SECURITY_POLICIES
|
35
|
+
all_server_keys = @preconnect_policies.keys
|
36
|
+
required = 'required'
|
37
|
+
required_server_keys = @preconnect_policies.keys.select do |key|
|
38
|
+
key if @preconnect_policies[key][required]
|
39
|
+
end
|
40
|
+
|
41
|
+
missing_from_agent = required_server_keys - agent_keys
|
42
|
+
unless missing_from_agent.empty?
|
43
|
+
message = "The agent received one or more required security policies \
|
44
|
+
that it does not recognize and will shut down: #{missing_from_agent.join(',')}. \
|
45
|
+
Please check if a newer agent version supports these policies or contact support."
|
46
|
+
raise NewRelic::Agent::UnrecoverableAgentException.new(message)
|
47
|
+
end
|
48
|
+
|
49
|
+
missing_from_server = agent_keys - all_server_keys
|
50
|
+
unless missing_from_server.empty?
|
51
|
+
message = "The agent did not receive one or more security policies \
|
52
|
+
that it expected and will shut down: #{missing_from_server.join(',')}. Please \
|
53
|
+
contact support."
|
54
|
+
raise NewRelic::Agent::UnrecoverableAgentException.new(message)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -3,10 +3,11 @@
|
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
5
|
require 'new_relic/agent/heap'
|
6
|
+
require 'new_relic/agent/event_buffer'
|
6
7
|
|
7
8
|
module NewRelic
|
8
9
|
module Agent
|
9
|
-
class PrioritySampledBuffer <
|
10
|
+
class PrioritySampledBuffer < EventBuffer
|
10
11
|
PRIORITY_KEY = "priority".freeze
|
11
12
|
|
12
13
|
attr_reader :seen_lifetime, :captured_lifetime
|
@@ -28,12 +29,17 @@ module NewRelic
|
|
28
29
|
if full?
|
29
30
|
priority ||= priority_for(event)
|
30
31
|
if priority_for(@items[0]) < priority
|
31
|
-
|
32
|
+
incoming = event || blk.call
|
33
|
+
@items[0] = incoming
|
32
34
|
@items.fix(0)
|
35
|
+
incoming
|
36
|
+
else
|
37
|
+
nil
|
33
38
|
end
|
34
39
|
else
|
35
40
|
@items << (event || blk.call)
|
36
41
|
@captured_lifetime += 1
|
42
|
+
@items[-1]
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
@@ -52,6 +58,22 @@ module NewRelic
|
|
52
58
|
@items.to_a.dup
|
53
59
|
end
|
54
60
|
|
61
|
+
def decrement_lifetime_counts_by n
|
62
|
+
@captured_lifetime -= n
|
63
|
+
@seen_lifetime -= n
|
64
|
+
end
|
65
|
+
|
66
|
+
def sample_rate_lifetime
|
67
|
+
@captured_lifetime > 0 ? (@captured_lifetime.to_f / @seen_lifetime) : 0.0
|
68
|
+
end
|
69
|
+
|
70
|
+
def metadata
|
71
|
+
super.merge!(
|
72
|
+
:captured_lifetime => @captured_lifetime,
|
73
|
+
:seen_lifetime => @seen_lifetime
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
55
77
|
private
|
56
78
|
|
57
79
|
def increment_seen
|
@@ -4,30 +4,23 @@
|
|
4
4
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
5
5
|
|
6
6
|
require 'new_relic/agent/event_aggregator'
|
7
|
-
require 'new_relic/agent/
|
7
|
+
require 'new_relic/agent/timestamp_sampled_buffer'
|
8
8
|
|
9
9
|
module NewRelic
|
10
10
|
module Agent
|
11
11
|
class SyntheticsEventAggregator < EventAggregator
|
12
|
+
TIMESTAMP = 'timestamp'.freeze
|
12
13
|
|
13
14
|
named :SyntheticsEventAggregator
|
14
15
|
capacity_key :'synthetics.events_limit'
|
15
16
|
enabled_key :'analytics_events.enabled'
|
16
|
-
buffer_class
|
17
|
+
buffer_class TimestampSampledBuffer
|
17
18
|
|
18
|
-
def
|
19
|
+
def record event
|
19
20
|
return unless enabled?
|
20
21
|
|
21
22
|
@lock.synchronize do
|
22
|
-
@buffer.
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
# slightly different semantics than the EventAggregator for merge
|
27
|
-
def merge! payload
|
28
|
-
_, events = payload
|
29
|
-
@lock.synchronize do
|
30
|
-
events.each { |e| @buffer.append_with_reject e}
|
23
|
+
@buffer.append event: event, priority: -event[0][TIMESTAMP]
|
31
24
|
end
|
32
25
|
end
|
33
26
|
|
@@ -0,0 +1,19 @@
|
|
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/heap'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
class TimestampSampledBuffer < PrioritySampledBuffer
|
10
|
+
TIMESTAMP_KEY = "timestamp".freeze
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def priority_for(event)
|
15
|
+
-event[0][TIMESTAMP_KEY]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -30,6 +30,7 @@ module NewRelic
|
|
30
30
|
SYNTHETICS_RESOURCE_ID_KEY = "nr.syntheticsResourceId".freeze
|
31
31
|
SYNTHETICS_JOB_ID_KEY = "nr.syntheticsJobId".freeze
|
32
32
|
SYNTHETICS_MONITOR_ID_KEY = "nr.syntheticsMonitorId".freeze
|
33
|
+
PRIORITY_KEY = "priority".freeze
|
33
34
|
|
34
35
|
def create noticed_error, payload
|
35
36
|
[
|
@@ -54,6 +55,7 @@ module NewRelic
|
|
54
55
|
attrs[NAME_KEY] = payload[:name]
|
55
56
|
attrs[DURATION_KEY] = payload[:duration]
|
56
57
|
attrs[SAMPLED_KEY] = payload[:'sampled'] if Agent.config[:'distributed_tracing.enabled']
|
58
|
+
attrs[PRIORITY_KEY] = payload[:'priority']
|
57
59
|
append_synthetics payload, attrs
|
58
60
|
append_cat payload, attrs
|
59
61
|
append_distributed_trace_intrinsics payload, attrs
|
@@ -17,7 +17,7 @@ module NewRelic
|
|
17
17
|
enabled_key :'analytics_events.enabled'
|
18
18
|
buffer_class PrioritySampledBuffer
|
19
19
|
|
20
|
-
def
|
20
|
+
def record priority: nil, event:nil, &blk
|
21
21
|
unless(event || priority && blk)
|
22
22
|
raise ArgumentError, "Expected priority and block, or event"
|
23
23
|
end
|
@@ -30,18 +30,6 @@ module NewRelic
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def merge! payload, adjust_count = true
|
34
|
-
@lock.synchronize do
|
35
|
-
_, samples = payload
|
36
|
-
|
37
|
-
if adjust_count
|
38
|
-
@buffer.decrement_lifetime_counts_by samples.count
|
39
|
-
end
|
40
|
-
|
41
|
-
samples.each { |s| @buffer.append event: s }
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
33
|
private
|
46
34
|
|
47
35
|
def after_harvest metadata
|
@@ -24,10 +24,10 @@ module NewRelic
|
|
24
24
|
|
25
25
|
if synthetics_event? payload
|
26
26
|
event = create_event payload
|
27
|
-
|
28
|
-
transaction_event_aggregator.
|
27
|
+
result = synthetics_event_aggregator.record event
|
28
|
+
transaction_event_aggregator.record event: event if result.nil?
|
29
29
|
else
|
30
|
-
transaction_event_aggregator.
|
30
|
+
transaction_event_aggregator.record(priority: payload[:priority]) { create_event(payload) }
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -68,7 +68,10 @@ module NewRelic
|
|
68
68
|
Module.send :include, NewRelic::Agent::MethodTracer
|
69
69
|
init_config(options)
|
70
70
|
NewRelic::Agent.agent = NewRelic::Agent::Agent.instance
|
71
|
-
|
71
|
+
|
72
|
+
if !security_settings_valid?
|
73
|
+
handle_invalid_security_settings
|
74
|
+
elsif Agent.config[:agent_enabled] && !NewRelic::Agent.instance.started?
|
72
75
|
start_agent
|
73
76
|
install_instrumentation
|
74
77
|
elsif !Agent.config[:agent_enabled]
|
@@ -100,12 +103,26 @@ module NewRelic
|
|
100
103
|
config_file_path = @config_file_override || Agent.config[:config_path]
|
101
104
|
Agent.config.replace_or_add_config(Agent::Configuration::YamlSource.new(config_file_path, env))
|
102
105
|
|
103
|
-
if Agent.config[:high_security]
|
106
|
+
if security_settings_valid? && Agent.config[:high_security]
|
104
107
|
Agent.logger.info("Installing high security configuration based on local configuration")
|
105
108
|
Agent.config.replace_or_add_config(Agent::Configuration::HighSecuritySource.new(Agent.config))
|
106
109
|
end
|
107
110
|
end
|
108
111
|
|
112
|
+
def security_settings_valid?
|
113
|
+
!Agent.config[:high_security] ||
|
114
|
+
Agent.config[:security_policies_token].empty?
|
115
|
+
end
|
116
|
+
|
117
|
+
def handle_invalid_security_settings
|
118
|
+
NewRelic::Agent.logger.error "Security Policies and High Security " \
|
119
|
+
"Mode cannot both be present in the agent configuration. If " \
|
120
|
+
"Security Policies have been set for your account, please " \
|
121
|
+
"ensure the security_policies_token is set but high_security is " \
|
122
|
+
"disabled (default)."
|
123
|
+
install_shim
|
124
|
+
end
|
125
|
+
|
109
126
|
# Install the real agent into the Agent module, and issue the start command.
|
110
127
|
def start_agent
|
111
128
|
@started_in_env = self.env
|
data/lib/new_relic/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: newrelic_rpm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.2.0.345
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Wear
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2018-
|
14
|
+
date: 2018-05-23 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rake
|
@@ -217,6 +217,7 @@ files:
|
|
217
217
|
- lib/new_relic/agent/configuration/manager.rb
|
218
218
|
- lib/new_relic/agent/configuration/manual_source.rb
|
219
219
|
- lib/new_relic/agent/configuration/mask_defaults.rb
|
220
|
+
- lib/new_relic/agent/configuration/security_policy_source.rb
|
220
221
|
- lib/new_relic/agent/configuration/server_source.rb
|
221
222
|
- lib/new_relic/agent/configuration/yaml_source.rb
|
222
223
|
- lib/new_relic/agent/cross_app_monitor.rb
|
@@ -331,6 +332,7 @@ files:
|
|
331
332
|
- lib/new_relic/agent/new_relic_service/encoders.rb
|
332
333
|
- lib/new_relic/agent/new_relic_service/json_marshaller.rb
|
333
334
|
- lib/new_relic/agent/new_relic_service/marshaller.rb
|
335
|
+
- lib/new_relic/agent/new_relic_service/security_policy_settings.rb
|
334
336
|
- lib/new_relic/agent/null_logger.rb
|
335
337
|
- lib/new_relic/agent/obfuscator.rb
|
336
338
|
- lib/new_relic/agent/parameter_filtering.rb
|
@@ -343,7 +345,6 @@ files:
|
|
343
345
|
- lib/new_relic/agent/rules_engine.rb
|
344
346
|
- lib/new_relic/agent/rules_engine/replacement_rule.rb
|
345
347
|
- lib/new_relic/agent/rules_engine/segment_terms_rule.rb
|
346
|
-
- lib/new_relic/agent/sampled_buffer.rb
|
347
348
|
- lib/new_relic/agent/sampler.rb
|
348
349
|
- lib/new_relic/agent/sampler_collection.rb
|
349
350
|
- lib/new_relic/agent/samplers/cpu_sampler.rb
|
@@ -351,7 +352,6 @@ files:
|
|
351
352
|
- lib/new_relic/agent/samplers/memory_sampler.rb
|
352
353
|
- lib/new_relic/agent/samplers/object_sampler.rb
|
353
354
|
- lib/new_relic/agent/samplers/vm_sampler.rb
|
354
|
-
- lib/new_relic/agent/sized_buffer.rb
|
355
355
|
- lib/new_relic/agent/sql_sampler.rb
|
356
356
|
- lib/new_relic/agent/stats.rb
|
357
357
|
- lib/new_relic/agent/stats_engine.rb
|
@@ -359,13 +359,13 @@ files:
|
|
359
359
|
- lib/new_relic/agent/stats_engine/stats_hash.rb
|
360
360
|
- lib/new_relic/agent/supported_versions.rb
|
361
361
|
- lib/new_relic/agent/synthetics_event_aggregator.rb
|
362
|
-
- lib/new_relic/agent/synthetics_event_buffer.rb
|
363
362
|
- lib/new_relic/agent/synthetics_monitor.rb
|
364
363
|
- lib/new_relic/agent/system_info.rb
|
365
364
|
- lib/new_relic/agent/threading/agent_thread.rb
|
366
365
|
- lib/new_relic/agent/threading/backtrace_node.rb
|
367
366
|
- lib/new_relic/agent/threading/backtrace_service.rb
|
368
367
|
- lib/new_relic/agent/threading/thread_profile.rb
|
368
|
+
- lib/new_relic/agent/timestamp_sampled_buffer.rb
|
369
369
|
- lib/new_relic/agent/transaction.rb
|
370
370
|
- lib/new_relic/agent/transaction/abstract_segment.rb
|
371
371
|
- lib/new_relic/agent/transaction/attributes.rb
|
@@ -484,7 +484,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
484
484
|
version: 1.3.1
|
485
485
|
requirements: []
|
486
486
|
rubyforge_project:
|
487
|
-
rubygems_version: 2.7.
|
487
|
+
rubygems_version: 2.7.7
|
488
488
|
signing_key:
|
489
489
|
specification_version: 4
|
490
490
|
summary: New Relic Ruby Agent
|
@@ -1,68 +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
|
-
# This class acts like an Array with a fixed capacity that randomly samples
|
6
|
-
# from a stream of items such that the probability of each item being included
|
7
|
-
# in the Array is equal. It uses reservoir sampling in order to achieve this:
|
8
|
-
# http://xlinux.nist.gov/dads/HTML/reservoirSampling.html
|
9
|
-
|
10
|
-
require 'new_relic/agent/event_buffer'
|
11
|
-
|
12
|
-
module NewRelic
|
13
|
-
module Agent
|
14
|
-
class SampledBuffer < EventBuffer
|
15
|
-
attr_reader :seen_lifetime, :captured_lifetime
|
16
|
-
|
17
|
-
def initialize(capacity)
|
18
|
-
super
|
19
|
-
@captured_lifetime = 0
|
20
|
-
@seen_lifetime = 0
|
21
|
-
end
|
22
|
-
|
23
|
-
def append(x = nil, &blk)
|
24
|
-
@seen += 1
|
25
|
-
@seen_lifetime += 1
|
26
|
-
append_event(x, &blk)
|
27
|
-
end
|
28
|
-
|
29
|
-
def append_event(x = nil, &blk)
|
30
|
-
raise ArgumentError, "Expected argument or block, but received both" if x && blk
|
31
|
-
|
32
|
-
if @items.size < @capacity
|
33
|
-
x = blk.call if block_given?
|
34
|
-
@items << x
|
35
|
-
@captured_lifetime += 1
|
36
|
-
return x
|
37
|
-
else
|
38
|
-
m = rand(@seen) # [0, @seen)
|
39
|
-
if m < @capacity
|
40
|
-
x = blk.call if block_given?
|
41
|
-
@items[m] = x
|
42
|
-
return x
|
43
|
-
else
|
44
|
-
# discard current sample
|
45
|
-
return nil
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def decrement_lifetime_counts_by n
|
51
|
-
@captured_lifetime -= n
|
52
|
-
@seen_lifetime -= n
|
53
|
-
end
|
54
|
-
|
55
|
-
def sample_rate_lifetime
|
56
|
-
@captured_lifetime > 0 ? (@captured_lifetime.to_f / @seen_lifetime) : 0.0
|
57
|
-
end
|
58
|
-
|
59
|
-
def metadata
|
60
|
-
super.merge!(
|
61
|
-
:captured_lifetime => @captured_lifetime,
|
62
|
-
:seen_lifetime => @seen_lifetime
|
63
|
-
)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
@@ -1,23 +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/event_buffer'
|
6
|
-
|
7
|
-
module NewRelic
|
8
|
-
module Agent
|
9
|
-
class SizedBuffer < EventBuffer
|
10
|
-
|
11
|
-
def append_event(x)
|
12
|
-
if @items.size < @capacity
|
13
|
-
@items << x
|
14
|
-
return x
|
15
|
-
else
|
16
|
-
return nil
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
@@ -1,40 +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/sized_buffer'
|
6
|
-
|
7
|
-
module NewRelic
|
8
|
-
module Agent
|
9
|
-
class SyntheticsEventBuffer < SizedBuffer
|
10
|
-
|
11
|
-
def append_with_reject(x)
|
12
|
-
@seen += 1
|
13
|
-
if full?
|
14
|
-
timestamp = timestamp_for(x)
|
15
|
-
latest_event = @items.max_by do |item|
|
16
|
-
timestamp_for(item)
|
17
|
-
end
|
18
|
-
|
19
|
-
if timestamp < timestamp_for(latest_event)
|
20
|
-
# Make room!
|
21
|
-
@items.delete(latest_event)
|
22
|
-
return [append_event(x), latest_event]
|
23
|
-
else
|
24
|
-
return [nil, x]
|
25
|
-
end
|
26
|
-
else
|
27
|
-
return [append_event(x), nil]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
TIMESTAMP = "timestamp".freeze
|
32
|
-
|
33
|
-
def timestamp_for(event)
|
34
|
-
main_event, _ = event
|
35
|
-
main_event[TIMESTAMP]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|