scout_apm 1.5.3 → 1.5.4

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: 27f05793dcadc7719efffe143482e56f78c869f4
4
- data.tar.gz: c1edab9ff98a8a78076eaeb42d77bf63c5e970ca
3
+ metadata.gz: 0494dfededbaa29426c0b087bb80e97f865ed237
4
+ data.tar.gz: dcbbf372d00781f4aa349d4a343650558599fb3c
5
5
  SHA512:
6
- metadata.gz: 83b0652fd7a20995670d3a2d2670d3945fcd7a122bbcd31f617509c977904f8f4d60e31c3a554aa3b56ccc71cfeb965869e7ddb080e8035c4676c47c569b6dc4
7
- data.tar.gz: be85c7d2de39976a10940a89839c242b9f8866d13b0991e3cf787a6d863ec050dd2ea12213540b6336ca2a5b1ccc079365ccd79ea40e5bffd88bc3c6ac13f04f
6
+ metadata.gz: 11b61029f1561d2ed7806224f219e8c177cc38f9cce5165a1f91eed25786f50edfae50545ab77c974b92c71386a614ed4f4f2658ee2d190f356aedf6ab0d7bac
7
+ data.tar.gz: 1c4ff4b60d1c27ec6f4df40435fa0f96feb60c18e633e6be1cbfb6c90d09e480e954d4a2c39935ea02373d939dfdd20aeccf31c582c0321ce8114a208d4fb77b
data/CHANGELOG.markdown CHANGED
@@ -1,3 +1,8 @@
1
+ # 1.5.4
2
+
3
+ * Fix issue where error counts were being misreported
4
+ * Politely ignore cases when `request.remote_ip` raises exceptions.
5
+
1
6
  # 1.5.3
2
7
 
3
8
  * Fix another minor bug related to iso8601 timestamps
@@ -61,7 +61,10 @@ module ScoutApm
61
61
  req = ScoutApm::RequestManager.lookup
62
62
  path = ScoutApm::Agent.instance.config.value("uri_reporting") == 'path' ? request.path : request.fullpath
63
63
  req.annotate_request(:uri => path)
64
- req.context.add_user(:ip => request.remote_ip)
64
+
65
+ # IP Spoofing Protection can throw an exception, just move on w/o remote ip
66
+ req.context.add_user(:ip => request.remote_ip) rescue nil
67
+
65
68
  req.set_headers(request.headers)
66
69
  req.web!
67
70
 
@@ -18,10 +18,7 @@ module ScoutApm
18
18
  new_req = new_val.request_count
19
19
  ScoutApm::Agent.instance.logger.debug("Merging Two reporting periods (#{old_val.timestamp.to_s}, #{new_val.timestamp.to_s}): old req #{old_req}, new req #{new_req}")
20
20
 
21
- old_val.
22
- merge_metrics!(new_val.metrics_payload).
23
- merge_slow_transactions!(new_val.slow_transactions).
24
- merge_jobs!(new_val.jobs)
21
+ old_val.merge(new_val)
25
22
  }
26
23
 
27
24
  ScoutApm::Agent.instance.logger.debug("AddReportingPeriod: AfterMerge Timestamps: #{existing_data.keys.map(&:to_s).inspect}")
@@ -23,11 +23,15 @@ module ScoutApm
23
23
  @metrics[meta].combine!(stat)
24
24
 
25
25
  elsif meta.type == "Errors" # Sadly special cased, we want both raw and aggregate values
26
- @metrics[meta] ||= MetricStats.new
27
- @metrics[meta].combine!(stat)
28
- agg_meta = MetricMeta.new("Errors/Request", :scope => meta.scope)
29
- @metrics[agg_meta] ||= MetricStats.new
30
- @metrics[agg_meta].combine!(stat)
26
+ # When combining MetricSets between different
27
+ @metrics[meta] ||= MetricStats.new
28
+ @metrics[meta].combine!(stat)
29
+
30
+ if !@combine_in_progress
31
+ agg_meta = MetricMeta.new("Errors/Request", :scope => meta.scope)
32
+ @metrics[agg_meta] ||= MetricStats.new
33
+ @metrics[agg_meta].combine!(stat)
34
+ end
31
35
 
