scout_rails 1.1.5.pre → 1.1.5.pre3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.markdown +5 -0
- data/lib/scout_rails/agent/reporting.rb +5 -3
- data/lib/scout_rails/layaway.rb +28 -12
- data/lib/scout_rails/store.rb +25 -14
- data/lib/scout_rails/version.rb +1 -1
- metadata +1 -1
data/CHANGELOG.markdown
CHANGED
@@ -7,8 +7,10 @@ module ScoutRails
|
|
7
7
|
def process_metrics
|
8
8
|
logger.debug "Processing metrics"
|
9
9
|
run_samplers
|
10
|
-
|
11
|
-
|
10
|
+
payload = layaway.deposit_and_deliver
|
11
|
+
metrics = payload[:metrics]
|
12
|
+
samples = payload[:samples]
|
13
|
+
if payload.any?
|
12
14
|
add_metric_ids(metrics)
|
13
15
|
logger.warn "Some data may be lost - metric size is at limit" if metrics.size == ScoutRails::Store::MAX_SIZE
|
14
16
|
# for debugging, count the total number of requests
|
@@ -18,7 +20,7 @@ module ScoutRails
|
|
18
20
|
controller_count += stats.call_count
|
19
21
|
end
|
20
22
|
end
|
21
|
-
sample
|
23
|
+
sample = store.fetch_and_reset_sample!
|
22
24
|
payload = Marshal.dump(:metrics => metrics, :sample => sample, :samples => samples)
|
23
25
|
STATSD.timing('scout_rails.payload_kb',payload.size/1024)
|
24
26
|
STATSD.timing('scout_rails.samples',samples.size)
|
data/lib/scout_rails/layaway.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
# 1. A centralized store for multiple Agent processes. This way, only 1 checkin is sent to Scout rather than 1 per-process.
|
3
3
|
# 2. Bundling up reports from multiple timeslices to make updates more efficent server-side.
|
4
4
|
#
|
5
|
-
#
|
6
|
-
#
|
5
|
+
# Data is stored in a Hash, where the keys are Time.to_i on the minute. The value is a Hash {:metrics => Hash, :samples => Array}.
|
6
|
+
# When depositing data, the new data is either merged with an existing time or placed in a new key.
|
7
7
|
class ScoutRails::Layaway
|
8
8
|
attr_accessor :file
|
9
9
|
def initialize
|
@@ -11,24 +11,35 @@ class ScoutRails::Layaway
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def deposit_and_deliver
|
14
|
-
|
15
|
-
|
14
|
+
new_metrics = ScoutRails::Agent.instance.store.metric_hash
|
15
|
+
log_deposited_metrics(new_metrics)
|
16
|
+
log_deposited_samples(ScoutRails::Agent.instance.store.samples)
|
16
17
|
to_deliver = {}
|
17
18
|
file.read_and_write do |old_data|
|
18
19
|
old_data ||= Hash.new
|
19
20
|
# merge data
|
20
21
|
# if (1) there's data in the file and (2) there isn't any data yet for the current minute, this means we've
|
21
22
|
# collected all metrics for the previous slots and we're ready to deliver.
|
23
|
+
#
|
24
|
+
# Example w/2 processes:
|
25
|
+
#
|
26
|
+
# 12:00:34 ---
|
27
|
+
# Process 1: old_data.any? => false, so deposits.
|
28
|
+
# Process 2: old_data_any? => true and old_data[12:00].nil? => false, so deposits.
|
29
|
+
#
|
30
|
+
# 12:01:34 ---
|
31
|
+
# Process 1: old_data.any? => true and old_data[12:01].nil? => true, so delivers metrics.
|
32
|
+
# Process 2: old_data.any? => true and old_data[12:01].nil? => false, so deposits.
|
22
33
|
if old_data.any? and old_data[slot].nil?
|
23
34
|
to_deliver = old_data
|
24
35
|
old_data = Hash.new
|
25
36
|
elsif old_data.any?
|
26
|
-
ScoutRails::Agent.instance.logger.debug "Not yet time to deliver
|
37
|
+
ScoutRails::Agent.instance.logger.debug "Not yet time to deliver payload for slot [#{Time.at(old_data.keys.sort.last).strftime("%m/%d/%y %H:%M:%S %z")}]"
|
27
38
|
else
|
28
39
|
ScoutRails::Agent.instance.logger.debug "There is no data in the layaway file to deliver."
|
29
40
|
end
|
30
|
-
old_data[slot]=ScoutRails::Agent.instance.store.merge_data_and_clear(old_data[slot] ||
|
31
|
-
|
41
|
+
old_data[slot]=ScoutRails::Agent.instance.store.merge_data_and_clear(old_data[slot] || {:metrics => {}, :samples => []})
|
42
|
+
log_saved_data(old_data,new_metrics)
|
32
43
|
old_data
|
33
44
|
end
|
34
45
|
to_deliver.any? ? validate_data(to_deliver) : {}
|
@@ -53,32 +64,37 @@ class ScoutRails::Layaway
|
|
53
64
|
ScoutRails::Agent.instance.logger.debug $!.backtrace
|
54
65
|
end
|
55
66
|
|
67
|
+
# Data is stored under timestamp-keys (without the second).
|
56
68
|
def slot
|
57
69
|
t = Time.now
|
58
70
|
t -= t.sec
|
59
71
|
t.to_i
|
60
72
|
end
|
61
73
|
|
62
|
-
def
|
74
|
+
def log_deposited_metrics(new_metrics)
|
63
75
|
controller_count = 0
|
64
|
-
|
76
|
+
new_metrics.each do |meta,stats|
|
65
77
|
if meta.metric_name =~ /\AController/
|
66
78
|
controller_count += stats.call_count
|
67
79
|
end
|
68
80
|
end
|
69
81
|
ScoutRails::Agent.instance.logger.debug "Depositing #{controller_count} requests into #{Time.at(slot).strftime("%m/%d/%y %H:%M:%S %z")} slot."
|
70
82
|
end
|
83
|
+
|
84
|
+
def log_deposited_samples(new_samples)
|
85
|
+
ScoutRails::Agent.instance.logger.debug "Depositing #{new_samples.size} samples into #{Time.at(slot).strftime("%m/%d/%y %H:%M:%S %z")} slot."
|
86
|
+
end
|
71
87
|
|
72
|
-
def
|
88
|
+
def log_saved_data(old_data,new_metrics)
|
73
89
|
ScoutRails::Agent.instance.logger.debug "Saving the following #{old_data.size} time slots locally:"
|
74
90
|
old_data.each do |k,v|
|
75
91
|
controller_count = 0
|
76
|
-
|
92
|
+
new_metrics.each do |meta,stats|
|
77
93
|
if meta.metric_name =~ /\AController/
|
78
94
|
controller_count += stats.call_count
|
79
95
|
end
|
80
96
|
end
|
81
|
-
ScoutRails::Agent.instance.logger.debug "#{Time.at(k).strftime("%m/%d/%y %H:%M:%S %z")} => #{controller_count} requests"
|
97
|
+
ScoutRails::Agent.instance.logger.debug "#{Time.at(k).strftime("%m/%d/%y %H:%M:%S %z")} => #{controller_count} requests and #{v[:samples].size} samples"
|
82
98
|
end
|
83
99
|
end
|
84
100
|
end
|
data/lib/scout_rails/store.rb
CHANGED
@@ -85,7 +85,7 @@ class ScoutRails::Store
|
|
85
85
|
duplicate.each_pair do |k,v|
|
86
86
|
duplicate[k.dup] = v.dup
|
87
87
|
end
|
88
|
-
|
88
|
+
merge_metrics(duplicate.merge({meta.dup => stat.dup})) # aggregrates + controller
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
@@ -137,19 +137,18 @@ class ScoutRails::Store
|
|
137
137
|
# tree map of all slow transactions
|
138
138
|
if parent_stat.total_call_time >= 2
|
139
139
|
@samples.push(ScoutRails::TransactionSample.new(uri,parent_meta.metric_name,parent_stat.total_call_time,transaction_hash.dup))
|
140
|
+
ScoutRails::Agent.instance.logger.debug "Slow transaction sample added. Array Size: #{@samples.size}"
|
140
141
|
end
|
141
142
|
end
|
142
143
|
end
|
143
144
|
|
144
|
-
# Returns the slow
|
145
|
-
def
|
145
|
+
# Returns the slow sample and resets the values - used when reporting.
|
146
|
+
def fetch_and_reset_sample!
|
146
147
|
sample = @sample
|
147
|
-
samples = @samples
|
148
148
|
@transaction_sample_lock.synchronize do
|
149
149
|
self.sample = nil
|
150
|
-
self.samples = Array.new
|
151
150
|
end
|
152
|
-
|
151
|
+
sample
|
153
152
|
end
|
154
153
|
|
155
154
|
# Finds or creates the metric w/the given name in the metric_hash, and updates the time. Primarily used to
|
@@ -168,14 +167,7 @@ class ScoutRails::Store
|
|
168
167
|
|
169
168
|
# Combines old and current data
|
170
169
|
def merge_data(old_data)
|
171
|
-
old_data
|
172
|
-
if stats = metric_hash[old_meta]
|
173
|
-
metric_hash[old_meta] = stats.combine!(old_stats)
|
174
|
-
elsif metric_hash.size < MAX_SIZE
|
175
|
-
metric_hash[old_meta] = old_stats
|
176
|
-
end
|
177
|
-
end
|
178
|
-
metric_hash
|
170
|
+
{:metrics => merge_metrics(old_data[:metrics]), :samples => merge_samples(old_data[:samples])}
|
179
171
|
end
|
180
172
|
|
181
173
|
# Merges old and current data, clears the current in-memory metric hash, and returns
|
@@ -183,6 +175,25 @@ class ScoutRails::Store
|
|
183
175
|
def merge_data_and_clear(old_data)
|
184
176
|
merged = merge_data(old_data)
|
185
177
|
self.metric_hash = {}
|
178
|
+
# TODO - is this lock needed?
|
179
|
+
@transaction_sample_lock.synchronize do
|
180
|
+
self.samples = []
|
181
|
+
end
|
186
182
|
merged
|
187
183
|
end
|
184
|
+
|
185
|
+
def merge_metrics(old_metrics)
|
186
|
+
old_metrics.each do |old_meta,old_stats|
|
187
|
+
if stats = metric_hash[old_meta]
|
188
|
+
metric_hash[old_meta] = stats.combine!(old_stats)
|
189
|
+
elsif metric_hash.size < MAX_SIZE
|
190
|
+
metric_hash[old_meta] = old_stats
|
191
|
+
end
|
192
|
+
end
|
193
|
+
metric_hash
|
194
|
+
end
|
195
|
+
|
196
|
+
def merge_samples(old_samples)
|
197
|
+
self.samples += old_samples
|
198
|
+
end
|
188
199
|
end # class Store
|
data/lib/scout_rails/version.rb
CHANGED