madvertise-logging 0.2.2 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm use --create ruby-1.9.3-p0@madvertise-logging
1
+ rvm use --create ruby-1.9.3-p125@madvertise-logging
data/Gemfile CHANGED
@@ -3,6 +3,12 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in madvertise-logging.gemspec
4
4
  gemspec
5
5
 
6
+ group :development do
7
+ gem 'rake'
8
+ gem 'pry'
9
+ gem 'pry-doc'
10
+ end
11
+
6
12
  group :test do
7
13
  gem 'rspec'
8
14
  gem 'simplecov'
@@ -0,0 +1,159 @@
1
+ module Madvertise
2
+ module Logging
3
+
4
+ ##
5
+ # ImprovedIO is a subclass of IO with a bunch of methods reimplemented so
6
+ # that subclasses don't have to reimplement every IO method. Unfortunately
7
+ # this is necessary because Ruby does not provide a sane interface to IO
8
+ # like Enumerable for Arrays and Hashes.
9
+ #
10
+ class ImprovedIO < IO
11
+
12
+ def flush
13
+ self
14
+ end
15
+
16
+ def external_encoding
17
+ nil
18
+ end
19
+
20
+ def internal_encoding
21
+ nil
22
+ end
23
+
24
+ def set_encoding
25
+ self
26
+ end
27
+
28
+ def readbyte
29
+ getbyte.tap do |byte|
30
+ raise EOFError unless byte
31
+ end
32
+ end
33
+
34
+ def readchar
35
+ getc.tap do |char|
36
+ raise EOFError unless char
37
+ end
38
+ end
39
+
40
+ def readline
41
+ gets.tap do |string|
42
+ raise EOFError unless string
43
+ end
44
+ end
45
+
46
+ def tty?
47
+ false
48
+ end
49
+
50
+ def printf(format_string, *arguments)
51
+ write(sprintf(format_string, *arguments))
52
+ return nil
53
+ end
54
+
55
+ def print(*arguments)
56
+ args = if arguments.empty?
57
+ [$_]
58
+ else
59
+ arguments
60
+ end
61
+
62
+ write(args.join($,))
63
+ return nil
64
+ end
65
+
66
+ def putc
67
+ end
68
+
69
+ def puts(*arguments)
70
+ return nil if arguments.empty?
71
+
72
+ arguments.each do |arg|
73
+ if arg.is_a?(Array)
74
+ puts(*arg)
75
+ elsif arg.is_a?(String)
76
+ write(arg)
77
+ else
78
+ write(arg.to_s)
79
+ end
80
+ end
81
+
82
+ return nil
83
+ end
84
+
85
+ # provide sane aliases for IO compat
86
+ begin
87
+ alias_method :each_byte, :bytes
88
+ alias_method :each_char, :chars
89
+ alias_method :each_codepoint, :codepoints
90
+ alias_method :each_line, :lines
91
+ alias_method :each, :lines
92
+ alias_method :eof, :eof?
93
+ alias_method :isatty, :tty?
94
+ alias_method :sysread, :read
95
+ alias_method :syswrite, :write
96
+ rescue NameError
97
+ # do nothing, method may not exist in ruby 1.8
98
+ end
99
+
100
+ # skip these IO methods
101
+ [
102
+ :advise,
103
+ :autoclose=,
104
+ :autoclose?,
105
+ :binmode,
106
+ :binmode?,
107
+ :close_on_exec=,
108
+ :close_on_exec?,
109
+ :fcntl,
110
+ :fdatasync,
111
+ :fileno,
112
+ :fsync,
113
+ :ioctl,
114
+ :lineno,
115
+ :lineno=,
116
+ :pid,
117
+ :read_nonblock,
118
+ :stat,
119
+ :sysseek,
120
+ :tell,
121
+ :to_i,
122
+ :to_io,
123
+ :write_nonblock,
124
+ ].each do |meth|
125
+ begin
126
+ undef_method meth
127
+ rescue NameError
128
+ # do nothing, method may not exist in ruby 1.8
129
+ end
130
+ end
131
+
132
+ class << self
133
+ # skip these IO methods
134
+ [
135
+ :binread,
136
+ :binwrite,
137
+ :copy_stream,
138
+ :for_fd,
139
+ :foreach,
140
+ :open,
141
+ :pipe,
142
+ :popen,
143
+ :read,
144
+ :readlines,
145
+ :select,
146
+ :sysopen,
147
+ :try_convert,
148
+ :write,
149
+ ].each do |meth|
150
+ begin
151
+ undef_method meth
152
+ rescue NameError
153
+ # do nothing, method may not exist in ruby 1.8
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
@@ -1,6 +1,8 @@
1
1
  require 'logger'
