logster 1.2.11 → 1.3.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +18 -17
  3. data/.travis.yml +15 -16
  4. data/CHANGELOG.md +130 -130
  5. data/Gemfile +4 -4
  6. data/Guardfile +8 -8
  7. data/LICENSE.txt +22 -22
  8. data/README.md +99 -96
  9. data/Rakefile +24 -23
  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 -0
  21. data/assets/javascript/vendor.js +5302 -0
  22. data/assets/stylesheets/client-app.css +1 -0
  23. data/assets/stylesheets/vendor.css +4 -0
  24. data/build_client_app.sh +12 -0
  25. data/client-app/.editorconfig +20 -0
  26. data/client-app/.ember-cli +9 -0
  27. data/client-app/.eslintignore +19 -0
  28. data/client-app/.eslintrc.js +46 -0
  29. data/client-app/.gitignore +23 -0
  30. data/client-app/.travis.yml +27 -0
  31. data/client-app/.watchmanconfig +3 -0
  32. data/client-app/README.md +57 -0
  33. data/client-app/app/app.js +14 -0
  34. data/client-app/app/components/message-info.js +18 -0
  35. data/client-app/app/components/message-row.js +45 -0
  36. data/client-app/app/components/panel-resizer.js +75 -0
  37. data/client-app/app/components/tab-contents.js +27 -0
  38. data/client-app/app/components/tab-link.js +5 -0
  39. data/client-app/app/components/tabbed-section.js +32 -0
  40. data/client-app/app/components/time-formatter.js +25 -0
  41. data/client-app/app/components/update-time.js +21 -0
  42. data/client-app/app/controllers/index.js +83 -0
  43. data/client-app/app/controllers/show.js +13 -0
  44. data/client-app/app/index.html +29 -0
  45. data/client-app/app/initializers/app-init.js +55 -0
  46. data/client-app/app/lib/preload.js +14 -0
  47. data/client-app/app/lib/utilities.js +140 -0
  48. data/client-app/app/models/message-collection.js +158 -0
  49. data/client-app/app/models/message.js +99 -0
  50. data/client-app/app/resolver.js +3 -0
  51. data/client-app/app/router.js +14 -0
  52. data/client-app/app/routes/index.js +53 -0
  53. data/client-app/app/routes/show.js +14 -0
  54. data/{assets/stylesheets → client-app/app/styles}/app.css +387 -390
  55. data/{assets/javascript → client-app/app}/templates/application.hbs +2 -2
  56. data/client-app/app/templates/components/message-info.hbs +44 -0
  57. data/{assets/javascript → client-app/app/templates}/components/message-row.hbs +17 -17
  58. data/client-app/app/templates/components/tabbed-section.hbs +10 -0
  59. data/client-app/app/templates/components/time-formatter.hbs +1 -0
  60. data/{assets/javascript → client-app/app}/templates/index.hbs +57 -57
  61. data/{assets/javascript → client-app/app}/templates/show.hbs +4 -4
  62. data/client-app/config/environment.js +51 -0
  63. data/client-app/config/optional-features.json +3 -0
  64. data/client-app/config/targets.js +18 -0
  65. data/client-app/ember-cli-build.js +29 -0
  66. data/client-app/package-lock.json +11365 -0
  67. data/client-app/package.json +56 -0
  68. data/client-app/testem.js +25 -0
  69. data/client-app/tests/index.html +34 -0
  70. data/client-app/tests/integration/components/message-info-test.js +26 -0
  71. data/client-app/tests/integration/components/message-row-test.js +26 -0
  72. data/client-app/tests/integration/components/panel-resizer-test.js +26 -0
  73. data/client-app/tests/integration/components/tab-contents-test.js +26 -0
  74. data/client-app/tests/integration/components/tab-link-test.js +26 -0
  75. data/client-app/tests/integration/components/tabbed-section-test.js +26 -0
  76. data/client-app/tests/integration/components/time-formatter-test.js +26 -0
  77. data/client-app/tests/integration/components/update-time-test.js +26 -0
  78. data/client-app/tests/test-helper.js +8 -0
  79. data/client-app/tests/unit/controllers/index-test.js +12 -0
  80. data/client-app/tests/unit/controllers/show-test.js +12 -0
  81. data/client-app/tests/unit/initializers/app-init-test.js +31 -0
  82. data/client-app/tests/unit/routes/index-test.js +11 -0
  83. data/client-app/tests/unit/routes/show-test.js +11 -0
  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 +102 -101
  90. data/lib/logster/message.rb +227 -226
  91. data/lib/logster/middleware/debug_exceptions.rb +26 -26
  92. data/lib/logster/middleware/reporter.rb +56 -54
  93. data/lib/logster/middleware/viewer.rb +220 -251
  94. data/lib/logster/rails/railtie.rb +58 -58
  95. data/lib/logster/redis_store.rb +481 -477
  96. data/lib/logster/version.rb +3 -3
  97. data/lib/logster/web.rb +14 -14
  98. data/logster.gemspec +34 -33
  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 -70
  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 +74 -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 -414
  110. data/test/test_helper.rb +38 -37
  111. data/vendor/assets/javascripts/logster.js.erb +39 -39
  112. metadata +83 -24
  113. data/assets/javascript/app.js +0 -817
  114. data/assets/javascript/components/message-info.hbs +0 -47
  115. data/assets/javascript/components/panel-resizer.hbs +0 -0
  116. data/assets/javascript/components/tab-contents.hbs +0 -1
  117. data/assets/javascript/components/tab-link.hbs +0 -1
  118. data/assets/javascript/components/tabbed-section.hbs +0 -6
  119. data/assets/javascript/external/ember-template-compiler.js +0 -22346
  120. data/assets/javascript/external/ember.js +0 -58500
  121. data/assets/javascript/external/ember.min.js +0 -17
  122. data/assets/javascript/external/jquery.min.js +0 -5
  123. data/assets/javascript/external/lodash.min.js +0 -87
  124. data/assets/javascript/external/moment.min.js +0 -6
  125. data/assets/stylesheets/font-awesome.min.css +0 -4
  126. data/bower.json +0 -25
