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 +7 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.mdown +74 -0
- data/Rakefile +10 -0
- data/VERSION +1 -0
- data/lib/multiple_devices_logger.rb +93 -0
- data/multiple_devices_logger.gemspec +24 -0
- data/spec/multiple_devices_logger_spec.rb +448 -0
- data/spec/spec_helper.rb +6 -0
- metadata +136 -0
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
data/.rspec
ADDED
data/Gemfile
ADDED
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
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
|
data/spec/spec_helper.rb
ADDED
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
|