berkeley_library-logging 0.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.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +388 -0
  3. data/.idea/inspectionProfiles/Project_Default.xml +17 -0
  4. data/.idea/logging.iml +139 -0
  5. data/.idea/modules.xml +8 -0
  6. data/.idea/vcs.xml +6 -0
  7. data/.rubocop.yml +271 -0
  8. data/.ruby-version +1 -0
  9. data/.simplecov +4 -0
  10. data/.travis.yml +9 -0
  11. data/CHANGES.md +12 -0
  12. data/Dockerfile +57 -0
  13. data/Gemfile +3 -0
  14. data/Jenkinsfile +21 -0
  15. data/LICENSE.md +21 -0
  16. data/README.md +47 -0
  17. data/Rakefile +31 -0
  18. data/berkeley_library-logging.gemspec +47 -0
  19. data/docker-compose.yml +15 -0
  20. data/lib/berkeley_library/logging.rb +38 -0
  21. data/lib/berkeley_library/logging/configurator.rb +41 -0
  22. data/lib/berkeley_library/logging/env.rb +38 -0
  23. data/lib/berkeley_library/logging/events.rb +39 -0
  24. data/lib/berkeley_library/logging/formatters.rb +54 -0
  25. data/lib/berkeley_library/logging/logger.rb +12 -0
  26. data/lib/berkeley_library/logging/loggers.rb +79 -0
  27. data/lib/berkeley_library/logging/module_info.rb +16 -0
  28. data/lib/berkeley_library/logging/railtie.rb +15 -0
  29. data/lib/berkeley_library/logging/tagged_logging_extensions.rb +21 -0
  30. data/rakelib/.rubocop.yml +4 -0
  31. data/rakelib/bundle.rake +8 -0
  32. data/rakelib/coverage.rake +36 -0
  33. data/rakelib/gem.rake +56 -0
  34. data/rakelib/rubocop.rake +14 -0
  35. data/rakelib/spec.rake +31 -0
  36. data/spec/.rubocop.yml +27 -0
  37. data/spec/rails/ucblit/logging/configurator_spec.rb +101 -0
  38. data/spec/rails/ucblit/logging/env_spec.rb +25 -0
  39. data/spec/rails/ucblit/logging/formatters_spec.rb +44 -0
  40. data/spec/rails/ucblit/logging/loggers_spec.rb +117 -0
  41. data/spec/rails/ucblit/logging/railtie_spec.rb +46 -0
  42. data/spec/rails/ucblit/logging_spec.rb +132 -0
  43. data/spec/rails_helper.rb +15 -0
  44. data/spec/spec_helper.rb +34 -0
  45. data/spec/standalone/ucblit/logging/configurator_spec.rb +103 -0
  46. data/spec/standalone/ucblit/logging/formatters_spec.rb +44 -0
  47. data/spec/standalone/ucblit/logging/loggers_spec.rb +278 -0
  48. data/spec/standalone/ucblit/logging_spec.rb +133 -0
  49. data/spec/standalone_helper.rb +25 -0
  50. metadata +363 -0
