logster 1.3.0 → 1.3.1
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 +18 -18
- data/.travis.yml +15 -15
- data/CHANGELOG.md +137 -130
- data/Gemfile +4 -4
- data/Guardfile +8 -8
- data/LICENSE.txt +22 -22
- data/README.md +99 -99
- data/Rakefile +24 -24
- data/assets/fonts/FontAwesome.otf +0 -0
- data/assets/fonts/fontawesome-webfont.eot +0 -0
- data/assets/fonts/fontawesome-webfont.svg +639 -639
- data/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/assets/fonts/fontawesome-webfont.woff +0 -0
- data/assets/fonts/fontawesome-webfont.woff2 +0 -0
- data/assets/images/Icon-144_rounded.png +0 -0
- data/assets/images/Icon-144_square.png +0 -0
- data/assets/images/icon_144x144.png +0 -0
- data/assets/images/icon_64x64.png +0 -0
- data/assets/javascript/client-app.js +81 -81
- data/assets/javascript/vendor.js +5302 -5302
- data/assets/stylesheets/client-app.css +0 -0
- data/assets/stylesheets/vendor.css +3 -3
- data/build_client_app.sh +12 -12
- data/client-app/.editorconfig +20 -20
- data/client-app/.ember-cli +9 -9
- data/client-app/.eslintignore +19 -19
- data/client-app/.eslintrc.js +46 -46
- data/client-app/.gitignore +23 -23
- data/client-app/.travis.yml +27 -27
- data/client-app/.watchmanconfig +3 -3
- data/client-app/README.md +57 -57
- data/client-app/app/app.js +14 -14
- data/client-app/app/components/message-info.js +18 -18
- data/client-app/app/components/message-row.js +45 -45
- data/client-app/app/components/panel-resizer.js +75 -75
- data/client-app/app/components/tab-contents.js +27 -27
- data/client-app/app/components/tab-link.js +5 -5
- data/client-app/app/components/tabbed-section.js +32 -32
- data/client-app/app/components/time-formatter.js +25 -25
- data/client-app/app/components/update-time.js +21 -21
- data/client-app/app/controllers/index.js +83 -83
- data/client-app/app/controllers/show.js +13 -13
- data/client-app/app/index.html +29 -29
- data/client-app/app/initializers/app-init.js +55 -55
- data/client-app/app/lib/preload.js +14 -14
- data/client-app/app/lib/utilities.js +140 -140
- data/client-app/app/models/message-collection.js +158 -158
- data/client-app/app/models/message.js +99 -99
- data/client-app/app/resolver.js +3 -3
- data/client-app/app/router.js +14 -14
- data/client-app/app/routes/index.js +53 -53
- data/client-app/app/routes/show.js +14 -14
- data/client-app/app/styles/app.css +387 -387
- data/client-app/app/templates/application.hbs +2 -2
- data/client-app/app/templates/components/message-info.hbs +44 -44
- data/client-app/app/templates/components/message-row.hbs +17 -17
- data/client-app/app/templates/components/tabbed-section.hbs +10 -10
- data/client-app/app/templates/components/time-formatter.hbs +1 -1
- data/client-app/app/templates/index.hbs +57 -57
- data/client-app/app/templates/show.hbs +4 -4
- data/client-app/config/environment.js +51 -51
- data/client-app/config/optional-features.json +3 -3
- data/client-app/config/targets.js +18 -18
- data/client-app/ember-cli-build.js +29 -29
- data/client-app/package-lock.json +11365 -11365
- data/client-app/package.json +56 -56
- data/client-app/testem.js +25 -25
- data/client-app/tests/index.html +34 -34
- data/client-app/tests/integration/components/message-info-test.js +26 -26
- data/client-app/tests/integration/components/message-row-test.js +26 -26
- data/client-app/tests/integration/components/panel-resizer-test.js +26 -26
- data/client-app/tests/integration/components/tab-contents-test.js +26 -26
- data/client-app/tests/integration/components/tab-link-test.js +26 -26
- data/client-app/tests/integration/components/tabbed-section-test.js +26 -26
- data/client-app/tests/integration/components/time-formatter-test.js +26 -26
- data/client-app/tests/integration/components/update-time-test.js +26 -26
- data/client-app/tests/test-helper.js +8 -8
- data/client-app/tests/unit/controllers/index-test.js +12 -12
- data/client-app/tests/unit/controllers/show-test.js +12 -12
- data/client-app/tests/unit/initializers/app-init-test.js +31 -31
- data/client-app/tests/unit/routes/index-test.js +11 -11
- data/client-app/tests/unit/routes/show-test.js +11 -11
- data/lib/examples/sidekiq_logster_reporter.rb +21 -21
- data/lib/logster.rb +54 -54
- data/lib/logster/base_store.rb +130 -130
- data/lib/logster/configuration.rb +25 -25
- data/lib/logster/ignore_pattern.rb +65 -65
- data/lib/logster/logger.rb +108 -102
- data/lib/logster/message.rb +227 -227
- data/lib/logster/middleware/debug_exceptions.rb +26 -26
- data/lib/logster/middleware/reporter.rb +56 -56
- data/lib/logster/middleware/viewer.rb +220 -220
- data/lib/logster/rails/railtie.rb +58 -58
- data/lib/logster/redis_store.rb +481 -481
- data/lib/logster/version.rb +3 -3
- data/lib/logster/web.rb +14 -14
- data/logster.gemspec +34 -34
- data/test/examples/test_sidekiq_reporter_example.rb +46 -46
- data/test/fake_data/Gemfile +4 -4
- data/test/fake_data/generate.rb +10 -10
- data/test/logster/middleware/test_reporter.rb +21 -21
- data/test/logster/middleware/test_viewer.rb +96 -96
- data/test/logster/test_base_store.rb +147 -147
- data/test/logster/test_ignore_pattern.rb +41 -41
- data/test/logster/test_logger.rb +80 -74
- data/test/logster/test_message.rb +34 -34
- data/test/logster/test_redis_rate_limiter.rb +230 -230
- data/test/logster/test_redis_store.rb +427 -427
- data/test/test_helper.rb +38 -38
- data/vendor/assets/javascripts/logster.js.erb +39 -39
- metadata +3 -3
data/lib/logster/base_store.rb
CHANGED
|
@@ -1,130 +1,130 @@
|
|
|
1
|
-
|
|
2
|
-
module Logster
|
|
3
|
-
class BaseStore
|
|
4
|
-
|
|
5
|
-
attr_accessor :level, :max_retention, :skip_empty, :ignore
|
|
6
|
-
|
|
7
|
-
def initialize
|
|
8
|
-
@max_retention = 60 * 60 * 24 * 7
|
|
9
|
-
@skip_empty = true
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
# Save a new message at the front of the latest list.
|
|
13
|
-
def save(message)
|
|
14
|
-
not_implemented
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# Modify the saved message to the given one (identified by message.key) and bump it to the top of the latest list
|
|
18
|
-
def replace_and_bump(message)
|
|
19
|
-
not_implemented
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# Check if another message with the same grouping_key is already stored.
|
|
23
|
-
# Returns the similar message's message.key
|
|
24
|
-
def similar_key(message)
|
|
25
|
-
not_implemented
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# The number of messages currently stored.
|
|
29
|
-
def count
|
|
30
|
-
not_implemented
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Delete all unprotected messages in the store.
|
|
34
|
-
def clear
|
|
35
|
-
not_implemented
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Delete all messages, including protected messages.
|
|
39
|
-
def clear_all
|
|
40
|
-
not_implemented
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Get a message by its message_key
|
|
44
|
-
def get(message_key)
|
|
45
|
-
not_implemented
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Mark a message as protected; i.e. it is not deleted by the #clear method
|
|
49
|
-
def protect(message_key)
|
|
50
|
-
not_implemented
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def delete(message_key)
|
|
54
|
-
not_implemented
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Clear the protected mark for a message.
|
|
58
|
-
def unprotect(message_key)
|
|
59
|
-
not_implemented
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Solve a particular message, causing all old messages with matching version and backtrace
|
|
63
|
-
# to be deleted (report should delete any solved messages when called)
|
|
64
|
-
def solve(message_key)
|
|
65
|
-
not_implemented
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Registers a rate limit on the given severities of logs
|
|
69
|
-
def register_rate_limit(severities, limit, duration, &block)
|
|
70
|
-
not_implemented
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# Checks all the existing rate limiters to check if any has been exceeded
|
|
74
|
-
def check_rate_limits(severity)
|
|
75
|
-
not_implemented
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def report(severity, progname, msg, opts = {})
|
|
79
|
-
return if (!msg || (String === msg && msg.empty?)) && skip_empty
|
|
80
|
-
return if level && severity < level
|
|
81
|
-
|
|
82
|
-
message = Logster::Message.new(severity, progname, msg, opts[:timestamp])
|
|
83
|
-
|
|
84
|
-
env = opts[:env] || {}
|
|
85
|
-
backtrace = opts[:backtrace]
|
|
86
|
-
|
|
87
|
-
if env[:backtrace]
|
|
88
|
-
# Special - passing backtrace through env
|
|
89
|
-
backtrace = env.delete(:backtrace)
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
message.populate_from_env(env)
|
|
93
|
-
|
|
94
|
-
if backtrace
|
|
95
|
-
if backtrace.respond_to? :join
|
|
96
|
-
backtrace = backtrace.join("\n")
|
|
97
|
-
end
|
|
98
|
-
message.backtrace = backtrace
|
|
99
|
-
else
|
|
100
|
-
message.backtrace = caller.join("\n")
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
return if ignore && ignore.any? { |pattern| message =~ pattern}
|
|
104
|
-
|
|
105
|
-
similar = nil
|
|
106
|
-
|
|
107
|
-
if Logster.config.allow_grouping
|
|
108
|
-
key = self.similar_key(message)
|
|
109
|
-
similar = get key if key
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
if similar
|
|
113
|
-
similar.count += 1
|
|
114
|
-
similar.merge_similar_message(message)
|
|
115
|
-
|
|
116
|
-
replace_and_bump similar
|
|
117
|
-
similar
|
|
118
|
-
else
|
|
119
|
-
save message
|
|
120
|
-
message
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
private
|
|
125
|
-
|
|
126
|
-
def not_implemented
|
|
127
|
-
raise "Not Implemented"
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
end
|
|
1
|
+
|
|
2
|
+
module Logster
|
|
3
|
+
class BaseStore
|
|
4
|
+
|
|
5
|
+
attr_accessor :level, :max_retention, :skip_empty, :ignore
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@max_retention = 60 * 60 * 24 * 7
|
|
9
|
+
@skip_empty = true
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Save a new message at the front of the latest list.
|
|
13
|
+
def save(message)
|
|
14
|
+
not_implemented
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Modify the saved message to the given one (identified by message.key) and bump it to the top of the latest list
|
|
18
|
+
def replace_and_bump(message)
|
|
19
|
+
not_implemented
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Check if another message with the same grouping_key is already stored.
|
|
23
|
+
# Returns the similar message's message.key
|
|
24
|
+
def similar_key(message)
|
|
25
|
+
not_implemented
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# The number of messages currently stored.
|
|
29
|
+
def count
|
|
30
|
+
not_implemented
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Delete all unprotected messages in the store.
|
|
34
|
+
def clear
|
|
35
|
+
not_implemented
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Delete all messages, including protected messages.
|
|
39
|
+
def clear_all
|
|
40
|
+
not_implemented
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Get a message by its message_key
|
|
44
|
+
def get(message_key)
|
|
45
|
+
not_implemented
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Mark a message as protected; i.e. it is not deleted by the #clear method
|
|
49
|
+
def protect(message_key)
|
|
50
|
+
not_implemented
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def delete(message_key)
|
|
54
|
+
not_implemented
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Clear the protected mark for a message.
|
|
58
|
+
def unprotect(message_key)
|
|
59
|
+
not_implemented
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Solve a particular message, causing all old messages with matching version and backtrace
|
|
63
|
+
# to be deleted (report should delete any solved messages when called)
|
|
64
|
+
def solve(message_key)
|
|
65
|
+
not_implemented
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Registers a rate limit on the given severities of logs
|
|
69
|
+
def register_rate_limit(severities, limit, duration, &block)
|
|
70
|
+
not_implemented
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Checks all the existing rate limiters to check if any has been exceeded
|
|
74
|
+
def check_rate_limits(severity)
|
|
75
|
+
not_implemented
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def report(severity, progname, msg, opts = {})
|
|
79
|
+
return if (!msg || (String === msg && msg.empty?)) && skip_empty
|
|
80
|
+
return if level && severity < level
|
|
81
|
+
|
|
82
|
+
message = Logster::Message.new(severity, progname, msg, opts[:timestamp])
|
|
83
|
+
|
|
84
|
+
env = opts[:env] || {}
|
|
85
|
+
backtrace = opts[:backtrace]
|
|
86
|
+
|
|
87
|
+
if env[:backtrace]
|
|
88
|
+
# Special - passing backtrace through env
|
|
89
|
+
backtrace = env.delete(:backtrace)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
message.populate_from_env(env)
|
|
93
|
+
|
|
94
|
+
if backtrace
|
|
95
|
+
if backtrace.respond_to? :join
|
|
96
|
+
backtrace = backtrace.join("\n")
|
|
97
|
+
end
|
|
98
|
+
message.backtrace = backtrace
|
|
99
|
+
else
|
|
100
|
+
message.backtrace = caller.join("\n")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
return if ignore && ignore.any? { |pattern| message =~ pattern}
|
|
104
|
+
|
|
105
|
+
similar = nil
|
|
106
|
+
|
|
107
|
+
if Logster.config.allow_grouping
|
|
108
|
+
key = self.similar_key(message)
|
|
109
|
+
similar = get key if key
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
if similar
|
|
113
|
+
similar.count += 1
|
|
114
|
+
similar.merge_similar_message(message)
|
|
115
|
+
|
|
116
|
+
replace_and_bump similar
|
|
117
|
+
similar
|
|
118
|
+
else
|
|
119
|
+
save message
|
|
120
|
+
message
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
def not_implemented
|
|
127
|
+
raise "Not Implemented"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
module Logster
|
|
2
|
-
class Configuration
|
|
3
|
-
attr_accessor :current_context, :allow_grouping, :environments,
|
|
4
|
-
:application_version, :web_title
|
|
5
|
-
|
|
6
|
-
attr_writer :subdirectory
|
|
7
|
-
|
|
8
|
-
def initialize
|
|
9
|
-
# lambda |env,block|
|
|
10
|
-
@current_context = lambda{ |_, &block| block.call }
|
|
11
|
-
@environments = [:development, :production]
|
|
12
|
-
@subdirectory = nil
|
|
13
|
-
|
|
14
|
-
@allow_grouping = false
|
|
15
|
-
|
|
16
|
-
if defined?(::Rails) && defined?(::Rails.env) && ::Rails.env.production?
|
|
17
|
-
@allow_grouping = true
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def subdirectory
|
|
22
|
-
@subdirectory || '/logs'
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
1
|
+
module Logster
|
|
2
|
+
class Configuration
|
|
3
|
+
attr_accessor :current_context, :allow_grouping, :environments,
|
|
4
|
+
:application_version, :web_title
|
|
5
|
+
|
|
6
|
+
attr_writer :subdirectory
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
# lambda |env,block|
|
|
10
|
+
@current_context = lambda{ |_, &block| block.call }
|
|
11
|
+
@environments = [:development, :production]
|
|
12
|
+
@subdirectory = nil
|
|
13
|
+
|
|
14
|
+
@allow_grouping = false
|
|
15
|
+
|
|
16
|
+
if defined?(::Rails) && defined?(::Rails.env) && ::Rails.env.production?
|
|
17
|
+
@allow_grouping = true
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def subdirectory
|
|
22
|
+
@subdirectory || '/logs'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
module Logster
|
|
2
|
-
class IgnorePattern
|
|
3
|
-
|
|
4
|
-
def initialize(message_pattern=nil, env_patterns=nil)
|
|
5
|
-
@msg_match = message_pattern
|
|
6
|
-
@env_match = env_patterns
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def self.from_message_and_request_uri(msg, request)
|
|
10
|
-
IgnorePattern.new(msg, {REQUEST_URI: request})
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def matches?(message)
|
|
14
|
-
if @msg_match
|
|
15
|
-
return false unless compare(message.message, @msg_match)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
if @env_match
|
|
19
|
-
return false unless compare(message.env, @env_match)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
true
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def to_s
|
|
26
|
-
"<#Logster::IgnorePattern, msg_match: #{@msg_match.inspect}, env_match: #{@env_match.inspect}>"
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
private
|
|
30
|
-
|
|
31
|
-
def compare(message, pattern)
|
|
32
|
-
return false unless message && pattern
|
|
33
|
-
|
|
34
|
-
case pattern
|
|
35
|
-
when Regexp
|
|
36
|
-
message.to_s =~ pattern
|
|
37
|
-
when String
|
|
38
|
-
message.to_s.downcase =~ Regexp.new(pattern.downcase, Regexp::IGNORECASE)
|
|
39
|
-
when Hash
|
|
40
|
-
if Hash === message
|
|
41
|
-
compare_hash(message, pattern)
|
|
42
|
-
else
|
|
43
|
-
false
|
|
44
|
-
end
|
|
45
|
-
else
|
|
46
|
-
false
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def compare_hash(message_hash, pattern_hash)
|
|
51
|
-
return false unless message_hash
|
|
52
|
-
pattern_hash.each do |key, value|
|
|
53
|
-
return false unless compare(get_indifferent(message_hash, key), value)
|
|
54
|
-
end
|
|
55
|
-
true
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def get_indifferent(hash, key)
|
|
59
|
-
return hash[key] if hash[key]
|
|
60
|
-
return hash[key.to_s] if hash[key.to_s]
|
|
61
|
-
# no key.to_sym please, memory leak in Ruby < 2.2
|
|
62
|
-
nil
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
1
|
+
module Logster
|
|
2
|
+
class IgnorePattern
|
|
3
|
+
|
|
4
|
+
def initialize(message_pattern=nil, env_patterns=nil)
|
|
5
|
+
@msg_match = message_pattern
|
|
6
|
+
@env_match = env_patterns
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.from_message_and_request_uri(msg, request)
|
|
10
|
+
IgnorePattern.new(msg, {REQUEST_URI: request})
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def matches?(message)
|
|
14
|
+
if @msg_match
|
|
15
|
+
return false unless compare(message.message, @msg_match)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if @env_match
|
|
19
|
+
return false unless compare(message.env, @env_match)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_s
|
|
26
|
+
"<#Logster::IgnorePattern, msg_match: #{@msg_match.inspect}, env_match: #{@env_match.inspect}>"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def compare(message, pattern)
|
|
32
|
+
return false unless message && pattern
|
|
33
|
+
|
|
34
|
+
case pattern
|
|
35
|
+
when Regexp
|
|
36
|
+
message.to_s =~ pattern
|
|
37
|
+
when String
|
|
38
|
+
message.to_s.downcase =~ Regexp.new(pattern.downcase, Regexp::IGNORECASE)
|
|
39
|
+
when Hash
|
|
40
|
+
if Hash === message
|
|
41
|
+
compare_hash(message, pattern)
|
|
42
|
+
else
|
|
43
|
+
false
|
|
44
|
+
end
|
|
45
|
+
else
|
|
46
|
+
false
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def compare_hash(message_hash, pattern_hash)
|
|
51
|
+
return false unless message_hash
|
|
52
|
+
pattern_hash.each do |key, value|
|
|
53
|
+
return false unless compare(get_indifferent(message_hash, key), value)
|
|
54
|
+
end
|
|
55
|
+
true
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def get_indifferent(hash, key)
|
|
59
|
+
return hash[key] if hash[key]
|
|
60
|
+
return hash[key.to_s] if hash[key.to_s]
|
|
61
|
+
# no key.to_sym please, memory leak in Ruby < 2.2
|
|
62
|
+
nil
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
data/lib/logster/logger.rb
CHANGED
|
@@ -1,102 +1,108 @@
|
|
|
1
|
-
require 'logger'
|
|
2
|
-
|
|
3
|
-
module Logster
|
|
4
|
-
class Logger < ::Logger
|
|
5
|
-
LOGSTER_ENV = "logster_env".freeze
|
|
6
|
-
|
|
7
|
-
attr_accessor :store, :skip_store
|
|
8
|
-
attr_reader :chained
|
|
9
|
-
|
|
10
|
-
def initialize(store)
|
|
11
|
-
super(nil)
|
|
12
|
-
@store = store
|
|
13
|
-
@override_levels = nil
|
|
14
|
-
@chained = []
|
|
15
|
-
@skip_store = false
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def override_level=(val)
|
|
19
|
-
tid = Thread.current.object_id
|
|
20
|
-
|
|
21
|
-
ol = @override_levels
|
|
22
|
-
if val.nil? && ol && ol.key?(tid)
|
|
23
|
-
ol.delete(tid)
|
|
24
|
-
@override_levels = nil if ol.length == 0
|
|
25
|
-
elsif val
|
|
26
|
-
(@override_levels ||= {})[tid] = val
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def chain(logger)
|
|
31
|
-
@chained << logger
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def add_to_chained(logger, severity, message, progname, opts=nil, &block)
|
|
35
|
-
if logger.respond_to? :skip_store
|
|
36
|
-
old = logger.skip_store
|
|
37
|
-
logger.skip_store = @skip_store
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
if logger.is_a?(self.class)
|
|
41
|
-
logger.add(severity, message, progname, opts, &block)
|
|
42
|
-
else
|
|
43
|
-
logger.add(severity, message, progname, &block)
|
|
44
|
-
end
|
|
45
|
-
ensure
|
|
46
|
-
if logger.respond_to? :skip_store
|
|
47
|
-
logger.skip_store = old
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def add(*args, &block)
|
|
52
|
-
add_with_opts(*args,&block)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def level
|
|
56
|
-
ol = @override_levels
|
|
57
|
-
(ol && ol[Thread.current.object_id]) || @level
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def add_with_opts(severity, message, progname, opts=nil, &block)
|
|
61
|
-
if severity < level
|
|
62
|
-
return true
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
1
|
+
require 'logger'
|
|
2
|
+
|
|
3
|
+
module Logster
|
|
4
|
+
class Logger < ::Logger
|
|
5
|
+
LOGSTER_ENV = "logster_env".freeze
|
|
6
|
+
|
|
7
|
+
attr_accessor :store, :skip_store
|
|
8
|
+
attr_reader :chained
|
|
9
|
+
|
|
10
|
+
def initialize(store)
|
|
11
|
+
super(nil)
|
|
12
|
+
@store = store
|
|
13
|
+
@override_levels = nil
|
|
14
|
+
@chained = []
|
|
15
|
+
@skip_store = false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def override_level=(val)
|
|
19
|
+
tid = Thread.current.object_id
|
|
20
|
+
|
|
21
|
+
ol = @override_levels
|
|
22
|
+
if val.nil? && ol && ol.key?(tid)
|
|
23
|
+
ol.delete(tid)
|
|
24
|
+
@override_levels = nil if ol.length == 0
|
|
25
|
+
elsif val
|
|
26
|
+
(@override_levels ||= {})[tid] = val
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def chain(logger)
|
|
31
|
+
@chained << logger
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def add_to_chained(logger, severity, message, progname, opts=nil, &block)
|
|
35
|
+
if logger.respond_to? :skip_store
|
|
36
|
+
old = logger.skip_store
|
|
37
|
+
logger.skip_store = @skip_store
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if logger.is_a?(self.class)
|
|
41
|
+
logger.add(severity, message, progname, opts, &block)
|
|
42
|
+
else
|
|
43
|
+
logger.add(severity, message, progname, &block)
|
|
44
|
+
end
|
|
45
|
+
ensure
|
|
46
|
+
if logger.respond_to? :skip_store
|
|
47
|
+
logger.skip_store = old
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def add(*args, &block)
|
|
52
|
+
add_with_opts(*args,&block)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def level
|
|
56
|
+
ol = @override_levels
|
|
57
|
+
(ol && ol[Thread.current.object_id]) || @level
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def add_with_opts(severity, message, progname, opts=nil, &block)
|
|
61
|
+
if severity < level
|
|
62
|
+
return true
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# it is not fun losing messages cause encoding is bad
|
|
66
|
+
# protect all messages by scrubbing if needed
|
|
67
|
+
if message && !message.valid_encoding?
|
|
68
|
+
message = message.scrub
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if @chained
|
|
72
|
+
i = 0
|
|
73
|
+
# micro optimise for logging
|
|
74
|
+
while i < @chained.length
|
|
75
|
+
# TODO double yielding blocks
|
|
76
|
+
begin
|
|
77
|
+
add_to_chained(@chained[i], severity, message, progname, opts, &block)
|
|
78
|
+
rescue => e
|
|
79
|
+
# don't blow up if STDERR is somehow closed
|
|
80
|
+
STDERR.puts "Failed to report message to chained logger #{e}" rescue nil
|
|
81
|
+
end
|
|
82
|
+
i += 1
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
progname ||= @progname
|
|
87
|
+
if message.nil?
|
|
88
|
+
if block_given?
|
|
89
|
+
message = yield
|
|
90
|
+
else
|
|
91
|
+
message = progname
|
|
92
|
+
progname = @progname
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
return if @skip_store
|
|
97
|
+
|
|
98
|
+
opts ||= {}
|
|
99
|
+
opts[:env] ||= Thread.current[LOGSTER_ENV]
|
|
100
|
+
|
|
101
|
+
@store.report(severity, progname, message, opts)
|
|
102
|
+
|
|
103
|
+
rescue => e
|
|
104
|
+
# don't blow up if STDERR is somehow closed
|
|
105
|
+
STDERR.puts "Failed to report error: #{e} #{severity} #{message} #{progname}" rescue nil
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|