32
36
  else # Combine down to a single /all key
33
37
  agg_meta = MetricMeta.new("#{meta.type}/all", :scope => meta.scope)
@@ -36,8 +40,13 @@ module ScoutApm
36
40
  end
37
41
  end
38
42
 
43
+ # Sets a combine_in_progress flag to prevent double-counting Error metrics.
44
+ # Without it, the Errors/Request number would be increasingly off as
45
+ # metric_sets get merged in.
39
46
  def combine!(other)
47
+ @combine_in_progress = true
40
48
  absorb_all(other.metrics)
49
+ @combine_in_progress = false
41
50
  self
42
51
  end
43
52
  end
@@ -22,7 +22,7 @@ module ScoutApm
22
22
  # Save newly collected metrics
23
23
  def track!(metrics, options={})
24
24
  @mutex.synchronize {
25
- current_period.merge_metrics!(metrics)
25
+ current_period.absorb_metrics!(metrics)
26
26
  }
27
27
  end
28
28
 
@@ -129,14 +129,30 @@ module ScoutApm
129
129
  @jobs = Hash.new
130
130
  end
131
131
 
132
+ # Merges another StoreReportingPeriod into this one
133
+ def merge(new_val)
134
+ self.
135
+ merge_metrics!(new_val.metric_set).
136
+ merge_slow_transactions!(new_val.slow_transactions).
137
+ merge_jobs!(new_val.jobs)
138
+ end
139
+
132
140
  #################################
133
141
  # Add metrics as they are recorded
134
142
  #################################
135
- def merge_metrics!(metrics)
143
+
144
+ # For absorbing an array of metric {Meta => Stat} records
145
+ def absorb_metrics!(metrics)
136
146
  metric_set.absorb_all(metrics)
137
147
  self
138
148
  end
139
149
 
150
+ # For merging when you have another metric_set object
151
+ def merge_metrics!(other_metric_set)
152
+ metric_set.combine!(other_metric_set)
153
+ self
154
+ end
155
+
140
156
  def merge_slow_transactions!(new_transactions)
141
157
  Array(new_transactions).each do |one_transaction|
142
158
  slow_transactions << one_transaction
@@ -1,4 +1,4 @@
1
1
  module ScoutApm
2
- VERSION = "1.5.3"
2
+ VERSION = "1.5.4"
3
3
  end
4
4
 