@@ -0,0 +1,46 @@
1
+ require 'rails_helper'
2
+
3
+ module BerkeleyLibrary
4
+ module Logging
5
+ describe Railtie do
6
+ attr_reader :app
7
+ attr_reader :config
8
+
9
+ before(:each) do
10
+ @app = Class.new(Rails::Application).new
11
+ allow(Rails).to receive(:application).and_return(app)
12
+ @config = app.config
13
+ end
14
+
15
+ describe 'initializer' do
16
+ attr_reader :logging_initializer
17
+ attr_reader :bootstrap_logger_initializer
18
+
19
+ before(:each) do
20
+ expected_file, _line = Module.const_source_location(BerkeleyLibrary::Logging::Railtie.name)
21
+ @logging_initializer = app.initializers.find do |init|
22
+ block = init.block
23
+ file, _line = block.source_location
24
+ file == expected_file
25
+ end
26
+ @bootstrap_logger_initializer = app.initializers.find { |init| init.name == :initialize_logger }
27
+ end
28
+
29
+ it 'is added to the Rails application' do
30
+ expect(logging_initializer).not_to be_nil
31
+ end
32
+
33
+ it 'runs before the bootstrap logger initializer' do
34
+ expect(logging_initializer.before).to eq(bootstrap_logger_initializer.name)
35
+ end
36
+
37
+ it 'sets the logger' do
38
+ logging_initializer.run(app)
39
+ bootstrap_logger_initializer.run(app)
40
+
41
+ expect(Rails.logger).to be_a(BerkeleyLibrary::Logging::Logger)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,132 @@
1
+ require 'rails_helper'
2
+
3
+ module BerkeleyLibrary
4
+ describe Logging do
5
+
6
+ def logger_defined?
7
+ Logging.instance_variable_defined?(:@logger)
8
+ end
9
+
10
+ def reset_logger!
11
+ Logging.instance_variable_set(:@logger, @logging_logger_orig)
12
+ end
13
+
14
+ def undefine_logger!
15
+ Logging.send(:remove_instance_variable, :@logger) if logger_defined?
16
+ end
17
+
18
+ def new_mock_logger
19
+ mock_logger_class = Class.new do
20
+ def respond_to?(*args)
21
+ %i[debug info warn error].include?(args[0].to_sym) || super
22
+ end
23
+ end
24
+
25
+ mock_logger_class.new
26
+ end
27
+
28
+ before(:each) do
29
+ @rails_logger_orig = Rails.logger
30
+ Rails.logger = new_mock_logger
31
+
32
+ if (@logger_was_defined = logger_defined?)
33
+ @logging_logger_orig = Logging.instance_variable_get(:@logger)
34
+ undefine_logger!
35
+ end
36
+ end
37
+
38
+ after(:each) do
39
+ @logger_was_defined ? reset_logger! : undefine_logger!
40
+ Rails.logger = @rails_logger_orig
41
+ end
42
+
43
+ describe 'class methods' do
44
+ describe :logger do
45
+ it 'returns the default logger' do
46
+ logger = Logging::Loggers.default_logger
47
+ expect(Logging.logger).to be(logger)
48
+ end
49
+
50
+ it 'returns a set logger' do
51
+ logger = new_mock_logger
52
+ Logging.logger = logger
53
+ expect(Logging.logger).to be(logger)
54
+ end
55
+
56
+ end
57
+
58
+ describe :logger= do
59
+ it 'rejects a non-logger' do
60
+ original_logger = Logging.logger
61
+ expect { Logging.logger = Object.new }.to raise_error(ArgumentError)
62
+ expect(Logging.logger).to be(original_logger)
63
+ end
64
+
65
+ it 'can be reset to default with nil' do
66
+ default_logger = Logging::Loggers.default_logger
67
+ Logging.logger = new_mock_logger
68
+ Logging.logger = nil
69
+ expect(Logging.logger).to be(default_logger)
70
+ end
71
+ end
72
+ end
73
+
74
+ describe 'included' do
75
+ attr_reader :logificator
76
+
77
+ before(:each) do
78
+ @logificator = Object.new
79
+ @logificator.singleton_class.include(Logging)
80
+ end
81
+
82
+ describe :logger do
83
+ it 'returns the default logger' do
84
+ logger = Logging::Loggers.default_logger
85
+ expect(logificator.logger).to be(logger)
86
+ end
87
+
88
+ it 'returns a set logger' do
89
+ logger = new_mock_logger
90
+ logificator.logger = logger
91
+ expect(logificator.logger).to be(logger)
92
+ end
93
+
94
+ it 'returns a logger set via the class method' do
95
+ logger = new_mock_logger
96
+ Logging.logger = logger
97
+ expect(logificator.logger).to be(logger)
98
+ end
99
+ end
100
+
101
+ describe :logger= do
102
+ it 'sets the shared logger via the class method' do
103
+ logger = new_mock_logger
104
+ logificator.logger = logger
105
+ expect(Logging.logger).to be(logger)
106
+ end
107
+
108
+ it 'sets a shared logger accessible via another including class' do
109
+ logger = new_mock_logger
110
+ Object.new.tap do |logificator2|
111
+ logificator2.singleton_class.send(:include, Logging)
112
+ logificator2.logger = logger
113
+ end
114
+ expect(logificator.logger).to be(logger)
115
+ end
116
+
117
+ it 'rejects a non-logger' do
118
+ original_logger = logificator.logger
119
+ expect { logificator.logger = Object.new }.to raise_error(ArgumentError)
120
+ expect(logificator.logger).to be(original_logger)
121
+ end
122
+
123
+ it 'can be reset to default with nil' do
124
+ default_logger = Logging::Loggers.default_logger
125
+ logificator.logger = new_mock_logger
126
+ logificator.logger = nil
127
+ expect(logificator.logger).to be(default_logger)
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,15 @@
1
+ # ------------------------------------------------------------
2
+ # RSpec
3
+
4
+ require 'spec_helper'
5
+
6
+ # ------------------------------------------------------------
7
+ # Rails
8
+
9
+ require 'rails'
10
+ Rails.env = 'test'
11
+
12
+ # ------------------------------------------------------------
13
+ # Code under test
14
+
15
+ require 'berkeley_library/logging'
@@ -0,0 +1,34 @@
1
+ # ------------------------------------------------------------
2
+ # SimpleCov
3
+
4
+ if ENV['COVERAGE']
5
+ require 'simplecov'
6
+
7
+ spec_root = File.realpath(__dir__)
8
+ spec_group_re = %r{(?<=^#{spec_root}/)[^/]+(?=/)}
9
+
10
+ RSpec.configure do |config|
11
+ config.before(:each) do |example|
12
+ abs_path = File.realpath(example.metadata[:absolute_file_path])
13
+ match_data = spec_group_re.match(abs_path)
14
+ raise ArgumentError, "Unable to determine group for example at #{abs_path}" unless match_data
15
+
16
+ spec_group = match_data[0]
17
+ SimpleCov.command_name(spec_group)
18
+ SimpleCov.coverage_dir("artifacts/simplecov/#{spec_group}")
19
+ end
20
+ end
21
+ end
22
+
23
+ # ------------------------------------------------------------
24
+ # RSpec
25
+
26
+ RSpec.configure do |config|
27
+ config.color = true
28
+ config.tty = true
29
+ config.formatter = :documentation
30
+ config.mock_with :rspec do |mocks|
31
+ mocks.verify_partial_doubles = true
32
+ end
33
+ config.shared_context_metadata_behavior = :apply_to_host_groups
34
+ end
@@ -0,0 +1,103 @@
1
+ require 'standalone_helper'
2
+ require 'ostruct'
3
+ require 'lograge'
4
+
5
+ module BerkeleyLibrary
6
+ module Logging
7
+ describe Configurator do
8
+ describe :configure! do
9
+ attr_reader :config
10
+
11
+ before(:each) do
12
+ @stdout_orig = $stdout
13
+ $stdout = StringIO.new
14
+
15
+ @config = OpenStruct.new
16
+ config.lograge = Lograge::OrderedOptions.new
17
+ end
18
+
19
+ after(:each) do
20
+ $stdout = @stdout_orig
21
+ end
22
+
23
+ it 'sets the logger' do
24
+ Configurator.configure(config)
25
+ expect(config.logger).to be_a(Logging::Logger)
26
+ end
27
+
28
+ describe :configure_lograge! do
29
+ it 'enables Lograge' do
30
+ Configurator.configure(config)
31
+ lograge = config.lograge
32
+ expect(lograge.enabled).to eq(true)
33
+ end
34
+
35
+ it 'extracts request info from log events' do
36
+ Configurator.configure(config)
37
+ lograge = config.lograge
38
+
39
+ request_headers = {
40
+ 'HTTP_REFERER' => 'value from HTTP_REFERER',
41
+ 'action_dispatch.request_id' => 'value from action_dispatch.request_id',
42
+ 'action_dispatch.remote_ip' => 'value from action_dispatch.remote_ip',
43
+ 'REMOTE_ADDR' => 'value from REMOTE_ADDR',
44
+ 'HTTP_X_FORWARDED_FOR' => 'value from HTTP_X_FORWARDED_FOR',
45
+ 'HTTP_FORWARDED' => 'value from HTTP_FORWARDED'
46
+ }
47
+
48
+ expected_header_map = {
49
+ referer: 'HTTP_REFERER',
50
+ request_id: 'action_dispatch.request_id',
51
+ remote_ip: 'action_dispatch.remote_ip',
52
+ remote_addr: 'REMOTE_ADDR',
53
+ x_forwarded_for: 'HTTP_X_FORWARDED_FOR',
54
+ forwarded: 'HTTP_FORWARDED'
55
+ }
56
+
57
+ event = instance_double(ActiveSupport::Notifications::Event)
58
+ allow(event).to receive(:payload).and_return({ headers: request_headers })
59
+
60
+ custom_options = lograge.custom_options
61
+ data = custom_options.call(event)
62
+ expect(data).to be_a(Hash)
63
+ expect(data[:time]).to be_a(Time) # TODO: check for accuracy
64
+ expected_header_map.each { |xh, rh| expect(data[xh]).to eq(request_headers[rh]) }
65
+ end
66
+
67
+ it 'formats Lograge data as a hash' do
68
+ Configurator.configure(config)
69
+ lograge = config.lograge
70
+
71
+ formatter = lograge.formatter
72
+ expect(formatter.call(nil)).to eq({ msg: 'Request', request: {} })
73
+ expect(formatter.call('elvis')).to eq({ msg: 'Request', request: { msg: 'elvis' } })
74
+ some_hash = { foo: 'bar' }
75
+ expect(formatter.call(some_hash)).to eq({ msg: 'Request', request: some_hash })
76
+ end
77
+ end
78
+
79
+ describe 'Webpacker' do
80
+ it 'works if Webpacker is not present' do
81
+ expect(Object.const_defined?(:Webpacker)).to eq(false) # just to be sure
82
+ expect { Configurator.configure(config) }.not_to raise_error
83
+ end
84
+
85
+ it 'sets the Webpacker logger if Webpacker is present' do
86
+ module ::Webpacker
87
+ module Instance
88
+ class << self
89
+ attr_accessor :logger
90
+ end
91
+ end
92
+ end
93
+
94
+ Configurator.configure(config)
95
+ expect(Webpacker::Instance.logger).to eq(config.logger)
96
+ ensure
97
+ Object.send(:remove_const, :Webpacker) if defined?(Webpacker)
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,44 @@
1
+ require 'standalone_helper'
2
+ require 'json'
3
+ require 'berkeley_library/logging'
4
+
5
+ module BerkeleyLibrary
6
+ module Logging
7
+ describe Formatters do
8
+ describe :new_json_formatter do
9
+ it 'supports tagged logging' do
10
+ out = StringIO.new
11
+ logger = Logger.new(out)
12
+ logger.formatter = Formatters.new_json_formatter
13
+
14
+ logger = ActiveSupport::TaggedLogging.new(logger)
15
+
16
+ expected_tag = 'hello'
17
+ expected_msg = 'this is a test'
18
+
19
+ logger.tagged(expected_tag) { logger.info(expected_msg) }
20
+
21
+ logged_json = JSON.parse(out.string)
22
+ expect(logged_json['msg']).to eq(expected_msg)
23
+ expect(logged_json['tags']).to eq([expected_tag])
24
+ end
25
+ end
26
+
27
+ describe :ensure_hash do
28
+ it 'returns an empty hash for nil' do
29
+ expect(Formatters.ensure_hash(nil)).to eq({})
30
+ end
31
+
32
+ it 'returns the original hash for a hash' do
33
+ original_hash = { a: 1, b: 2 }
34
+ expect(Formatters.ensure_hash(original_hash)).to equal(original_hash)
35
+ end
36
+
37
+ it 'wraps anything else in a hash' do
38
+ message = 'this is a message'
39
+ expect(Formatters.ensure_hash(message)).to eq({ msg: message })
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,278 @@
1
+ require 'standalone_helper'
2
+ require 'json'
3
+
4
+ module BerkeleyLibrary
5
+ module Logging
6
+ describe Loggers do
7
+ attr_reader :out
8
+
9
+ # rubocop:disable Lint/ConstantDefinitionInBlock
10
+ before(:each) do
11
+ @out = StringIO.new
12
+ class ::TestError < StandardError; end
13
+ end
14
+ # rubocop:enable Lint/ConstantDefinitionInBlock
15
+
16
+ after(:each) do
17
+ Object.send(:remove_const, :TestError)
18
+ end
19
+
20
+ describe :new_json_logger do
21
+ it 'supports tagged logging' do
22
+ logger = Loggers.new_json_logger(out)
23
+ logger = ActiveSupport::TaggedLogging.new(logger)
24
+
25
+ expected_tag = 'hello'
26
+ expected_msg = 'this is a test'
27
+
28
+ logger.tagged(expected_tag) { logger.info(expected_msg) }
29
+
30
+ logged_json = JSON.parse(out.string)
31
+ expect(logged_json['msg']).to eq(expected_msg)
32
+ expect(logged_json['tags']).to eq([expected_tag])
33
+ end
34
+
35
+ it 'logs an error as a hash' do
36
+ msg = 'Help I am trapped in a unit test'
37
+
38
+ begin
39
+ raise TestError, msg
40
+ rescue TestError => e
41
+ ex = e
42
+ Loggers.new_json_logger(out).error(e)
43
+ end
44
+
45
+ logged_json = JSON.parse(out.string)
46
+ expect(logged_json['msg']).to eq(msg)
47
+ err_json = logged_json['err']
48
+ expect(err_json).to be_a(Hash)
49
+ expect(err_json['name']).to eq(TestError.name)
50
+ expect(err_json['message']).to eq(msg)
51
+
52
+ err_stack = err_json['stack']
53
+ backtrace = ex.backtrace
54
+ expect(backtrace).not_to be_nil # just to be sure
55
+ backtrace.each do |line|
56
+ expect(err_stack).to include(line)
57
+ end
58
+ end
59
+ end
60
+
61
+ describe :default_logger do
62
+ it 'returns a readable $stdout logger' do
63
+ logger = Loggers.default_logger
64
+ expect(logger).to be_a(Logger)
65
+ expect(logger.formatter).to be_a(Ougai::Formatters::Readable)
66
+
67
+ logdev = logger.instance_variable_get(:@logdev)
68
+ expect(logdev).to be_a(::Logger::LogDevice)
69
+ expect(logdev.dev).to eq($stdout)
70
+ end
71
+
72
+ describe 'errors' do
73
+ it 'logs an error alone with cause and backtrace' do
74
+ msg = 'Help I am trapped in a unit test'
75
+
76
+ begin
77
+ raise TestError, msg
78
+ rescue TestError => e
79
+ ex = e
80
+ Loggers.new_readable_logger(out).error(e)
81
+ end
82
+
83
+ logged_txt = out.string
84
+ expect(logged_txt).to include(msg)
85
+ expect(logged_txt).to include(TestError.name)
86
+ backtrace = ex.backtrace
87
+ expect(backtrace).not_to be_nil # just to be sure
88
+ backtrace.each do |line|
89
+ expect(logged_txt).to include(line)
90
+ end
91
+ end
92
+
93
+ end
94
+
95
+ describe 'messages with text and data' do
96
+ it 'logs an arbitrary hash in a reasonable way' do
97
+ out = StringIO.new
98
+ msg_txt = 'message text'
99
+ msg_h = {
100
+ foo: 'Foo',
101
+ bar: 'Bar',
102
+ baz: 'Baz'
103
+ }
104
+ Loggers.new_readable_logger(out).info(msg_txt, msg_h)
105
+
106
+ logged_txt = out.string
107
+ expect(logged_txt).to include(msg_txt)
108
+ msg_h.each do |k, v|
109
+ expect(logged_txt).to include(k.inspect)
110
+ expect(logged_txt).to include(v.inspect)
111
+ end
112
+ end
113
+
114
+ it 'logs something with #to_hash as a hash' do
115
+ out = StringIO.new
116
+ msg_txt = 'message text'
117
+ msg_h = {
118
+ foo: 'Foo',
119
+ bar: 'Bar',
120
+ baz: 'Baz'
121
+ }
122
+ msg_obj = Object.new
123
+ msg_obj.singleton_class.define_method(:to_hash) { msg_h }
124
+
125
+ Loggers.new_readable_logger(out).info(msg_txt, msg_obj)
126
+
127
+ logged_txt = out.string
128
+ expect(logged_txt).to include(msg_txt)
129
+ msg_h.each do |k, v|
130
+ expect(logged_txt).to include(k.inspect)
131
+ expect(logged_txt).to include(v.inspect)
132
+ end
133
+ end
134
+
135
+ it 'logs an error with cause and backtrace' do
136
+ msg_txt = 'message text'
137
+ ex_msg = 'Help I am trapped in a unit test'
138
+
139
+ begin
140
+ raise TestError, ex_msg
141
+ rescue TestError => e
142
+ ex = e
143
+ Loggers.new_readable_logger(out).error(msg_txt, e)
144
+ end
145
+
146
+ logged_txt = out.string
147
+ expect(logged_txt).to include(msg_txt)
148
+ expect(logged_txt).to include(ex_msg)
149
+ expect(logged_txt).to include(TestError.name)
150
+ backtrace = ex.backtrace
151
+ expect(backtrace).not_to be_nil # just to be sure
152
+ backtrace.each do |line|
153
+ expect(logged_txt).to include(line)
154
+ end
155
+ end
156
+
157
+ end
158
+
159
+ describe 'messages with data and no text' do
160
+ it 'logs an arbitrary hash in a reasonable way' do
161
+ out = StringIO.new
162
+ msg_h = {
163
+ foo: 'Foo',
164
+ bar: 'Bar',
165
+ baz: 'Baz'
166
+ }
167
+ Loggers.new_readable_logger(out).info(msg_h)
168
+ logged_txt = out.string
169
+ msg_h.each do |k, v|
170
+ expect(logged_txt).to include(k.inspect)
171
+ expect(logged_txt).to include(v.inspect)
172
+ end
173
+ end
174
+
175
+ it 'logs something with #to_hash as a hash' do
176
+ out = StringIO.new
177
+ msg_h = {
178
+ foo: 'Foo',
179
+ bar: 'Bar',
180
+ baz: 'Baz'
181
+ }
182
+ msg_obj = Object.new
183
+ msg_obj.singleton_class.define_method(:to_hash) { msg_h }
184
+
185
+ Loggers.new_readable_logger(out).info(msg_obj)
186
+
187
+ logged_txt = out.string
188
+ msg_h.each do |k, v|
189
+ expect(logged_txt).to include(k.inspect)
190
+ expect(logged_txt).to include(v.inspect)
191
+ end
192
+ end
193
+
194
+ it 'logs an error with cause and backtrace' do
195
+ ex_msg = 'Help I am trapped in a unit test'
196
+
197
+ begin
198
+ raise TestError, ex_msg
199
+ rescue TestError => e
200
+ ex = e
201
+ Loggers.new_readable_logger(out).error(e)
202
+ end
203
+
204
+ logged_txt = out.string
205
+ expect(logged_txt).to include(ex_msg)
206
+ expect(logged_txt).to include(TestError.name)
207
+ backtrace = ex.backtrace
208
+ expect(backtrace).not_to be_nil # just to be sure
209
+ backtrace.each do |line|
210
+ expect(logged_txt).to include(line)
211
+ end
212
+ end
213
+
214
+ end
215
+
216
+ end
217
+
218
+ describe :new_default_logger do
219
+ attr_reader :config
220
+
221
+ before(:each) do
222
+ @config = OpenStruct.new
223
+ end
224
+
225
+ after(:each) do
226
+ BerkeleyLibrary::Logging.instance_variable_set(:@env, nil)
227
+ end
228
+
229
+ it 'returns a readable $stdout logger if given no config' do
230
+ logger = Loggers.new_default_logger
231
+ expect(logger).not_to be_nil
232
+ expect(logger).to be_a(Logger)
233
+ expect(logger.formatter).to be_a(Ougai::Formatters::Readable)
234
+ end
235
+
236
+ it 'returns a file logger in test' do
237
+ BerkeleyLibrary::Logging.env = 'test'
238
+ logger = Loggers.new_default_logger(config)
239
+ expect(logger).not_to be_nil
240
+ logdev = logger.instance_variable_get(:@logdev)
241
+ expect(logdev.filename).to end_with('log/test.log')
242
+ end
243
+
244
+ it 'returns a stdout logger in production' do
245
+ BerkeleyLibrary::Logging.env = 'production'
246
+ stdout_orig = $stdout
247
+ stdout_tmp = StringIO.new
248
+ begin
249
+ $stdout = stdout_tmp
250
+ logger = Loggers.new_default_logger(config)
251
+ ensure
252
+ $stdout = stdout_orig
253
+ end
254
+ expect(logger).not_to be_nil
255
+ logdev = logger.instance_variable_get(:@logdev)
256
+ expect(logdev.filename).to be_nil
257
+ expect(logdev.dev).to eq(stdout_tmp)
258
+ end
259
+
260
+ it 'returns a stdout logger in development' do
261
+ BerkeleyLibrary::Logging.env = 'development'
262
+ logger = Loggers.new_default_logger(config)
263
+ expect(logger).not_to be_nil
264
+ logdev = logger.instance_variable_get(:@logdev)
265
+ expect(logdev.filename).to be_nil
266
+ expect(logdev.dev).to eq($stdout)
267
+
268
+ # TODO: come up with a succinct way to test broadcast to file
269
+ end
270
+
271
+ it 'fails on an unsupported environment' do
272
+ BerkeleyLibrary::Logging.env = 'some-unsupported-environment'
273
+ expect { Loggers.new_default_logger(config) }.to raise_error(ArgumentError)
274
+ end
275
+ end
276
+ end
277
+ end
278
+ end