2
2
  require 'stringio'
3
3
 
4
+ require 'madvertise/logging/improved_io'
5
+
4
6
  module Madvertise
5
7
  module Logging
6
8
 
@@ -8,9 +10,9 @@ module Madvertise
8
10
  # ImprovedLogger is an enhanced version of DaemonKits AbstractLogger class
9
11
  # with token support, buffer backend and more.
10
12
  #
11
- class ImprovedLogger
13
+ class ImprovedLogger < ImprovedIO
12
14
 
13
- # Write a copy of all log messages to STDOUT.
15
+ # Write a copy of all log messages to stdout.
14
16
  attr_accessor :copy_to_stdout
15
17
 
16
18
  # Program name prefix. Used as ident for syslog backends.
@@ -137,12 +139,8 @@ module Madvertise
137
139
  # @param [Exception, String] exc The exception to log. If exc is a
138
140
  # String no backtrace will be generated.
139
141
  def exception(exc)
140
- if exc.is_a?(::Exception)
141
- message = "EXCEPTION: #{exc.message}: #{clean_trace(exc.backtrace)}"
142
- else
143
- message = exc
144
- end
145
- add(:error, message, true)
142
+ exc = "EXCEPTION: #{exc.message}: #{clean_trace(exc.backtrace)}" if exc.is_a?(::Exception)
143
+ add(:error, exc, true)
146
144
  end
147
145
 
148
146
  # Save the current token and associate it with obj#object_id.
@@ -205,7 +203,7 @@ module Madvertise
205
203
 
206
204
  logger.add(severity) { message }
207
205
 
208
- STDOUT.puts(message) if self.copy_to_stdout && severity >= @logger.level
206
+ $stdout.puts(message) if self.copy_to_stdout && severity >= @logger.level
209
207
  end
210
208
 
211
209
  def create_backend
@@ -228,8 +226,8 @@ module Madvertise
228
226
  begin
229
227
  FileUtils.mkdir_p(File.dirname(@logfile))
230
228
  rescue
231
- STDERR.puts "#{@logfile} not writable, using STDERR for logging" if @logfile
232
- @logfile = STDERR
229
+ $stderr.puts "#{@logfile} not writable, using stderr for logging" if @logfile
230
+ @logfile = $stderr
233
231
  end
234
232
 
235
233
  create_logger
@@ -269,10 +267,62 @@ module Madvertise
269
267
 
270
268
  # @private
271
269
  def call(severity, time, progname, msg)
272
- time = time.strftime("%Y-%m-%d %H:%M:%S.") + time.usec.to_s
270
+ # this is so ugly because ruby 1.8 does not support %N in strftime
271
+ time = time.strftime("%Y-%m-%d %H:%M:%S.") + sprintf('%.6f', time.usec.to_f/1000/1000)[2..-1]
273
272
  self.class.format % [time, progname, $$, severity, msg.to_s]
274
273
  end
275
274
  end
