honeybadger 1.16.3 → 1.16.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 95c84537311090f380f204bebae0cad76c3a6ed0
4
+ data.tar.gz: ce0863f60d458ffb2adf191c1ddb3e45d425bd02
5
+ SHA512:
6
+ metadata.gz: 7fdc08780b454cdb572ba8f3958e884a329b5ef8eeeb561f202ad485d195ec2bc561b999f6467d8c08eb241674efb4d02e86f91e577e584b0bd522a0fef5ccc1
7
+ data.tar.gz: 576b88251d6d3ac32ad314229114fe855216cc5e7ed6e9f539efe2b28dbe020681be25d51ae839df7d557e138e74a2653d472eb4cdc6b9a963638f48aa1804bb
data/Appraisals CHANGED
@@ -45,7 +45,7 @@ if RUBY_VERSION > '1.9'
45
45
  appraise 'rails3.0' do
46
46
  gem 'rails', '~> 3.0.17'
47
47
  gem 'honeybadger', :path => '../'
48
- gem 'better_errors', :require => false
48
+ gem 'better_errors', '~> 1.0', :require => false
49
49
  gem 'rack-mini-profiler', '~>0.1.31 ', :require => false
50
50
  gem 'capistrano', '~> 2.0'
51
51
  end
@@ -53,7 +53,7 @@ if RUBY_VERSION > '1.9'
53
53
  appraise 'rails3.1' do
54
54
  gem 'rails', '~> 3.1.12'
55
55
  gem 'honeybadger', :path => '../'
56
- gem 'better_errors', :require => false
56
+ gem 'better_errors', '~> 1.0', :require => false
57
57
  gem 'rack-mini-profiler', :require => false
58
58
  gem 'capistrano', '~> 2.0'
59
59
  end
@@ -61,7 +61,7 @@ if RUBY_VERSION > '1.9'
61
61
  appraise 'rails3.2' do
62
62
  gem 'rails', '~> 3.2.12'
63
63
  gem 'honeybadger', :path => '../'
64
- gem 'better_errors', :require => false
64
+ gem 'better_errors', '~> 1.0', :require => false
65
65
  gem 'rack-mini-profiler', :require => false
66
66
  gem 'capistrano', '~> 2.0'
67
67
  end
@@ -72,7 +72,7 @@ if RUBY_VERSION > '1.9'
72
72
  gem 'rails', '~> 4.0.3'
73
73
  gem 'honeybadger', :path => '../'
74
74
  gem 'capistrano', '~> 3.0'
75
- gem 'better_errors', :require => false
75
+ gem 'better_errors', '~> 1.0', :require => false
76
76
  gem 'rack-mini-profiler', :require => false
77
77
  end
78
78
 
@@ -80,7 +80,7 @@ if RUBY_VERSION > '1.9'
80
80
  gem 'rails', '~> 4.1.0.beta1'
81
81
  gem 'honeybadger', :path => '../'
82
82
  gem 'capistrano', '~> 3.0'
83
- gem 'better_errors', :require => false
83
+ gem 'better_errors', '~> 1.0', :require => false
84
84
  gem 'rack-mini-profiler', :require => false
85
85
  end
86
86
  end
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## Honeybadger 1.16.4 ##
2
+
3
+ * Include a portion of longer queries with traces.
4
+
5
+ *Benjamin Curtis*
6
+
7
+ * Aggregate short queries when sending traces.
8
+
9
+ *Benjamin Curtis*
10
+
1
11
  ## Honeybadger 1.16.3 ##
2
12
 
