prefab-cloud-ruby 1.4.5 → 1.6.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +3 -0
  5. data/README.md +24 -15
  6. data/VERSION +1 -1
  7. data/lib/prefab/client.rb +2 -7
  8. data/lib/prefab/config_client.rb +12 -16
  9. data/lib/prefab/config_loader.rb +1 -1
  10. data/lib/prefab/config_resolver.rb +0 -2
  11. data/lib/prefab/config_value_unwrapper.rb +1 -1
  12. data/lib/prefab/context.rb +1 -1
  13. data/lib/prefab/context_shape_aggregator.rb +1 -2
  14. data/lib/prefab/criteria_evaluator.rb +3 -3
  15. data/lib/prefab/evaluation_summary_aggregator.rb +1 -2
  16. data/lib/prefab/example_contexts_aggregator.rb +1 -2
  17. data/lib/prefab/feature_flag_client.rb +2 -1
  18. data/lib/prefab/internal_logger.rb +36 -10
  19. data/lib/prefab/log_path_aggregator.rb +1 -2
  20. data/lib/prefab/logger_client.rb +34 -213
  21. data/lib/prefab/options.rb +0 -42
  22. data/lib/prefab/periodic_sync.rb +2 -1
  23. data/lib/prefab/prefab.rb +23 -1
  24. data/lib/prefab/yaml_config_parser.rb +1 -1
  25. data/lib/prefab-cloud-ruby.rb +2 -5
  26. data/prefab-cloud-ruby.gemspec +7 -9
  27. data/test/support/common_helpers.rb +14 -13
  28. data/test/support/mock_base_client.rb +0 -1
  29. data/test/test_client.rb +1 -10
  30. data/test/test_config_client.rb +1 -2
  31. data/test/test_context_shape_aggregator.rb +2 -5
  32. data/test/test_criteria_evaluator.rb +0 -4
  33. data/test/test_integration.rb +1 -1
  34. data/test/test_internal_logger.rb +25 -0
  35. data/test/test_log_path_aggregator.rb +5 -10
  36. data/test/test_logger.rb +57 -453
  37. data/test/test_logger_initialization.rb +1 -1
  38. metadata +19 -9
  39. data/lib/prefab/log_subscribers/action_controller_subscriber.rb +0 -55
  40. data/lib/prefab/logging/formatter_base.rb +0 -21
  41. data/lib/prefab/sse_logger.rb +0 -14
  42. data/lib/prefab/static_logger.rb +0 -29
  43. data/test/test_action_controller.rb +0 -81
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class TestInternalLogger < Minitest::Test
6
+
7
+ def test_levels
8
+ logger_a = Prefab::InternalLogger.new(A)
9
+ logger_b = Prefab::InternalLogger.new(B)
10
+
11
+ assert_equal :warn, logger_a.level
12
+ assert_equal :warn, logger_b.level
13
+
14
+ Prefab::InternalLogger.using_prefab_log_filter!
15
+ assert_equal :trace, logger_a.level
16
+ assert_equal :trace, logger_b.level
17
+ end
18
+
19
+ end
20
+
21
+ class A
22
+ end
23
+
24
+ class B
25
+ end
@@ -25,10 +25,10 @@ class TestLogPathAggregator < Minitest::Test
25
25
 
26
26
  def test_sync
27
27
  Timecop.freeze do
28
- client = new_client(namespace: 'this.is.a.namespace')
28
+ client = new_client(namespace: 'this.is.a.namespace', allow_telemetry_in_local_mode: true)
29
29
 
30
- 2.times { client.log.info('here is a message') }
31
- 3.times { client.log.error('here is a message') }
30
+ 2.times { client.log.should_log? 1, "test.test_log_path_aggregator.test_sync"}
31
+ 3.times { client.log.should_log? 3, "test.test_log_path_aggregator.test_sync"}
32
32
 
33
33
  requests = wait_for_post_requests(client) do
34
34
  client.log_path_aggregator.send(:sync)
@@ -41,12 +41,6 @@ class TestLogPathAggregator < Minitest::Test
41
41
  assert_equal Prefab::TimeHelpers.now_in_ms, sent_logger.end_at
