logatron 0.7.0 → 0.8.0

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: 3103d9cac1561ecd60127ba26110d18fb0fe720e
4
- data.tar.gz: d35300ec7cdc5165ec570f56faf38fc38436bf25
3
+ metadata.gz: a056f7a08b37ab427b57c039a5d5a9142e94e6a5
4
+ data.tar.gz: 58393a44fbb79cdf5b85fa6791bccd9ce47e5cc2
5
5
  SHA512:
6
- metadata.gz: 1fb22c5f504469d354b1dd7a0479ef89a45ecadd52d115c553fade502e33babb4b37c4a8eb507edae756fba59f5d0f89e4ecca17cd065e0ca998b3aca2e7b368
7
- data.tar.gz: d3476f1bde8fd841211d40b37697fe5498733a2cb3132102c3c4e27b8f7bebd83501e0cf53ce86e58a285359005b0b4eb60881ba7d18d992dad088ab04de0f30
6
+ metadata.gz: bdd6dd9bb5269402a9954f1572b6a478335678a7cdf2a2bed58d970b5d1ce72262a5a7dfc5f9b0d8b67ed2903a0b0c6e2bc7288571703d03bc0ba052d8745d76
7
+ data.tar.gz: 0e1c15b57f5ecf7a0b0bd52c18a81fa9105002270a863ab174fe3e51ddb43c1abeaef45db5922bb61e9c093e8d952a947e768b6338219e72f4407bc3a4c9c25d
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  .idea/
2
2
  .DS_Store
3
3
  *.gem
4
+ Gemfile.lock
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.2.2
1
+ 2.4.1
@@ -0,0 +1,46 @@
1
+ module Logatron
2
+ class BacktraceCleaner
3
+ # Suppress irrelevant "external" frames. In practice, these are often the frames
4
+ # leading up to the "entry point" we care about, whether that's a rails controller
5
+ # or a rabbit_stew handler.
6
+ #
7
+ # Algorithm: partition frames into contiguous external/internal chunks.
8
+ # Starting at the bottom, suppress chunks until we find the entry point chunk.
9
+
10
+ def clean(backtrace)
11
+ all_chunks = backtrace.chunk { |x| external_frame?(x) }.to_a.reverse
12
+ good_chunks = all_chunks.drop_while { |(is_ext, frames)| !entry_point_chunk?(is_ext, frames) }
13
+ bad_chunks = all_chunks.take(all_chunks.size - good_chunks.size)
14
+ good_bt = good_chunks.reverse.map(&:last).flatten
15
+ bad_bt = bad_chunks.reverse.map(&:last).flatten
16
+ good_bt + suppress(bad_bt)
17
+ rescue
18
+ # if something went wrong, give up on cleaning the backtrace
19
+ backtrace
20
+ end
21
+
22
+ private
23
+
24
+ # heuristic for determining externality of a frame.
25
+ # Note: bundle/gems does not include git-sourced gems (those go in
26
+ # bundle/bundler/gems), so git-sourced gems are considered internal.
27
+ def external_frame?(f)
28
+ !!(f =~ %r{bundle/gems})
29
+ end
30
+
31
+ # heuristic for finding the entry point
32
+ def entry_point_chunk?(is_ext, frames)
33
+ !is_ext && frames.size >= 3
34
+ end
35
+
36
+ def suppress(backtrace)
37
+ if backtrace.size <= 3
38
+ backtrace
39
+ else
40
+ [ backtrace.first,
41
+ "... #{backtrace.size - 2} frames suppressed ...",
42
+ backtrace.last ]
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,6 +1,8 @@
1
1
  require 'logger'
2
2
  require 'logatron/const'
3
3
  require 'logatron/basic_formatter'
4
+ require 'logatron/error_formatter'
5
+ require 'logatron/backtrace_cleaner'
4
6
  require 'active_support/backtrace_cleaner'
5
7
  require 'active_support/json'
6
8
 
@@ -21,7 +23,7 @@ module Logatron
21
23
  end
22
24
 
23
25
  class Configuration
24
- attr_accessor :logger, :host, :level, :transformer, :app_id
26
+ attr_accessor :logger, :host, :level, :transformer, :app_id, :error_formatter
25
27
  attr_reader :loggable_levels, :backtrace_cleaner
26
28
 
27
29
  def initialize
@@ -33,10 +35,8 @@ module Logatron
33
35
  level_threshold = SEVERITY_MAP[@level]
34
36
  levels = Logatron::SEVERITY_MAP.keys
35
37
  @loggable_levels = levels.select { |level| SEVERITY_MAP[level] >= level_threshold }
36
- bc = ActiveSupport::BacktraceCleaner.new
37
- bc.add_filter { |line| line.gsub(Rails.root.to_s, '') } if defined? Rails
38
- bc.add_silencer { |line| line =~ /gems/ }
39
- @backtrace_cleaner = bc
38
+ @backtrace_cleaner = Logatron::BacktraceCleaner.new
39
+ @error_formatter = Logatron::ErrorFormatter.new
40
40
  end
