logster 1.1.1 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 10338f67f3b0de4bc895fab64a21addb21987b02
4
- data.tar.gz: 3d4b900cba51c32ccbf7aad9b15843c3f2cb5a97
3
+ metadata.gz: 97266a5b02f788e8537daaf28e0adff771a3bf6b
4
+ data.tar.gz: f43b618a847f9e98f54ecb9e469a29e0354a6947
5
5
  SHA512:
6
- metadata.gz: 6ff41f127c57daf3404518e1311d980887b25366f20b7330d73b8b0814e8d5ca9ceed7ad5df4d33cc270806d9eb7a1c3f81787ba805566102dfd06eda42a9186
7
- data.tar.gz: 9f62de9005f735c84c121ac9a7dc09259afc42dc8c032a162b7d0770bb96b62f8045a0e679febbc9d8a74af8fb2488fa27e08cb077a3aea1bce185a252929075
6
+ metadata.gz: 22657415d4f4173ed2a1850e43a146d81db3c53e33d6009f99069fbe81671fb65d88809fc79a963b06744a17e288364706d1ef63127bcacb3076cc9be789e28d
7
+ data.tar.gz: 7e57a8c7862c3375948e2a097b89c1c1d3f023e33a32c928196371e3c7ef4c02b90df6828790d12fafb49c21acccf5b7810abe32220f4030e012ed463a271081
data/README.md CHANGED
@@ -97,6 +97,10 @@ Logster UI is built using [Ember.js](http://emberjs.com/)
97
97
 
98
98
  # CHANGELOG
99
99
 
100
+ - 2015-03-18: Version 1.2.0
101
+ - Fix: Move Redis configuration into RedisStore.
102
+ - Feature: Allow `RedisStore#redis_prefix` to either be a String or a Proc.
103
+
100
104
  - 2015-02-11: Version 1.1.1
101
105
  - Feature: Error rate can now be tracked in one minute and one hour buckets.
102
106
 
@@ -1,7 +1,7 @@
1
1
  module Logster
2
2
  class Configuration
3
3
  attr_accessor :current_context, :allow_grouping, :environments,
4
- :application_version, :web_title, :redis_prefix, :redis_raw_connection
4
+ :application_version, :web_title
5
5
 
6
6
  attr_writer :subdirectory
7
7
 
@@ -4,20 +4,15 @@ require 'logster/base_store'
4
4
  module Logster
5
5
  class RedisRateLimiter
6
6
  BUCKETS = 6
7
+ PREFIX = "__LOGSTER__RATE_LIMIT".freeze
7
8
 
8
- attr_reader :key, :callback_key
9
-
10
- def initialize(redis, severities, limit, duration, callback = nil)
11
- @redis = use_raw_connection? ? Logster.config.redis_raw_connection : redis
9
+ def initialize(redis, severities, limit, duration, redis_prefix = nil, callback = nil)
12
10
  @severities = severities
13
11
  @limit = limit
14
12
  @duration = duration
15
13
  @callback = callback
16
-
17
- # "_LOGSTER_RATE_LIMIT:012:20:30"
18
- # Triggers callback when log levels of :debug, :info and :warn occurs 20 times within 30 secs
19
- @key = "#{key_prefix}#{@severities.join("")}:#{@limit}:#{@duration}"
20
- @callback_key = "#{@key}:callback_triggered"
14
+ @redis_prefix = redis_prefix
15
+ @redis = redis
21
16
  @bucket_range = @duration / BUCKETS
22
17
  end
23
18
 
@@ -25,7 +20,7 @@ module Logster
25
20
  return unless @severities.include?(severity)
26
21
  time = Time.now.to_i
27
22
  num = bucket_number(time)
28
- redis_key = "#{@key}:#{num}"
23
+ redis_key = "#{key}:#{num}"
29
24
 
30
25
  current_rate = @redis.eval <<-LUA
31
26
  local bucket_number = #{num}
@@ -48,20 +43,32 @@ module Logster
48
43
  return (retrieve_rate() + bucket_count)
49
44
  LUA
50
45
 
51
- if !@redis.get(@callback_key) && (current_rate >= @limit)
46
+ if !@redis.get(callback_key) && (current_rate >= @limit)
52
47
  @callback.call(current_rate) if @callback
53
- @redis.set(@callback_key, 1)
48
+ @redis.set(callback_key, 1)
54
49
  end
55
50
 
56
51
  current_rate
57
52
  end
58
53
 
54
+ def key
55
+ # "_LOGSTER_RATE_LIMIT:012:20:30"
56
+ # Triggers callback when log levels of :debug, :info and :warn occurs 20 times within 30 secs
57
+ "#{key_prefix}:#{@severities.join("")}:#{@limit}:#{@duration}"
58
+ end
59
+
60
+ def callback_key
61
+ "#{@key}:callback_triggered"
62
+ end
63
+
59
64
  private
60
65
 
61
66
  def key_prefix
62
- prefix = "__LOGSTER__RATE_LIMIT:".freeze
63
- prefix = "#{Logster.config.redis_prefix}:#{prefix}" if use_raw_connection?
64
- prefix
67
+ if @redis_prefix
68
+ "#{@redis_prefix.call}:#{PREFIX}"
69
+ else
70
+ PREFIX
71
+ end
65
72
  end
66
73
 
67
74
  def mget_keys(bucket_num)
@@ -78,15 +85,12 @@ module Logster
78
85
  def bucket_expiry(time)
79
86
  @duration - ((time % @duration) % @bucket_range)
80
87
  end
81
-
82
- def use_raw_connection?
83
- Logster.config.redis_prefix && Logster.config.redis_raw_connection
84
- end
85
88
  end
86
89
 
87
90
  class RedisStore < BaseStore
88
91
 
89
- attr_accessor :redis, :max_backlog
92
+ attr_accessor :redis, :max_backlog, :redis_raw_connection
93
+ attr_writer :redis_prefix
90
94
 
91
95
  def initialize(redis = nil)
92
96
  super()
@@ -269,10 +273,16 @@ module Logster
269
273
  register_rate_limit(severities, limit, 3600, block)
270
274
  end
271
275
 
276
+ def redis_prefix
277
+ return 'default'.freeze if !@redis_prefix
278
+ @prefix_is_proc ||= @redis_prefix.respond_to?(:call)
279
+ @prefix_is_proc ? @redis_prefix.call : @redis_prefix
280
+ end
281
+
272
282
  protected
273
283
 
274
284
  def rate_limits
275
- @rate_limits ||= []
285
+ @rate_limits ||= {}
276
286
  end
277
287
 
278
288
  def clear_solved(count = nil)
@@ -395,7 +405,9 @@ module Logster
395
405
  end
396
406
 
397
407
  def check_rate_limits(severity)
398
- rate_limits.each { |rate_limit| rate_limit.check(severity) }
408
+ rate_limits_to_check = rate_limits[self.redis_prefix]
409
+ return if !rate_limits_to_check
410
+ rate_limits_to_check.each { |rate_limit| rate_limit.check(severity) }
399
411
  end
400
412
 
401
413
  def solved_key
@@ -422,8 +434,14 @@ module Logster
422
434
 
423
435
  def register_rate_limit(severities, limit, duration, callback)
424
436
  severities = [severities] unless severities.is_a?(Array)
425
- rate_limiter = RedisRateLimiter.new(@redis, severities, limit, duration, callback)
426
- rate_limits << rate_limiter
437
+ redis = (@redis_raw_connection && @redis_prefix) ? @redis_raw_connection : @redis
438
+
439
+ rate_limiter = RedisRateLimiter.new(
440
+ redis, severities, limit, duration, Proc.new { redis_prefix }, callback
441
+ )
442
+
443
+ rate_limits[self.redis_prefix] ||= []
444
+ rate_limits[self.redis_prefix] << rate_limiter
427
445
  rate_limiter
428
446
  end
429
447
  end
@@ -1,3 +1,3 @@
1
1
  module Logster
2
- VERSION = "1.1.1"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -17,7 +17,7 @@ class TestRedisRateLimiter < Minitest::Test
17
17
  called = 0
18
18
 
19
19
  @rate_limiter = Logster::RedisRateLimiter.new(
20
- @redis, [Logger::WARN], 8, 60, Proc.new { called += 1 }
20
+ @redis, [Logger::WARN], 8, 60, nil, Proc.new { called += 1 }
21
21
  )
22
22
 
23
23
  assert_equal(1, @rate_limiter.check(Logger::WARN))
@@ -82,7 +82,7 @@ class TestRedisRateLimiter < Minitest::Test
82
82
  called = 0
83
83
 
84
84
  @rate_limiter = Logster::RedisRateLimiter.new(
85
- @redis, [Logger::WARN, Logger::ERROR], 4, 60, Proc.new { called += 1 }
85
+ @redis, [Logger::WARN, Logger::ERROR], 4, 60, nil, Proc.new { called += 1 }
86
86
  )
87
87
 
88
88
  assert_equal(1, @rate_limiter.check(Logger::WARN))
@@ -138,14 +138,19 @@ class TestRedisRateLimiter < Minitest::Test
138
138
  def test_raw_connection
139
139
  time = Time.new(2015, 1, 1, 1, 1)
140
140
  Timecop.freeze(time)
141
- Logster.config.redis_prefix = "lobster"
142
- Logster.config.redis_raw_connection = @redis
143
-
144
- @rate_limiter = Logster::RedisRateLimiter.new(nil, [Logger::WARN], 1, 60)
141
+ @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60, Proc.new { "lobster" })
145
142
 