42
42
  assert_equal client.instance_hash, sent_logger.instance_hash
43
43
  assert_includes sent_logger.loggers, PrefabProto::Logger.new(logger_name: 'test.test_log_path_aggregator.test_sync', infos: 2, errors: 3)
44
- assert_includes sent_logger.loggers, PrefabProto::Logger.new(logger_name: 'cloud.prefab.client.client', debugs: 1) # spot test that internal logging is here too
45
-
46
- assert_logged [
47
- 'WARN 2023-08-09 15:18:12 -0400: cloud.prefab.client.configclient No success loading checkpoints',
48
- 'ERROR 2023-08-09 15:18:12 -0400: test.test_log_path_aggregator.test_sync here is a message'
49
- ]
50
44
  end
51
45
  end
52
46
 
@@ -54,8 +48,9 @@ class TestLogPathAggregator < Minitest::Test
54
48
 
55
49
  def new_client(overrides = {})
56
50
  super(**{
57
- prefab_datasources: Prefab::Options::DATASOURCES::ALL,
51
+ prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY,
58
52
  api_key: '123-development-yourapikey-SDK',
53
+ collect_max_paths: 1000,
59
54
  collect_sync_interval: 1000 # we'll trigger sync manually in our test
60
55
  }.merge(overrides))
61
56
  end
data/test/test_logger.rb CHANGED
@@ -20,165 +20,41 @@ class TestLogger < Minitest::Test
20
20
 
21
21
  def setup
22
22
  super
23
- Prefab::LoggerClient.send(:public, :get_path)
24
- Prefab::LoggerClient.send(:public, :get_loc_path)
23
+ Prefab::LoggerClient.send(:public, :class_path_name)
25
24
  Prefab::LoggerClient.send(:public, :level_of)
26
- @logger = Prefab::LoggerClient.new($stdout)
25
+ @client = new_client
26
+ @logger = @client.log
27
27
  end
28
28
 
29
- def test_get_path
30
- assert_equal 'test_l.foo_warn',
31
- @logger.get_path('/Users/jdwyah/Documents/workspace/RateLimitInc/prefab-cloud-ruby/lib/test_l.rb',
32
- 'foo_warn')
33
-
34
- assert_equal 'active_support.log_subscriber.info',
35
- @logger.get_path('/Users/jdwyah/.rvm/gems/ruby-2.3.3@forcerank/gems/activesupport-4.1.16/lib/active_support/log_subscriber.rb',
36
- 'info')
37
- assert_equal 'active_support.log_subscriber.info',
38
- @logger.get_path("/Users/jeffdwyer/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/activesupport-7.0.2.4/lib/active_support/log_subscriber.rb:130:in `info'",
39
- 'info')
40
- assert_equal 'unknown.info',
41
- @logger.get_path(nil,
42
- 'info')
43
- end
44
-
45
- def test_loc_resolution
46
- backtrace_location = Struct.new(:absolute_path, :base_label, :string) do
47
- def to_s
48
- string
49
- end
50
- end # https://ruby-doc.org/core-3.0.0/Thread/Backtrace/Location.html
51
-
52
- # verify that even if the Thread::Backtrace::Location does not have an absolute_location, we do our best
53
- assert_equal 'active_support.log_subscriber.info',
54
- @logger.get_loc_path(backtrace_location.new(nil,
55
- 'info',
56
- "/Users/jeffdwyer/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/activesupport-7.0.2.4/lib/active_support/log_subscriber.rb:130:in `info'"))
57
- assert_equal 'test_l.info',
58
- @logger.get_loc_path(backtrace_location.new('/Users/jdwyah/Documents/workspace/RateLimitInc/prefab-cloud-ruby/lib/test_l.rb',
59
- 'info',
60
- "/Users/jeffdwyer/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/activesupport-7.0.2.4/lib/active_support/log_subscriber.rb:130:in `info'"))
61
- end
62
-
63
- def test_level_of
29
+ def test_bootstrap_log_level
30
+ assert !Prefab.bootstrap_log_level(SemanticLogger::Log.new("TestLogger",:info))
64
31
  with_env('PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL', 'info') do