41
41
 
42
42
  def logger=(logger)
@@ -0,0 +1,67 @@
1
+ require 'abstractivator/enumerator_ext'
2
+
3
+ module Logatron
4
+ class ErrorFormatter
5
+ def format_short_message(e)
6
+ "#{e.class}: #{e.message}"
7
+ end
8
+
9
+ def format_full_message(e, additional_info = nil)
10
+ format_short_message(e) + format_additional_info(e, additional_info)
11
+ end
12
+
13
+ def format_backtrace(error_or_bt)
14
+ bt = error_or_bt.is_a?(Exception) ? error_or_bt.backtrace : error_or_bt
15
+ bt.map { |f| " #{f.starts_with?('...') ? f : "at #{f}"}\n" }.join
16
+ end
17
+
18
+ def format_additional_info(e, additional_info = nil)
19
+ info = additional_info || (e.respond_to?(:meta) && e.meta)
20
+ info ? "; MORE_INFO( #{info.to_s} )" : ''
21
+ end
22
+
23
+ # Returns a human-readable exception report.
24
+ # Includes nested exception information.
25
+ # Suppresses duplicate frames in nested exception backtraces.
26
+ def format_error_report(e, additional_info = nil)
27
+ error_chain = Enumerator.unfold(e) { |e| [e.cause, e.cause] }.to_a
28
+ initial_report = format_single_error(e, clean_backtrace(nil, e), additional_info)
29
+ # starting with the outermost error, reduce the error chain into the formatted report
30
+ error_chain.reduce([e, initial_report]) do |(prev_e, report), e|
31
+ new_report = format_single_error(e, clean_backtrace(prev_e, e)) + " which caused:\n " + report
32
+ [e, new_report]
33
+ end[1]
34
+ rescue
35
+ # if something went wrong, fall back to something simpler
36
+ format_short_message(e) + "\n" + e.backtrace.join("\n")
37
+ end
38
+
39
+ private
40
+
41
+ def format_single_error(e, cleaned_backtrace, additional_info = nil)
42
+ format_full_message(e, additional_info) + "\n" + format_backtrace(cleaned_backtrace)
43
+ end
44
+
45
+ def clean_backtrace(prev, e)
46
+ base_size = prev ? num_common_base_frames(prev, e) : 0
47
+ cleaned_backtrace =
48
+ if base_size > 1
49
+ num_to_suppress = base_size - 1
50
+ e.backtrace.take(e.backtrace.size - num_to_suppress) +
51
+ ["... #{num_to_suppress} frames suppressed ..."]
52
+ else
53
+ backtrace_cleaner.clean(e.backtrace)
54
+ end
55
+ end
56
+
57
+ def backtrace_cleaner
58
+ Logatron.configuration.backtrace_cleaner
59
+ end
60
+
61
+ def num_common_base_frames(e1, e2)
62
+ e1.backtrace.reverse.zip(e2.backtrace.reverse)
63
+ .take_while { |(a, b)| a == b }
64
+ .size
65
+ end
66
+ end
67
+ end
@@ -2,7 +2,9 @@ require 'active_support/all'
2
2
  require 'logatron/version'
3
3
  require 'logatron/const'
4
4
  require 'logatron/contexts'
5
+ require 'logatron/error_formatter'
5
6
  require 'logatron/message_formatting'
7
+ require 'logatron/backtrace_cleaner'
6
8
  require 'logatron/basic_scoped_logger'
7
9
  require 'logatron/basic_formatter'
8
10
  require 'logatron/basic_logger'
@@ -16,10 +18,10 @@ module Logatron
16
18
  @log ||= Logatron::BasicLogger.new
17
19
  end
18
20
 
21
+ # @param additional_info [Object] Typically a flat hash, but can be anything that responds to '#to_s'
19
22
  def log_exception(e, severity, additional_info = {})
20
- # 'additional_info' can be a flat hash or anything with '#to_s'
21
- message = exception_message(e, additional_info)
22
- logger.send(severity.downcase, message)
23
+ error_report = configuration.error_formatter.format_error_report(e, additional_info)
24
+ logger.send(severity.downcase, error_report)
23
25
  end
24
26
 
25
27
  def level=(level)
@@ -90,14 +92,5 @@ module Logatron
90
92
  def msg_id=(id)
91
93
  Logatron::Contexts.msg_id = id
92
94
  end
93
-
94
- private
95
-
96
- def exception_message(e, additional)
97
- info = additional.is_a?(Hash) ? additional.map { |(k, v)| "#{k}=>#{v}" }.join(', ') : additional
98
- info_msg = info.nil? || info.empty? ? '' : "; MORE_INFO( #{info} )"
99
- backtrace = configuration.backtrace_cleaner.clean(e.backtrace).join(' -> ')
100
- "#{e.class} #{e.message}#{info_msg} -> #{backtrace}"
101
- end
102
95
  end
103
96
  end
data/logatron.gemspec CHANGED
@@ -5,7 +5,7 @@ require 'logatron/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'logatron'
8
- spec.version = '0.7.0'
8
+ spec.version = '0.8.0'
9
9
  spec.authors = ['Justin Grimes']
10
10
  spec.email = ['justin.mgrimes@gmail.com']
11
11
 
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ['lib']
20
20
  spec.add_runtime_dependency 'activesupport', '< 6.0', '>= 4.2.1'
21
+ spec.add_runtime_dependency 'abstractivator', '~> 0.16.0'
21
22
  spec.add_development_dependency 'bundler', '~> 1.10'
22
23
  spec.add_development_dependency 'rake', '~> 10.0'
23
24
  spec.add_development_dependency 'rspec', '~> 3'
data/update_version.sh CHANGED
@@ -8,7 +8,6 @@ SCRIPT_DIR="$(cd "$(dirname "$0")"; pwd)"
8
8
 
9
9
  updateVersion(){
10
10
  updateGemspec
11
- updateLockfile
12
11
  commitStagedFiles "Update version to ${VERSION}"
13
12
  }
14
13
 
@@ -19,13 +18,6 @@ updateGemspec(){
19
18
  stageFiles "${gemspecPath}"
20
19
  }
21
20
 
22
- updateLockfile(){
23
- echo -e "\nUpdating lockfile"
24
- bundle package --no-install > /dev/null
25
- rm -rf .bundle/ vendor/
26
- stageFiles "${SCRIPT_DIR}/Gemfile.lock"
27
- }
28
-
29
21
  stageAndCommit(){
30
22
  local msg="$1"
31
23
  shift
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logatron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Grimes
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-03-01 00:00:00.000000000 Z
11
+ date: 2017-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -30,6 +30,20 @@ dependencies:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 4.2.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: abstractivator
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 0.16.0
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.16.0
33
47
  - !ruby/object:Gem::Dependency
34
48
  name: bundler
35
49
  requirement: !ruby/object:Gem::Requirement
@@ -98,18 +112,19 @@ files:
98
112
  - CHANGES.md
99
113
  - CODE_OF_CONDUCT.md
100
114
  - Gemfile
101
- - Gemfile.lock
102
115
  - README.md
103
116
  - Rakefile
104
117
  - bin/console
105
118
  - bin/setup
106
119
  - build.yml
120
+ - lib/logatron/backtrace_cleaner.rb
107
121
  - lib/logatron/basic_formatter.rb
108
122
  - lib/logatron/basic_logger.rb
109
123
  - lib/logatron/basic_scoped_logger.rb
110
124
  - lib/logatron/configuration.rb
111
125
  - lib/logatron/const.rb
112
126
  - lib/logatron/contexts.rb
127
+ - lib/logatron/error_formatter.rb
113
128
  - lib/logatron/logatron.rb
114
129
  - lib/logatron/message_formatting.rb
115
130
  - lib/logatron/railtie.rb
@@ -135,9 +150,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
150
  version: '0'
136
151
  requirements: []
137
152
  rubyforge_project:
138
- rubygems_version: 2.6.2
153
+ rubygems_version: 2.6.12
139
154
  signing_key:
140
155
  specification_version: 4
141
156
  summary: Logging for ascent
142
157
  test_files: []
143
- has_rdoc:
data/Gemfile.lock DELETED
@@ -1,53 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- logatron (0.6.0)
5
- activesupport (>= 4.2.1, < 6.0)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- activesupport (4.2.7.1)
11
- i18n (~> 0.7)
12
- json (~> 1.7, >= 1.7.7)
13
- minitest (~> 5.1)
14
- thread_safe (~> 0.3, >= 0.3.4)
15
- tzinfo (~> 1.1)
16
- builder (3.2.2)
17
- diff-lcs (1.2.5)
18
- i18n (0.7.0)
19
- json (1.8.3)
20
- minitest (5.9.1)
21
- rake (10.4.2)
22
- rspec (3.3.0)
23
- rspec-core (~> 3.3.0)
24
- rspec-expectations (~> 3.3.0)
25
- rspec-mocks (~> 3.3.0)
26
- rspec-core (3.3.2)
27
- rspec-support (~> 3.3.0)
28
- rspec-expectations (3.3.1)
29
- diff-lcs (>= 1.2.0, < 2.0)
30
- rspec-support (~> 3.3.0)
31
- rspec-mocks (3.3.2)
32
- diff-lcs (>= 1.2.0, < 2.0)
33
- rspec-support (~> 3.3.0)
34
- rspec-support (3.3.0)
35
- rspec_junit_formatter (0.2.3)
36
- builder (< 4)
37
- rspec-core (>= 2, < 4, != 2.12.0)
38
- thread_safe (0.3.5)
39
- tzinfo (1.2.2)
40
- thread_safe (~> 0.1)
41
-
42
- PLATFORMS
43
- ruby
44
-
45
- DEPENDENCIES
46
- bundler (~> 1.10)
47
- logatron!
48
- rake (~> 10.0)
49
- rspec (~> 3)
50
- rspec_junit_formatter (~> 0.2.0)
51
-
52
- BUNDLED WITH
53
- 1.13.1