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.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +18 -18
  3. data/.travis.yml +15 -15
  4. data/CHANGELOG.md +137 -130
  5. data/Gemfile +4 -4
  6. data/Guardfile +8 -8
  7. data/LICENSE.txt +22 -22
  8. data/README.md +99 -99
  9. data/Rakefile +24 -24
  10. data/assets/fonts/FontAwesome.otf +0 -0
  11. data/assets/fonts/fontawesome-webfont.eot +0 -0
  12. data/assets/fonts/fontawesome-webfont.svg +639 -639
  13. data/assets/fonts/fontawesome-webfont.ttf +0 -0
  14. data/assets/fonts/fontawesome-webfont.woff +0 -0
  15. data/assets/fonts/fontawesome-webfont.woff2 +0 -0
  16. data/assets/images/Icon-144_rounded.png +0 -0
  17. data/assets/images/Icon-144_square.png +0 -0
  18. data/assets/images/icon_144x144.png +0 -0
  19. data/assets/images/icon_64x64.png +0 -0
  20. data/assets/javascript/client-app.js +81 -81
  21. data/assets/javascript/vendor.js +5302 -5302
  22. data/assets/stylesheets/client-app.css +0 -0
  23. data/assets/stylesheets/vendor.css +3 -3
  24. data/build_client_app.sh +12 -12
  25. data/client-app/.editorconfig +20 -20
  26. data/client-app/.ember-cli +9 -9
  27. data/client-app/.eslintignore +19 -19
  28. data/client-app/.eslintrc.js +46 -46
  29. data/client-app/.gitignore +23 -23
  30. data/client-app/.travis.yml +27 -27
  31. data/client-app/.watchmanconfig +3 -3
  32. data/client-app/README.md +57 -57
  33. data/client-app/app/app.js +14 -14
  34. data/client-app/app/components/message-info.js +18 -18
  35. data/client-app/app/components/message-row.js +45 -45
  36. data/client-app/app/components/panel-resizer.js +75 -75
  37. data/client-app/app/components/tab-contents.js +27 -27
  38. data/client-app/app/components/tab-link.js +5 -5
  39. data/client-app/app/components/tabbed-section.js +32 -32
  40. data/client-app/app/components/time-formatter.js +25 -25
  41. data/client-app/app/components/update-time.js +21 -21
  42. data/client-app/app/controllers/index.js +83 -83
  43. data/client-app/app/controllers/show.js +13 -13
  44. data/client-app/app/index.html +29 -29
  45. data/client-app/app/initializers/app-init.js +55 -55
  46. data/client-app/app/lib/preload.js +14 -14
  47. data/client-app/app/lib/utilities.js +140 -140
  48. data/client-app/app/models/message-collection.js +158 -158
  49. data/client-app/app/models/message.js +99 -99
  50. data/client-app/app/resolver.js +3 -3
  51. data/client-app/app/router.js +14 -14
  52. data/client-app/app/routes/index.js +53 -53
  53. data/client-app/app/routes/show.js +14 -14
  54. data/client-app/app/styles/app.css +387 -387
  55. data/client-app/app/templates/application.hbs +2 -2
  56. data/client-app/app/templates/components/message-info.hbs +44 -44
  57. data/client-app/app/templates/components/message-row.hbs +17 -17
  58. data/client-app/app/templates/components/tabbed-section.hbs +10 -10
  59. data/client-app/app/templates/components/time-formatter.hbs +1 -1
  60. data/client-app/app/templates/index.hbs +57 -57
  61. data/client-app/app/templates/show.hbs +4 -4
  62. data/client-app/config/environment.js +51 -51
  63. data/client-app/config/optional-features.json +3 -3
  64. data/client-app/config/targets.js +18 -18
  65. data/client-app/ember-cli-build.js +29 -29
  66. data/client-app/package-lock.json +11365 -11365
  67. data/client-app/package.json +56 -56
  68. data/client-app/testem.js +25 -25
  69. data/client-app/tests/index.html +34 -34
  70. data/client-app/tests/integration/components/message-info-test.js +26 -26
  71. data/client-app/tests/integration/components/message-row-test.js +26 -26
  72. data/client-app/tests/integration/components/panel-resizer-test.js +26 -26
  73. data/client-app/tests/integration/components/tab-contents-test.js +26 -26
  74. data/client-app/tests/integration/components/tab-link-test.js +26 -26
  75. data/client-app/tests/integration/components/tabbed-section-test.js +26 -26
  76. data/client-app/tests/integration/components/time-formatter-test.js +26 -26
  77. data/client-app/tests/integration/components/update-time-test.js +26 -26
  78. data/client-app/tests/test-helper.js +8 -8
  79. data/client-app/tests/unit/controllers/index-test.js +12 -12
  80. data/client-app/tests/unit/controllers/show-test.js +12 -12
  81. data/client-app/tests/unit/initializers/app-init-test.js +31 -31
  82. data/client-app/tests/unit/routes/index-test.js +11 -11
  83. data/client-app/tests/unit/routes/show-test.js +11 -11
  84. data/lib/examples/sidekiq_logster_reporter.rb +21 -21
  85. data/lib/logster.rb +54 -54
  86. data/lib/logster/base_store.rb +130 -130
  87. data/lib/logster/configuration.rb +25 -25
  88. data/lib/logster/ignore_pattern.rb +65 -65
  89. data/lib/logster/logger.rb +108 -102
  90. data/lib/logster/message.rb +227 -227
  91. data/lib/logster/middleware/debug_exceptions.rb +26 -26
  92. data/lib/logster/middleware/reporter.rb +56 -56
  93. data/lib/logster/middleware/viewer.rb +220 -220
  94. data/lib/logster/rails/railtie.rb +58 -58
  95. data/lib/logster/redis_store.rb +481 -481
  96. data/lib/logster/version.rb +3 -3
  97. data/lib/logster/web.rb +14 -14
  98. data/logster.gemspec +34 -34
  99. data/test/examples/test_sidekiq_reporter_example.rb +46 -46
  100. data/test/fake_data/Gemfile +4 -4
  101. data/test/fake_data/generate.rb +10 -10
  102. data/test/logster/middleware/test_reporter.rb +21 -21
  103. data/test/logster/middleware/test_viewer.rb +96 -96
  104. data/test/logster/test_base_store.rb +147 -147
  105. data/test/logster/test_ignore_pattern.rb +41 -41
  106. data/test/logster/test_logger.rb +80 -74
  107. data/test/logster/test_message.rb +34 -34
  108. data/test/logster/test_redis_rate_limiter.rb +230 -230
  109. data/test/logster/test_redis_store.rb +427 -427
  110. data/test/test_helper.rb +38 -38
  111. data/vendor/assets/javascripts/logster.js.erb +39 -39
  112. metadata +3 -3
@@ -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
@@ -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
- if @chained
66
- i = 0
67
- # micro optimise for logging
68
- while i < @chained.length
69
- # TODO double yielding blocks
70
- begin
71
- add_to_chained(@chained[i], severity, message, progname, opts, &block)
72
- rescue => e
73
- # don't blow up if STDERR is somehow closed
74
- STDERR.puts "Failed to report message to chained logger #{e}" rescue nil
75
- end
76
- i += 1
77
- end
78
- end
79
-
80
- progname ||= @progname
81
- if message.nil?
82
- if block_given?
83
- message = yield
84
- else
85
- message = progname
86
- progname = @progname
87
- end
88
- end
89
-
90
- return if @skip_store
91
-
92
- opts ||= {}
93
- opts[:env] ||= Thread.current[LOGSTER_ENV]
94
-
95
- @store.report(severity, progname, message, opts)
96
-
97
- rescue => e
98
- # don't blow up if STDERR is somehow closed
99
- STDERR.puts "Failed to report error: #{e} #{severity} #{message} #{progname}" rescue nil
100
- end
101
- end
102
- end
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