logster 2.19.1 → 2.20.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,6 +4,9 @@ source "https://rubygems.org"
4
4
 
5
5
  group :test do
6
6
  gem "rails", "~> 6.1.0"
7
+ gem "concurrent-ruby", "1.3.4"
8
+ gem "mutex_m"
9
+ gem "bigdecimal"
7
10
  end
8
11
 
9
12
  gemspec path: "../"
@@ -4,6 +4,9 @@ source "https://rubygems.org"
4
4
 
5
5
  group :test do
6
6
  gem "rails", "~> 7.0.0"
7
+ gem "concurrent-ruby", "1.3.4"
8
+ gem "mutex_m"
9
+ gem "bigdecimal"
7
10
  end
8
11
 
9
12
  gemspec path: "../"
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ group :test do
6
+ gem "rails", "~> 7.2.0"
7
+ end
8
+
9
+ gemspec path: "../"
data/lib/logster/group.rb CHANGED
@@ -94,7 +94,6 @@ module Logster
94
94
  @timestamp = 0
95
95
  @changed = true
96
96
  end
97
- @messages
98
97
  end
99
98
 
100
99
  def changed?
@@ -13,6 +13,7 @@ module Logster
13
13
  super(nil)
14
14
  @store = store
15
15
  @chained = []
16
+ @subscribers = []
16
17
  @skip_store = false
17
18
  @logster_override_level_key = "logster_override_level_#{object_id}"
18
19
  end
@@ -29,6 +30,17 @@ module Logster
29
30
  @chained << logger
30
31
  end
31
32
 
33
+ ##
34
+ # Subscribe to log events.
35
+ #
36
+ # Example:
37
+ # logger.subscribe do |severity, message, progname, opts, &block|
38
+ # YourCustomLogger.log(severity, message, progname, opts, &block)
39
+ # end
40
+ def subscribe(&block)
41
+ @subscribers << block
42
+ end
43
+
32
44
  def add_to_chained(logger, severity, message, progname, opts = nil, &block)
33
45
  if logger.respond_to? :skip_store
34
46
  old = logger.skip_store
@@ -73,24 +85,8 @@ module Logster
73
85
  opts[:backtrace] = backtrace
74
86
  end
75
87
 
76
- if @chained
77
- i = 0
78
- # micro optimise for logging
79
- while i < @chained.length
80
- # TODO double yielding blocks
81
- begin
82
- add_to_chained(@chained[i], severity, message, progname, opts, &block)
83
- rescue => e
84
- # don't blow up if STDERR is somehow closed
85
- begin
86
- STDERR.puts "Failed to report message to chained logger #{e}"
87
- rescue StandardError
88
- nil
89
- end
90
- end
91
- i += 1
92
- end
93
- end
88
+ notify_subscribers(severity, message, progname, opts, &block)
89
+ add_to_chained_loggers(severity, message, progname, opts, &block)
94
90
 
95
91
  return if @skip_store
96
92
 
@@ -121,6 +117,52 @@ module Logster
121
117
 
122
118
  private
123
119
 
120
+ def add_to_chained_loggers(severity, message, progname, opts, &block)
121
+ chained_length = @chained.length
122
+
123
+ if chained_length > 0
124
+ i = 0
125
+ # micro optimise for logging since while loop is almost twice as fast
126
+ while i < chained_length
127
+ begin
128
+ add_to_chained(@chained[i], severity, message, progname, opts, &block)
129
+ rescue => e
130
+ # don't blow up if STDERR is somehow closed
131
+ begin
132
+ STDERR.puts "Failed to report message to chained logger: #{e.class} (#{e.message})\n#{e.backtrace.join("\n")}"
133
+ rescue StandardError
134
+ nil
135
+ end
136
+ end
137
+ i += 1
138
+ end
139
+ end
140
+ end
141
+
142
+ def notify_subscribers(severity, message, progname, opts, &block)
143
+ subscribers_length = @subscribers.length
144
+
145
+ if subscribers_length > 0
146
+ i = 0
147
+
148
+ # micro optimise for logging since while loop is almost twice as fast
149
+ while i < subscribers_length
150
+ begin
151
+ @subscribers[i].call(severity, message, progname, opts, &block)
152
+ rescue => e
153
+ # don't blow up if STDERR is somehow closed
154
+ begin
155
+ STDERR.puts "Failed to report message to subscriber: #{e.class} (#{e.message})\n#{e.backtrace.join("\n")}"
156
+ rescue StandardError
157
+ nil
158
+ end
159
+ end
160
+
161
+ i += 1
162
+ end
163
+ end
164
+ end
165
+
124
166
  def report_to_store(severity, progname, message, opts = {})