@@ -0,0 +1,101 @@
1
+ require 'test_helper'
2
+
3
+ require 'scout_apm/metric_set'
4
+
5
+ module ScoutApm
6
+ class MetricSetTest < Minitest::Test
7
+ def setup
8
+ @metric_set = ScoutApm::MetricSet.new
9
+ end
10
+
11
+ def test_absorb_one_passthrough_metric
12
+ @metric_set.absorb(make_fake_stat("Controller/Foo", 1))
13
+
14
+ assert_equal 1, @metric_set.metrics.length
15
+ assert_equal "Controller/Foo", @metric_set.metrics.first.first.metric_name
16
+ end
17
+
18
+ def test_absorb_one_aggregate_metric
19
+ @metric_set.absorb(make_fake_stat("ActiveRecord/Foo", 1))
20
+
21
+ assert_equal 1, @metric_set.metrics.length
22
+ assert_equal "ActiveRecord/all", @metric_set.metrics.first.first.metric_name
23
+ end
24
+
25
+ def test_absorb_many_aggregate_metric
26
+ @metric_set.absorb(make_fake_stat("ActiveRecord/Foo", 1))
27
+ @metric_set.absorb(make_fake_stat("ActiveRecord/Bar", 1))
28
+ @metric_set.absorb(make_fake_stat("ActiveRecord/Baz", 1))
29
+ @metric_set.absorb(make_fake_stat("HTTP/Get", 1))
30
+ @metric_set.absorb(make_fake_stat("HTTP/Post", 1))
31
+
32
+ metrics = @metric_set.metrics.to_a.sort_by { |m| m.first.metric_name }
33
+ assert_equal 2, metrics.length
34
+ assert_equal "ActiveRecord/all", metrics[0][0].metric_name
35
+ assert_equal "HTTP/all", metrics[1][0].metric_name
36
+ assert_equal 3, metrics[0][1].call_count
37
+ assert_equal 2, metrics[1][1].call_count
38
+ end
39
+
40
+ def test_absorb_one_error
41
+ @metric_set.absorb(make_fake_stat("Errors/Controller/public/index", 1))
42
+
43
+ metrics = @metric_set.metrics.to_a.sort_by { |m| m.first.metric_name }
44
+ assert_equal 2, metrics.length
45
+ assert_equal "Errors/Controller/public/index", metrics[0].first.metric_name
46
+ assert_equal "Errors/Request", metrics[1].first.metric_name
47
+ end
48
+
49
+ def test_absorb_many_metrics
50
+ @metric_set.absorb_all([
51
+ make_fake_stat("ActiveRecord/Foo", 1),
52
+ make_fake_stat("Controller/Bar", 1)
53
+ ])
54
+
55
+ metrics = @metric_set.metrics.to_a.sort_by { |m| m.first.metric_name }
56
+ assert_equal 2, metrics.length
57
+ assert_equal "ActiveRecord/all", metrics[0].first.metric_name
58
+ assert_equal "Controller/Bar", metrics[1].first.metric_name
59
+ end
60
+
61
+ def test_combine
62
+ @other_set = ScoutApm::MetricSet.new
63
+
64
+ @metric_set.absorb_all([
65
+ make_fake_stat("ActiveRecord/Foo", 1),
66
+ make_fake_stat("Controller/Bar", 1),
67
+ make_fake_stat("Errors/Controller/public/index", 1),
68
+ ])
69
+
70
+ @other_set.absorb_all([
71
+ make_fake_stat("ActiveRecord/Foo", 1),
72
+ make_fake_stat("Controller/Bar", 1),
73
+ make_fake_stat("Errors/Controller/public/index", 1),
74
+ ])
75
+
76
+ @metric_set.combine!(@other_set)
77
+
78
+ metrics = @metric_set.metrics.to_a.sort_by { |m| m.first.metric_name }
79
+ assert_equal 4, metrics.length
80
+ assert_equal "ActiveRecord/all", metrics[0][0].metric_name
81
+ assert_equal "Controller/Bar", metrics[1][0].metric_name
82
+ assert_equal "Errors/Controller/public/index", metrics[2][0].metric_name
83
+ assert_equal "Errors/Request", metrics[3][0].metric_name
84
+
85
+ assert_equal 2, metrics[0][1].call_count
86
+ assert_equal 2, metrics[1][1].call_count
87
+ assert_equal 2, metrics[2][1].call_count
88
+ assert_equal 2, metrics[3][1].call_count
89
+ end
90
+
91
+ ############################################################
92
+ # Test helper functions
93
+ ############################################################
94
+ def make_fake_stat(name, count)
95
+ meta = MetricMeta.new(name)
96
+ stat = MetricStats.new
97
+ stat.update!(count)
98
+ [meta, stat]
99
+ end
100
+ end
101
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout_apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 1.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek Haynes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-05-16 00:00:00.000000000 Z
12
+ date: 2016-05-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
@@ -188,6 +188,7 @@ files:
188
188
  - test/unit/histogram_test.rb
189
189
  - test/unit/instruments/active_record_instruments_test.rb
190
190
  - test/unit/layaway_test.rb
191
+ - test/unit/metric_set_test.rb
191
192
  - test/unit/serializers/payload_serializer_test.rb
192
193
  - test/unit/slow_item_set_test.rb
193
194
  - test/unit/slow_job_policy_test.rb
@@ -226,6 +227,7 @@ test_files:
226
227
  - test/unit/histogram_test.rb
227
228
  - test/unit/instruments/active_record_instruments_test.rb
228
229
  - test/unit/layaway_test.rb
230
+ - test/unit/metric_set_test.rb
229
231
  - test/unit/serializers/payload_serializer_test.rb
230
232
  - test/unit/slow_item_set_test.rb
231
233
  - test/unit/slow_job_policy_test.rb