transitional_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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +50 -0
- data/Rakefile +10 -0
- data/lib/transitional_logger.rb +106 -0
- data/test/transitional_logger_spec.rb +49 -0
- data/transitional_logger.gemspec +24 -0
- metadata +103 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 Elon Flegenheimer
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# TransitionalLogger
|
|
2
|
+
|
|
3
|
+
A singleton logger accessible from ALL objects. It is intended to be used to:
|
|
4
|
+
|
|
5
|
+
* send logger data to stdout OR
|
|
6
|
+
* log to a file while consuming stdout & stderr data as log input OR
|
|
7
|
+
* destroy stdout, stderr, & log data OR
|
|
8
|
+
* do one of the above until transitioned to another of the above
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
Add this line to your application's Gemfile:
|
|
13
|
+
|
|
14
|
+
gem 'transitional_logger'
|
|
15
|
+
|
|
16
|
+
And then execute:
|
|
17
|
+
|
|
18
|
+
$ bundle
|
|
19
|
+
|
|
20
|
+
Or install it yourself as:
|
|
21
|
+
|
|
22
|
+
$ gem install transitional_logger
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
The logger can be altered just like a normal Logger:
|
|
27
|
+
|
|
28
|
+
logger.level = Logger::WARN
|
|
29
|
+
|
|
30
|
+
Example usage:
|
|
31
|
+
|
|
32
|
+
TransitionalLogger.stdout
|
|
33
|
+
logger.info 'this message goes through the logger to stdout'
|
|
34
|
+
puts 'this works like usual'
|
|
35
|
+
|
|
36
|
+
TransitionalLogger.file('/tmp/whatever.log')
|
|
37
|
+
Object.new.logger.info 'this message goes through the logger to the file above'
|
|
38
|
+
puts 'this message also goes through the logger above'
|
|
39
|
+
|
|
40
|
+
TransitionalLogger.blackhole
|
|
41
|
+
Object.new.logger.error 'this message disappears'
|
|
42
|
+
puts 'this message disappears too!'
|
|
43
|
+
|
|
44
|
+
## Contributing
|
|
45
|
+
|
|
46
|
+
1. Fork it
|
|
47
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
48
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
49
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
50
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
|
|
3
|
+
# Author:: Elon Flegenheimer
|
|
4
|
+
# Copyright:: Copyright (c) 2013 Elon Flegenheimer
|
|
5
|
+
# License:: The MIT License (MIT)
|
|
6
|
+
#
|
|
7
|
+
# A singleton logger accessible from ALL objects. It is intended to be used to:
|
|
8
|
+
# * send logger data to stdout OR
|
|
9
|
+
# * log to a file while consuming stdout & stderr data as log input OR
|
|
10
|
+
# * destroy stdout, stderr, & log data OR
|
|
11
|
+
# * do one of the above until transitioned to another of the above
|
|
12
|
+
#
|
|
13
|
+
# The logger can be altered just like a normal Logger:
|
|
14
|
+
# logger.level = Logger::WARN
|
|
15
|
+
#
|
|
16
|
+
# Example usage:
|
|
17
|
+
#
|
|
18
|
+
# TransitionalLogger.stdout
|
|
19
|
+
# logger.info 'this message goes through the logger to stdout'
|
|
20
|
+
# puts 'this works like usual'
|
|
21
|
+
#
|
|
22
|
+
# TransitionalLogger.file('/tmp/whatever.log')
|
|
23
|
+
# Object.new.logger.info 'this message goes through the logger to the file above'
|
|
24
|
+
# puts 'this message also goes through the logger above'
|
|
25
|
+
#
|
|
26
|
+
# TransitionalLogger.blackhole
|
|
27
|
+
# Object.new.logger.error 'this message disappears'
|
|
28
|
+
# puts 'this message disappears too!'
|
|
29
|
+
#
|
|
30
|
+
module TransitionalLogger
|
|
31
|
+
|
|
32
|
+
VERSION = '1.0.0'
|
|
33
|
+
|
|
34
|
+
class << self
|
|
35
|
+
|
|
36
|
+
# Creates a logger that is accessible from all objects. The logger points
|
|
37
|
+
# to stdout. Stdout is otherwise unaffected.
|
|
38
|
+
def stdout
|
|
39
|
+
reset if @streams
|
|
40
|
+
@master_logger = infect_object(Logger.new($stdout))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Creates the specified logger that is accessible from all objects. stdout
|
|
44
|
+
# and stderr are redirected to this logger.
|
|
45
|
+
#
|
|
46
|
+
# Parameters match Logger#new.
|
|
47
|
+
def file(*args)
|
|
48
|
+
raise ArgumentError, 'Logger#new params must be specified for #file' if args.size == 0
|
|
49
|
+
reset if @streams
|
|
50
|
+
@master_logger = infect_object(Logger.new(*args))
|
|
51
|
+
|
|
52
|
+
@streams = [$stdout, $stderr, $stdin]
|
|
53
|
+
$stdout = CommandeeredOut.new(@master_logger)
|
|
54
|
+
$stderr = CommandeeredErr.new(@master_logger)
|
|
55
|
+
@master_logger
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Creates a logger that consumes stdout, stderr, and all logger messages.
|
|
59
|
+
def blackhole
|
|
60
|
+
file('/dev/null')
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Reset the changes that this object has introduced
|
|
64
|
+
def reset
|
|
65
|
+
@master_logger = nil
|
|
66
|
+
Object.send :remove_method, :logger rescue nil
|
|
67
|
+
if @streams
|
|
68
|
+
$stdout, $stderr = @streams[0..1]
|
|
69
|
+
@streams = nil
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Logger accessor - otherwise accessible from any object
|
|
74
|
+
def logger
|
|
75
|
+
@master_logger
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
# Define the logger method to return this in all objects
|
|
81
|
+
def infect_object(logger)
|
|
82
|
+
Object.send :define_method, :logger, ->{logger}
|
|
83
|
+
logger
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
class CommandeeredIO < IO
|
|
91
|
+
def initialize(logger)
|
|
92
|
+
@logger = logger
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
class CommandeeredOut < CommandeeredIO
|
|
97
|
+
def write(s)
|
|
98
|
+
@logger.info(s)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
class CommandeeredErr < CommandeeredIO
|
|
103
|
+
def write(s)
|
|
104
|
+
@logger.error(s)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'minitest/spec'
|
|
2
|
+
require 'minitest/autorun'
|
|
3
|
+
require 'mocha/setup'
|
|
4
|
+
require_relative '../lib/transitional_logger'
|
|
5
|
+
|
|
6
|
+
describe TransitionalLogger do
|
|
7
|
+
|
|
8
|
+
before { TransitionalLogger.reset }
|
|
9
|
+
|
|
10
|
+
it '#reset clears #logger from Object' do
|
|
11
|
+
TransitionalLogger.stdout
|
|
12
|
+
TransitionalLogger.reset
|
|
13
|
+
Object.wont_respond_to :logger
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'responds to info' do
|
|
17
|
+
TransitionalLogger.stdout
|
|
18
|
+
TransitionalLogger.logger.must_respond_to :info
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'responds to error' do
|
|
22
|
+
TransitionalLogger.stdout
|
|
23
|
+
TransitionalLogger.logger.must_respond_to :error
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it '#infect_object creates Object#logger, which returns param' do
|
|
27
|
+
TransitionalLogger.send :infect_object, 2
|
|
28
|
+
Object.new.logger.must_equal 2
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'puts should not normally delegate to logger' do
|
|
32
|
+
TransitionalLogger.expects(:infect_object).returns(Logger.new('/dev/null'))
|
|
33
|
+
TransitionalLogger.stdout
|
|
34
|
+
TransitionalLogger.logger.expects(:info).never
|
|
35
|
+
puts 'rem: test case sequence varies'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it '#file should result in puts delegating to logger' do
|
|
39
|
+
TransitionalLogger.stdout
|
|
40
|
+
TransitionalLogger.file('/dev/null')
|
|
41
|
+
TransitionalLogger.logger.expects(:info).at_least_once
|
|
42
|
+
puts 'hi'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it '#file requires args' do
|
|
46
|
+
lambda {TransitionalLogger.file}.must_raise ArgumentError
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'transitional_logger'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "transitional_logger"
|
|
8
|
+
spec.version = TransitionalLogger::VERSION
|
|
9
|
+
spec.authors = ["Elon Flegenheimer"]
|
|
10
|
+
spec.email = ["elonf@hotmail.com"]
|
|
11
|
+
spec.description = "Singleton logger available in all Objects that can transition destinations."
|
|
12
|
+
spec.summary = "Singleton logger available in all Objects that can transition destinations."
|
|
13
|
+
spec.homepage = ""
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files`.split($/)
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
|
22
|
+
spec.add_development_dependency "rake"
|
|
23
|
+
spec.add_development_dependency "mocha"
|
|
24
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: transitional_logger
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Elon Flegenheimer
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2013-10-04 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: bundler
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ~>
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '1.3'
|
|
22
|
+
type: :development
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ~>
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '1.3'
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
name: rake
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
none: false
|
|
34
|
+
requirements:
|
|
35
|
+
- - ! '>='
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '0'
|
|
38
|
+
type: :development
|
|
39
|
+
prerelease: false
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ! '>='
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: mocha
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
none: false
|
|
50
|
+
requirements:
|
|
51
|
+
- - ! '>='
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ! '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
description: Singleton logger available in all Objects that can transition destinations.
|
|
63
|
+
email:
|
|
64
|
+
- elonf@hotmail.com
|
|
65
|
+
executables: []
|
|
66
|
+
extensions: []
|
|
67
|
+
extra_rdoc_files: []
|
|
68
|
+
files:
|
|
69
|
+
- .gitignore
|
|
70
|
+
- Gemfile
|
|
71
|
+
- LICENSE.txt
|
|
72
|
+
- README.md
|
|
73
|
+
- Rakefile
|
|
74
|
+
- lib/transitional_logger.rb
|
|
75
|
+
- test/transitional_logger_spec.rb
|
|
76
|
+
- transitional_logger.gemspec
|
|
77
|
+
homepage: ''
|
|
78
|
+
licenses:
|
|
79
|
+
- MIT
|
|
80
|
+
post_install_message:
|
|
81
|
+
rdoc_options: []
|
|
82
|
+
require_paths:
|
|
83
|
+
- lib
|
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
85
|
+
none: false
|
|
86
|
+
requirements:
|
|
87
|
+
- - ! '>='
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
|
+
none: false
|
|
92
|
+
requirements:
|
|
93
|
+
- - ! '>='
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0'
|
|
96
|
+
requirements: []
|
|
97
|
+
rubyforge_project:
|
|
98
|
+
rubygems_version: 1.8.25
|
|
99
|
+
signing_key:
|
|
100
|
+
specification_version: 3
|
|
101
|
+
summary: Singleton logger available in all Objects that can transition destinations.
|
|
102
|
+
test_files:
|
|
103
|
+
- test/transitional_logger_spec.rb
|