65
- # env var overrides the default level
66
- assert_equal ::Logger::INFO,
67
- @logger.level_of('app.models.user'), 'PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL is info'
68
-
69
- @logger.config_client = MockConfigClient.new({})
70
- assert_equal ::Logger::WARN,
71
- @logger.level_of('app.models.user'), 'default is warn'
72
-
73
- @logger.config_client = MockConfigClient.new('log-level.app' => :INFO)
74
- assert_equal ::Logger::INFO,
75
- @logger.level_of('app.models.user')
76
-
77
- @logger.config_client = MockConfigClient.new('log-level.app' => :DEBUG)
78
- assert_equal ::Logger::DEBUG,
79
- @logger.level_of('app.models.user')
80
-
81
- @logger.config_client = MockConfigClient.new('log-level.app' => :DEBUG,
82
- 'log-level.app.models' => :ERROR)
83
- assert_equal ::Logger::ERROR,
84
- @logger.level_of('app.models.user'), 'test leveling'
85
- end
86
- end
87
-
88
- def test_log_internal
89
- prefab, io = captured_logger
90
- prefab.log.log_internal(::Logger::WARN, 'test message', 'cloud.prefab.client.test.path')
91
- assert_logged io, 'WARN', "cloud.prefab.client.test.path", "test message"
92
- end
93
-
94
- def test_log_internal_unknown
95
- prefab, io = captured_logger
96
- prefab.log.log_internal(::Logger::UNKNOWN, 'test message', 'cloud.prefab.client.test.path')
97
- assert_logged io, 'ANY', "cloud.prefab.client.test.path", "test message"
98
- end
99
-
100
- def test_log_internal_silencing
101
- prefab, io = captured_logger
102
- prefab.log.silence do
103
- prefab.log.log_internal(::Logger::WARN, 'should not log', 'cloud.prefab.client.test.path')
104
- end
105
- prefab.log.log_internal(::Logger::WARN, 'should log', 'cloud.prefab.client.test.path')
106
- assert_logged io, 'WARN', "cloud.prefab.client.test.path", "should log"
107
- refute_logged io, 'should not log'
108
- end
109
-
110
- def test_log
111
- prefab, io = captured_logger
112
- prefab.log.log('test message', 'test.path', '', ::Logger::WARN)
113
- assert_logged io, 'WARN', "test.path", "test message"
114
- end
115
-
116
- def test_log_unknown
117
- prefab, io = captured_logger
118
- prefab.log.log('test message', 'test.path', '', ::Logger::UNKNOWN)
119
- assert_logged io, 'ANY', "test.path", "test message"
120
- end
121
-
122
- def test_log_silencing
123
- prefab, io = captured_logger
124
- prefab.log.silence do
125
- prefab.log.log('should not log', 'test.path', '', ::Logger::WARN)
32
+ assert Prefab.bootstrap_log_level(SemanticLogger::Log.new("TestLogger",:info))
126
33
  end
127
- prefab.log.log('should log', 'test.path', '', ::Logger::WARN)
128
- assert_logged io, 'WARN', "test.path", "should log"
129
- refute_logged io, 'should not log'
130
- end
131
-
132
- def test_logging_with_prefix
133
- prefix = 'my.own.prefix'
134
- message = 'this is a test'
135
-
136
- prefab, io = captured_logger(log_prefix: prefix)
137
-
138
- prefixed_logger = prefab.log
139
- prefixed_logger.error message
140
-
141
- assert_logged io, 'ERROR', "#{prefix}.test.test_logger.test_logging_with_prefix", message
142
- end
143
-
144
- def test_logging_without_a_progname
145
- prefab, io = captured_logger
146
- message = 'MY MESSAGE'
147
-
148
- prefab.log.error message
149
-
150
- assert_logged io, 'ERROR', 'test.test_logger.test_logging_without_a_progname', message
151
34
  end
152
35
 
