madvertise-logging 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use --create ruby-1.9.3-p0@madvertise-logging
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in madvertise-logging.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'rspec'
8
+ gem 'simplecov'
9
+ gem 'syslogger', :require => false
10
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 madvertise Mobile Advertising GmbH
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,29 @@
1
+ # Madvertise::Logging
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'madvertise-logging'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install madvertise-logging
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require "bundler/setup"
4
+ require "bundler/gem_tasks"
5
+
6
+ Dir['tasks/**/*.rake'].each { |t| load t }
7
+
8
+ task :default => [:spec]
@@ -0,0 +1,3 @@
1
+ require 'madvertise/logging/version'
2
+ require 'madvertise/logging/improved_logger'
3
+ require 'madvertise/logging/multi_logger'
@@ -0,0 +1,265 @@
1
+ require 'logger'
2
+ require 'stringio'
3
+
4
+ module Madvertise
5
+ module Logging
6
+ class ImprovedLogger
7
+
8
+ attr_accessor :copy_to_stdout
9
+ attr_accessor :transaction_token
10
+ attr_accessor :progname
11
+
12
+ @severities = {
13
+ :debug => Logger::DEBUG,
14
+ :info => Logger::INFO,
15
+ :warn => Logger::WARN,
16
+ :error => Logger::ERROR,
17
+ :fatal => Logger::FATAL,
18
+ :unknown => Logger::UNKNOWN
19
+ }
20
+
21
+ @silencer = true
22
+
23
+ class << self
24
+ attr_reader :severities
25
+ attr_accessor :silencer
26
+ end
27
+
28
+ def initialize(logfile = nil, progname = nil)
29
+ @copy_to_stdout = false
30
+ @progname = progname || File.basename($0)
31
+ self.logger = logfile || STDERR
32
+ end
33
+
34
+ # Silence the logger for the duration of the block.
35
+ def silence(temporary_level = :error)
36
+ if self.class.silencer
37
+ begin
38
+ old_level, self.level = self.level, temporary_level
39
+ yield self
40
+ ensure
41
+ self.level = old_level
42
+ end
43
+ else
44
+ yield self
45
+ end
46
+ end
47
+
48
+ def debug(msg)
49
+ add(:debug, msg)
50
+ end
51
+
52
+ def debug?
53
+ self.level == :debug
54
+ end
55
+
56
+ def info(msg)
57
+ add(:info, msg)
58
+ end
59
+
60
+ def info?
61
+ self.level == :info
62
+ end
63
+
64
+ def warn(msg)
65
+ add(:warn, msg)
66
+ end
67
+
68
+ def warn?
69
+ self.level == :warn
70
+ end
71
+
72
+ def error(msg)
73
+ add(:error, msg)
74
+ end
75
+
76
+ def error?
77
+ self.level == :error
78
+ end
79
+
80
+ def fatal(msg)
81
+ add(:fatal, msg)
82
+ end
83
+
84
+ def fatal?
85
+ self.level == :fatal
86
+ end
87
+
88
+ def unknown(msg)
89
+ add(:unknown, msg)
90
+ end
91
+
92
+ def unknown?
93
+ self.level == :unknown
94
+ end
95
+
96
+ def exception(e)
97
+ if e.is_a?(::Exception)
98
+ message = "EXCEPTION: #{e.message}: #{clean_trace(e.backtrace)}"
99
+ else
100
+ message = e
101
+ end
102
+ add(:error, message, true)
103
+ end
104
+
105
+ def add(severity, message, skip_caller = false)
106
+ message = "#{called(caller)}: #{message}" unless skip_caller
107
+ message = "[#{@transaction_token}] #{message}" if @transaction_token
108
+
109
+ self.logger.add(self.class.severities[severity]) { message }
110
+
111
+ STDOUT.puts(message) if self.copy_to_stdout && self.class.severities[severity] >= self.logger.level
112
+ end
113
+
114
+ def level
115
+ self.class.severities.invert[@logger.level]
116
+ end
117
+
118
+ def level=(level)
119
+ level = (Symbol === level ? self.class.severities[level] : level)
120
+ self.logger.level = level
121
+ end
122
+
123
+ def new_transaction(v)
124
+ @transaction_token = v
125
+ end
126
+
127
+ def end_transaction
128
+ @transaction_token = nil
129
+ end
130
+
131
+ def save_transaction(obj)
132
+ if @transaction_token && obj
133
+ @transactions ||= {}
134
+ @transactions[obj.object_id] = @transaction_token
135
+ end
136
+ end
137
+
138
+ def restore_transaction(obj)
139
+ @transactions ||= {}
140
+ @transaction_token = @transactions.delete(obj.object_id) if obj
141
+ end
142
+
143
+ def logger
144
+ @logger ||= create_logger
145
+ end
146
+
147
+ def logger=(value)
148
+ @logger.close rescue nil
149
+
150
+ if value.is_a?(Logger)
151
+ @backend = :logger
152
+ @logger = value
153
+ elsif value.is_a?(Symbol)
154
+ @backend = value
155
+ @logger = create_logger
156
+ else
157
+ @backend = :logger
158
+ @logfile = value
159
+ @logger = create_logger
160
+ end
161
+ end
162
+
163
+ def clean_trace(trace)
164
+ trace = trace.map { |l| l.gsub(ROOT, '') }
165
+ trace = trace.reject { |l| l =~ /gems\/madvertise-logging/ }
166
+ trace = trace.reject { |l| l =~ /vendor\/madvertise-logging/ }
167
+ trace
168
+ end
169
+
170
+ def close
171
+ case @backend
172
+ when :logger
173
+ self.logger.close
174
+ @logger = nil
175
+ end
176
+ end
177
+
178
+ def buffer
179
+ if @backend == :buffer && @buffer
180
+ @buffer.string
181
+ end
182
+ end
183
+
184
+ private
185
+
186
+ def called(trace)
187
+ l = trace.detect('unknown:0') do |l|
188
+ l.index(File.basename(__FILE__)).nil?
189
+ end
190
+
191
+ file, num, _ = l.split(':')
192
+ [ File.basename(file), num ].join(':')
193
+ end
194
+
195
+ def create_logger
196
+ case @backend
197
+ when :buffer
198
+ create_buffering_logger
199
+ when :syslog
200
+ create_syslog_logger
201
+ else
202
+ create_standard_logger
203
+ end
204
+ end
205
+
206
+ def create_buffering_logger
207
+ @buffer = StringIO.new
208
+ Logger.new(@buffer).tap do |l|
209
+ l.formatter = Formatter.new
210
+ l.progname = progname
211
+ end
212
+ end
213
+
214
+ def create_standard_logger
215
+ @logfile ||= STDERR
216
+
217
+ if @logfile.is_a?(String)
218
+ logdir = File.dirname(@logfile)
219
+
220
+ begin
221
+ FileUtils.mkdir_p(logdir)
222
+ rescue
223
+ STDERR.puts "#{logdir} not writable, using STDERR for logging"
224
+ @logfile = STDERR
225
+ end
226
+ end
227
+
228
+ Logger.new(@logfile).tap do |l|
229
+ l.formatter = Formatter.new
230
+ l.progname = progname
231
+ end
232
+ end
233
+
234
+ def create_syslog_logger
235
+ begin
236
+ require 'syslogger'
237
+ Syslogger.new(progname, Syslog::LOG_PID, Syslog::LOG_LOCAL1)
238
+ rescue LoadError
239
+ self.logger = :logger
240
+ self.error("Couldn't load syslogger gem, reverting to standard logger")
241
+ end
242
+ end
243
+
244
+ class Formatter
245
+
246
+ # YYYY:MM:DD HH:MM:SS.MS daemon_name(pid) level: message
247
+ @format = "%s %s(%d) [%s] %s\n"
248
+
249
+ class << self
250
+ attr_accessor :format
251
+ end
252
+
253
+ def call(severity, time, progname, msg)
254
+ self.class.format % [format_time( time ), progname, $$, severity, msg.to_s]
255
+ end
256
+
257
+ private
258
+
259
+ def format_time(time)
260
+ time.strftime("%Y-%m-%d %H:%M:%S.") + time.usec.to_s
261
+ end
262
+ end
263
+ end
264
+ end
265
+ end
@@ -0,0 +1,24 @@
1
+ module Madvertise
2
+ module Logging
3
+ class MultiLogger
4
+ def initialize(*loggers)
5
+ @loggers = loggers
6
+ end
7
+
8
+ def attach(logger)
9
+ logger.new_transaction(@loggers.first.transaction_token)
10
+ @loggers << logger
11
+ end
12
+
13
+ def detach(logger)
14
+ @loggers.delete(logger)
15
+ end
16
+
17
+ def method_missing(name, *args)
18
+ @loggers.each do |l|
19
+ l.send(name, *args)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ module Madvertise
2
+ module Logging
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/madvertise/logging/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Benedikt Böhm"]
6
+ gem.email = ["benedikt.boehm@madvertise.com"]
7
+ gem.description = %q{Advanced logging classes with buffer backend, transactions, multi logger, etc}
8
+ gem.summary = %q{Advanced logging classes with buffer backend, transactions, multi logger, etc}
9
+ gem.homepage = "https://github.com/madvertise/logging"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "madvertise-logging"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Madvertise::Logging::VERSION
17
+
18
+ gem.add_development_dependency("bundler")
19
+ gem.add_development_dependency("rake")
20
+ end
@@ -0,0 +1,239 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ include Madvertise::Logging
4
+
5
+ RSpec::Matchers.define :have_received_message do |expected|
6
+ match do |actual|
7
+ IO.readlines(actual).last.match(Regexp.new(expected))
8
+ end
9
+ end
10
+
11
+ describe ImprovedLogger do
12
+
13
+ before(:each) do
14
+ @logfile = "#{ROOT}/log/spec.log"
15
+ @logger = ImprovedLogger.new(@logfile)
16
+ @logger.level = :debug
17
+ end
18
+
19
+ it "should have a backend logger" do
20
+ @logger.logger.should_not be_nil
21
+ end
22
+
23
+ it "should accept a different backend" do
24
+ l = Logger.new('/dev/null')
25
+ @logger.logger = l
26
+ @logger.logger.should == l
27
+ end
28
+
29
+ it "should be able to log to STDOUT as well" do
30
+ @logger.copy_to_stdout = true
31
+ STDOUT.should_receive(:puts).with(/test/)
32
+
33
+ @logger.debug "test"
34
+ @logfile.should have_received_message("test")
35
+ end
36
+
37
+ it "should log debug level messages" do
38
+ @logger.debug("Debug test")
39
+ @logfile.should have_received_message(/\[DEBUG\].*Debug test/)
40
+ end
41
+
42
+ it "should return true if debug level is set" do
43
+ @logger.level = :debug
44
+ @logger.debug?.should be true
45
+ end
46
+
47
+ it "should log info level messages" do
48
+ @logger.info("Info test")
49
+ @logfile.should have_received_message(/\[INFO\].*Info test/)
50
+ end
51
+
52
+ it "should return true if info level is set" do
53
+ @logger.level = :info
54
+ @logger.info?.should be true
55
+ end
56
+
57
+ it "should log warn level messages" do
58
+ @logger.warn("Warn test")
59
+ @logfile.should have_received_message(/\[WARN\].*Warn test/)
60
+ end
61
+
62
+ it "should return true if warn level is set" do
63
+ @logger.level = :warn
64
+ @logger.warn?.should be true
65
+ end
66
+
67
+ it "should log error level messages" do
68
+ @logger.error("Err test")
69
+ @logfile.should have_received_message(/\[ERROR\].*Err test/)
70
+ end
71
+
72
+ it "should return true if error level is set" do
73
+ @logger.level = :error
74
+ @logger.error?.should be true
75
+ end
76
+
77
+ it "should log fatal level messages" do
78
+ @logger.fatal("Fatal test")
79
+
80
+ @logfile.should have_received_message(/\[FATAL\].*Fatal test/)
81
+ end
82
+
83
+ it "should return true if fatal level is set" do
84
+ @logger.level = :fatal
85
+ @logger.fatal?.should be true
86
+ end
87
+
88
+ it "should log unknown level messages" do
89
+ @logger.unknown("Unknown test")
90
+ @logfile.should have_received_message(/\[ANY\].*Unknown test/)
91
+ end
92
+
93
+ it "should return true if unknown level is set" do
94
+ @logger.level = :unknown
95
+ @logger.unknown?.should be true
96
+ end
97
+
98
+ it "should log the caller file and line number" do
99
+ f = File.basename(__FILE__)
100
+ l = __LINE__ + 2
101
+
102
+ @logger.info("Caller test")
103
+ @logfile.should have_received_message("#{f}:#{l}:")
104
+ end
105
+
106
+ it "should log exceptions with daemon traces" do
107
+ fake_trace = [
108
+ "/home/jdoe/app/libexec/app.rb:1:in `foo'",
109
+ "/usr/lib/ruby/gems/1.8/gems/madvertise-logging-0.1.0/lib/madvertise/logging/improved_logger.rb:42: in `info'"
110
+ ]
111
+
112
+ e = RuntimeError.new('Test error')
113
+ e.set_backtrace(fake_trace)
114
+
115
+ @logger.exception(e)
116
+ @logfile.should have_received_message("EXCEPTION: Test error")
117
+ end
118
+
119
+ it "should log exceptions without framework traces" do
120
+ fake_trace = [
121
+ "/home/jdoe/app/libexec/app.rb:1:in `foo'",
122
+ "/usr/lib/ruby/gems/1.8/gems/madvertise-logging-0.1.0/lib/madvertise/logging/improved_logger.rb:42: in `info'"
123
+ ]
124
+
125
+ clean_trace = @logger.clean_trace(fake_trace)
126
+ clean_trace.should include("/home/jdoe/app/libexec/app.rb:1:in `foo'")
127
+ clean_trace.should_not include("/usr/lib/ruby/gems/1.8/gems/madvertise-logging-0.1.0/lib/madvertise/logging/improved_logger.rb:42: in `info'")
128
+ end
129
+
130
+ it "should not handle a backtrace if object is not an exception" do
131
+ @logger.exception("not an exception object")
132
+ @logfile.should_not have_received_message("EXCEPTION:")
133
+ end
134
+
135
+ it "should support reopening log files" do
136
+ @logger.close
137
+
138
+ FileUtils.rm(@logfile)
139
+
140
+ @logger.info('Reopen')
141
+ @logfile.should have_received_message("Reopen")
142
+ end
143
+
144
+ it "should support silencing" do
145
+ @logger.silence do |logger|
146
+ logger.info "This should never be logged"
147
+ end
148
+
149
+ @logfile.should_not have_received_message("This should never be logged")
150
+
151
+ @logger.info "This should be logged"
152
+ @logfile.should have_received_message("This should be logged")
153
+ end
154
+
155
+ it "should not discard messages if silencer is disabled globally" do
156
+ ImprovedLogger.silencer = false
157
+
158
+ @logger.silence do |logger|
159
+ logger.info "This should actually be logged"
160
+ end
161
+
162
+ @logfile.should have_received_message("This should actually be logged")
163
+
164
+ ImprovedLogger.silencer = true
165
+ end
166
+
167
+ it "should support a transaction token" do
168
+ token = "3d5e27f7-b97c-4adc-b1fd-adf1bd4314e0"
169
+
170
+ @logger.new_transaction(token)
171
+ @logger.info "This should include a transaction token"
172
+ @logfile.should have_received_message(token)
173
+
174
+ @logger.end_transaction
175
+ @logger.info "This should not include a transaction token"
176
+ @logfile.should_not have_received_message(token)
177
+ end
178
+
179
+ it "should support save/restore on transaction tokens" do
180
+ token1 = "3d5e27f7-b97c-4adc-b1fd-adf1bd4314e0"
181
+ token2 = "1bdef605-34b9-4ec7-9a1c-cb58efc8a635"
182
+
183
+ obj1 = Object.new
184
+
185
+ @logger.new_transaction(token1)
186
+ @logger.info "This should include transaction token1"
187
+ @logfile.should have_received_message(token1)
188
+
189
+ @logger.save_transaction(obj1)
190
+ @logger.new_transaction(token2)
191
+ @logger.info "This should include transaction token2"
192
+ @logfile.should have_received_message(token2)
193
+ @logger.end_transaction
194
+
195
+ @logger.restore_transaction(obj1)
196
+ @logger.info "This should include transaction token1"
197
+ @logfile.should have_received_message(token1)
198
+
199
+ @logger.end_transaction
200
+ @logger.info "This should not include a transaction token"
201
+ @logfile.should_not have_received_message(token1)
202
+ @logfile.should_not have_received_message(token2)
203
+ end
204
+
205
+ it "should support a buffered logger" do
206
+ @logger = ImprovedLogger.new(:buffer)
207
+ @logger.level = :debug
208
+ @logger.info "test"
209
+ @logger.buffer.should match(/test/)
210
+ end
211
+
212
+ it "should fall back to STDERR if logfile is not writable" do
213
+ STDERR.should_receive(:puts).with(/not writable.*STDERR/)
214
+
215
+ @logfile = "/not/writable/spec.log"
216
+ @logger = ImprovedLogger.new(@logfile)
217
+ @logger.level = :debug
218
+
219
+ STDERR.should_receive(:write).with(/test/)
220
+ @logger.info "test"
221
+ end
222
+
223
+ it "should fallback to standard logger if syslogger gem is missing" do
224
+ syslogger_paths = $:.select { |p| p.match(/gems\/.*syslogger-/) }
225
+ $:.replace($: - syslogger_paths)
226
+
227
+ STDERR.should_receive(:write).with(/reverting to standard logger/)
228
+ @logger = ImprovedLogger.new(:syslog)
229
+ @logger.logger.should be_instance_of(Logger)
230
+
231
+ $:.replace($: + syslogger_paths)
232
+ end
233
+
234
+ it "should support a syslog backend" do
235
+ @logger = ImprovedLogger.new(:syslog)
236
+ @logger.level = :debug
237
+ @logger.logger.should be_instance_of(Syslogger)
238
+ end
239
+ end
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ include Madvertise::Logging
4
+
5
+ describe MultiLogger do
6
+
7
+ before(:each) do
8
+ @logger = ImprovedLogger.new
9
+ @logger.level = :debug
10
+ @ml = MultiLogger.new(@logger)
11
+ end
12
+
13
+ it "should support attach/detach of loggers" do
14
+ buflog = ImprovedLogger.new(:buffer)
15
+ @ml.attach(buflog)
16
+
17
+ STDERR.should_receive(:write).with(/test1/)
18
+ @ml.info("test1")
19
+ buflog.buffer.should match(/test1/)
20
+
21
+ @ml.detach(buflog)
22
+
23
+ STDERR.should_receive(:write).with(/test2/)
24
+ @ml.info("test2")
25
+ buflog.buffer.should_not match(/test2/)
26
+ end
27
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'fileutils'
4
+
5
+ require 'simplecov'
6
+ SimpleCov.start
7
+
8
+ ROOT = "#{File.dirname(__FILE__)}/../tmp"
9
+
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
+ require 'madvertise-logging'
12
+
13
+ RSpec.configure do |config|
14
+ # == Mock Framework
15
+ #
16
+ # RSpec uses it's own mocking framework by default. If you prefer to
17
+ # use mocha, flexmock or RR, uncomment the appropriate line:
18
+ #
19
+ # config.mock_with :mocha
20
+ # config.mock_with :flexmock
21
+ # config.mock_with :rr
22
+
23
+ # setup a fake root
24
+ config.before(:all) { File.directory?(ROOT) ? FileUtils.rm_rf("#{ROOT}/*") : FileUtils.mkdir_p(ROOT) }
25
+ config.after(:all) { FileUtils.rm_rf("#{ROOT}/*") }
26
+ end
data/tasks/rspec.rake ADDED
@@ -0,0 +1,20 @@
1
+ begin
2
+ require 'rspec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'rspec'
6
+ end
7
+
8
+ begin
9
+ require 'rspec/core/rake_task'
10
+
11
+ desc "Run the specs"
12
+ RSpec::Core::RakeTask.new do |t|
13
+ t.rspec_opts = ['--options', "spec/spec.opts"]
14
+ end
15
+ rescue LoadError
16
+ puts <<-EOS
17
+ To use rspec for testing you must install rspec gem:
18
+ gem install rspec
19
+ EOS
20
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: madvertise-logging
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Benedikt Böhm
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: &15364280 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *15364280
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &15363560 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *15363560
36
+ description: Advanced logging classes with buffer backend, transactions, multi logger,
37
+ etc
38
+ email:
39
+ - benedikt.boehm@madvertise.com
40
+ executables: []
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - .gitignore
45
+ - .rvmrc
46
+ - Gemfile
47
+ - LICENSE
48
+ - README.md
49
+ - Rakefile
50
+ - lib/madvertise-logging.rb
51
+ - lib/madvertise/logging/improved_logger.rb
52
+ - lib/madvertise/logging/multi_logger.rb
53
+ - lib/madvertise/logging/version.rb
54
+ - madvertise-logging.gemspec
55
+ - spec/improved_logger_spec.rb
56
+ - spec/multi_logger_spec.rb
57
+ - spec/spec.opts
58
+ - spec/spec_helper.rb
59
+ - tasks/rspec.rake
60
+ homepage: https://github.com/madvertise/logging
61
+ licenses: []
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ segments:
73
+ - 0
74
+ hash: 3354586897547183297
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ segments:
82
+ - 0
83
+ hash: 3354586897547183297
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 1.8.10
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Advanced logging classes with buffer backend, transactions, multi logger,
90
+ etc
91
+ test_files:
92
+ - spec/improved_logger_spec.rb
93
+ - spec/multi_logger_spec.rb
94
+ - spec/spec.opts
95
+ - spec/spec_helper.rb