@@ -1,41 +1,41 @@
1
- require_relative '../test_helper'
2
- require 'logster/ignore_pattern'
3
-
4
- class TestIgnorePattern < Minitest::Test
5
-
6
- def test_string_message_pattern
7
- msg = Logster::Message.new(Logger::WARN, "test", "my error")
8
- msg_frog = Logster::Message.new(Logger::WARN, "test", "a frog")
9
- msg_nil = Logster::Message.new(Logger::WARN, "test", nil)
10
-
11
- pattern = Logster::IgnorePattern.new("ERROR")
12
-
13
- assert pattern.matches? msg
14
- assert !pattern.matches?(msg_frog)
15
- assert !pattern.matches?(msg_nil)
16
- end
17
-
18
- def test_env_pattern
19
- msg = Logster::Message.new(Logger::WARN, "test", "my error")
20
- msg.env = {"frogs" => "are big"}
21
-
22
- pattern = Logster::IgnorePattern.new(nil, {frogs: "big"})
23
-
24
- assert pattern.matches? msg
25
-
26
- msg.env = {legs: nil}
27
- assert !(pattern.matches? msg)
28
-
29
- msg.env = {legs: 3}
30
- assert !(pattern.matches? msg)
31
-
32
- msg.env = {frogs: "small"}
33
- assert !pattern.matches?(msg)
34
-
35
- pattern = Logster::IgnorePattern.new(nil, "small")
36
- assert pattern.matches? msg
37
-
38
- msg.env = {frogs: "big"}
39
- assert !(pattern.matches? msg)
40
- end
41
- end
1
+ require_relative '../test_helper'
2
+ require 'logster/ignore_pattern'
3
+
4
+ class TestIgnorePattern < Minitest::Test
5
+
6
+ def test_string_message_pattern
7
+ msg = Logster::Message.new(Logger::WARN, "test", "my error")
8
+ msg_frog = Logster::Message.new(Logger::WARN, "test", "a frog")
9
+ msg_nil = Logster::Message.new(Logger::WARN, "test", nil)
10
+
11
+ pattern = Logster::IgnorePattern.new("ERROR")
12
+
13
+ assert pattern.matches? msg
14
+ assert !pattern.matches?(msg_frog)
15
+ assert !pattern.matches?(msg_nil)
16
+ end
17
+
18
+ def test_env_pattern
19
+ msg = Logster::Message.new(Logger::WARN, "test", "my error")
20
+ msg.env = {"frogs" => "are big"}
21
+
22
+ pattern = Logster::IgnorePattern.new(nil, {frogs: "big"})
23
+
24
+ assert pattern.matches? msg
25
+
26
+ msg.env = {legs: nil}
27
+ assert !(pattern.matches? msg)
28
+
29
+ msg.env = {legs: 3}
30
+ assert !(pattern.matches? msg)
31
+
32
+ msg.env = {frogs: "small"}
33
+ assert !pattern.matches?(msg)
34
+
35
+ pattern = Logster::IgnorePattern.new(nil, "small")
36
+ assert pattern.matches? msg
37
+
38
+ msg.env = {frogs: "big"}
39
+ assert !(pattern.matches? msg)
40
+ end
41
+ end
@@ -1,74 +1,74 @@
1
- require_relative '../test_helper'
2
- require 'logster/logger'
3
- require 'logger'
4
-
5
- class TestStore
6
- attr_accessor :calls
7
-
8
- def report(*args)
9
- (@calls ||= []) << args
10
- end
11
- end
12
-
13
- class TestLogger < Minitest::Test
14
-
15
- def setup
16
- @store = TestStore.new
17
- @logger = Logster::Logger.new(@store)
18
- end
19
-
20
- def test_per_thread_override
21
- @logger.override_level = 2
22
-
23
- @logger.add(0, "test", "prog", backtrace: "backtrace", env: {a: "x"})
24
- Thread.new do
25
- @logger.add(0, "test", "prog", backtrace: "backtrace", env: {a: "x"})
26
- end.join
27
-
28
- @logger.override_level = nil
29
- @logger.add(0, "test", "prog", backtrace: "backtrace", env: {a: "x"})
30
-
31
- assert_equal 2, @store.calls.length
32
- end
33
-
34
- def test_backtrace
35
- @logger.add(0, "test", "prog", backtrace: "backtrace", env: {a: "x"})
36
- assert_equal "backtrace", @store.calls[0][3][:backtrace]
37
- end
38
-
39
- def test_chain
40
- io = StringIO.new
41
- @logger.chain Logger.new(io)
42
- @logger.warn "boom"
43
-
44
- assert_match(/W,.*boom/, io.string)
45
- end
46
-
47
- def test_backtrace_with_chain
48
- @other_store = TestStore.new
49
- @logger.chain(Logster::Logger.new(@other_store))
50
-
51
- @logger.add(0, "test", "prog", backtrace: "backtrace", env: {a: "x"})
52
-
53
- [@store, @other_store].each do |store|
54
- assert_equal "backtrace", store.calls[0][3][:backtrace]
55
- end
56
- end
57
-
58
- class PlayLogger
59
- attr_accessor :skip_store
60
- def initialize(tester)
61
- @tester = tester
62
- end
63
-
64
- def add(s,m,p,&block)
65
- @tester.assert(skip_store)
66
- end
67
- end
68
-
69
- def test_chain_with_ignore
70
- @logger.chain PlayLogger.new(self)
71
- @logger.skip_store = true
72
- @logger.warn("testing")
73
- end
74
- end
1
+ require_relative '../test_helper'
2
+ require 'logster/logger'
3
+ require 'logger'
4
+
5
+ class TestStore
6
+ attr_accessor :calls
7
+
8
+ def report(*args)
9
+ (@calls ||= []) << args
10
+ end
11
+ end
12
+
13
+ class TestLogger < Minitest::Test
14
+
15
+ def setup
16
+ @store = TestStore.new
17
+ @logger = Logster::Logger.new(@store)
18
+ end
19
+
20
+ def test_per_thread_override
21
+ @logger.override_level = 2
22
+
23
+ @logger.add(0, "test", "prog", backtrace: "backtrace", env: {a: "x"})
24
+ Thread.new do
25
+ @logger.add(0, "test", "prog", backtrace: "backtrace", env: {a: "x"})
26
+ end.join
27
+
28
+ @logger.override_level = nil
29
+ @logger.add(0, "test", "prog", backtrace: "backtrace", env: {a: "x"})
30
+
31
+ assert_equal 2, @store.calls.length
32
+ end
33
+
34
+ def test_backtrace
35
+ @logger.add(0, "test", "prog", backtrace: "backtrace", env: {a: "x"})
36
+ assert_equal "backtrace", @store.calls[0][3][:backtrace]
37
+ end
38
+
39
+ def test_chain
40
+ io = StringIO.new
41
+ @logger.chain Logger.new(io)
42
+ @logger.warn "boom"
43
+
44
+ assert_match(/W,.*boom/, io.string)
45
+ end
46
+
47
+ def test_backtrace_with_chain
48
+ @other_store = TestStore.new
49
+ @logger.chain(Logster::Logger.new(@other_store))
50
+
51
+ @logger.add(0, "test", "prog", backtrace: "backtrace", env: {a: "x"})
52
+
53
+ [@store, @other_store].each do |store|
54
+ assert_equal "backtrace", store.calls[0][3][:backtrace]
55
+ end
56
+ end
57
+
58
+ class PlayLogger
59
+ attr_accessor :skip_store
60
+ def initialize(tester)
61
+ @tester = tester
62
+ end
63
+
64
+ def add(s,m,p,&block)
65
+ @tester.assert(skip_store)
66
+ end
67
+ end
68
+
69
+ def test_chain_with_ignore
70
+ @logger.chain PlayLogger.new(self)
71
+ @logger.skip_store = true
72
+ @logger.warn("testing")
73
+ end
74
+ end
@@ -1,34 +1,34 @@
1
- require_relative '../test_helper'
2
- require 'logster/message'
3
-
4
- class TestMessage < MiniTest::Test
5
-
6
- def test_merge_similar
7
- msg1 = Logster::Message.new(0, '', 'test', 10)
8
- msg1.populate_from_env(a: "1", b: "2")
9
-
10
- msg2 = Logster::Message.new(0, '', 'test', 20)
11
- msg2.populate_from_env(a: "2", c: "3")
12
-
13
- assert_equal(msg2.grouping_key, msg1.grouping_key)
14
-
15
- msg1.merge_similar_message(msg2)
16
-
17
- msg1 = Logster::Message.from_json(msg1.to_json)
18
-
19
- assert_equal(20, msg1.timestamp)
20
- assert_equal(10, msg1.first_timestamp)
21
- end
22
-
23
- def test_adds_application_version
24
- Logster.config.application_version = "abc"
25
- msg = Logster::Message.new(0, '', 'test', 10)
26
- msg.populate_from_env({})
27
-
28
- assert_equal("abc", msg.env["application_version"])
29
-
30
- ensure
31
- Logster.config.application_version = nil
32
- end
33
-
34
- end
1
+ require_relative '../test_helper'
2
+ require 'logster/message'
3
+
4
+ class TestMessage < MiniTest::Test
5
+
6
+ def test_merge_similar
7
+ msg1 = Logster::Message.new(0, '', 'test', 10)
8
+ msg1.populate_from_env(a: "1", b: "2")
9
+
10
+ msg2 = Logster::Message.new(0, '', 'test', 20)
11
+ msg2.populate_from_env(a: "2", c: "3")
12
+
13
+ assert_equal(msg2.grouping_key, msg1.grouping_key)
14
+
15
+ msg1.merge_similar_message(msg2)
16
+
17
+ msg1 = Logster::Message.from_json(msg1.to_json)
18
+
19
+ assert_equal(20, msg1.timestamp)
20
+ assert_equal(10, msg1.first_timestamp)
21
+ end
22
+
23
+ def test_adds_application_version
24
+ Logster.config.application_version = "abc"
25
+ msg = Logster::Message.new(0, '', 'test', 10)
26
+ msg.populate_from_env({})
27
+
28
+ assert_equal("abc", msg.env["application_version"])
29
+
30
+ ensure
31
+ Logster.config.application_version = nil
32
+ end
33
+
34
+ end
@@ -1,230 +1,230 @@
1
- require_relative '../test_helper'
2
- require 'logster/redis_store'
3
- require 'rack'
4
-
5
- class TestRedisRateLimiter < Minitest::Test
6
- def setup
7
- @redis = Redis.new
8
- end
9
-
10
- def teardown
11
- @redis.flushall
12
- Timecop.return
13
- end
14
-
15
- def test_clear_all
16
- called = 0
17
-
18
- @redis.set("dont_nuke", "1")
19
-
20
- @rate_limiter = Logster::RedisRateLimiter.new(
21
- @redis, [Logger::WARN], 8, 60, Proc.new { "prefix" }, Proc.new { called += 1 }
22
- )
23
-
24
- 9.times do
25
- @rate_limiter.check(Logger::WARN)
26
- end
27
-
28
- assert_equal 10, @rate_limiter.check(Logger::WARN)
29
-
30
- Logster::RedisRateLimiter.clear_all(@redis, Proc.new { "prefix" })
31
-
32
- assert_equal 1, @rate_limiter.check(Logger::WARN)
33
-
34
- # also clears when prefix missing
35
- Logster::RedisRateLimiter.clear_all(@redis)
36
-
37
- assert_equal 1, @rate_limiter.check(Logger::WARN)
38
-
39
- assert_equal "1", @redis.get("dont_nuke")
40
- @redis.del("dont_nuke")
41
-
42
- end
43
-
44
- def test_check
45
- time = Time.new(2015, 1, 1, 1, 1)
46
- Timecop.freeze(time)
47
- called = 0
48
-
49
- @rate_limiter = Logster::RedisRateLimiter.new(
50
- @redis, [Logger::WARN], 8, 60, nil, Proc.new { called += 1 }
51
- )
52
-
53
- assert_equal(1, @rate_limiter.check(Logger::WARN))
54
- assert_redis_key(60, 0)
55
- assert_equal(1, number_of_buckets)
56
-
57
- Timecop.freeze(time + 10) do
58
- assert_equal(2, @rate_limiter.check(Logger::WARN))
59
- assert_redis_key(60, 1)
60
- assert_equal(3, @rate_limiter.check(Logger::WARN))
61
- assert_equal(2, number_of_buckets)
62
- end
63
-
64
- Timecop.freeze(time + 20) do
65
- assert_equal(4, @rate_limiter.check(Logger::WARN))
66
- assert_redis_key(60, 2)
67
- assert_equal(3, number_of_buckets)
68
- end
69
-
70
- Timecop.freeze(time + 30) do
71
- assert_equal(5, @rate_limiter.check(Logger::WARN))
72
- assert_redis_key(60, 3)
73
- assert_equal(4, number_of_buckets)
74
- end
75
-
76
- Timecop.freeze(time + 40) do
77
- assert_equal(6, @rate_limiter.check(Logger::WARN))
78
- assert_redis_key(60, 4)
79
- assert_equal(5, number_of_buckets)
80
- end
81
-
82
- Timecop.freeze(time + 50) do
83
- assert_equal(7, @rate_limiter.check(Logger::WARN))
84
- assert_redis_key(60, 5)
85
- assert_equal(6, number_of_buckets)
86
- end
87
-
88
- Timecop.freeze(time + 60) do
89
- @redis.del("#{key}:0")
90
- assert_equal(5, number_of_buckets)
91
-
92
- assert_equal(7, @rate_limiter.check(Logger::WARN))
93
- assert_redis_key(60, 0)
94
- assert_equal(6, number_of_buckets)
95
-
96
- assert_equal(8, @rate_limiter.check(Logger::WARN))
97
- assert_equal(1, called)
98
- assert_equal(6, number_of_buckets)
99
- assert_equal("1", @redis.get(@rate_limiter.callback_key))
100
- end
101
-
102
- Timecop.freeze(time + 70) do
103
- @redis.del("#{key}:1")
104
- assert_equal(7, @rate_limiter.check(Logger::WARN))
105
- assert_nil(@redis.get(@rate_limiter.callback_key))
106
- end
107
- end
108
-
109
- def test_check_with_multiple_severities
110
- time = Time.new(2015, 1, 1, 1, 1)
111
- Timecop.freeze(time)
112
- called = 0
113
-
114
- @rate_limiter = Logster::RedisRateLimiter.new(
115
- @redis, [Logger::WARN, Logger::ERROR], 4, 60, nil, Proc.new { called += 1 }
116
- )
117
-
118
- assert_equal(1, @rate_limiter.check(Logger::WARN))
119
- assert_equal(2, @rate_limiter.check(Logger::ERROR))
120
-
121
- Timecop.freeze(time + 50) do
122
- assert_equal(3, @rate_limiter.check(Logger::WARN))
123
- assert_equal(4, @rate_limiter.check(Logger::ERROR))
124
- assert_equal(2, number_of_buckets)
125
- end
126
-
127
- assert_equal(5, @rate_limiter.check(Logger::ERROR))
128
- assert_equal(1, called)
129
- end
130
-
131
- def test_bucket_number_per_minute
132
- time = Time.new(2015, 1, 1, 1, 1)
133
- Timecop.freeze(time)
134
- @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60)
135
-
136
- assert_bucket_number(0, time)
137
- assert_bucket_number(0, time + 9)
138
- assert_bucket_number(1, time + 11)
139
- assert_bucket_number(5, time + 59)
140
- end
141
-
142
- def test_bucket_number_per_hour
143
- time = Time.new(2015, 1, 1, 1, 0)
144
- Timecop.freeze(time)
145
- @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 3600)
146
-
147
- assert_bucket_number(0, time)
148
- assert_bucket_number(1, time + 1199)
149
- assert_bucket_number(2, time + 1200)
150
- assert_bucket_number(5, time + 3599)
151
- end
152
-
153
- def test_bucket_expiry
154
- time = Time.new(2015, 1, 1, 1, 1)
155
- Timecop.freeze(time)
156
- @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60)
157
-
158
- assert_bucket_expiry(60, time)
159
- assert_bucket_expiry(55, time + 5)
160
- assert_bucket_expiry(60, time + 10)
161
- assert_bucket_expiry(58, time + 12)
162
- assert_bucket_expiry(55, time + 15)
163
- assert_bucket_expiry(51, time + 19)
164
- assert_bucket_expiry(60, time + 20)
165
- assert_bucket_expiry(55, time + 35)
166
- end
167
-
168
- def test_raw_connection
169
- time = Time.new(2015, 1, 1, 1, 1)
170
- Timecop.freeze(time)
171
- @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60, Proc.new { "lobster" })
172
-
173
- assert_equal(1, @rate_limiter.check(Logger::WARN))
174
- assert_redis_key(60, 0)
175
-
176
- toggle = true
177
-
178
- @rate_limiter = Logster::RedisRateLimiter.new(
179
- @redis, [Logger::WARN], 1, 60, Proc.new { toggle ? 'lobster1' : 'lobster2' }
180
- )
181
-
182
- assert_includes(key, "lobster1")
183
-
184
- toggle = false
185
- assert_includes(key, "lobster2")
186
- end
187
-
188
- def test_retrieve_rate
189
- time = Time.new(2015, 1, 1, 1 , 1)
190
- Timecop.freeze(time)
191
-
192
- @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60)
193
-
194
- @rate_limiter.check(Logger::WARN)
195
- assert_equal(@rate_limiter.retrieve_rate, 1)
196
-
197
- Timecop.freeze(time + 50) do
198
- @rate_limiter.check(Logger::WARN)
199
- assert_equal(@rate_limiter.retrieve_rate, 2)
200
- end
201
- end
202
-
203
- private
204
-
205
- def key
206
- @rate_limiter.key
207
- end
208
-
209
- def number_of_buckets
210
- @redis.keys("#{key}:[0-#{Logster::RedisRateLimiter::BUCKETS}]").size
211
- end
212
-
213
- def assert_bucket_number(expected, time)
214
- Timecop.freeze(time) do
215
- assert_equal(expected, @rate_limiter.send(:bucket_number, Time.now.to_i))
216
- end
217
- end
218
-
219
- def assert_bucket_expiry(expected, time)
220
- Timecop.freeze(time) do
221
- assert_equal(expected, @rate_limiter.send(:bucket_expiry, Time.now.to_i))
222
- end
223
- end
224
-
225
- def assert_redis_key(expected_ttl, expected_bucket_number)
226
- redis_key = "#{key}:#{expected_bucket_number}"
227
- assert(@redis.get(redis_key), "the right bucket should be created")
228
- assert_equal(expected_ttl, @redis.ttl(redis_key))
229
- end
230
- end
1
+ require_relative '../test_helper'
2
+ require 'logster/redis_store'
3
+ require 'rack'
4
+
5
+ class TestRedisRateLimiter < Minitest::Test
6
+ def setup
7
+ @redis = Redis.new
8
+ end
9
+
10
+ def teardown
11
+ @redis.flushall
12
+ Timecop.return
13
+ end
14
+
15
+ def test_clear_all
16
+ called = 0
17
+
18
+ @redis.set("dont_nuke", "1")
19
+
20
+ @rate_limiter = Logster::RedisRateLimiter.new(
21
+ @redis, [Logger::WARN], 8, 60, Proc.new { "prefix" }, Proc.new { called += 1 }
22
+ )
23
+
24
+ 9.times do
25
+ @rate_limiter.check(Logger::WARN)
26
+ end
27
+
28
+ assert_equal 10, @rate_limiter.check(Logger::WARN)
29
+
30
+ Logster::RedisRateLimiter.clear_all(@redis, Proc.new { "prefix" })
31
+
32
+ assert_equal 1, @rate_limiter.check(Logger::WARN)
33
+
34
+ # also clears when prefix missing
35
+ Logster::RedisRateLimiter.clear_all(@redis)
36
+
37
+ assert_equal 1, @rate_limiter.check(Logger::WARN)
38
+
39
+ assert_equal "1", @redis.get("dont_nuke")
40
+ @redis.del("dont_nuke")
41
+
42
+ end
43
+
44
+ def test_check
45
+ time = Time.new(2015, 1, 1, 1, 1)
46
+ Timecop.freeze(time)
47
+ called = 0
48
+
49
+ @rate_limiter = Logster::RedisRateLimiter.new(
50
+ @redis, [Logger::WARN], 8, 60, nil, Proc.new { called += 1 }
51
+ )
52
+
53
+ assert_equal(1, @rate_limiter.check(Logger::WARN))
54
+ assert_redis_key(60, 0)
55
+ assert_equal(1, number_of_buckets)
56
+
57
+ Timecop.freeze(time + 10) do
58
+ assert_equal(2, @rate_limiter.check(Logger::WARN))
59
+ assert_redis_key(60, 1)
60
+ assert_equal(3, @rate_limiter.check(Logger::WARN))
61
+ assert_equal(2, number_of_buckets)
62
+ end
63
+
64
+ Timecop.freeze(time + 20) do
65
+ assert_equal(4, @rate_limiter.check(Logger::WARN))
66
+ assert_redis_key(60, 2)
67
+ assert_equal(3, number_of_buckets)
68
+ end
69
+
70
+ Timecop.freeze(time + 30) do
71
+ assert_equal(5, @rate_limiter.check(Logger::WARN))
72
+ assert_redis_key(60, 3)
73
+ assert_equal(4, number_of_buckets)
74
+ end
75
+
76
+ Timecop.freeze(time + 40) do
77
+ assert_equal(6, @rate_limiter.check(Logger::WARN))
78
+ assert_redis_key(60, 4)
79
+ assert_equal(5, number_of_buckets)
80
+ end
81
+
82
+ Timecop.freeze(time + 50) do
83
+ assert_equal(7, @rate_limiter.check(Logger::WARN))
84
+ assert_redis_key(60, 5)
85
+ assert_equal(6, number_of_buckets)
86
+ end
87
+
88
+ Timecop.freeze(time + 60) do
89
+ @redis.del("#{key}:0")
90
+ assert_equal(5, number_of_buckets)
91
+
92
+ assert_equal(7, @rate_limiter.check(Logger::WARN))
93
+ assert_redis_key(60, 0)
94
+ assert_equal(6, number_of_buckets)
95
+
96
+ assert_equal(8, @rate_limiter.check(Logger::WARN))
97
+ assert_equal(1, called)
98
+ assert_equal(6, number_of_buckets)
99
+ assert_equal("1", @redis.get(@rate_limiter.callback_key))
100
+ end
101
+
102
+ Timecop.freeze(time + 70) do
103
+ @redis.del("#{key}:1")
104
+ assert_equal(7, @rate_limiter.check(Logger::WARN))
105
+ assert_nil(@redis.get(@rate_limiter.callback_key))
106
+ end
107
+ end
108
+
109
+ def test_check_with_multiple_severities
110
+ time = Time.new(2015, 1, 1, 1, 1)
111
+ Timecop.freeze(time)
112
+ called = 0
113
+
114
+ @rate_limiter = Logster::RedisRateLimiter.new(
115
+ @redis, [Logger::WARN, Logger::ERROR], 4, 60, nil, Proc.new { called += 1 }
116
+ )
117
+
118
+ assert_equal(1, @rate_limiter.check(Logger::WARN))
119
+ assert_equal(2, @rate_limiter.check(Logger::ERROR))
120
+
121
+ Timecop.freeze(time + 50) do
122
+ assert_equal(3, @rate_limiter.check(Logger::WARN))
123
+ assert_equal(4, @rate_limiter.check(Logger::ERROR))
124
+ assert_equal(2, number_of_buckets)
125
+ end
126
+
127
+ assert_equal(5, @rate_limiter.check(Logger::ERROR))
128
+ assert_equal(1, called)
129
+ end
130
+
131
+ def test_bucket_number_per_minute
132
+ time = Time.new(2015, 1, 1, 1, 1)
133
+ Timecop.freeze(time)
134
+ @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60)
135
+
136
+ assert_bucket_number(0, time)
137
+ assert_bucket_number(0, time + 9)
138
+ assert_bucket_number(1, time + 11)
139
+ assert_bucket_number(5, time + 59)
140
+ end
141
+
142
+ def test_bucket_number_per_hour
143
+ time = Time.new(2015, 1, 1, 1, 0)
144
+ Timecop.freeze(time)
145
+ @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 3600)
146
+
147
+ assert_bucket_number(0, time)
148
+ assert_bucket_number(1, time + 1199)
149
+ assert_bucket_number(2, time + 1200)
150
+ assert_bucket_number(5, time + 3599)
151
+ end
152
+
153
+ def test_bucket_expiry
154
+ time = Time.new(2015, 1, 1, 1, 1)
155
+ Timecop.freeze(time)
156
+ @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60)
157
+
158
+ assert_bucket_expiry(60, time)
159
+ assert_bucket_expiry(55, time + 5)
160
+ assert_bucket_expiry(60, time + 10)
161
+ assert_bucket_expiry(58, time + 12)
162
+ assert_bucket_expiry(55, time + 15)
163
+ assert_bucket_expiry(51, time + 19)
164
+ assert_bucket_expiry(60, time + 20)
165
+ assert_bucket_expiry(55, time + 35)
166
+ end
167
+
168
+ def test_raw_connection
169
+ time = Time.new(2015, 1, 1, 1, 1)
170
+ Timecop.freeze(time)
171
+ @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60, Proc.new { "lobster" })
172
+
173
+ assert_equal(1, @rate_limiter.check(Logger::WARN))
174
+ assert_redis_key(60, 0)
175
+
176
+ toggle = true
177
+
178
+ @rate_limiter = Logster::RedisRateLimiter.new(
179
+ @redis, [Logger::WARN], 1, 60, Proc.new { toggle ? 'lobster1' : 'lobster2' }
180
+ )
181
+
182
+ assert_includes(key, "lobster1")
183
+
184
+ toggle = false
185
+ assert_includes(key, "lobster2")
186
+ end
187
+
188
+ def test_retrieve_rate
189
+ time = Time.new(2015, 1, 1, 1 , 1)
190
+ Timecop.freeze(time)
191
+
192
+ @rate_limiter = Logster::RedisRateLimiter.new(@redis, [Logger::WARN], 1, 60)
193
+
194
+ @rate_limiter.check(Logger::WARN)
195
+ assert_equal(@rate_limiter.retrieve_rate, 1)
196
+
197
+ Timecop.freeze(time + 50) do
198
+ @rate_limiter.check(Logger::WARN)
199
+ assert_equal(@rate_limiter.retrieve_rate, 2)
200
+ end
201
+ end
202
+
203
+ private
204
+
205
+ def key
206
+ @rate_limiter.key
207
+ end
208
+
209
+ def number_of_buckets
210
+ @redis.keys("#{key}:[0-#{Logster::RedisRateLimiter::BUCKETS}]").size
211
+ end
212
+
213
+ def assert_bucket_number(expected, time)
214
+ Timecop.freeze(time) do
215
+ assert_equal(expected, @rate_limiter.send(:bucket_number, Time.now.to_i))
216
+ end
217
+ end
218
+
219
+ def assert_bucket_expiry(expected, time)
220
+ Timecop.freeze(time) do
221
+ assert_equal(expected, @rate_limiter.send(:bucket_expiry, Time.now.to_i))
222
+ end
223
+ end
224
+
225
+ def assert_redis_key(expected_ttl, expected_bucket_number)
226
+ redis_key = "#{key}:#{expected_bucket_number}"
227
+ assert(@redis.get(redis_key), "the right bucket should be created")
228
+ assert_equal(expected_ttl, @redis.ttl(redis_key))
229
+ end
230
+ end