153
- def test_logging_without_a_progname_or_message
154
- prefab, io = captured_logger
36
+ def test_level_of
37
+ @logger.config_client = MockConfigClient.new({})
38
+ assert_equal SemanticLogger::Levels.index(:warn),
39
+ @logger.level_of('app.models.user'), 'default is warn'
155
40
 
156
- prefab.log.error
41
+ @logger.config_client = MockConfigClient.new('log-level.app' => :INFO)
42
+ assert_equal SemanticLogger::Levels.index(:info),
43
+ @logger.level_of('app.models.user')
157
44
 
158
- assert_logged io, 'ERROR', 'test.test_logger.test_logging_without_a_progname_or_message', ''
159
- end
45
+ @logger.config_client = MockConfigClient.new('log-level.app' => :DEBUG)
46
+ assert_equal SemanticLogger::Levels.index(:debug),
47
+ @logger.level_of('app.models.user')
160
48
 
161
- def test_logging_with_a_progname
162
- prefab, io = captured_logger
163
- message = 'MY MESSAGE'
49
+ @logger.config_client = MockConfigClient.new('log-level.app' => :DEBUG,
50
+ 'log-level.app.models' => :ERROR)
51
+ assert_equal SemanticLogger::Levels.index(:error),
52
+ @logger.level_of('app.models.user'), 'test leveling'
164
53
 
165
- prefab.log.progname = 'MY_PROGNAME'
166
- prefab.log.error message
167
-
168
- assert_logged io, 'ERROR', 'MY_PROGNAME: test.test_logger.test_logging_with_a_progname', message
169
54
  end
170
55
 
171
- def test_logging_with_a_progname_and_no_message
172
- prefab, io = captured_logger
173
-
174
- prefab.log.progname = 'MY_PROGNAME'
175
- prefab.log.error
176
-
177
- assert_logged io, 'ERROR', 'MY_PROGNAME: test.test_logger.test_logging_with_a_progname_and_no_message', 'MY_PROGNAME'
178
- end
179
56
 
180
57
  def test_logging_with_criteria_on_top_level_key
181
- prefix = 'my.own.prefix'
182
58
 
183
59
  config = PrefabProto::Config.new(
184
60
  key: 'log-level',
@@ -224,57 +100,36 @@ class TestLogger < Minitest::Test
224
100
  ]
225
101
  )
226
102
 
227
- prefab, io = captured_logger(log_prefix: prefix)
228
-
229
- inject_config(prefab, config)
230
- inject_project_env_id(prefab, PROJECT_ENV_ID)
103
+ inject_config(@client, config)
104
+ inject_project_env_id(@client, PROJECT_ENV_ID)
231
105
 
232
106
  # without any context, the level should be the default for the env (info)
233
- prefab.with_context({}) do
234
- prefab.log.debug 'Test debug'
235
- refute_logged io, 'Test debug'
236
-
237
- prefab.log.info 'Test info'
238
- assert_logged io, 'INFO', "#{prefix}.test.test_logger.test_logging_with_criteria_on_top_level_key", 'Test info'
239
-
240
- prefab.log.error 'Test error'
241
- assert_logged io, 'ERROR', "#{prefix}.test.test_logger.test_logging_with_criteria_on_top_level_key", 'Test error'
107
+ @client.with_context({}) do
108
+ refute @logger.should_log?(SemanticLogger::Levels.index(:debug), "test.test_logger" )
109
+ assert @logger.should_log?(SemanticLogger::Levels.index(:info), "test.test_logger" )
110
+ assert @logger.should_log?(SemanticLogger::Levels.index(:error), "test.test_logger" )
242
111
  end
243
112
 
244
- reset_io(io)
245
113
 
246
114
  # with the wrong context, the level should be the default for the env (info)
247
- prefab.with_context(user: { email_suffix: 'yahoo.com' }) do
248
- prefab.log.debug 'Test debug'
249
- refute_logged io, 'Test debug'
250
-
251
- prefab.log.info 'Test info'
252
- assert_logged io, 'INFO', "#{prefix}.test.test_logger.test_logging_with_criteria_on_top_level_key", 'Test info'
253
-
254
- prefab.log.error 'Test error'
255
- assert_logged io, 'ERROR', "#{prefix}.test.test_logger.test_logging_with_criteria_on_top_level_key", 'Test error'
115
+ @client.with_context(user: { email_suffix: 'yahoo.com' }) do
116
+ refute @logger.should_log?(SemanticLogger::Levels.index(:debug), "test.test_logger" )
117
+ assert @logger.should_log?(SemanticLogger::Levels.index(:info), "test.test_logger" )
118
+ assert @logger.should_log?(SemanticLogger::Levels.index(:error), "test.test_logger" )
256
119
  end
