multiple_devices_logger 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e1ab6f46b22a880122cfcf4c6b84ce37c4fb229b
4
+ data.tar.gz: c69bcdc6a13537e8267e98435d80d4fc48f3be97
5
+ SHA512:
6
+ metadata.gz: 9938b033da846d237f8ab0746e84092e1024198026a3afd020661403eafc49a5e6ab0449a588078577f9658fcaa0784492296c0eb15d10fe17ef29e647321b72
7
+ data.tar.gz: c100f7447b874b85245ff97b3fed4d4c770c5977bfd1f242455d32123904e60052595dd147ffe0c9742e5f918ccf6db17f15892770f66cb09c007ce8002e7193
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .DS_Store
2
+ /.bundle/
3
+ /.byebug_history
4
+ /.ruby-version
5
+ /Gemfile.lock
6
+ /pkg/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --order random
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2017 Alexis Toulotte
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.mdown ADDED
@@ -0,0 +1,74 @@
1
+ # MultipleDevicesLogger
2
+
3
+ Logger that support many and different devices for specified levels.
4
+
5
+ ## Setup
6
+
7
+ Just add this into your `Gemfile`:
8
+
9
+ ```ruby
10
+ gem 'multiple_devices_logger'
11
+ ```
12
+
13
+ Then, just run a `bundle install`.
14
+
15
+ ## Usage
16
+
17
+ ### Simple usage
18
+
19
+ This will add `STDOUT` device for `debug` and `info` severities and a file
20
+ for all others.
21
+
22
+ ```ruby
23
+ require 'multiple_devices_logger'
24
+
25
+ logger = MultipleDevicesLogger.new
26
+ logger.add_device(STDOUT, Logger::DEBUG, Logger::INFO)
27
+ logger.add_device('/tmp/logs', Logger::WARN, Logger::ERROR, Logger::FATAL)
28
+ logger.warn('BAM!')
29
+ ```
30
+
31
+ Note that severty can specified as string or symbol.
32
+
33
+ ### Define default device
34
+
35
+ If there is no device for given severity, default device is used. It can be
36
+ defined thanks to `default_device` accessor.
37
+
38
+ ```ruby
39
+ logger.default_device = STDERR
40
+ ```
41
+
42
+ ### Adding a device for all severities
43
+
44
+ If you don't specify any severity to `#add_device` method, specified device
45
+ will be added to all sevrities.
46
+
47
+ Here is an example that logs all messages to `STDERR` and fatal messages to
48
+ both a file and `STDERR`.
49
+
50
+ ```ruby
51
+ logger.add_device(STDERR)
52
+ logger.add_device('/tmp/fatal.log', :fatal)
53
+ ```
54
+
55
+ ### Operators
56
+
57
+ To simplify devices definition, you can use `>`, `>=`, `<`, `<=` operators:
58
+
59
+ ```ruby
60
+ logger.add_device('/var/log/myapp.log', '>= warn')
61
+ ```
62
+
63
+ ### Clear all devices
64
+
65
+ Just use `#clear_devices` to clear all registered devices:
66
+
67
+ ```ruby
68
+ logger.clear_devices
69
+ ```
70
+
71
+ ## Executing test suite
72
+
73
+ This project is fully tested with [Rspec 3](http://github.com/rspec/rspec).
74
+ Just run `bundle exec rake` (after a `bundle install`).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ desc 'Default: runs specs.'
7
+ task default: :spec
8
+
9
+ desc 'Run all specs in spec directory.'
10
+ RSpec::Core::RakeTask.new(:spec)
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,93 @@
1
+ require 'active_support/core_ext/array'
2
+ require 'active_support/core_ext/object'
3
+ require 'logger'
4
+
5
+ class MultipleDevicesLogger < Logger
6
+
7
+ SEVERITIES = {
8
+ 'debug' => DEBUG,
9
+ 'info' => INFO,
10
+ 'warn' => WARN,
11
+ 'error' => ERROR,
12
+ 'fatal' => FATAL,
13
+ 'unknown' => UNKNOWN,
14
+ }.freeze
15
+
16
+ attr_reader :default_device
17
+
18
+ def initialize
19
+ super(nil)
20
+ clear_devices
21
+ end
22
+
23
+ def add(severity, message = nil, progname = nil)
24
+ severity ||= UNKNOWN
25
+ return true if severity < level
26
+ progname ||= self.progname
27
+ if message.nil?
28
+ if block_given?
29
+ message = yield
30
+ else
31
+ message = progname
32
+ progname = self.progname
33
+ end
34
+ end
35
+ text = format_message(format_severity(severity), Time.now, progname, message)
36
+ devices_for(severity).each do |device|
37
+ device.write(text)
38
+ end
39
+ true
40
+ end
41
+ alias_method :log, :add
42
+
43
+ def add_device(device, *severities)
44
+ severities = [severities].flatten
45
+ options = severities.extract_options!
46
+ device = LogDevice.new(device, options) unless device.is_a?(LogDevice)
47
+ if severities.empty?
48
+ keys = SEVERITIES.values
49
+ else
50
+ keys = severities.map { |severity| parse_severities_with_operator(severity) }.flatten.uniq
51
+ end
52
+ keys.each do |key|
53
+ @devices[key] ||= []
54
+ @devices[key] << device
55
+ end
56
+ self
57
+ end
58
+
59
+ def clear_devices
60
+ @devices = {}
61
+ end
62
+
63
+ def default_device=(value)
64
+ @default_device = value.is_a?(LogDevice) ? value : LogDevice.new(value)
65
+ end
66
+
67
+ def devices_for(severity)
68
+ @devices[parse_severity(severity)] || [default_device].compact || []
69
+ end
70
+
71
+ def reopen(log = nil)
72
+ raise NotImplementedError.new("#{self.class}#reopen")
73
+ end
74
+
75
+ private
76
+
77
+ def parse_severity(value)
78
+ int_value = value.is_a?(Fixnum) ? value : (Integer(value.to_s) rescue nil)
79
+ return int_value if SEVERITIES.values.include?(int_value)
80
+ severity = value.to_s
81
+ SEVERITIES[value.to_s.strip.downcase] || raise(ArgumentError.new("Invalid log severity: #{value.inspect}"))
82
+ end
83
+
84
+ def parse_severities_with_operator(value)
85
+ if match = value.to_s.strip.match(/^([<>]=?)\s*(.+)$/)
86
+ operator = match[1]
87
+ severity = parse_severity(match[2])
88
+ return SEVERITIES.values.select { |l| l.send(operator, severity) }
89
+ end
90
+ [parse_severity(value)]
91
+ end
92
+
93
+ end
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'multiple_devices_logger'
3
+ s.version = File.read("#{File.dirname(__FILE__)}/VERSION").strip
4
+ s.platform = Gem::Platform::RUBY
5
+ s.author = 'Alexis Toulotte'
6
+ s.email = 'al@alweb.org'
7
+ s.homepage = 'https://github.com/alexistoulotte/multiple_devices_logger'
8
+ s.summary = 'Logger than can have many devices'
9
+ s.description = 'Logger that support many and different devices for specified levels'
10
+ s.license = 'MIT'
11
+
12
+ s.rubyforge_project = 'multiple_devices_logger'
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ['lib']
18
+
19
+ s.add_dependency 'activesupport', '>= 5.0.0', '< 6.0.0'
20
+
21
+ s.add_development_dependency 'byebug', '>= 9.0.0', '< 10.0.0'
22
+ s.add_development_dependency 'rake', '>= 12.0.0', '< 13.0.0'
23
+ s.add_development_dependency 'rspec', '>= 3.5.0', '< 3.6.0'
24
+ end
@@ -0,0 +1,448 @@
1
+ require 'spec_helper'
2
+
3
+ describe MultipleDevicesLogger do
4
+
5
+ let(:logger) { MultipleDevicesLogger.new }
6
+
7
+ it 'is a Logger' do
8
+ expect(logger).to be_a(Logger)
9
+ end
10
+
11
+ describe '#add' do
12
+
13
+ before :each do
14
+ logger.add_device(STDERR, '>= WARN')
15
+ end
16
+
17
+ it 'write to device' do
18
+ expect(STDERR).to receive(:write).with(/BAM!/)
19
+ logger.add(Logger::WARN, 'BAM!')
20
+ end
21
+
22
+ it 'use a default formatter' do
23
+ expect(STDERR).to receive(:write).with(/^W, \[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+ #\d+\] WARN -- MyApp: BAM!\n$/)
24
+ logger.add(Logger::WARN, 'BAM!', 'MyApp')
25
+ end
26
+
27
+ it 'write to multiple device if configured' do
28
+ logger.add_device(STDOUT)
29
+ expect(STDERR).to receive(:write).with(/BAM!/)
30
+ expect(STDOUT).to receive(:write).with(/BAM!/)
31
+ logger.add(Logger::WARN, 'BAM!')
32
+ end
33
+
34
+ it 'does not write anything if given severity is lower than configured level' do
35
+ logger.level = :error
36
+ expect(STDERR).not_to receive(:write)
37
+ logger.add(Logger::WARN, 'BAM!')
38
+ end
39
+
40
+ it 'severity is UNKNOWN if not specified' do
41
+ expect(STDERR).to receive(:write).with(/ANY -- : BIM!/)
42
+ logger.add(nil, 'BIM!')
43
+ end
44
+
45
+ it 'a block can be given' do
46
+ expect(STDERR).to receive(:write).with(/BIM!/)
47
+ logger.add(Logger::ERROR) { 'BIM!' }
48
+ end
49
+
50
+ it 'accepts progname' do
51
+ expect(STDERR).to receive(:write).with(/FATAL -- MyApp: BAM!/)
52
+ logger.add(Logger::FATAL, 'BAM!', 'MyApp')
53
+ end
54
+
55
+ it 'returns true' do
56
+ expect(STDERR).to receive(:write)
57
+ expect(logger.add(Logger::WARN, 'BAM!')).to be(true)
58
+ end
59
+
60
+ it 'returns true if nothing is written' do
61
+ logger.level = :error
62
+ expect(STDERR).not_to receive(:write)
63
+ expect(logger.add(Logger::WARN, 'BAM!')).to be(true)
64
+ end
65
+
66
+ it 'block is ignored if message is given' do
67
+ expect(STDERR).to receive(:write).with(/BAM!/)
68
+ logger.add(Logger::WARN, 'BAM!') { 'BIM!' }
69
+ end
70
+
71
+ it 'message is progname if nil' do
72
+ expect(STDERR).to receive(:write).with(/WARN -- : BAM!/)
73
+ logger.add(Logger::WARN, nil, 'BAM!')
74
+ end
75
+
76
+ it 'a formatter could be given' do
77
+ logger.formatter = -> (severity, time, progname, message) { "Hello #{progname}: #{message}" }
78
+ expect(STDERR).to receive(:write).with('Hello World: cool')
79
+ logger.add(Logger::WARN, 'cool', 'World')
80
+ end
81
+
82
+ end
83
+
84
+ describe '#add_device' do
85
+
86
+ it 'adds a device for all severities if given severity is nil' do
87
+ expect {
88
+ logger.add_device(STDOUT)
89
+ }.to change { logger.devices_for(Logger::INFO).size }.by(1)
90
+ expect(logger.devices_for(Logger::WARN).first.dev).to be(STDOUT)
91
+ end
92
+
93
+ it 'does not adds to other severities if severity is specified' do
94
+ logger.add_device(STDERR, Logger::WARN)
95
+ expect(logger.devices_for(Logger::WARN)).not_to be_empty
96
+ expect(logger.devices_for(Logger::INFO)).to be_empty
97
+ expect(logger.devices_for(Logger::ERROR)).to be_empty
98
+ end
99
+
100
+ it 'severity can be specified as constant' do
101
+ expect {
102
+ logger.add_device(STDERR, Logger::WARN)
103
+ }.to change { logger.devices_for(Logger::WARN).first.try(:dev) }.from(nil).to(STDERR)
104
+ end
105
+
106
+ it 'severity can be specified as symbol' do
107
+ expect {
108
+ logger.add_device(STDOUT, :warn)
109
+ }.to change { logger.devices_for(Logger::WARN).size }.by(1)
110
+ end
111
+
112
+ it 'severity can be specified as symbol (ignore case)' do
113
+ expect {
114
+ logger.add_device(STDOUT, :waRN)
115
+ }.to change { logger.devices_for(Logger::WARN).size }.by(1)
116
+ end
117
+
118
+ it 'severity can be specified as string' do
119
+ expect {
120
+ logger.add_device(STDOUT, 'fatal')
121
+ }.to change { logger.devices_for(Logger::FATAL).size }.by(1)
122
+ end
123
+
124
+ it 'severity can be specified as string (ignore case)' do
125
+ expect {
126
+ logger.add_device(STDOUT, 'FATal')
127
+ }.to change { logger.devices_for(Logger::FATAL).size }.by(1)
128
+ end
129
+
130
+ it 'severity can be specified as string (with extra spaces)' do
131
+ expect {
132
+ logger.add_device(STDOUT, " fatal \n")
133
+ }.to change { logger.devices_for(Logger::FATAL).size }.by(1)
134
+ end
135
+
136
+ it 'severity can be specified as integer' do
137
+ expect {
138
+ logger.add_device(STDOUT, 0)
139
+ }.to change { logger.devices_for(Logger::DEBUG).size }.by(1)
140
+ end
141
+
142
+ it 'severity can be specified as integer (as string)' do
143
+ expect {
144
+ logger.add_device(STDOUT, '3')
145
+ }.to change { logger.devices_for(Logger::ERROR).size }.by(1)
146
+ end
147
+
148
+ it 'severity can be specified as integer (as string with spaces)' do
149
+ expect {
150
+ logger.add_device(STDOUT, ' 2 ')
151
+ }.to change { logger.devices_for(Logger::WARN).size }.by(1)
152
+ end
153
+
154
+ it 'many severities can be given' do
155
+ logger.add_device(STDERR, Logger::DEBUG, Logger::WARN)
156
+ expect(logger.devices_for(Logger::DEBUG)).not_to be_empty
157
+ expect(logger.devices_for(Logger::WARN)).not_to be_empty
158
+ expect(logger.devices_for(Logger::INFO)).to be_empty
159
+ expect(logger.devices_for(Logger::ERROR)).to be_empty
160
+ end
161
+
162
+ it 'an array of severities can be given' do
163
+ logger.add_device(STDERR, [Logger::DEBUG, Logger::WARN])
164
+ expect(logger.devices_for(Logger::DEBUG)).not_to be_empty
165
+ expect(logger.devices_for(Logger::WARN)).not_to be_empty
166
+ expect(logger.devices_for(Logger::INFO)).to be_empty
167
+ end
168
+
169
+ it 'avoids doubloons on severities' do
170
+ logger.add_device(STDOUT, Logger::DEBUG, Logger::INFO, Logger::DEBUG)
171
+ expect(logger.devices_for(Logger::DEBUG).size).to eq(1)
172
+ end
173
+
174
+ it 'raise an error if severity specified as integer is too high' do
175
+ expect {
176
+ logger.add_device(STDERR, 8)
177
+ }.to raise_error(ArgumentError, 'Invalid log severity: 8')
178
+ end
179
+
180
+ it 'raise an error if severity specified as integer is negative' do
181
+ expect {
182
+ logger.add_device(STDERR, -1)
183
+ }.to raise_error(ArgumentError, 'Invalid log severity: -1')
184
+ end
185
+
186
+ it 'does not add any device if one severity is invalid' do
187
+ expect {
188
+ expect {
189
+ logger.add_device(STDOUT, Logger::DEBUG, 'bim')
190
+ }.to raise_error(ArgumentError, 'Invalid log severity: "bim"')
191
+ }.not_to change { logger.devices_for(Logger::DEBUG).size }
192
+ end
193
+
194
+ it 'raise an error if severity is unknown (as string)' do
195
+ expect {
196
+ logger.add_device(STDOUT, 'errors')
197
+ }.to raise_error(ArgumentError, 'Invalid log severity: "errors"')
198
+ end
199
+
200
+ it 'may have many device for a severity' do
201
+ logger.add_device(STDERR, Logger::INFO).add_device(STDOUT, Logger::INFO)
202
+ expect(logger.devices_for(Logger::DEBUG)).to be_empty
203
+ expect(logger.devices_for(Logger::INFO).size).to eq(2)
204
+ expect(logger.devices_for(Logger::FATAL)).to be_empty
205
+ end
206
+
207
+ it 'returns self' do
208
+ expect(logger.add_device(STDOUT)).to be(logger)
209
+ expect(logger.add_device(STDOUT, Logger::DEBUG)).to be(logger)
210
+ end
211
+
212
+ it 'accepts <= operator' do
213
+ logger.add_device(STDOUT, '<= warn')
214
+ expect(logger.devices_for(Logger::DEBUG)).not_to be_empty
215
+ expect(logger.devices_for(Logger::INFO)).not_to be_empty
216
+ expect(logger.devices_for(Logger::WARN)).not_to be_empty
217
+ expect(logger.devices_for(Logger::ERROR)).to be_empty
218
+ end
219
+
220
+ it 'accepts < operator' do
221
+ logger.add_device(STDOUT, '< warn')
222
+ expect(logger.devices_for(Logger::DEBUG)).not_to be_empty
223
+ expect(logger.devices_for(Logger::INFO)).not_to be_empty
224
+ expect(logger.devices_for(Logger::WARN)).to be_empty
225
+ expect(logger.devices_for(Logger::ERROR)).to be_empty
226
+ end
227
+
228
+ it 'accepts > operator' do
229
+ logger.add_device(STDOUT, '> error')
230
+ expect(logger.devices_for(Logger::UNKNOWN)).not_to be_empty
231
+ expect(logger.devices_for(Logger::FATAL)).not_to be_empty
232
+ expect(logger.devices_for(Logger::ERROR)).to be_empty
233
+ end
234
+
235
+ it 'accepts >= operator' do
236
+ logger.add_device(STDOUT, '>= error')
237
+ expect(logger.devices_for(Logger::UNKNOWN)).not_to be_empty
238
+ expect(logger.devices_for(Logger::FATAL)).not_to be_empty
239
+ expect(logger.devices_for(Logger::ERROR)).not_to be_empty
240
+ expect(logger.devices_for(Logger::WARN)).to be_empty
241
+ end
242
+
243
+ it 'accepts operator with spaces and with a different case' do
244
+ logger.add_device(STDOUT, " \n > eRRor ")
245
+ expect(logger.devices_for(Logger::UNKNOWN)).not_to be_empty
246
+ expect(logger.devices_for(Logger::FATAL)).not_to be_empty
247
+ expect(logger.devices_for(Logger::ERROR)).to be_empty
248
+ end
249
+
250
+ it 'accepts operator with no spaces' do
251
+ logger.add_device(STDOUT, ">error")
252
+ expect(logger.devices_for(Logger::UNKNOWN)).not_to be_empty
253
+ expect(logger.devices_for(Logger::FATAL)).not_to be_empty
254
+ expect(logger.devices_for(Logger::ERROR)).to be_empty
255
+ end
256
+
257
+ it 'raise an error if operator is invalid' do
258
+ expect {
259
+ logger.add_device(STDERR, '!> error')
260
+ }.to raise_error(ArgumentError, 'Invalid log severity: "!> error"')
261
+ end
262
+
263
+ it 'raise an error if severity is invalid (with operator)' do
264
+ expect {
265
+ logger.add_device(STDERR, '>= foo')
266
+ }.to raise_error(ArgumentError, 'Invalid log severity: "foo"')
267
+ end
268
+
269
+ it 'avoid doubloons with operator' do
270
+ logger.add_device(STDERR, Logger::INFO, '>= DEBUG')
271
+ expect(logger.devices_for(Logger::DEBUG).size).to eq(1)
272
+ expect(logger.devices_for(Logger::INFO).size).to eq(1)
273
+ expect(logger.devices_for(Logger::WARN).size).to eq(1)
274
+ end
275
+
276
+ it 'may have many devices for a severity with an operator' do
277
+ logger.add_device(STDERR, Logger::INFO).add_device(STDOUT, '<= error')
278
+ expect(logger.devices_for(Logger::DEBUG).size).to eq(1)
279
+ expect(logger.devices_for(Logger::INFO).size).to eq(2)
280
+ expect(logger.devices_for(Logger::FATAL)).to be_empty
281
+ end
282
+
283
+ it 'register LogDevice directly if a LogDevice is given' do
284
+ device = Logger::LogDevice.new(STDERR)
285
+ logger.add_device(device, Logger::INFO)
286
+ expect(logger.devices_for(Logger::INFO).first).to be(device)
287
+ end
288
+
289
+ it 'given options are forwared to LogDevice constructor' do
290
+ expect(Logger::LogDevice).to receive(:new).with(STDOUT, foo: 'bar')
291
+ logger.add_device(STDOUT, Logger::INFO, foo: 'bar')
292
+ end
293
+
294
+ it 'raise an error for default severity' do
295
+ expect {
296
+ logger.add_device(STDERR, 'default')
297
+ }.to raise_error(ArgumentError, 'Invalid log severity: "default"')
298
+ end
299
+
300
+ end
301
+
302
+ describe '#clear_devices' do
303
+
304
+ it 'removes registered loggers' do
305
+ logger.add_device(STDERR)
306
+ expect {
307
+ logger.clear_devices
308
+ }.to change { logger.devices_for(Logger::DEBUG) }.to([])
309
+ end
310
+
311
+ end
312
+
313
+ describe '#default_device' do
314
+
315
+ it 'is nil by default' do
316
+ expect(logger.default_device).to be_nil
317
+ end
318
+
319
+ it 'can be changed' do
320
+ logger.default_device = STDERR
321
+ expect(logger.default_device).not_to be_nil
322
+ end
323
+
324
+ it 'is converted to a LogDevice when set' do
325
+ logger.default_device = STDERR
326
+ expect(logger.default_device).to be_a(Logger::LogDevice)
327
+ expect(logger.default_device.dev).to be(STDERR)
328
+ end
329
+
330
+ it 'is not converted to a LogDevice when a LogDevice is set' do
331
+ device = Logger::LogDevice.new(STDOUT)
332
+ logger.default_device = device
333
+ expect(logger.default_device).to be(device)
334
+ expect(logger.default_device.dev).to be(STDOUT)
335
+ end
336
+
337
+ end
338
+
339
+ describe '#devices_for' do
340
+
341
+ it 'accepts strings' do
342
+ logger.add_device(STDERR, 'warn')
343
+ expect(logger.devices_for('warn').size).to eq(1)
344
+ end
345
+
346
+ it 'returns a LogDevice instance' do
347
+ logger.add_device(STDERR, 'warn')
348
+ expect(logger.devices_for(:warn).first).to be_a(Logger::LogDevice)
349
+ expect(logger.devices_for(:warn).first.dev).to be(STDERR)
350
+ end
351
+
352
+ it 'returns an empty array if there is not registered device for given severity' do
353
+ expect(logger.devices_for(Logger::WARN)).to eq([])
354
+ end
355
+
356
+ it 'returns default device if there is no device for given severity' do
357
+ logger.default_device = STDERR
358
+ logger.add_device(STDOUT, '>= warn')
359
+ expect(logger.devices_for(:debug).first.dev).to be(STDERR)
360
+ expect(logger.devices_for(:warn).first.dev).to be(STDOUT)
361
+ expect(logger.devices_for(:error).first.dev).to be(STDOUT)
362
+ end
363
+
364
+ it 'default is never used if a logger has been added to all severity' do
365
+ logger.default_device = STDERR
366
+ logger.add_device(STDOUT)
367
+ expect(logger.devices_for(:debug).first.dev).to be(STDOUT)
368
+ expect(logger.devices_for(:warn).first.dev).to be(STDOUT)
369
+ expect(logger.devices_for(:error).first.dev).to be(STDOUT)
370
+ end
371
+
372
+ end
373
+
374
+ describe '#initialize' do
375
+
376
+ it 'accepts no argument' do
377
+ expect {
378
+ MultipleDevicesLogger.new
379
+ }.not_to raise_error
380
+ end
381
+
382
+ it 'logdev is nil' do
383
+ expect(logger.instance_variable_get(:@logdev)).to be_nil
384
+ end
385
+
386
+ end
387
+
388
+ describe '#level' do
389
+
390
+ it 'is debug by default' do
391
+ expect(logger.level).to eq(Logger::DEBUG)
392
+ end
393
+
394
+ it 'is not changed when adding devices' do
395
+ expect {
396
+ logger.add_device(STDOUT, '> WARN')
397
+ }.not_to change { logger.level }
398
+ end
399
+
400
+ end
401
+
402
+ describe '#log' do
403
+
404
+ it 'works like expected' do
405
+ logger.add_device(STDOUT, Logger::WARN)
406
+ expect(STDOUT).to receive(:write).with(/WARN -- : BAM!/)
407
+ logger.log(Logger::WARN, 'BAM!')
408
+ end
409
+
410
+ end
411
+
412
+ describe '#reopen' do
413
+
414
+ it 'raise an NotImplementedError' do
415
+ expect {
416
+ logger.reopen
417
+ }.to raise_error(NotImplementedError, 'MultipleDevicesLogger#reopen')
418
+ end
419
+
420
+ end
421
+
422
+ describe '#warn' do
423
+
424
+ it 'does not output anything if there is no device' do
425
+ logger.add_device(STDOUT, Logger::DEBUG)
426
+ expect(STDOUT).not_to receive(:write)
427
+ logger.warn('BAM!')
428
+ end
429
+
430
+ it 'output message to device if configured' do
431
+ logger.add_device(STDOUT, Logger::WARN)
432
+ expect(STDOUT).to receive(:write).with(/WARN -- : BAM!/)
433
+ logger.warn('BAM!')
434
+ end
435
+
436
+ end
437
+
438
+ describe '@logdev' do
439
+
440
+ let(:logdev) { logger.instance_variable_get(:@logdev) }
441
+
442
+ it 'is nil' do
443
+ expect(logdev).to be_nil
444
+ end
445
+
446
+ end
447
+
448
+ end
@@ -0,0 +1,6 @@
1
+ require File.expand_path("#{__dir__}/../lib/multiple_devices_logger")
2
+ require 'byebug'
3
+
4
+ RSpec.configure do |config|
5
+ config.raise_errors_for_deprecations!
6
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: multiple_devices_logger
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexis Toulotte
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 5.0.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 6.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 5.0.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 6.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: byebug
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 9.0.0
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: 10.0.0
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 9.0.0
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: 10.0.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: rake
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 12.0.0
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: 13.0.0
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 12.0.0
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: 13.0.0
73
+ - !ruby/object:Gem::Dependency
74
+ name: rspec
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: 3.5.0
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: 3.6.0
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 3.5.0
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: 3.6.0
93
+ description: Logger that support many and different devices for specified levels
94
+ email: al@alweb.org
95
+ executables: []
96
+ extensions: []
97
+ extra_rdoc_files: []
98
+ files:
99
+ - ".gitignore"
100
+ - ".rspec"
101
+ - Gemfile
102
+ - MIT-LICENSE
103
+ - README.mdown
104
+ - Rakefile
105
+ - VERSION
106
+ - lib/multiple_devices_logger.rb
107
+ - multiple_devices_logger.gemspec
108
+ - spec/multiple_devices_logger_spec.rb
109
+ - spec/spec_helper.rb
110
+ homepage: https://github.com/alexistoulotte/multiple_devices_logger
111
+ licenses:
112
+ - MIT
113
+ metadata: {}
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubyforge_project: multiple_devices_logger
130
+ rubygems_version: 2.5.2
131
+ signing_key:
132
+ specification_version: 4
133
+ summary: Logger than can have many devices
134
+ test_files:
135
+ - spec/multiple_devices_logger_spec.rb
136
+ - spec/spec_helper.rb