125
167
  @store.report(severity, progname, message, opts)
126
168
  end
@@ -182,7 +182,7 @@ module Logster
182
182
 
183
183
  def self.populate_env_helper(env)
184
184
  env[LOGSTER_ENV] ||= begin
185
- unless env.include? "rack.input"
185
+ if !env.include? "rack.input"
186
186
  # Not a web request
187
187
  return env
188
188
  end
@@ -7,7 +7,7 @@ module Logster::Rails
7
7
 
8
8
  class << self
9
9
  def set_logger(config)
10
- return unless Logster.config.environments.include?(Rails.env.to_sym)
10
+ return if !Logster.config.environments.include?(Rails.env.to_sym)
11
11
 
12
12
  require "logster/middleware/debug_exceptions"
13
13
  require "logster/middleware/reporter"
@@ -35,7 +35,7 @@ module Logster::Rails
35
35
  end
36
36
 
37
37
  def initialize!(app)
38
- return unless Logster.config.environments.include?(Rails.env.to_sym)
38
+ return if !Logster.config.environments.include?(Rails.env.to_sym)
39
39
  return unless logster_enabled?
40
40
 
41
41
  if Logster.config.enable_js_error_reporting
@@ -34,7 +34,7 @@ module Logster
34
34
  end
35
35
 
36
36
  def check(severity)
37
- return unless @severities.include?(severity)
37
+ return if !@severities.include?(severity)
38
38
  time = Time.now.to_i
39
39
  num = bucket_number(time)
40
40
  redis_key = "#{key}:#{num}"
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "json"
4
- require "set"
4
+ # Disable rubocop because the require is only redundant for Ruby 3.2+ but we still support Ruby 3.1
5
+ require "set" # rubocop:disable Lint/RedundantRequireStatement
5
6
  require "logster/base_store"
6
7
  require "logster/redis_rate_limiter"
7
8
 
@@ -409,12 +410,12 @@ module Logster
409
410
  if @redis.llen(list_key) > max_backlog
410
411
  removed_keys = []
411
412
  while removed_key = @redis.lpop(list_key)
412
- unless @redis.sismember(protected_key, removed_key)
413
+ if @redis.sismember(protected_key, removed_key)
414
+ removed_keys << removed_key
415
+ else
413
416
  rmsg = get(removed_key, load_env: false)
414
417
  delete(rmsg)
415
418
  break
416
- else
417
- removed_keys << removed_key
418
419
  end
419
420
  end
420
421
  removed_keys.reverse.each { |key| @redis.lpush(list_key, key) }
@@ -533,7 +534,7 @@ module Logster
533
534
  when Regexp
534
535
  value.to_s =~ search
535
536
  when String
536
- value.to_s =~ Regexp.new(search, Regexp::IGNORECASE)
537
+ value.to_s =~ Regexp.new(Regexp.escape(search), Regexp::IGNORECASE)
537
538
  else
538
539
  false
539
540
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Logster
4
- VERSION = "2.19.1"
4
+ VERSION = "2.20.1"
5
5
  end
data/logster.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  lib = File.expand_path("../lib", __FILE__)
5
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ $LOAD_PATH.unshift(lib) if !$LOAD_PATH.include?(lib)
6
6
  require "logster/version"
7
7
 
8
8
  Gem::Specification.new do |spec|
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_development_dependency "guard-minitest"
38
38
  spec.add_development_dependency "timecop"
39
39
  spec.add_development_dependency "byebug", "~> 11.1.0"
40
- spec.add_development_dependency "rubocop-discourse", "~> 2.4.1"
40
+ spec.add_development_dependency "rubocop-discourse"
41
41
  spec.add_development_dependency "syntax_tree"
42
42
  spec.add_development_dependency "sqlite3"
43
43
  end
@@ -317,7 +317,7 @@ class TestViewer < Minitest::Test
317
317
  %w[/logsie/javascript/client-app.js /logsie/javascript/vendor.js].each do |path|
318
318
  response = request.get(path)
319
319
  assert_equal(200, response.status)
320
- assert_equal("application/javascript", response.headers["content-type"])
320
+ assert %w[text/javascript application/javascript].include?(response.headers["content-type"])
321
321
  end
322
322
  end
323
323
 
@@ -71,6 +71,46 @@ class TestLogger < Minitest::Test
71
71
  assert_equal "test", @store.calls.first[2]
72
72
  end
73
73
 