257
120
 
258
- reset_io(io)
259
-
260
121
  # with the correct context, the level should be the desired value (debug)
261
- prefab.with_context(user: { email_suffix: 'hotmail.com' }) do
262
- prefab.log.debug 'Test debug'
263
- assert_logged io, 'DEBUG', "#{prefix}.test.test_logger.test_logging_with_criteria_on_top_level_key", 'Test debug'
264
-
265
- prefab.log.info 'Test info'
266
- assert_logged io, 'INFO', "#{prefix}.test.test_logger.test_logging_with_criteria_on_top_level_key", 'Test info'
267
-
268
- prefab.log.error 'Test error'
269
- assert_logged io, 'ERROR', "#{prefix}.test.test_logger.test_logging_with_criteria_on_top_level_key", 'Test error'
122
+ @client.with_context(user: { email_suffix: 'hotmail.com' }) do
123
+ assert @logger.should_log?(SemanticLogger::Levels.index(:debug), "test.test_logger" )
124
+ assert @logger.should_log?(SemanticLogger::Levels.index(:info), "test.test_logger" )
125
+ assert @logger.should_log?(SemanticLogger::Levels.index(:error), "test.test_logger" )
270
126
  end
271
127
  end
272
128
 
273
129
  def test_logging_with_criteria_on_key_path
274
- prefix = 'my.own.prefix'
275
130
 
276
131
  config = PrefabProto::Config.new(
277
- key: 'log-level.my.own.prefix.test.test_logger',
132
+ key: 'log-level.test.test_logger',
278
133
  rows: [
279
134
  DEFAULT_ROW,
280
135
 
@@ -328,294 +183,43 @@ class TestLogger < Minitest::Test
328
183
  )
329
184
  ]
330
185
  )
186
+ inject_config(@client, config)
187
+ inject_project_env_id(@client, PROJECT_ENV_ID)
331
188
 
332
- prefab, io = captured_logger(log_prefix: prefix)
333
-
334
- inject_config(prefab, config)
335
- inject_project_env_id(prefab, PROJECT_ENV_ID)
336
189
 
337
190
  # without any context, the level should be the default for the env (info)
338
- prefab.with_context({}) do
339
- prefab.log.debug 'Test debug'
340
- refute_logged io, 'Test debug'
341
-
342
- prefab.log.info 'Test info'
343
- assert_logged io, 'INFO', "#{prefix}.test.test_logger.test_logging_with_criteria_on_key_path", 'Test info'
344
-
345
- prefab.log.error 'Test error'
346
- assert_logged io, 'ERROR', "#{prefix}.test.test_logger.test_logging_with_criteria_on_key_path", 'Test error'
191
+ @client.with_context({ }) do
192
+ refute @logger.should_log?(SemanticLogger::Levels.index(:debug), "test.test_logger" )
193
+ assert @logger.should_log?(SemanticLogger::Levels.index(:info), "test.test_logger" )
194
+ assert @logger.should_log?(SemanticLogger::Levels.index(:error), "test.test_logger" )
347
195
  end
348
196
 
349
- reset_io(io)
350
-
351
197
  # with the wrong context, the level should be the default for the env (info)