146
143
  assert_equal(1, @rate_limiter.check(Logger::WARN))
147
- assert_includes(key, "lobster")
148
144
  assert_redis_key(60, 0)
145
+
146
+ array = ['lobster1', 'lobster2']
147
+
148
+ @rate_limiter = Logster::RedisRateLimiter.new(
149
+ @redis, [Logger::WARN], 1, 60, Proc.new { array.delete_at(0) }
150
+ )
151
+
152
+ assert_includes(key, "lobster1")
153
+ assert_includes(key, "lobster2")
149
154
  end
150
155
 
151
156
  private
@@ -172,7 +177,7 @@ class TestRedisRateLimiter < Minitest::Test
172
177
 
173
178
  def assert_redis_key(expected_ttl, expected_bucket_number)
174
179
  redis_key = "#{key}:#{expected_bucket_number}"
175
- assert(@redis.get(redis_key))
180
+ assert(@redis.get(redis_key), "the right bucket should be created")
176
181
  assert_equal(expected_ttl, @redis.ttl(redis_key))
177
182
  end
178
183
  end
@@ -326,19 +326,61 @@ class TestRedisStore < Minitest::Test
326
326
  assert_equal(orig, env)
327
327
  end
328
328
 
329
- %w{minute hour}.each do |duration|
330
- define_method "test_register_rate_limit_per_#{duration}" do
331
- called = false
329
+ def test_rate_limits
330
+ %w{minute hour}.each do |duration|
331
+ begin
332
+ called = false
333
+
334
+ assert_instance_of(
335
+ Logster::RedisRateLimiter,
336
+ @store.public_send("register_rate_limit_per_#{duration}", Logger::WARN, 0) do
337
+ called = true
338
+ end
339
+ )
340
+
341
+ @store.report(Logger::WARN, "test", "test")
342
+ assert called
343
+ ensure
344
+ reset_redis
345
+ end
346
+ end
347
+ end
348
+
349
+ def test_rate_limits_with_prefix
350
+ begin
351
+ time = Time.now
352
+ Timecop.freeze(time)
353
+ current_namespace = 'first'
354
+ @store.redis_prefix = Proc.new { current_namespace }
355
+
356
+ called_first = 0
357
+ called_second = 0
332
358
 
