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 +4 -4
- data/.travis.yml +5 -6
- data/lib/rubysl/logger/logger.rb +174 -76
- data/lib/rubysl/logger/version.rb +1 -1
- data/rubysl-logger.gemspec +1 -2
- metadata +2 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4289a82a3a4e798295bcd9db969140f9cc14fcc9
|
4
|
+
data.tar.gz: 8fb80a06ecc540a8775fe75fc03c43c0b9a3d051
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2419fb218cf686cfb4553e437dd7b1156c206736071205780c94243b9e4be3a05302b969e882827f0e23c789b7f72ecf79d3f47a4f081977d1bafd5dabba1e8
|
7
|
+
data.tar.gz: 13660278cc0dba622a8dc7e3157d0bdb8cedc0a64b8da04ccbfb77f3072c2b24786907a6759e7df074b8ee37ea55454b988df40be7f71bb3b305bc45519656f4
|
data/.travis.yml
CHANGED
data/lib/rubysl/logger/logger.rb
CHANGED
@@ -1,27 +1,26 @@
|
|
1
1
|
# logger.rb - simple logging utility
|
2
|
-
# Copyright (C) 2000-2003, 2005 NAKAMURA, Hiroshi <
|
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
|
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
|
-
#
|
17
|
+
# you can use to output messages.
|
19
18
|
#
|
20
|
-
# The
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
# levels
|
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
|
-
#
|
33
|
-
#
|
34
|
-
#
|
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
|
-
#
|
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
|
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
|
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
|
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
|
-
#
|
167
|
-
#
|
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.
|
173
|
-
|
174
|
-
|
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
|
177
|
-
|
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
|
-
#
|
234
|
+
# program name to include in log messages.
|
194
235
|
attr_accessor :progname
|
195
236
|
|
196
|
-
#
|
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
|
206
|
-
#
|
207
|
-
#
|
208
|
-
#
|
209
|
-
# when
|
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
|
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
|
-
# *
|
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
|
-
#
|
355
|
-
#
|
356
|
-
#
|
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
|
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
|
-
|
497
|
-
|
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
|
-
|
568
|
+
@dev.write(message)
|
500
569
|
rescue
|
501
|
-
|
570
|
+
warn("log writing failed. #{$!}")
|
502
571
|
end
|
503
572
|
end
|
504
|
-
|
573
|
+
rescue Exception => ignored
|
574
|
+
warn("log writing failed. #{ignored}")
|
505
575
|
end
|
506
576
|
end
|
507
577
|
|
508
578
|
def close
|
509
|
-
|
510
|
-
@
|
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
|
-
|
592
|
+
open(filename, (File::WRONLY | File::APPEND))
|
519
593
|
else
|
520
|
-
|
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
|
-
|
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
|
-
|
548
|
-
|
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(
|
566
|
-
postfix =
|
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
|
-
|
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
|
-
|
659
|
-
|
740
|
+
log(INFO, "Start of #{ @appname }.")
|
741
|
+
status = run
|
660
742
|
rescue
|
661
|
-
|
743
|
+
log(FATAL, "Detected an exception. Stopping ... #{$!} (#{$!.class})\n" << $@.join("\n"))
|
662
744
|
ensure
|
663
|
-
|
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
|
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
|
data/rubysl-logger.gemspec
CHANGED
@@ -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
|
-
|
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:
|
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-
|
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
|