teelogger 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 269cc8e131a866bd9a63206c5e20f33c02c3c3a9
4
+ data.tar.gz: 4aa61d289eebf2f4696ca5629be0a147c318f788
5
+ SHA512:
6
+ metadata.gz: 5182be9dadb8218c3cefd5507ade52d58a431507ef8f179bc743dff1486fc7f71d62284610f09505315e63f1693a32d7152ed03ce3275558baf63ea47906b8ac
7
+ data.tar.gz: 9401f09297f125f6aecc8bfa07eeb657e22a269af817a6afa32fe2bee3e6dab7a801f0f3cfde02ab00b9dcacca0bd05ad43b9c50dec284f2ce5426fd0fbc4eed
@@ -0,0 +1,24 @@
1
+ *.gem
2
+ *.rbc
3
+ .*.sw*
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ *.bundle
20
+ *.so
21
+ *.o
22
+ *.a
23
+ mkmf.log
24
+ .ruby-version
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in teelogger.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,30 @@
1
+ Copyright spriteCloud B.V. (http://www.spritecloud.com/) and other teelogger
2
+ contributors. All rights not covered below are reserved.
3
+
4
+ MIT +no-false-attribs License
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to
8
+ deal in the Software without restriction, including without limitation the
9
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10
+ sell copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ Distributions of all or part of the Software intended to be used by the
17
+ recipients as they would use the unmodified Software, containing modifications
18
+ that substantially alter, remove, or disable functionality of the Software,
19
+ outside of the documented configuration mechanisms provided by the Software,
20
+ shall be modified such that the Original Author's bug reporting email addresses
21
+ and urls are either replaced with the contact information of the parties
22
+ responsible for the changes, or removed entirely.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30
+ IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # Teelogger
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'teelogger'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install teelogger
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/teelogger/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,42 @@
1
+ @logger
2
+ Feature: Logger
3
+ As a user of the teelogger gem
4
+ When I use the TeeLogger class
5
+ I expect it to work as documented.
6
+
7
+ @logger_01
8
+ Scenario Outline: Default parameters
9
+ Given I create a TeeLogger with default parameters
10
+ And I set the log level to "<level>"
11
+ And I write a log message at log level "<level>"
12
+ Then I expect the log level "<level>" to have taken hold
13
+ And I expect the log message to appear on the screen
14
+
15
+ Examples:
16
+ | level |
17
+ | DEBUG |
18
+ | INFO |
19
+ | WARN |
20
+ | ERROR |
21
+ | FATAL |
22
+
23
+ @logger_02
24
+ Scenario Outline: I/O object
25
+ Given I create a TeeLogger with an IO object
26
+ And I set the log level to "<level>"
27
+ And I write a log message at log level "<level>"
28
+ Then I expect the log level "<level>" to have taken hold
29
+ And I expect the log message to appear in the IO object
30
+
31
+ Examples:
32
+ | level |
33
+ | DEBUG |
34
+ | INFO |
35
+ | WARN |
36
+ | ERROR |
37
+ | FATAL |
38
+
39
+ @logger_03
40
+ Scenario: multiple loggers
41
+ Given I create a TeeLogger with multiple loggers
42
+ Then I expect the class to let me access all loggers like a hash
@@ -0,0 +1,55 @@
1
+ require 'test/unit/assertions'
2
+
3
+ message = "test message"
4
+ io = nil
5
+ logger = nil
6
+
7
+ Given(/^I create a TeeLogger with default parameters$/) do
8
+ logger = TeeLogger::TeeLogger.new
9
+ end
10
+
11
+ Given(/^I set the log level to "(.*?)"$/) do |level|
12
+ logger.level = level
13
+ end
14
+
15
+ Given(/^I write a log message at log level "(.*?)"$/) do |level|
16
+ meth = level.downcase.to_sym
17
+ res = logger.send(meth, message)
18
+ end
19
+
20
+ Then(/^I expect the log message to appear on the screen$/) do
21
+ puts "Can't test this; please check manually"
22
+ end
23
+
24
+ Then(/^I expect the log level "(.*?)" to have taken hold$/) do |level|
25
+ meth = "#{level.downcase}?".to_sym
26
+ res = logger.send(meth)
27
+
28
+ assert res, "Log level not active!"
29
+ end
30
+
31
+
32
+ Given(/^I create a TeeLogger with an IO object$/) do
33
+ io = StringIO.new
34
+ logger = TeeLogger::TeeLogger.new io
35
+ end
36
+
37
+ Then(/^I expect the log message to appear in the IO object$/) do
38
+ assert io.string.include?(message), "Test message '#{message}' not included in output."
39
+ end
40
+
41
+ Given(/^I create a TeeLogger with multiple loggers$/) do
42
+ args = []
43
+ 3.times do
44
+ args << StringIO.new
45
+ end
46
+ logger = TeeLogger::TeeLogger.new *args
47
+ end
48
+
49
+ Then(/^I expect the class to let me access all loggers like a hash$/) do
50
+ assert (3 == logger.length), "Expected 3 loggers, got #{logger.length}"
51
+ logger.each do |key, logger|
52
+ assert logger.is_a?(Logger), "Found a non-Logger object."
53
+ end
54
+ end
55
+
@@ -0,0 +1 @@
1
+ require "teelogger"
@@ -0,0 +1,199 @@
1
+ #
2
+ # TeeLogger
3
+ # https://github.com/spriteCloud/teelogger
4
+ #
5
+ # Copyright (c) 2014 spriteCloud B.V. and other TeeLogger contributors.
6
+ # All rights reserved.
7
+ #
8
+ require "teelogger/version"
9
+
10
+ require "logger"
11
+
12
+ module TeeLogger
13
+ ##
14
+ # Logger that writes to multiple outputs. Behaves just like Ruby's Logger,
15
+ # and like a hash of String => Logger.
16
+ #
17
+ # A typical use might be to log to STDOUT, but also to a file:
18
+ # log = TeeLogger.new(STDOUT, "filename.log")
19
+ # log.level = Logger::WARN # applies to all outputs
20
+ # log.level = "INFO" # convenience shortcut
21
+ #
22
+ # By using the instance as a hash, you can also set individual log levels
23
+ # for individual loggers:
24
+ # log = TeeLogger.new(STDOUT, "filename.log")
25
+ # log.each do |name, logger|
26
+ # if name.include?("filename.log")
27
+ # logger.level = "WARN"
28
+ # else
29
+ # logger.level = "DEBUG"
30
+ # end
31
+ # end
32
+ class TeeLogger
33
+ @default_level = Logger::Severity::INFO
34
+ @loggers
35
+
36
+
37
+ ##
38
+ # Add a logger to the current loggers.
39
+ def add_logger(arg)
40
+ key = nil
41
+ logger = nil
42
+ if arg.is_a? String
43
+ # We have a filename
44
+ key = File.basename(arg)
45
+
46
+ # Try to create the logger.
47
+ file = File.new(arg, File::WRONLY | File::APPEND | File::CREAT)
48
+ logger = Logger.new(file)
49
+
50
+ # Initialize logger
51
+ logger.unknown "Logging to '#{arg}' initialized with level #{string_level(@default_level)}."
52
+ logger.level = convert_level(@default_level)
53
+ else
54
+ # We have some other object - let's hope it's an IO object
55
+ key = arg.to_s
56
+
57
+ # Try to create the logger.
58
+ logger = Logger.new(arg)
59
+
60
+ # Initialize logger
61
+ logger.unknown "Logging to #{key} initialized with level #{string_level(@default_level)}."
62
+ logger.level = convert_level(@default_level)
63
+ end
64
+
65
+ if not key.nil? and not logger.nil?
66
+ @loggers[key] = logger
67
+ end
68
+ end
69
+
70
+
71
+ ##
72
+ # Start with any amount of IO objects or filenames; defaults to STDOUT
73
+ def initialize(*args)
74
+ # Handle default
75
+ if args.empty?
76
+ args = [STDOUT]
77
+ end
78
+
79
+ # Initialization
80
+ @loggers = {}
81
+
82
+ # Create logs for all arguments
83
+ args.each do |arg|
84
+ add_logger(arg)
85
+ end
86
+ end
87
+
88
+ ##
89
+ # Convert a log level to its string name
90
+ def string_level(level)
91
+ if level.is_a? String
92
+ return level
93
+ end
94
+
95
+ Logger::Severity.constants.each do |const|
96
+ if level == Logger.const_get(const)
97
+ return const
98
+ end
99
+ end
100
+
101
+ return nil
102
+ end
103
+
104
+ ##
105
+ # Convert a string log level to its constant value
106
+ def convert_level(val)
107
+ if val.is_a? String
108
+ begin
109
+ val = Logger.const_get(val)
110
+ rescue NameError
111
+ val = Logger::Severity::WARN
112
+ end
113
+ end
114
+
115
+ return val
116
+ end
117
+
118
+
119
+ ##
120
+ # Set log level; override this to also accept strings
121
+ def level=(val)
122
+ # Convert strings to the constant value
123
+ val = convert_level(val)
124
+
125
+ # Update the default log level
126
+ @default_level = val
127
+
128
+ # Set all loggers' log levels
129
+ @loggers.each do |key, logger|
130
+ logger.level = val
131
+ end
132
+ end
133
+
134
+
135
+ ##
136
+ # Log an exception
137
+ def exception(message, ex)
138
+ error("#{message} got #{ex.message}:\n#{ex.backtrace.join("\n")}")
139
+ end
140
+
141
+
142
+ ##
143
+ # Every function this class doesn't have should be mapped to the original
144
+ # logger
145
+ def respond_to?(meth)
146
+ if @loggers.nil? or @loggers.empty?
147
+ raise "No loggers created, can't do anything."
148
+ end
149
+
150
+ meth_name = meth.to_s
151
+
152
+ # All loggers are the same, so we need to check only one of them.
153
+ @loggers.each do |key, logger|
154
+ if logger.respond_to? meth_name
155
+ return true
156
+ end
157
+ break
158
+ end
159
+
160
+ # If this didn't work, we're also emulating a hash
161
+ return @loggers.respond_to? meth_name
162
+ end
163
+
164
+ def method_missing(meth, *args, &block)
165
+ meth_name = meth.to_s
166
+
167
+ if @loggers.nil? or @loggers.empty?
168
+ raise "No loggers created, can't do anything."
169
+ end
170
+
171
+ # Compose message
172
+ message = ""
173
+ args.each do |arg|
174
+ message += arg.inspect
175
+ end
176
+
177
+ # Try to write the message to all loggers.
178
+ ret = []
179
+ @loggers.each do |key, logger|
180
+ if logger.respond_to? meth_name
181
+ if args.length > 0
182
+ ret << logger.send(meth_name, "[#{key}] #{message}", &block)
183
+ else
184
+ ret << logger.send(meth_name, *args, &block)
185
+ end
186
+ end
187
+ end
188
+
189
+ # Some double checking on the return value(s).
190
+ if not ret.empty?
191
+ return ret
192
+ end
193
+
194
+ # If the method wasn't from the loggers, we'll try to send it to the
195
+ # hash.
196
+ return @loggers.send(meth_name, *args, &block)
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,10 @@
1
+ #
2
+ # TeeLogger
3
+ # https://github.com/spriteCloud/teelogger
4
+ #
5
+ # Copyright (c) 2014 spriteCloud B.V. and other TeeLogger contributors.
6
+ # All rights reserved.
7
+ #
8
+ module TeeLogger
9
+ VERSION = "0.1.0"
10
+ 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 'teelogger/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "teelogger"
8
+ spec.version = TeeLogger::VERSION
9
+ spec.authors = ["Jens Finkhaeuser"]
10
+ spec.email = ["foss@spritecloud.com"]
11
+ spec.summary = %q{Mini wrapper around Ruby Logger for logging to multiple destinations.}
12
+ spec.description = %q{Mini wrapper around Ruby Logger for logging to multiple destinations.}
13
+ spec.homepage = "https://github.com/spriteCloud/teelogger"
14
+ spec.license = "MITNFA"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
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.6"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "cucumber"
24
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: teelogger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jens Finkhaeuser
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cucumber
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Mini wrapper around Ruby Logger for logging to multiple destinations.
56
+ email:
57
+ - foss@spritecloud.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE
65
+ - README.md
66
+ - Rakefile
67
+ - features/logger.feature
68
+ - features/step_definitions/steps.rb
69
+ - features/support/env.rb
70
+ - lib/teelogger.rb
71
+ - lib/teelogger/version.rb
72
+ - teelogger.gemspec
73
+ homepage: https://github.com/spriteCloud/teelogger
74
+ licenses:
75
+ - MITNFA
76
+ metadata: {}
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 2.0.3
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: Mini wrapper around Ruby Logger for logging to multiple destinations.
97
+ test_files:
98
+ - features/logger.feature
99
+ - features/step_definitions/steps.rb
100
+ - features/support/env.rb