352
- prefab.with_context(user: { email_suffix: 'yahoo.com' }) do
353
- prefab.log.debug 'Test debug'
354
- refute_logged io, 'Test debug'
355
-
356
- prefab.log.info 'Test info'
357
- assert_logged io, 'INFO', "#{prefix}.test.test_logger.test_logging_with_criteria_on_key_path", 'Test info'
358
-
359
- prefab.log.error 'Test error'
360
- assert_logged io, 'ERROR', "#{prefix}.test.test_logger.test_logging_with_criteria_on_key_path", 'Test error'
198
+ @client.with_context(user: { email_suffix: 'yahoo.com' }) do
199
+ refute @logger.should_log?(SemanticLogger::Levels.index(:debug), "test.test_logger" )
200
+ assert @logger.should_log?(SemanticLogger::Levels.index(:info), "test.test_logger" )
201
+ assert @logger.should_log?(SemanticLogger::Levels.index(:error), "test.test_logger" )
361
202
  end
362
203
 
363
- reset_io(io)
364
-
365
204
  # with the correct context, the level should be the desired value (debug)
366
- prefab.with_context(user: { email_suffix: 'hotmail.com' }) do
367
- prefab.log.debug 'Test debug'
368
- assert_logged io, 'DEBUG', "#{prefix}.test.test_logger.test_logging_with_criteria_on_key_path", 'Test debug'
369
-
370
- prefab.log.info 'Test info'
371
- assert_logged io, 'INFO', "#{prefix}.test.test_logger.test_logging_with_criteria_on_key_path", 'Test info'
372
-
373
- prefab.log.error 'Test error'
374
- assert_logged io, 'ERROR', "#{prefix}.test.test_logger.test_logging_with_criteria_on_key_path", 'Test error'
205
+ @client.with_context(user: { email_suffix: 'hotmail.com' }) do
206
+ assert @logger.should_log?(SemanticLogger::Levels.index(:debug), "test.test_logger" )
207
+ assert @logger.should_log?(SemanticLogger::Levels.index(:info), "test.test_logger" )
208
+ assert @logger.should_log?(SemanticLogger::Levels.index(:error), "test.test_logger" )
375
209
  end
376
210
 
377
- reset_io(io)
378
-
379
211
  # with the correct lookup key
380
- prefab.with_context(user: { tracking_id: 'user:4567' }) do
381
- prefab.log.debug 'Test debug'
382
- assert_logged io, 'DEBUG', "#{prefix}.test.test_logger.test_logging_with_criteria_on_key_path", 'Test debug'
383
-
384
- prefab.log.info 'Test info'
385
- assert_logged io, 'INFO', "#{prefix}.test.test_logger.test_logging_with_criteria_on_key_path", 'Test info'
386
-
387
- prefab.log.error 'Test error'
388
- assert_logged io, 'ERROR', "#{prefix}.test.test_logger.test_logging_with_criteria_on_key_path", 'Test error'
212
+ @client.with_context(user: { tracking_id: 'user:4567' }) do
213
+ assert @logger.should_log?(SemanticLogger::Levels.index(:debug), "test.test_logger" )
214
+ assert @logger.should_log?(SemanticLogger::Levels.index(:info), "test.test_logger" )
215
+ assert @logger.should_log?(SemanticLogger::Levels.index(:info), "test.test_logger" )
389
216
  end
390
217
  end
391
218
 
392
- def test_logging_with_a_block
393
- prefab, io = captured_logger
394
- message = 'MY MESSAGE'
395
-
396
- prefab.log.error do
397
- message
398
- end
399
-
400
- prefab.log.info do
401
- raise 'THIS WILL NEVER BE EVALUATED'
402
- end
403
-
404
- assert_logged io, 'ERROR', 'test.test_logger.test_logging_with_a_block', message
219
+ def test_class_path_name
220
+ assert_equal "minitest.test.test_logger", @logger.class_path_name("TestLogger")
221
+ assert_equal "prefab.logger_client", @logger.class_path_name("Prefab::LoggerClient")
222
+ assert_equal "semantic_logger.logger.prefab.internal_logger", @logger.class_path_name("Prefab::InternalLogger")
405
223
  end
406
224
 