74
+ def test_subscribing_to_logger_events
75
+ custom_logger_klass =
76
+ Class.new do
77
+ attr_reader :events
78
+
79
+ def initialize
80
+ @events = []
81
+ end
82
+
83
+ def log(severity, message, progname, opts, &block)
84
+ @events.push({ severity:, message:, progname:, opts:, block: })
85
+ end
86
+ end
87
+
88
+ custom_logger = custom_logger_klass.new
89
+
90
+ @logger.subscribe do |severity, message, progname, opts, &block|
91
+ custom_logger.log(severity, message, progname, opts, &block)
92
+ end
93
+
94
+ @logger.add(0, "test", "prog", backtrace: "backtrace", env: { a: "x" })
95
+ @logger.add(1, nil, nil, backtrace: "backtrace") { "yielded message" }
96
+
97
+ first_event = custom_logger.events[0]
98
+
99
+ assert_equal(0, first_event[:severity])
100
+ assert_equal("test", first_event[:message])
101
+ assert_equal("prog", first_event[:progname])
102
+ assert_equal({ backtrace: "backtrace", env: { a: "x" } }, first_event[:opts])
103
+ assert_nil first_event[:block]
104
+
105
+ second_event = custom_logger.events[1]
106
+
107
+ assert_equal(1, second_event[:severity])
108
+ assert_nil second_event[:message]
109
+ assert_nil second_event[:progname]
110
+ assert_equal({ backtrace: "backtrace", env: nil }, second_event[:opts])
111
+ assert_equal("yielded message", second_event[:block].call)
112
+ end
113
+
74
114
  class NewLogger < Logster::Logger
75
115
  end
76
116
 
@@ -428,6 +428,16 @@ class TestRedisStore < Minitest::Test
428
428
  assert_equal("TUVWXYZ", latest[0].message)
429
429
  end
430
430
 
431
+ def test_search_works_with_invalid_regex_chars
432
+ @store.report(Logger::INFO, "test", "ABCDEFG\\")
433
+ @store.report(Logger::INFO, "test", "TUVWXYZ")
434
+
435
+ result = @store.latest(search: "EFG\\")
436
+
437
+ assert_equal(1, result.size)
438
+ assert_equal("ABCDEFG\\", result[0].message)
439
+ end
440
+
431
441
  def test_search_exclude_results
432
442
  @store.report(Logger::INFO, "test", "ABCDEFG")
433
443
  @store.report(Logger::INFO, "test", "TUVWXYZ")
@@ -749,7 +759,9 @@ class TestRedisStore < Minitest::Test
749
759
  Rack::MockRequest.env_for("/test").merge(
750
760
  "HTTP_HOST" => "www.site.com",
751
761
  "HTTP_USER_AGENT" => "SOME WHERE",
762
+ "rack.input" => StringIO.new("test"),
752
763
  )
764
+
753
765
  orig = env.dup
754
766
  orig["test"] = "tests"
755
767
  orig["test1"] = "tests1"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logster
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.19.1
4
+ version: 2.20.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-12 00:00:00.000000000 Z
11
+ date: 2025-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -126,16 +126,16 @@ dependencies:
126
126
  name: rubocop-discourse
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - "~>"
129
+ - - ">="
130
130
  - !ruby/object:Gem::Version
131
- version: 2.4.1
131
+ version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - "~>"
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
- version: 2.4.1
138
+ version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: syntax_tree
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -186,10 +186,10 @@ files:
186
186
  - assets/images/icon_144x144.png
187
187
  - assets/images/icon_64x64.png
188
188
  - assets/javascript/.gitkeep
189
- - assets/javascript/chunk.143.86f7820bfe6482b8dcd5.js
190
- - assets/javascript/chunk.178.c5fac0c2a2035839a91e.js
191
- - assets/javascript/chunk.468.95dd450003497c781cb3.js
192
- - assets/javascript/chunk.916.85a3fc9d873df80f5ea5.js
189
+ - assets/javascript/chunk.524.c3042190e39d148beaf9.js
190
+ - assets/javascript/chunk.582.695dcbfb11a784b110cd.js
191
+ - assets/javascript/chunk.747.a730c497582bb6742a6e.js
192
+ - assets/javascript/chunk.761.64949d89942c829e5c1b.js
193
193
  - assets/javascript/client-app.js
194
194
  - assets/javascript/vendor.js
195
195
  - assets/stylesheets/.gitkeep
@@ -280,6 +280,7 @@ files:
280
280
  - gemfiles/rails_6.1.gemfile
281
281
  - gemfiles/rails_7.0.gemfile
282
282
  - gemfiles/rails_7.1.gemfile
283
+ - gemfiles/rails_7.2.gemfile
283
284
  - lib/examples/sidekiq_logster_reporter.rb
284
285
  - lib/logster.rb
285
286
  - lib/logster/base_store.rb