prefab-cloud-ruby 1.5.1 → 1.6.0.pre1
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 +4 -4
- data/CHANGELOG.md +4 -2
- data/Gemfile +2 -0
- data/Gemfile.lock +3 -0
- data/README.md +24 -15
- data/VERSION +1 -1
- data/lib/prefab/client.rb +2 -7
- data/lib/prefab/config_client.rb +12 -16
- data/lib/prefab/config_loader.rb +1 -1
- data/lib/prefab/config_value_unwrapper.rb +1 -1
- data/lib/prefab/context_shape_aggregator.rb +1 -2
- data/lib/prefab/criteria_evaluator.rb +3 -3
- data/lib/prefab/evaluation_summary_aggregator.rb +1 -2
- data/lib/prefab/example_contexts_aggregator.rb +1 -2
- data/lib/prefab/feature_flag_client.rb +2 -1
- data/lib/prefab/internal_logger.rb +36 -10
- data/lib/prefab/log_path_aggregator.rb +1 -2
- data/lib/prefab/logger_client.rb +34 -213
- data/lib/prefab/options.rb +0 -44
- data/lib/prefab/periodic_sync.rb +2 -1
- data/lib/prefab/prefab.rb +23 -1
- data/lib/prefab/yaml_config_parser.rb +1 -1
- data/lib/prefab-cloud-ruby.rb +2 -5
- data/prefab-cloud-ruby.gemspec +6 -8
- data/test/support/common_helpers.rb +14 -13
- data/test/support/mock_base_client.rb +0 -1
- data/test/test_client.rb +1 -10
- data/test/test_config_client.rb +1 -2
- data/test/test_context_shape_aggregator.rb +2 -5
- data/test/test_criteria_evaluator.rb +0 -4
- data/test/test_integration.rb +1 -1
- data/test/test_internal_logger.rb +25 -0
- data/test/test_log_path_aggregator.rb +5 -10
- data/test/test_logger.rb +57 -453
- data/test/test_logger_initialization.rb +1 -1
- metadata +18 -8
- data/lib/prefab/log_subscribers/action_controller_subscriber.rb +0 -55
- data/lib/prefab/logging/formatter_base.rb +0 -21
- data/lib/prefab/sse_logger.rb +0 -14
- data/lib/prefab/static_logger.rb +0 -29
- 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.
|
31
|
-
3.times { client.log.
|
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::
|
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, :
|
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
|
-
@
|
25
|
+
@client = new_client
|
26
|
+
@logger = @client.log
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
30
|
-
|
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
|
-
|
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
|
154
|
-
|
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
|
-
|
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
|
-
|
159
|
-
|
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
|
-
|
162
|
-
|
163
|
-
|
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
|
-
|
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
|
-
|
234
|
-
|
235
|
-
|
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
|
-
|
248
|
-
|
249
|
-
|
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
|
-
|
262
|
-
|
263
|
-
|
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.
|
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
|
-
|
339
|
-
|
340
|
-
|
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
|
-
|
353
|
-
|
354
|
-
|
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
|
-
|
367
|
-
|
368
|
-
|
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
|
-
|
381
|
-
|
382
|
-
|
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
|
393
|
-
|
394
|
-
|
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
|