scout_apm 1.5.3 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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