logster 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
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