logatron 0.7.0 → 0.8.0
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 +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/lib/logatron/backtrace_cleaner.rb +46 -0
- data/lib/logatron/configuration.rb +5 -5
- data/lib/logatron/error_formatter.rb +67 -0
- data/lib/logatron/logatron.rb +5 -12
- data/logatron.gemspec +2 -1
- data/update_version.sh +0 -8
- metadata +19 -5
- data/Gemfile.lock +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a056f7a08b37ab427b57c039a5d5a9142e94e6a5
|
4
|
+
data.tar.gz: 58393a44fbb79cdf5b85fa6791bccd9ce47e5cc2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bdd6dd9bb5269402a9954f1572b6a478335678a7cdf2a2bed58d970b5d1ce72262a5a7dfc5f9b0d8b67ed2903a0b0c6e2bc7288571703d03bc0ba052d8745d76
|
7
|
+
data.tar.gz: 0e1c15b57f5ecf7a0b0bd52c18a81fa9105002270a863ab174fe3e51ddb43c1abeaef45db5922bb61e9c093e8d952a947e768b6338219e72f4407bc3a4c9c25d
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
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
|
-
|
37
|
-
|
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
|
data/lib/logatron/logatron.rb
CHANGED
@@ -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
|
-
|
21
|
-
|
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.
|
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.
|
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-
|
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.
|
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
|