275
+
276
+ module IOCompat
277
+ def close_read
278
+ nil
279
+ end
280
+
281
+ def close_write
282
+ close
283
+ end
284
+
285
+ def closed?
286
+ raise NotImplementedError
287
+ end
288
+
289
+ def sync
290
+ @backend != :buffer
291
+ end
292
+
293
+ def sync=(value)
294
+ raise NotImplementedError, "#{self} cannot change sync mode"
295
+ end
296
+
297
+ # ImprovedLogger is write-only
298
+ def _raise_write_only
299
+ raise IOError, "#{self} is a buffer-less, write-only, non-seekable stream."
300
+ end
301
+
302
+ [
303
+ :bytes,
304
+ :chars,
305
+ :codepoints,
306
+ :lines,
307
+ :eof?,
308
+ :getbyte,
309
+ :getc,
310
+ :gets,
311
+ :pos,
312
+ :pos=,
313
+ :read,
314
+ :readlines,
315
+ :readpartial,
316
+ :rewind,
317
+ :seek,
318
+ :ungetbyte,
319
+ :ungetc
320
+ ].each do |meth|
321
+ alias_method meth, :_raise_write_only
322
+ end
323
+ end
324
+
325
+ include IOCompat
276
326
  end
277
327
  end
278
328
  end
@@ -0,0 +1,14 @@
1
+ ---
2
+ LongParameterList:
3
+ exclude:
4
+ - Formatter#call
5
+ FeatureEnvy:
6
+ exclude:
7
+ - ImprovedLogger#clean_trace
8
+ - ImprovedLogger#exception
9
+ UtilityFunction:
10
+ exclude:
11
+ - ImprovedLogger#clean_trace
12
+ LargeClass:
13
+ exclude:
14
+ - ImprovedLogger
@@ -1,6 +1,6 @@
1
1
  module Madvertise
2
2
  module Logging
3
3
  # @private
4
- VERSION = "0.2.2"
4
+ VERSION = "0.3.1"
5
5
  end
6
6
  end
@@ -14,7 +14,4 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "madvertise-logging"
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Madvertise::Logging::VERSION
17
-
18
- gem.add_development_dependency("bundler")
19
- gem.add_development_dependency("rake")
20
17
  end
@@ -16,6 +16,10 @@ describe ImprovedLogger do
16
16
  @logger.level = :debug
17
17
  end
18
18
 
19
+ it "should be an IO object" do
20
+ @logger.should be_a(IO)
21
+ end
22
+
19
23
  it "should have a backend logger" do
20
24
  @logger.logger.should_not be_nil
21
25
  end
@@ -26,9 +30,18 @@ describe ImprovedLogger do
26
30
  @logger.logger.should == l
27
31
  end
28
32
 
29
- it "should be able to log to STDOUT as well" do
33
+ it "should support reopening log files" do
34
+ @logger.close
35
+
36
+ FileUtils.rm(@logfile)
37
+
38
+ @logger.info('Reopen')
39
+ @logfile.should have_received_message("Reopen")
40
+ end
41
+
42
+ it "should be able to log to stdout as well" do
30
43
  @logger.copy_to_stdout = true
31
- STDOUT.should_receive(:puts).with(/test/)
44
+ $stdout.should_receive(:puts).with(/test/)
32
45
 
33
46
  @logger.debug "test"
34
47
  @logfile.should have_received_message("test")
@@ -109,15 +122,6 @@ describe ImprovedLogger do
109
122
  @logfile.should_not have_received_message("EXCEPTION:")
110
123
  end
111
124
 
112
- it "should support reopening log files" do
113
- @logger.close
114
-
115
- FileUtils.rm(@logfile)
116
-
117
- @logger.info('Reopen')
118
- @logfile.should have_received_message("Reopen")
119
- end
120
-
121
125
  it "should support silencing" do
122
126
  @logger.silence do |logger|
123
127
  logger.info "This should never be logged"
@@ -178,21 +182,14 @@ describe ImprovedLogger do
178
182
  @logfile.should_not have_received_message(token2)
179
183
  end
180
184
 
181
- it "should support a buffered logger" do
182
- @logger = ImprovedLogger.new(:buffer)
183
- @logger.level = :debug
184
- @logger.info "test"
185
- @logger.buffer.should match(/test/)
186
- end
187
-
188
- it "should fall back to STDERR if logfile is not writable" do
189
- STDERR.should_receive(:puts).with(/not writable.*STDERR/)
185
+ it "should fall back to stderr if logfile is not writable" do
186
+ $stderr.should_receive(:puts).with(/not writable.*stderr/)
190
187
 
191
188
  @logfile = "/not/writable/spec.log"
192
189
  @logger = ImprovedLogger.new(@logfile)
193
190
  @logger.level = :debug
194
191
 
195
- STDERR.should_receive(:write).with(/test/)
192
+ $stderr.should_receive(:write).with(/test/)
196
193
  @logger.info "test"
197
194
  end
198
195
 
@@ -200,17 +197,138 @@ describe ImprovedLogger do
200
197
  syslogger_paths = $:.select { |p| p.match(/gems\/.*syslogger-/) }
201
198
  $:.replace($: - syslogger_paths)
202
199
 
203
- STDERR.should_receive(:puts).with(/using STDERR for logging/)
204
- STDERR.should_receive(:write).with(/reverting to standard logger/)
200
+ $stderr.should_receive(:puts).with(/using stderr for logging/)
201
+ $stderr.should_receive(:write).with(/reverting to standard logger/)
205
202
  @logger = ImprovedLogger.new(:syslog)
206
203
  @logger.logger.should be_instance_of(Logger)
207
204
 
208
205
  $:.replace($: + syslogger_paths)
209
206
  end
210
207
 
211
- it "should support a syslog backend" do
212
- @logger = ImprovedLogger.new(:syslog)
213
- @logger.level = :debug
214
- @logger.logger.should be_instance_of(Syslogger)
208
+ context "should behave like write-only IO and" do
209
+ it "should close on close_write" do
210
+ @logger.should_receive(:close)
211
+ @logger.close_write
212
+ end
213
+
214
+ it "should be in sync mode" do
215
+ @logger.sync.should == true
216
+ end
217
+
218
+ it "should return self on flush" do
219
+ @logger.flush.should == @logger
220
+ end
221
+
222
+ it "should return self on set_encoding" do
223
+ @logger.set_encoding.should == @logger
224
+ end
225
+
226
+ it "should ne be a tty" do
227
+ @logger.tty?.should == false
228
+ end
229
+
230
+ it "should support printf" do
231
+ @logger.printf("%.2f %s", 1.12345, "foo")
232
+ @logfile.should have_received_message("1.12 foo")
233
+ end
234
+
235
+ it "should support print" do
236
+ $,, old = ' ', $,
237
+ @logger.print("foo", "bar", 123, ["baz", 345])
238
+ @logfile.should have_received_message("foo bar 123 baz 345")
239
+ $, = old
240
+ end
241
+
242
+ it "should support puts" do
243
+ @logger.puts("a", "b")
244
+ @logfile.should have_received_message("b")
245
+ @logger.puts(["c", "d"])
246
+ @logfile.should have_received_message("b")
247
+ @logger.puts(1, 2, 3)
248
+ @logfile.should have_received_message("3")
249
+ end
250
+
251
+ it "should implement readbyte, readchar, readline" do
252
+ {
253
+ :readbyte => :getbyte,
254
+ :readchar => :getc,
255
+ :readline => :gets,
256
+ }.each do |m, should|
257
+ @logger.should_receive(should)
258
+ lambda {
259
+ @logger.send(m)
260
+ }.should raise_error(IOError)
261
+ end
262
+ end
263
+
264
+ it "should not implement closed?" do
265
+ lambda {
266
+ @logger.closed?
267
+ }.should raise_error(NotImplementedError)
268
+ end
269
+
270
+ it "should not implement sync=" do
271
+ lambda {
272
+ @logger.sync = false
273
+ }.should raise_error(NotImplementedError)
274
+ end
275
+
276
+ [
277
+ :bytes,
278
+ :chars,
279
+ :codepoints,
280
+ :lines,
281
+ :eof?,
282
+ :getbyte,
283
+ :getc,
284
+ :gets,
285
+ :pos,
286
+ :pos=,
287
+ :read,
288
+ :readlines,
289
+ :readpartial,
290
+ :rewind,
291
+ :seek,
292
+ :ungetbyte,
293
+ :ungetc
294
+ ].each do |m|
295
+ it "should raise IOError for method #{m}" do
296
+ lambda {
297
+ @logger.send(m)
298
+ }.should raise_error(IOError)
299
+ end
300
+ end
301
+ end
302
+
303
+ context "buffer backend" do
304
+ before(:each) do
305
+ @logger = ImprovedLogger.new(:buffer)
306
+ @logger.level = :debug
307
+ end
308
+
309
+ it "should support a buffered logger" do
310
+ @logger.info "test"
311
+ @logger.buffer.should match(/test/)
312
+ end
313
+
314
+ it "should not be in sync mode" do
315
+ @logger.sync.should == false
316
+ end
215
317
  end
318
+
319
+ context "syslog backend" do
320
+ before(:each) do
321
+ @logger = ImprovedLogger.new(:syslog)
322
+ @logger.level = :debug
323
+ end
324
+
325
+ it "should have a syslog backend" do
326
+ @logger.logger.should be_instance_of(Syslogger)
327
+ end
328
+
329
+ it "should be in sync mode" do
330
+ @logger.sync.should == true
331
+ end
332
+ end
333
+
216
334
  end
@@ -14,13 +14,13 @@ describe MultiLogger do
14
14
  buflog = ImprovedLogger.new(:buffer)
15
15
  @ml.attach(buflog)
16
16
 
17
- STDERR.should_receive(:write).with(/test1/)
17
+ $stderr.should_receive(:write).with(/test1/)
18
18
  @ml.info("test1")
19
19
  buflog.buffer.should match(/test1/)
20
20
 
21
21
  @ml.detach(buflog)
22
22
 
23
- STDERR.should_receive(:write).with(/test2/)
23
+ $stderr.should_receive(:write).with(/test2/)
24
24
  @ml.info("test2")
25
25
  buflog.buffer.should_not match(/test2/)
26
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: madvertise-logging
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,30 +9,8 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-30 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: bundler
16
- requirement: &17876120 !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: *17876120
25
- - !ruby/object:Gem::Dependency
26
- name: rake
27
- requirement: &17874940 !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: *17874940
12
+ date: 2012-04-06 00:00:00.000000000 Z
13
+ dependencies: []
36
14
  description: Advanced logging classes with buffer backend, transactions, multi logger,
37
15
  etc
38
16
  email:
@@ -50,7 +28,9 @@ files:
50
28
  - README.md
51
29
  - Rakefile
52
30
  - lib/madvertise-logging.rb
31
+ - lib/madvertise/logging/improved_io.rb
53
32
  - lib/madvertise/logging/improved_logger.rb
33
+ - lib/madvertise/logging/mask.reek
54
34
  - lib/madvertise/logging/multi_logger.rb
55
35
  - lib/madvertise/logging/version.rb
56
36
  - madvertise-logging.gemspec
@@ -75,7 +55,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
75
55
  version: '0'
76
56
  segments:
77
57
  - 0
78
- hash: -4131016161241756641
58
+ hash: 2162367042257566853
79
59
  required_rubygems_version: !ruby/object:Gem::Requirement
80
60
  none: false
81
61
  requirements:
@@ -84,10 +64,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
64
  version: '0'
85
65
  segments:
86
66
  - 0
87
- hash: -4131016161241756641
67
+ hash: 2162367042257566853
88
68
  requirements: []
89
69
  rubyforge_project:
90
- rubygems_version: 1.8.10
70
+ rubygems_version: 1.8.17
91
71
  signing_key:
92
72
  specification_version: 3
93
73
  summary: Advanced logging classes with buffer backend, transactions, multi logger,