Skip to content

Commit b28cf18

Browse files
committed
it fixes metric's bugs
1 parent f8a8541 commit b28cf18

4 files changed

Lines changed: 47 additions & 82 deletions

File tree

lib/stackify/metrics/metric_aggregate.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Stackify::Metrics
22
class MetricAggregate
33

44
attr_accessor :name, :category, :value, :count, :occurred_utc,
5-
:monitor_id, :metric_type, :name_key
5+
:monitor_id, :metric_type, :name_key, :sent, :is_increment
66

77
def initialize metric
88
@name = metric.name
@@ -12,6 +12,8 @@ def initialize metric
1212
@count = 0
1313
@occurred_utc = metric.get_rounded_time
1414
@name_key = metric.calc_name_key
15+
@sent = false
16+
@is_increment = metric.is_increment
1517
end
1618

1719
def aggregate_key

lib/stackify/metrics/metrics.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ def time category, metric_name, start_time, advanced_settings = nil
6767
avarage_time category, metric_name, time_taken, advanced_settings
6868
end
6969

70+
def time_duration category, metric_name, duration_time, advanced_settings = nil
71+
avarage_time category, metric_name, duration_time, advanced_settings
72+
end
73+
7074
def avarage_time category, metric_name, elapsed_time, advanced_settings = nil
7175
m = Metric.new category, metric_name, Stackify::Metrics::METRIC_TYPES[:counter_time]
7276
m.value = elapsed_time.round #seconds

lib/stackify/metrics/metrics_client.rb

Lines changed: 32 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -60,83 +60,41 @@ def start_upload_metrics
6060
#read everything up to the start of the current minute
6161
read_queued_metrics_batch current_time
6262
handle_zero_reports current_time
63-
get_for_recent = @aggregate_metrics.select do |_k, v|
64-
v.occurred_utc < current_time && v.occurred_utc > current_time - 5.minutes
65-
end
66-
set_latest_aggregates get_for_recent
63+
6764
selected_aggr_metrics = @aggregate_metrics.select { |_key, aggr| aggr.occurred_utc < current_time }
6865
first_50_metrics = Hash[selected_aggr_metrics.to_a.take 50]
6966
if first_50_metrics.length > 0
7067
#only getting metrics less than 10 minutes old to drop old data in case we get backed up
7168
#they are removed from the @aggregated_metrics in the upload function upon success
72-
all_success = upload_aggregates(first_50_metrics.select { |_key, aggr| aggr.occurred_utc > current_time - 10.minutes })
73-
all_success.map {|key, _aggr| @aggregate_metrics[key].occurred_utc = current_time }
69+
upload_aggregates(first_50_metrics.select { |_key, aggr| aggr.occurred_utc > current_time - 10.minutes })
7470
end
7571
@aggregate_metrics.delete_if { |_key, aggr| aggr.occurred_utc < purge_older_than }
7672
end
7773

78-
def read_queued_metrics_batch chosen_time
79-
batches = {}
80-
74+
def read_queued_metrics_batch current_time
8175
while @metrics_queue.size > 0 do
76+
break if Stackify::Utils.rounded_current_time.to_i != current_time.to_i
8277
metric = @metrics_queue.pop
8378
metric.calc_and_set_aggregate_key
84-
unless batches.has_key? metric.aggregate_key
85-
name_key = metric.calc_name_key
86-
if metric.is_increment && @last_aggregates.has_key?(name_key)
87-
#if wanting to do increments we need to grab the last value so we know what to increment
88-
metric.value = @last_aggregates[name_key].value
89-
end
90-
batches[metric.aggregate_key] = MetricAggregate.new metric
91-
#if it is nil don't do anything
92-
#we are doing it where the aggregates are created so we don't do it one very single metric,
93-
#just once per batch to optimize performance
94-
95-
@metric_settings[name_key] = metric.settings if metric.settings != nil
79+
metric_for_aggregation = MetricAggregate.new(metric)
80+
name_key = metric.calc_name_key
81+
if @last_aggregates.has_key?(name_key) &&
82+
(metric.is_increment || @last_aggregates[name_key].occurred_utc.to_i == current_time.to_i)
83+
metric_for_aggregation.value = @last_aggregates[name_key].value
84+
metric_for_aggregation.count = @last_aggregates[name_key].count
9685
end
97-
batches[metric.aggregate_key].count += 1
98-
if metric.is_increment
99-
#add or subtract
100-
batches[metric.aggregate_key].value += metric.value
101-
elsif metric.metric_type == Stackify::Metrics::METRIC_TYPES[:metric_last]
102-
#should end up the last value
103-
batches[metric.aggregate_key].value = metric.value
104-
else
105-
batches[metric.aggregate_key].value += metric.value
106-
end
107-
#we don't need anything more this recent so bail
108-
break if metric.occurred > chosen_time
109-
end
110-
batches.each_pair do |_key, aggregated_metric|
111-
aggregate aggregated_metric
112-
end
113-
end
11486

115-
def aggregate am
116-
agg_key = am.aggregate_key
117-
if @aggregate_metrics.has_key? agg_key
118-
agg = @aggregate_metrics[agg_key]
119-
else
120-
if @aggregate_metrics.length > 1000
121-
str = 'No longer aggregating new metrics because more than 1000 are queued'
122-
Stackify.internal_log :warn, str
123-
return
124-
end
125-
Stackify.internal_log :debug, 'Creating aggregate for ' + agg_key
126-
@aggregate_metrics[agg_key] = am
127-
agg = Stackify::Metrics::Metric.new am.category, am.name, am.metric_type
128-
agg = MetricAggregate.new agg
129-
agg.occurred_utc = am.occurred_utc
130-
end
87+
@metric_settings[name_key] = metric.settings if metric.settings != nil
13188

