rubysl-logger 1.0.0 → 2.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.
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