407
- def test_add_context_keys
408
- assert @logger.context_keys.empty?
409
- @logger.add_context_keys("user.name", "role.admin", "company.name")
410
-
411
- assert @logger.context_keys.to_a == %w(user.name role.admin company.name)
412
- end
413
-
414
- def test_context_keys_are_a_set
415
- @logger.add_context_keys("user.name", "role.admin", "company.name")
416
-
417
- assert @logger.context_keys.to_a == %w(user.name role.admin company.name)
418
-
419
- @logger.add_context_keys("user.name", "user.role")
420
-
421
- assert @logger.context_keys.to_a == %w(user.name role.admin company.name user.role)
422
- end
423
-
424
- def test_with_context_keys
425
- @logger.add_context_keys("company.name")
426
-
427
- assert @logger.context_keys.to_a == %w(company.name)
428
-
429
- @logger.with_context_keys("user.name", "role.admin") do
430
- assert @logger.context_keys.to_a == %w(company.name user.name role.admin)
431
- end
432
-
433
- assert @logger.context_keys.to_a == %w(company.name)
434
- end
435
-
436
- def test_structured_logging
437
- prefab, io = captured_logger
438
- message = 'HELLO'
439
-
440
- prefab.log.error message, user: "michael", id: 123
441
-
442
- assert_logged io, 'ERROR', 'test.test_logger.test_structured_logging', "#{message} id=123 user=michael"
443
- end
444
-
445
- def test_structured_json_logging
446
- prefab, io = captured_logger(log_formatter: Prefab::Options::JSON_LOG_FORMATTER)
447
- message = 'HELLO'
448
-
449
- prefab.log.error message, user: "michael", id: 123
450
-
451
- log_data = JSON.parse(io.string)
452
- assert log_data["message"] == message
453
- assert log_data["user"] == "michael"
454
- assert log_data["id"] == 123
455
- end
456
-
457
- def test_structured_internal_logging
458
- prefab, io = captured_logger
459
-
460
- prefab.log.log_internal(::Logger::WARN, 'test', 'cloud.prefab.client.test.path', user: "michael")
461
-
462
- assert_logged io, 'WARN', 'cloud.prefab.client.test.path', "test user=michael"
463
- end
464
-
465
- def test_structured_block_logger
466
- prefab, io = captured_logger
467
- message = 'MY MESSAGE'
468
-
469
- prefab.log.error user: "michael" do
470
- message
471
- end
472
-
473
- assert_logged io, 'ERROR', 'test.test_logger.test_structured_block_logger', "#{message} user=michael"
474
- end
475
-
476
- def test_structured_logger_with_context_keys
477
- prefab, io = captured_logger
478
-
479
- prefab.with_context({user: {name: "michael", job: "developer", admin: false}, company: { name: "Prefab" }}) do
480
-
481
- prefab.log.add_context_keys "user.name", "company.name", "user.admin"
482
-
483
- prefab.log.error "UH OH"
484
-
485
- assert_logged io, 'ERROR', 'test.test_logger.test_structured_logger_with_context_keys',
486
- "UH OH company.name=Prefab user.admin=false user.name=michael"
487
- end
488
- end
489
-
490
- def test_structured_logger_with_context_keys_ignores_nils
491
- prefab, io = captured_logger
492
-
493
- prefab.with_context({user: {name: "michael", job: "developer"}, company: { name: "Prefab" }}) do
494
-
495
- prefab.log.add_context_keys "user.name", "company.name", "user.admin"
496
-
497
- prefab.log.error "UH OH"
498
-
499
- assert_logged io, 'ERROR', 'test.test_logger.test_structured_logger_with_context_keys_ignores_nils',
500
- "UH OH company.name=Prefab user.name=michael"
501
- end
502
- end
503
-
504
- def test_structured_logger_with_context_keys_and_log_hash
505
- prefab, io = captured_logger
506
-
507
- prefab.with_context({user: {name: "michael", job: "developer", admin: false}, company: { name: "Prefab" }}) do
508
-
509
- prefab.log.add_context_keys "user.name", "company.name", "user.admin"
510
-
511
- prefab.log.error "UH OH", user_id: 6
512
-
513
- assert_logged io, 'ERROR', 'test.test_logger.test_structured_logger_with_context_keys_and_log_hash',
514
- "UH OH company.name=Prefab user.admin=false user.name=michael user_id=6"
515
- end
516
-
517
- end
518
-
519
- def test_structured_logger_with_context_keys_block
520
- prefab, io = captured_logger
521
-
522
- prefab.with_context({user: {name: "michael", job: "developer", admin: false}, company: { name: "Prefab" }}) do
523
-
524
- prefab.log.add_context_keys "user.name"
525
-
526
- prefab.log.error "UH OH"
527
-
528
- assert_logged io, 'ERROR', 'test.test_logger.test_structured_logger_with_context_keys_block',
529
- 'UH OH user.name=michael'
530
-
531
- prefab.log.with_context_keys("company.name") do
532
- prefab.log.error "UH OH"
533
-
534
- assert_logged io, 'ERROR', 'test.test_logger.test_structured_logger_with_context_keys_block',
535
- 'UH OH company.name=Prefab user.name=michael'
536
- end
537
-
538
- prefab.log.error "UH OH"
539
-
540
- assert_logged io, 'ERROR', 'test.test_logger.test_structured_logger_with_context_keys_block',
541
- 'UH OH user.name=michael'
542
- end
543
- end
544
-
545
- def test_context_key_threads
546
- prefab, io = captured_logger
547
-
548
- threads = []
549
- 1000.times.map do |i|
550
- threads << Thread.new do
551
- prefab.with_context({test: {"thread_#{i}": "thread_#{i}"}}) do
552
- prefab.log.add_context_keys "test.thread_#{i}"
553
- prefab.log.error "UH OH"
554
- assert_logged io, 'ERROR', 'test.test_logger.test_context_key_threads',
555
- "UH OH test.thread_#{i}=thread_#{i}"
556
- end
557
- end
558
- end
559
- threads.each { |thr| thr.join }
560
- end
561
-
562
- def test_tagged
563
- prefab, io = captured_logger
564
-
565
- prefab.log.tagged([[]]) do # rails sends some of these
566
- prefab.log.tagged("outside") do
567
- prefab.log.tagged("nested", "tag2") do
568
- prefab.log.error "msg"
569
- assert_logged io, 'ERROR', 'test.test_logger.test_tagged',
570
- 'msg log.tags=\["outside", "nested", "tag2"\]'
571
- end
572
- end
573
- end
574
- end
575
-
576
- def test_req_tagged
577
- prefab, io = captured_logger
578
- prefab.log.tagged("tag-1").error "first"
579
- assert_logged io, 'ERROR', 'test.test_logger.test_req_tagged',
580
- 'first req.tags=\["tag-1"\]'
581
- reset_io(io)
582
-
583
- prefab.log.tagged("tag-2").error "2nd"
584
- assert_logged io, 'ERROR', 'test.test_logger.test_req_tagged',
585
- '2nd req.tags=\["tag-1", "tag-2"\]'
586
- prefab.log.flush
587
-
588
- prefab.log.tagged("tag-3").error "3rd"
589
- assert_logged io, 'ERROR', 'test.test_logger.test_req_tagged',
590
- '3rd req.tags=\["tag-3"\]'
591
- prefab.log.flush
592
- end
593
-
594
- private
595
-
596
- def assert_logged(logged_io, level, path, message)
597
- assert_match(/#{level}\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-+]?\d+:\s+#{path} #{message}\n/, logged_io.string)
598
- end
599
-
600
- def refute_logged(logged_io, message)
601
- refute_match(/#{message}/, logged_io.string)
602
- end
603
-
604
- def captured_logger(options = {})
605
- io = StringIO.new
606
- options = Prefab::Options.new(**options.merge(
607
- logdev: io,
608
- prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY
609
- ))
610
- prefab = Prefab::Client.new(options)
611
-
612
- [prefab, io]
613
- end
614
-
615
- def reset_io(io)
616
- io.close
617
- io.reopen
618
-
619
- assert_equal '', io.string
620
- end
621
225
  end
@@ -6,7 +6,7 @@ class TestLoggerInitialization < Minitest::Test
6
6
 
7
7
  def test_init_out_of_order
8
8
  # assert nothing blows up
9
- Prefab::LoggerClient.instance.info "anything"
9
+ Prefab.log_filter
10
10
  end
11
11
 
12
12
  end