333
- assert_instance_of(
334
- Logster::RedisRateLimiter,
335
- @store.public_send("register_rate_limit_per_#{duration}", Logger::WARN, 0) do
336
- called = true
337
- end
338
- )
359
+ @store.register_rate_limit_per_minute(Logger::WARN, 0) { called_first += 1 }
360
+ @store.report(Logger::WARN, "test", "test")
361
+ assert_equal(1, called_first)
339
362
 
363
+ current_namespace = 'second'
364
+ @store.register_rate_limit_per_minute(Logger::WARN, 0) { called_second += 1 }
340
365
  @store.report(Logger::WARN, "test", "test")
341
- assert called
366
+ assert_equal(1, called_first)
367
+ assert_equal(1, called_second)
368
+
369
+ Timecop.freeze(time + 10) do
370
+ current_namespace = 'first'
371
+ @store.report(Logger::WARN, "test", "test")
372
+
373
+ assert_equal(2, called_first)
374
+ assert_equal(1, called_second)
375
+ end
376
+ ensure
377
+ reset_redis
342
378
  end
343
379
  end
380
+
381
+ private
382
+
383
+ def reset_redis
384
+ @store.redis.flushall
385
+ end
344
386
  end
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: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - UI for viewing logs in Rack
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-22 00:00:00.000000000 Z
11
+ date: 2016-03-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler