rubysl-logger 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9fc1851a1f5fabf2faf3a5e0ed9829501144dbae
4
- data.tar.gz: c8e86a774d933647be2ef11623e0e4eba75d9443
3
+ metadata.gz: 4289a82a3a4e798295bcd9db969140f9cc14fcc9
4
+ data.tar.gz: 8fb80a06ecc540a8775fe75fc03c43c0b9a3d051
5
5
  SHA512:
6
- metadata.gz: 8a7a38a3e746fa94771bddc89f68ce1ecba71fc39352763da1a9aae32a881cdc59be16d9353f145458050fddda71373182785f10aece0e935a8b9498f84f24e2
7
- data.tar.gz: 44947ec784be7739007a72ec808ec6895654fa75d820247684cda68a6833807dcf38ed0774c2828521a28d5c3e50c430dd791a867f907b8f0b7ccb0e66359a58
6
+ metadata.gz: a2419fb218cf686cfb4553e437dd7b1156c206736071205780c94243b9e4be3a05302b969e882827f0e23c789b7f72ecf79d3f47a4f081977d1bafd5dabba1e8
7
+ data.tar.gz: 13660278cc0dba622a8dc7e3157d0bdb8cedc0a64b8da04ccbfb77f3072c2b24786907a6759e7df074b8ee37ea55454b988df40be7f71bb3b305bc45519656f4
data/.travis.yml CHANGED
@@ -1,8 +1,7 @@
1
1
  language: ruby
2
- before_install:
3
- - gem update --system
4
- - gem --version
5
- - gem install rubysl-bundler
6
- script: bundle exec mspec spec
2
+ env:
3
+ - RUBYLIB=lib
4
+ script: bundle exec mspec
7
5
  rvm:
8
- - rbx-nightly-18mode
6
+ - 1.9.3
7
+ - rbx-nightly-19mode
@@ -1,27 +1,26 @@
1
1
  # logger.rb - simple logging utility
2
- # Copyright (C) 2000-2003, 2005 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>.
3
-
4
- require 'monitor'
5
-
6
- # Simple logging utility.
2
+ # Copyright (C) 2000-2003, 2005, 2008, 2011 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
7
3
  #
8
- # Author:: NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>
9
4
  # Documentation:: NAKAMURA, Hiroshi and Gavin Sinclair
10
5
  # License::
11
6
  # You can redistribute it and/or modify it under the same terms of Ruby's
12
7
  # license; either the dual license version in 2003, or any later version.
13
- # Revision:: $Id: logger.rb 22285 2009-02-13 10:19:04Z shyouhei $
8
+ # Revision:: $Id$
14
9
  #
10
+ # A simple system for logging messages. See Logger for more documentation.
11
+
12
+ require 'monitor'
13
+
15
14
  # == Description
16
15
  #
17
16
  # The Logger class provides a simple but sophisticated logging utility that
18
- # anyone can use because it's included in the Ruby 1.8.x standard library.
17
+ # you can use to output messages.
19
18
  #
20
- # The HOWTOs below give a code-based overview of Logger's usage, but the basic
21
- # concept is as follows. You create a Logger object (output to a file or
22
- # elsewhere), and use it to log messages. The messages will have varying
23
- # levels (+info+, +error+, etc), reflecting their varying importance. The
24
- # levels, and their meanings, are:
19
+ # The messages have associated levels, such as +INFO+ or +ERROR+ that indicate
20
+ # their importance. You can then give the Logger a level, and only messages
21
+ # at that level of higher will be printed.
22
+ #
23
+ # The levels are:
25
24
  #
26
25
  # +FATAL+:: an unhandleable error that results in a program crash
27
26
  # +ERROR+:: a handleable error condition
@@ -29,19 +28,30 @@ require 'monitor'
29
28
  # +INFO+:: generic (useful) information about system operation
30
29
  # +DEBUG+:: low-level information for developers
31
30
  #
32
- # So each message has a level, and the Logger itself has a level, which acts
33
- # as a filter, so you can control the amount of information emitted from the
34
- # logger without having to remove actual messages.
35
- #
36
- # For instance, in a production system, you may have your logger(s) set to
37
- # +INFO+ (or +WARN+ if you don't want the log files growing large with
38
- # repetitive information). When you are developing it, though, you probably
39
- # want to know about the program's internal state, and would set them to
31
+ # For instance, in a production system, you may have your Logger set to
32
+ # +INFO+ or even +WARN+
33
+ # When you are developing the system, however, you probably
34
+ # want to know about the program's internal state, and would set the Logger to
40
35
  # +DEBUG+.
41
36
  #
37
+ # *Note*: Logger does not escape or sanitize any messages passed to it.
38
+ # Developers should be aware of when potentially malicious data (user-input)
39
+ # is passed to Logger, and manually escape the untrusted data:
40
+ #
41
+ # logger.info("User-input: #{input.dump}")
42
+ # logger.info("User-input: %p" % input)
43
+ #
44
+ # You can use #formatter= for escaping all data.
45
+ #
46
+ # original_formatter = Logger::Formatter.new
47
+ # logger.formatter = proc { |severity, datetime, progname, msg|
48
+ # original_formatter.call(severity, datetime, progname, msg.dump)
49
+ # }
50
+ # logger.info(input)
51
+ #
42
52
  # === Example
43
53
  #
44
- # A simple example demonstrates the above explanation:
54
+ # This creates a logger to the standard output stream, with a level of +WARN+
45
55
  #
46
56
  # log = Logger.new(STDOUT)
47
57
  # log.level = Logger::WARN
@@ -110,7 +120,7 @@ require 'monitor'
110
120
  # === How to log a message
111
121
  #
112
122
  # Notice the different methods (+fatal+, +error+, +info+) being used to log
113
- # messages of various levels. Other methods in this family are +warn+ and
123
+ # messages of various levels? Other methods in this family are +warn+ and
114
124
  # +debug+. +add+ is used below to log a message of an arbitrary (perhaps
115
125
  # dynamic) level.
116
126
  #
@@ -130,6 +140,20 @@ require 'monitor'
130
140
  #
131
141
  # logger.add(Logger::FATAL) { 'Fatal error!' }
132
142
  #
143
+ # The block form allows you to create potentially complex log messages,
144
+ # but to delay their evaluation until and unless the message is
145
+ # logged. For example, if we have the following:
146
+ #
147
+ # logger.debug { "This is a " + potentially + " expensive operation" }
148
+ #
149
+ # If the logger's level is +INFO+ or higher, no debug messages will be logged,
150
+ # and the entire block will not even be evaluated. Compare to this:
151
+ #
152
+ # logger.debug("This is a " + potentially + " expensive operation")
153
+ #
154
+ # Here, the string concatenation is done every time, even if the log
155
+ # level is not set to show the debug message.
156
+ #
133
157
  # === How to close a logger
134
158
  #
135
159
  # logger.close
@@ -143,14 +167,14 @@ require 'monitor'
143
167
  # 2. Log4r (somewhat) compatible interface.
144
168
  #
145
169
  # logger.level = Logger::INFO
146
- #
170
+ #
147
171
  # DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
148
172
  #
149
173
  #
150
174
  # == Format
151
175
  #
152
- # Log messages are rendered in the output stream in a certain format. The
153
- # default format and a sample are shown below:
176
+ # Log messages are rendered in the output stream in a certain format by
177
+ # default. The default format and a sample are shown below:
154
178
  #
155
179
  # Log format:
156
180
  # SeverityID, [Date Time mSec #pid] SeverityLabel -- ProgName: message
@@ -158,31 +182,48 @@ require 'monitor'
158
182
  # Log sample:
159
183
  # I, [Wed Mar 03 02:34:24 JST 1999 895701 #19074] INFO -- Main: info.
160
184
  #
161
- # You may change the date and time format in this manner:
185
+ # You may change the date and time format via #datetime_format=
162
186
  #
163
187
  # logger.datetime_format = "%Y-%m-%d %H:%M:%S"
164
188
  # # e.g. "2004-01-03 00:54:26"
165
189
  #
166
- # There is currently no supported way to change the overall format, but you may
167
- # have some luck hacking the Format constant.
190
+ # Or, you may change the overall format with #formatter= method.
191
+ #
192
+ # logger.formatter = proc do |severity, datetime, progname, msg|
193
+ # "#{datetime}: #{msg}\n"
194
+ # end
195
+ # # e.g. "Thu Sep 22 08:51:08 GMT+9:00 2005: hello world"
168
196
  #
169
-
170
-
171
197
  class Logger
172
- VERSION = "1.2.6"
173
- id, name, rev = %w$Id: logger.rb 22285 2009-02-13 10:19:04Z shyouhei $
174
- ProgName = "#{name.chomp(",v")}/#{rev}"
198
+ VERSION = "1.2.7"
199
+ _, name, rev = %w$Id$
200
+ if name
201
+ name = name.chomp(",v")
202
+ else
203
+ name = File.basename(__FILE__)
204
+ end
205
+ rev ||= "v#{VERSION}"
206
+ ProgName = "#{name}/#{rev}"
175
207
 
176
- class Error < RuntimeError; end
177
- class ShiftingError < Error; end
208
+ class Error < RuntimeError # :nodoc:
209
+ end
210
+ # not used after 1.2.7. just for compat.
211
+ class ShiftingError < Error # :nodoc:
212
+ end
178
213
 
179
214
  # Logging severity.
180
215
  module Severity
216
+ # Low-level information, mostly for developers
181
217
  DEBUG = 0
218
+ # generic, useful information about system operation
182
219
  INFO = 1
220
+ # a warning
183
221
  WARN = 2
222
+ # a handleable error condition
184
223
  ERROR = 3
224
+ # an unhandleable error that results in a program crash
185
225
  FATAL = 4
226
+ # an unknown message that should always be logged
186
227
  UNKNOWN = 5
187
228
  end
188
229
  include Severity
@@ -190,23 +231,33 @@ class Logger
190
231
  # Logging severity threshold (e.g. <tt>Logger::INFO</tt>).
191
232
  attr_accessor :level
192
233
 
193
- # Logging program name.
234
+ # program name to include in log messages.
194
235
  attr_accessor :progname
195
236
 
196
- # Logging date-time format (string passed to +strftime+).
237
+ # Set date-time format.
238
+ #
239
+ # +datetime_format+:: A string suitable for passing to +strftime+.
197
240
  def datetime_format=(datetime_format)
198
241
  @default_formatter.datetime_format = datetime_format
199
242
  end
200
243
 
244
+ # Returns the date format being used. See #datetime_format=
201
245
  def datetime_format
202
246
  @default_formatter.datetime_format
203
247
  end
204
248
 
205
- # Logging formatter. formatter#call is invoked with 4 arguments; severity,
206
- # time, progname and msg for each log. Bear in mind that time is a Time and
207
- # msg is an Object that user passed and it could not be a String. It is
208
- # expected to return a logdev#write-able Object. Default formatter is used
209
- # when no formatter is set.
249
+ # Logging formatter, as a +Proc+ that will take four arguments and
250
+ # return the formatted message. The arguments are:
251
+ #
252
+ # +severity+:: The Severity of the log message
253
+ # +time+:: A Time instance representing when the message was logged
254
+ # +progname+:: The #progname configured, or passed to the logger method
255
+ # +msg+:: The _Object_ the user passed to the log message; not necessarily a
256
+ # String.
257
+ #
258
+ # The block should return an Object that can be written to the logging
259
+ # device via +write+. The default formatter is used when no formatter is
260
+ # set.
210
261
  attr_accessor :formatter
211
262
 
212
263
  alias sev_threshold level
@@ -278,8 +329,8 @@ class Logger
278
329
  # +message+::
279
330
  # The log message. A String or Exception.
280
331
  # +progname+::
281
- # Program name string. Can be omitted. Treated as a message if no +message+ and
282
- # +block+ are given.
332
+ # Program name string. Can be omitted. Treated as a message if no
333
+ # +message+ and +block+ are given.
283
334
  # +block+::
284
335
  # Can be omitted. Called to get a message string if +message+ is nil.
285
336
  #
@@ -307,7 +358,7 @@ class Logger
307
358
  #
308
359
  # * Logfile is not locked.
309
360
  # * Append open does not need to lock file.
310
- # * But on the OS which supports multi I/O, records possibly be mixed.
361
+ # * If the OS which supports multi I/O, records possibly be mixed.
311
362
  #
312
363
  def add(severity, message = nil, progname = nil, &block)
313
364
  severity ||= UNKNOWN
@@ -348,12 +399,21 @@ class Logger
348
399
  add(DEBUG, nil, progname, &block)
349
400
  end
350
401
 
402
+ #
403
+ # :call-seq:
404
+ # info(message)
405
+ # info(progname,&block)
351
406
  #
352
407
  # Log an +INFO+ message.
353
408
  #
354
- # The message can come either from the +progname+ argument or the +block+. If
355
- # both are provided, then the +block+ is used as the message, and +progname+
356
- # is used as the program name.
409
+ # +message+:: the message to log; does not need to be a String
410
+ # +progname+:: in the block form, this is the #progname to use in the
411
+ # the log message. The default can be set with #progname=
412
+ # <tt>&block</tt>:: evaluates to the message to log. This is not evaluated
413
+ # unless the logger's level is sufficient
414
+ # to log the message. This allows you to create
415
+ # potentially expensive logging messages that are
416
+ # only called when the logger is configured to show them.
357
417
  #
358
418
  # === Examples
359
419
  #
@@ -364,7 +424,7 @@ class Logger
364
424
  # logger.info { "User typed #{input}" }
365
425
  #
366
426
  # You'll probably stick to the second form above, unless you want to provide a
367
- # program name (which you can do with <tt>Logger#progname=</tt> as well).
427
+ # program name (which you can do with #progname= as well).
368
428
  #
369
429
  # === Return
370
430
  #
@@ -402,7 +462,7 @@ class Logger
402
462
  end
403
463
 
404
464
  #
405
- # Log an +UNKNOWN+ message. This will be printed no matter what the logger
465
+ # Log an +UNKNOWN+ message. This will be printed no matter what the logger's
406
466
  # level.
407
467
  #
408
468
  # See #info for more information.
@@ -432,6 +492,7 @@ private
432
492
  end
433
493
 
434
494
 
495
+ # Default formatter for log messages
435
496
  class Formatter
436
497
  Format = "%s, [%s#%d] %5s -- %s: %s\n"
437
498
 
@@ -470,6 +531,7 @@ private
470
531
  end
471
532
 
472
533
 
534
+ # Device used for logging messages.
473
535
  class LogDevice
474
536
  attr_reader :dev
475
537
  attr_reader :filename
@@ -493,21 +555,33 @@ private
493
555
  end
494
556
 
495
557
  def write(message)
496
- @mutex.synchronize do
497
- if @shift_age and @dev.respond_to?(:stat)
558
+ begin
559
+ @mutex.synchronize do
560
+ if @shift_age and @dev.respond_to?(:stat)
561
+ begin
562
+ check_shift_log
563
+ rescue
564
+ warn("log shifting failed. #{$!}")
565
+ end
566
+ end
498
567
  begin
499
- check_shift_log
568
+ @dev.write(message)
500
569
  rescue
501
- raise Logger::ShiftingError.new("Shifting failed. #{$!}")
570
+ warn("log writing failed. #{$!}")
502
571
  end
503
572
  end
504
- @dev.write(message)
573
+ rescue Exception => ignored
574
+ warn("log writing failed. #{ignored}")
505
575
  end
506
576
  end
507
577
 
508
578
  def close
509
- @mutex.synchronize do
510
- @dev.close
579
+ begin
580
+ @mutex.synchronize do
581
+ @dev.close rescue nil
582
+ end
583
+ rescue Exception
584
+ @dev.close rescue nil
511
585
  end
512
586
  end
513
587
 
@@ -515,9 +589,9 @@ private
515
589
 
516
590
  def open_logfile(filename)
517
591
  if (FileTest.exist?(filename))
518
- open(filename, (File::WRONLY | File::APPEND))
592
+ open(filename, (File::WRONLY | File::APPEND))
519
593
  else
520
- create_logfile(filename)
594
+ create_logfile(filename)
521
595
  end
522
596
  end
523
597
 
@@ -530,8 +604,8 @@ private
530
604
 
531
605
  def add_log_header(file)
532
606
  file.write(
533
- "# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]
534
- )
607
+ "# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]
608
+ )
535
609
  end
536
610
 
537
611
  SiD = 24 * 60 * 60
@@ -544,8 +618,9 @@ private
544
618
  end
545
619
  else
546
620
  now = Time.now
547
- if @dev.stat.mtime <= previous_period_end(now)
548
- shift_log_period(now)
621
+ period_end = previous_period_end(now)
622
+ if @dev.stat.mtime <= period_end
623
+ shift_log_period(period_end)
549
624
  end
550
625
  end
551
626
  end
@@ -556,19 +631,26 @@ private
556
631
  File.rename("#{@filename}.#{i}", "#{@filename}.#{i+1}")
557
632
  end
558
633
  end
559
- @dev.close
634
+ @dev.close rescue nil
560
635
  File.rename("#{@filename}", "#{@filename}.0")
561
636
  @dev = create_logfile(@filename)
562
637
  return true
563
638
  end
564
639
 
565
- def shift_log_period(now)
566
- postfix = previous_period_end(now).strftime("%Y%m%d") # YYYYMMDD
640
+ def shift_log_period(period_end)
641
+ postfix = period_end.strftime("%Y%m%d") # YYYYMMDD
567
642
  age_file = "#{@filename}.#{postfix}"
568
643
  if FileTest.exist?(age_file)
569
- raise RuntimeError.new("'#{ age_file }' already exists.")
644
+ # try to avoid filename crash caused by Timestamp change.
645
+ idx = 0
646
+ # .99 can be overridden; avoid too much file search with 'loop do'
647
+ while idx < 100
648
+ idx += 1
649
+ age_file = "#{@filename}.#{postfix}.#{idx}"
650
+ break unless FileTest.exist?(age_file)
651
+ end
570
652
  end
571
- @dev.close
653
+ @dev.close rescue nil
572
654
  File.rename("#{@filename}", age_file)
573
655
  @dev = create_logfile(@filename)
574
656
  return true
@@ -625,8 +707,8 @@ private
625
707
  class Application
626
708
  include Logger::Severity
627
709
 
710
+ # Name of the application given at initialize.
628
711
  attr_reader :appname
629
- attr_reader :logdev
630
712
 
631
713
  #
632
714
  # == Synopsis
@@ -655,19 +737,34 @@ private
655
737
  def start
656
738
  status = -1
657
739
  begin
658
- log(INFO, "Start of #{ @appname }.")
659
- status = run
740
+ log(INFO, "Start of #{ @appname }.")
741
+ status = run
660
742
  rescue
661
- log(FATAL, "Detected an exception. Stopping ... #{$!} (#{$!.class})\n" << $@.join("\n"))
743
+ log(FATAL, "Detected an exception. Stopping ... #{$!} (#{$!.class})\n" << $@.join("\n"))
662
744
  ensure
663
- log(INFO, "End of #{ @appname }. (status: #{ status.to_s })")
745
+ log(INFO, "End of #{ @appname }. (status: #{ status.to_s })")
664
746
  end
665
747
  status
666
748
  end
667
749
 
750
+ # Logger for this application. See the class Logger for an explanation.
751
+ def logger
752
+ @log
753
+ end
754
+
755
+ #
756
+ # Sets the logger for this application. See the class Logger for an
757
+ # explanation.
758
+ #
759
+ def logger=(logger)
760
+ @log = logger
761
+ @log.progname = @appname
762
+ @log.level = @level
763
+ end
764
+
668
765
  #
669
- # Sets the log device for this application. See the class Logger for an
670
- # explanation of the arguments.
766
+ # Sets the log device for this application. See <tt>Logger.new</tt> for
767
+ # an explanation of the arguments.
671
768
  #
672
769
  def set_log(logdev, shift_age = 0, shift_size = 1024000)
673
770
  @log = Logger.new(logdev, shift_age, shift_size)
@@ -697,6 +794,7 @@ private
697
794
  private
698
795
 
699
796
  def run
797
+ # TODO: should be an NotImplementedError
700
798
  raise RuntimeError.new('Method run must be defined in the derived class.')
701
799
  end
702
800
  end
@@ -1,5 +1,5 @@
1
1
  module RubySL
2
2
  module Logger
3
- VERSION = "1.0.0"
3
+ VERSION = "2.0.0"
4
4
  end
5
5
  end
@@ -19,5 +19,4 @@ Gem::Specification.new do |spec|
19
19
  spec.add_development_dependency "bundler", "~> 1.3"
20
20
  spec.add_development_dependency "rake", "~> 10.0"
21
21
  spec.add_development_dependency "mspec", "~> 1.5"
22
- spec.add_development_dependency "rubysl-prettyprint", "~> 1.0"
23
- end
22
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubysl-logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Shirai
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-27 00:00:00.000000000 Z
11
+ date: 2013-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.5'
55
- - !ruby/object:Gem::Dependency
56
- name: rubysl-prettyprint
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- version: '1.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ~>
67
- - !ruby/object:Gem::Version
68
- version: '1.0'
69
55
  description: Ruby standard library logger.
70
56
  email:
71
57
  - brixen@gmail.com