3
13
  * Handle `nil` session in Rails controllers (i.e., when the `session_off` gem is
data/Gemfile CHANGED
@@ -1,2 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
+
4
+ unless RUBY_VERSION < '2.1'
5
+ gem 'allocation_stats'
6
+ end
data/Gemfile.lock CHANGED
@@ -1,12 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- honeybadger (1.16.3)
4
+ honeybadger (1.16.4)
5
5
  json
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
+ allocation_stats (0.1.5)
10
11
  appraisal (0.5.1)
11
12
  bundler
12
13
  rake
@@ -109,6 +110,7 @@ PLATFORMS
109
110
  ruby
110
111
 
111
112
  DEPENDENCIES
113
+ allocation_stats
112
114
  appraisal
113
115
  aruba
114
116
  capistrano (~> 2.0)
@@ -2,6 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "binding_of_caller"
6
7
  gem "honeybadger", :path=>"../"
7
8
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "delayed_job"
6
7
  gem "honeybadger", :path=>"../"
7
8
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "rack"
6
7
  gem "honeybadger", :path=>"../"
7
8
 
@@ -2,10 +2,11 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "rails", "~> 4.0.3"
6
7
  gem "honeybadger", :path=>"../"
7
8
  gem "capistrano", "~> 3.0"
8
- gem "better_errors", :require=>false
9
+ gem "better_errors", "~> 1.0", :require=>false
9
10
  gem "rack-mini-profiler", :require=>false
10
11
 
11
12
  gemspec :path=>"../"
@@ -2,6 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "rails", "~> 2.3.18"
6
7
  gem "rake", "0.9.5"
7
8
  gem "honeybadger", :path=>"../"
@@ -2,9 +2,10 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "rails", "~> 3.0.17"
6
7
  gem "honeybadger", :path=>"../"
7
- gem "better_errors", :require=>false
8
+ gem "better_errors", "~> 1.0", :require=>false
8
9
  gem "rack-mini-profiler", "~>0.1.31 ", :require=>false
9
10
  gem "capistrano", "~> 2.0"
10
11
 
@@ -2,9 +2,10 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "rails", "~> 3.1.12"
6
7
  gem "honeybadger", :path=>"../"
7
- gem "better_errors", :require=>false
8
+ gem "better_errors", "~> 1.0", :require=>false
8
9
  gem "rack-mini-profiler", :require=>false
9
10
  gem "capistrano", "~> 2.0"
10
11
 
@@ -2,9 +2,10 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "rails", "~> 3.2.12"
6
7
  gem "honeybadger", :path=>"../"
7
- gem "better_errors", :require=>false
8
+ gem "better_errors", "~> 1.0", :require=>false
8
9
  gem "rack-mini-profiler", :require=>false
9
10
  gem "capistrano", "~> 2.0"
10
11
 
@@ -2,10 +2,11 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "rails", "~> 4.1.0.beta1"
6
7
  gem "honeybadger", :path=>"../"
7
8
  gem "capistrano", "~> 3.0"
8
- gem "better_errors", :require=>false
9
+ gem "better_errors", "~> 1.0", :require=>false
9
10
  gem "rack-mini-profiler", :require=>false
10
11
 
11
12
  gemspec :path=>"../"
@@ -2,6 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "rake"
6
7
  gem "honeybadger", :path=>"../"
7
8
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "sinatra"
6
7
  gem "honeybadger", :path=>"../"
7
8
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "honeybadger", :path=>"../"
6
7
 
7
8
  gemspec :path=>"../"
@@ -2,6 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "allocation_stats"
5
6
  gem "thor"
6
7
  gem "honeybadger", :path=>"../"
7
8
 
data/honeybadger.gemspec CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
  s.rubygems_version = '1.3.5'
5
5
 
6
6
  s.name = 'honeybadger'
7
- s.version = '1.16.3'
8
- s.date = '2014-07-21'
7
+ s.version = '1.16.4'
8
+ s.date = '2014-08-26'
9
9
 
10
10
  s.summary = 'Error reports you can be happy about.'
11
11
  s.description = 'Make managing application errors a more pleasant experience.'
@@ -136,6 +136,7 @@ Gem::Specification.new do |s|
136
136
  resources/README.md
137
137
  resources/ca-bundle.crt
138
138
  script/integration_test.rb
139
+ spec/allocation_stats.rb
139
140
  spec/honeybadger/backtrace_spec.rb
140
141
  spec/honeybadger/capistrano_spec.rb
141
142
  spec/honeybadger/configuration_spec.rb
data/lib/honeybadger.rb CHANGED
@@ -19,7 +19,7 @@ require 'honeybadger/railtie' if defined?(Rails::Railtie)
19
19
  require 'honeybadger/monitor'
20
20
 
21
21
  module Honeybadger
22
- VERSION = '1.16.3'.freeze
22
+ VERSION = '1.16.4'.freeze
23
23
  LOG_PREFIX = "** [Honeybadger] ".freeze
24
24
 
25
25
  HEADERS = {
@@ -10,7 +10,7 @@ module Honeybadger
10
10
 
11
11
  ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
12
12
  event = ActiveSupport::Notifications::Event.new(*args)
13
- Monitor.worker.trace.add(event) if Monitor.worker.trace and event.name != 'SCHEMA'
13
+ Monitor.worker.trace.add_query(event) if Monitor.worker.trace and event.name != 'SCHEMA'
14
14
  end
15
15
 
16
16
  ActiveSupport::Notifications.subscribe(/^render_(template|action|collection)\.action_view/) do |*args|
@@ -24,6 +24,7 @@ module Honeybadger
24
24
  @id = id
25
25
  @events = []
26
26
  @meta = {}
27
+ @fast_queries = {}
27
28
  @duration = 0
28
29
  end
29
30
 
@@ -32,6 +33,22 @@ module Honeybadger
32
33
  @events << ce.to_a if ce.render?
33
34
  end
34
35
 
36
+ def add_query(event)
37
+ if event.duration < 6
38
+ ce = clean_event(event)
39
+ return unless ce.render?
40
+ query = ce.to_s
41
+ if @fast_queries[query]
42
+ @fast_queries[query][:duration] += ce.event.duration
43
+ @fast_queries[query][:count] += 1
44
+ else
45
+ @fast_queries[query] = { :duration => ce.event.duration, :count => 1 }
46
+ end
47
+ else
48
+ add(event)
49
+ end
50
+ end
51
+
35
52
  def complete(event)
36
53
  @meta = clean_event(event).to_h
37
54
  @duration = event.duration
@@ -53,7 +70,7 @@ module Honeybadger
53
70
  end
54
71
 
55
72
  def to_h
56
- @meta.merge({ :events => @events, :key => @key })
73
+ @meta.merge({ :events => @events, :key => @key, :fast_queries => @fast_queries.map {|k,v| [ k, v[:duration], v[:count] ] } })
57
74
  end
58
75
 
59
76
  protected
@@ -127,11 +144,11 @@ module Honeybadger
127
144
  end
128
145
 
129
146
  def to_s
130
- return "Super long query" if event.payload[:sql].length > 1024
131
147
  sql = event.payload[:sql]
132
148
  sql = sql.gsub(EscapedQuotes, EmptyReplacement).gsub(SQuotedData, Replacement)
133
149
  sql = sql.gsub(DQuotedData, Replacement) unless ::ActiveRecord::Base.connection_pool.spec.config[:adapter] =~ DoubleQuoters
134
150
  sql.gsub(NumericData, Replacement).gsub(Newline, EmptyReplacement).squeeze(' ')
151
+ sql.bytesize < 1024 ? sql : sql[0..1023] + '...'
135
152
  end
136
153
  end
137
154
 
@@ -0,0 +1,32 @@
1
+ require 'allocation_stats'
2
+ require 'honeybadger'
3
+ require 'benchmark'
4
+ require 'sham_rack'
5
+
6
+ ShamRack.at('api.honeybadger.io', 443).stub.tap do |app|
7
+ app.register_resource('/v1/notices/', %({"id":"123456789"}), "application/json")
8
+ app.register_resource('/v1/ping/', %({"features":{"notices":true,"feedback":true}, "limit":null}), "application/json")
9
+ end
10
+
11
+ group_by = if ENV['GROUP']
12
+ ENV['GROUP'].split(',').lazy.map(&:strip).map(&:to_sym).freeze
13
+ else
14
+ [:sourcefile, :sourceline, :class].freeze
15
+ end
16
+
17
+ puts Benchmark.measure {
18
+ stats = AllocationStats.trace do
19
+ Honeybadger.configure do |config|
20
+ config.api_key = 'badgers'
21
+ config.environment_name = 'production'
22
+ config.development_environments = []
23
+ end
24
+
25
+ 1000.times do
26
+ Honeybadger.notify(error_class: 'AllocationStats', error_message: 'Profiling Honeybadger -- this should never actually be reported.')
27
+ end
28
+ end
29
+
30
+ puts stats.allocations(alias_paths: true).group_by(*group_by).to_text
31
+ puts "\n\n"
32
+ }
metadata CHANGED
@@ -1,222 +1,195 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeybadger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.3
5
- prerelease:
4
+ version: 1.16.4
6
5
  platform: ruby
7
6
  authors:
8
7
  - Joshua Wood
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-07-21 00:00:00.000000000 Z
11
+ date: 2014-08-26 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: json
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: cucumber
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
33
  version: 1.3.10
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
40
  version: 1.3.10
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ~>
45
+ - - "~>"
52
46
  - !ruby/object:Gem::Version
53
47
  version: 2.14.0
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ~>
52
+ - - "~>"
60
53
  - !ruby/object:Gem::Version
61
54
  version: 2.14.0
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: sham_rack
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ~>
59
+ - - "~>"
68
60
  - !ruby/object:Gem::Version
69
61
  version: 1.3.0
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ~>
66
+ - - "~>"
76
67
  - !ruby/object:Gem::Version
77
68
  version: 1.3.0
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: capistrano
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ~>
73
+ - - "~>"
84
74
  - !ruby/object:Gem::Version
85
75
  version: '2.0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ~>
80
+ - - "~>"
92
81
  - !ruby/object:Gem::Version
93
82
  version: '2.0'
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: guard
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
- - - ~>
87
+ - - "~>"
100
88
  - !ruby/object:Gem::Version
101
89
  version: 1.8.3
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
- - - ~>
94
+ - - "~>"
108
95
  - !ruby/object:Gem::Version
109
96
  version: 1.8.3
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: guard-rspec
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
- - - ! '>='
101
+ - - ">="
116
102
  - !ruby/object:Gem::Version
117
103
  version: '0'
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
- - - ! '>='
108
+ - - ">="
124
109
  - !ruby/object:Gem::Version
125
110
  version: '0'
126
111
  - !ruby/object:Gem::Dependency
127
112
  name: rake
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
- - - ! '>='
115
+ - - ">="
132
116
  - !ruby/object:Gem::Version
133
117
  version: '0'
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
- - - ! '>='
122
+ - - ">="
140
123
  - !ruby/object:Gem::Version
141
124
  version: '0'
142
125
  - !ruby/object:Gem::Dependency
143
126
  name: sinatra
144
127
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
128
  requirements:
147
- - - ! '>='
129
+ - - ">="
148
130
  - !ruby/object:Gem::Version
149
131
  version: '0'
150
132
  type: :development
151
133
  prerelease: false
152
134
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
135
  requirements:
155
- - - ! '>='
136
+ - - ">="
156
137
  - !ruby/object:Gem::Version
157
138
  version: '0'
158
139
  - !ruby/object:Gem::Dependency
159
140
  name: aruba
160
141
  requirement: !ruby/object:Gem::Requirement
161
- none: false
162
142
  requirements:
163
- - - ! '>='
143
+ - - ">="
164
144
  - !ruby/object:Gem::Version
165
145
  version: '0'
166
146
  type: :development
167
147
  prerelease: false
168
148
  version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
149
  requirements:
171
- - - ! '>='
150
+ - - ">="
172
151
  - !ruby/object:Gem::Version
173
152
  version: '0'
174
153
  - !ruby/object:Gem::Dependency
175
154
  name: appraisal
176
155
  requirement: !ruby/object:Gem::Requirement
177
- none: false
178
156
  requirements:
179
- - - ! '>='
157
+ - - ">="
180
158
  - !ruby/object:Gem::Version
181
159
  version: '0'
182
160
  type: :development
183
161
  prerelease: false
184
162
  version_requirements: !ruby/object:Gem::Requirement
185
- none: false
186
163
  requirements:
187
- - - ! '>='
164
+ - - ">="
188
165
  - !ruby/object:Gem::Version
189
166
  version: '0'
190
167
  - !ruby/object:Gem::Dependency
191
168
  name: fuubar
192
169
  requirement: !ruby/object:Gem::Requirement
193
- none: false
194
170
  requirements:
195
- - - ! '>='
171
+ - - ">="
196
172
  - !ruby/object:Gem::Version
197
173
  version: '0'
198
174
  type: :development
199
175
  prerelease: false
200
176
  version_requirements: !ruby/object:Gem::Requirement
201
- none: false
202
177
  requirements:
203
- - - ! '>='
178
+ - - ">="
204
179
  - !ruby/object:Gem::Version
205
180
  version: '0'
206
181
  - !ruby/object:Gem::Dependency
207
182
  name: growl
208
183
  requirement: !ruby/object:Gem::Requirement
209
- none: false
210
184
  requirements:
211
- - - ! '>='
185
+ - - ">="
212
186
  - !ruby/object:Gem::Version
213
187
  version: '0'
214
188
  type: :development
215
189
  prerelease: false
216
190
  version_requirements: !ruby/object:Gem::Requirement
217
- none: false
218
191
  requirements:
219
- - - ! '>='
192
+ - - ">="
220
193
  - !ruby/object:Gem::Version
221
194
  version: '0'
222
195
  description: Make managing application errors a more pleasant experience.
@@ -324,6 +297,7 @@ files:
324
297
  - resources/README.md
325
298
  - resources/ca-bundle.crt
326
299
  - script/integration_test.rb
300
+ - spec/allocation_stats.rb
327
301
  - spec/honeybadger/backtrace_spec.rb
328
302
  - spec/honeybadger/capistrano_spec.rb
329
303
  - spec/honeybadger/configuration_spec.rb
@@ -357,30 +331,26 @@ files:
357
331
  - spec/support/helpers.rb
358
332
  homepage: http://www.honeybadger.io
359
333
  licenses: []
334
+ metadata: {}
360
335
  post_install_message:
361
336
  rdoc_options:
362
- - --charset=UTF-8
363
- - --markup tomdoc
337
+ - "--charset=UTF-8"
338
+ - "--markup tomdoc"
364
339
  require_paths:
365
340
  - lib
366
341
  required_ruby_version: !ruby/object:Gem::Requirement
367
- none: false
368
342
  requirements:
369
- - - ! '>='
343
+ - - ">="
370
344
  - !ruby/object:Gem::Version
371
345
  version: '0'
372
- segments:
373
- - 0
374
- hash: 3175357828774041606
375
346
  required_rubygems_version: !ruby/object:Gem::Requirement
376
- none: false
377
347
  requirements:
378
- - - ! '>='
348
+ - - ">="
379
349
  - !ruby/object:Gem::Version
380
350
  version: '0'
381
351
  requirements: []
382
352
  rubyforge_project:
383
- rubygems_version: 1.8.23
353
+ rubygems_version: 2.2.2
384
354
  signing_key:
385
355
  specification_version: 2
386
356
  summary: Error reports you can be happy about.