132-
if am.metric_type == Stackify::Metrics::METRIC_TYPES[:metric_last]
133-
agg.count = 1
134-
agg.value = am.value
135-
else
136-
agg.count += am.count
137-
agg.value += am.value
89+
if metric.metric_type == Stackify::Metrics::METRIC_TYPES[:metric_last] && !metric.is_increment
90+
metric_for_aggregation.value = metric.value
91+
metric_for_aggregation.count = 1
92+
else
93+
metric_for_aggregation.value += metric.value
94+
metric_for_aggregation.count += 1
95+
end
96+
@last_aggregates[name_key] = @aggregate_metrics[metric.aggregate_key] = metric_for_aggregation
13897
end
139-
@aggregate_metrics[agg_key]= agg
14098
end
14199

142100
def submit_metrics_task
@@ -153,29 +111,31 @@ def handle_zero_reports current_time
153111
@metric_settings.delete[aggregate.name_key]
154112
next
155113
end
156-
#agg = MetricAggregate.new aggregate.category, aggregate.name, aggregate.metric_type
157-
agg = aggregate
114+
agg = aggregate.dup
158115
agg.occurred_utc = current_time
159-
case aggregate.metric_type
160-
when Stackify::Metrics::METRIC_TYPES[:metric_last]
161-
settings.autoreport_last_value_if_nothing_reported = false #do not allow this
162-
when Stackify::Metrics::METRIC_TYPES[:counter]
116+
117+
disabled_autoreport_last = [
118+
Stackify::Metrics::METRIC_TYPES[:counter],
119+
Stackify::Metrics::METRIC_TYPES[:timer]
120+
]
121+
if disabled_autoreport_last.include? aggregate.metric_type
163122
settings.autoreport_last_value_if_nothing_reported = false #do not allow this
164123
end
124+
165125
if settings.autoreport_zero_if_nothing_reported
166-
agg.count = 1
126+
agg.count = 0
167127
agg.value = 0
168128
elsif settings.autoreport_last_value_if_nothing_reported
169-
agg.count = aggregate.value.to_i
129+
agg.count = aggregate.count.to_i
170130
agg.value = aggregate.value
171131
else
172132
next
173133
end
174134
agg_key = agg.aggregate_key
175135
unless @aggregate_metrics.has_key? agg_key
176-
agg.occurred_utc = current_time - 60
177136
agg.name_key = aggregate.name_key
178-
Stackify.internal_log :debug, 'Creating 0 default value for ' + agg_key
137+
agg.sent = false
138+
Stackify.internal_log :debug, 'Creating default value for ' + agg_key
179139
@aggregate_metrics[agg_key] = agg
180140
end
181141
end
@@ -194,11 +154,6 @@ def set_latest_aggregates aggregates
194154
end
195155

196156
def upload_aggregates aggr_metrics
197-
s = ''
198-
aggr_metrics.each_pair do |_k, m|
199-
s = s + m.inspect.to_s + "\n --------------------------- \n"
200-
end
201-
Stackify.internal_log :debug, "Uploading Aggregate Metrics at #{ Time.now }: \n" + s
202157
all_success = true
203158
aggr_metrics.each_pair do |_key, metric|
204159
if @monitor_ids.has_key? metric.name_key
@@ -230,8 +185,7 @@ def upload_aggregates aggr_metrics
230185

231186
#get identified once
232187
aggr_metrics_for_upload = aggr_metrics.select { |_key, aggr_metric| !aggr_metric.monitor_id.nil? }
233-
response = @metrics_sender.upload_metrics aggr_metrics_for_upload
234-
Stackify.internal_log :info, 'Metrics are uploaded successfully' if response.try(:status) == 200
188+
@metrics_sender.upload_metrics aggr_metrics_for_upload
235189
all_success
236190
end
237191
end

lib/stackify/metrics/metrics_sender.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,19 @@ def monitor_info aggr_metric
1313

1414
def upload_metrics aggr_metrics
1515
return true if aggr_metrics.nil? || aggr_metrics.length == 0
16+
current_time = Stackify::Utils.rounded_current_time
1617
if Stackify.authorized?
1718
records = []
1819
aggr_metrics.each_pair do |_key, metric|
20+
next if metric.sent || metric.occurred_utc.to_i >= current_time.to_i
1921
records << Stackify::Metrics::MetricForSubmit.new(metric).to_h
20-
prms = [metric.category, metric.name, metric.count, metric.value, metric.monitor_id ]
21-
Stackify.internal_log :debug, 'Uploading metric: %s: %s count %s, value %s, ID %s' % prms
22+
metric.sent = true
23+
end
24+
if records.any?
25+
Stackify.internal_log :debug, "Uploading Aggregate Metrics at #{ Time.now }: \n" + JSON.pretty_generate(records)
26+
response = send_request SUBMIT_METRIS_URI, records.to_json
27+
Stackify.internal_log :info, 'Metrics are uploaded successfully' if response.try(:status) == 200
2228
end
23-
send_request SUBMIT_METRIS_URI, records.to_json
2429
else
2530
Stackify.log_internal_error "Uploading of metrics is failed because of authorization failure"
2631
end

0 commit comments

Comments
 (0)