logging 0.1.0 → 0.2.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.
@@ -0,0 +1,63 @@
1
+
2
+ purpose : TestA
3
+ description: This is the 1st YAML doc
4
+ say : Hi
5
+
6
+ ---
7
+ # *** YAML2LOGGING ***
8
+ logging_config:
9
+ # define all pre config ...
10
+ pre_config:
11
+ define_levels:
12
+ - DEB
13
+ - INF
14
+ - PRT
15
+ - WRN
16
+ - ERR
17
+ - FAT
18
+ format_as : inspect
19
+ root:
20
+ level : WRN
21
+
22
+ # define all loggers ...
23
+ loggers:
24
+ - name : mylogger
25
+ level : DEB
26
+ additive : false
27
+ trace : false
28
+ appenders:
29
+ - stderr
30
+ - logfile
31
+
32
+ - name : yourlogger
33
+ level : INF
34
+ appenders:
35
+ - stderr
36
+ - logfile
37
+
38
+ # define all appenders (incl. layouts)
39
+ appenders:
40
+ - type : Stderr
41
+ name : stderr
42
+ level : DEB
43
+ layout:
44
+ type : Basic
45
+ format_as : string
46
+
47
+ - type : File
48
+ name : logfile
49
+ level : DEB
50
+ filename : 'temp.log'
51
+ truncate : true
52
+ layout:
53
+ type : Pattern
54
+ date_method : to_s
55
+ pattern : '[%d] %l %c : %m\n'
56
+
57
+ ---
58
+ purpose : TestB
59
+ description: This is the last YAML doc
60
+ say : Bye
61
+
62
+
63
+ # EOF
data/lib/logging.rb CHANGED
@@ -1,16 +1,20 @@
1
- # $Id: logging.rb 12 2007-01-14 20:03:40Z tim_pease $
1
+ # $Id: logging.rb 22 2007-01-29 16:20:54Z tim_pease $
2
2
 
3
3
  require 'logging/repository'
4
4
 
5
5
  # require all appenders
6
6
  require 'logging/appenders/console'
7
7
  require 'logging/appenders/file'
8
+ require 'logging/appenders/rolling_file'
8
9
  require 'logging/appenders/static_appender'
9
10
 
10
11
  # require all layouts
11
12
  require 'logging/layouts/basic'
12
13
  require 'logging/layouts/pattern'
13
14
 
15
+ # require all configurators
16
+ require 'logging/config/yaml_configurator'
17
+
14
18
 
15
19
  #
16
20
  #
@@ -21,6 +25,21 @@ module Logging
21
25
  LNAMES = {} # :nodoc:
22
26
 
23
27
  class << self
28
+ #
29
+ # call-seq:
30
+ # Logging.configure( filename )
31
+ #
32
+ # Configures the Logging framework using the configuration information
33
+ # found in the given file. The file extension should be either '.yaml'
34
+ # or '.yml' (XML configuration is not yet supported).
35
+ #
36
+ def configure( filename )
37
+ case File.extname(filename)
38
+ when '.yaml', '.yml':
39
+ ::Logging::Config::YamlConfigurator.load(filename)
40
+ else raise ArgumentError, 'unknown configuration file format' end
41
+ end
42
+
24
43
  #
25
44
  # call-seq:
26
45
  # define_levels( levels )
@@ -99,6 +118,8 @@ module Logging
99
118
  # +:inspect+, +:yaml+ is passed to this method.
100
119
  #
101
120
  def format_as( f )
121
+ f = f.intern if f.instance_of? String
122
+
102
123
  unless [:string, :inspect, :yaml].include? f
103
124
  raise ArgumentError, "unknown object format '#{f}'"
104
125
  end
@@ -119,7 +140,7 @@ module Logging
119
140
  case l
120
141
  when 'all': 0
121
142
  when 'off': LEVELS.length
122
- else LEVELS[l] end
143
+ else begin; Integer(l); rescue ArgumentError; LEVELS[l] end end
123
144
  end
124
145
  # :startdoc:
125
146
  end
@@ -1,6 +1,6 @@
1
- # $Id: appender.rb 12 2007-01-14 20:03:40Z tim_pease $
1
+ # $Id: appender.rb 20 2007-01-26 20:18:42Z tim_pease $
2
2
 
3
- require 'sync'
3
+ require 'thread'
4
4
  require 'logging'
5
5
  require 'logging/logger'
6
6
  require 'logging/layout'
@@ -39,11 +39,14 @@ module Logging
39
39
  def initialize( name, opts = {} )
40
40
  @name = name.to_s
41
41
  @closed = false
42
- @level = 0
43
- self.layout = opts[:layout] if opts.include? :layout
42
+
43
+ layout = opts[:layout] || opts['layout']
44
+ self.layout = layout unless layout.nil?
44
45
  @layout ||= ::Logging::Layouts::Basic.new
45
46
 
46
- @sync = Sync.new
47
+ self.level = opts[:level] || opts['level']
48
+
49
+ @mutex = Mutex.new
47
50
  sync {write(@layout.header)}
48
51
 
49
52
  ::Logging::Appender[@name] = self
@@ -195,8 +198,7 @@ module Logging
195
198
  # can call +sync+ multiple times without hanging the thread.
196
199
  #
197
200
  def sync
198
- if Thread.current == @sync.sync_ex_locker then yield
199
- else @sync.synchronize(:EX) {yield} end
201
+ @mutex.synchronize {yield}
200
202
  end
201
203
 
202
204
  end # class Appender
@@ -1,4 +1,4 @@
1
- # $Id: console.rb 2 2007-01-09 18:10:50Z tim_pease $
1
+ # $Id: console.rb 17 2007-01-20 18:47:43Z tim_pease $
2
2
 
3
3
  require 'logging/appenders/io'
4
4
 
@@ -8,7 +8,7 @@ module Appenders
8
8
  #
9
9
  # This class provides an Appender that can write to STDOUT.
10
10
  #
11
- class StdOut< ::Logging::Appenders::IO
11
+ class Stdout< ::Logging::Appenders::IO
12
12
 
13
13
  #
14
14
  # call-seq:
@@ -18,15 +18,17 @@ module Appenders
18
18
  # Creates a new StdOut Appender. The name 'stdout' will always be used for
19
19
  # this appender.
20
20
  #
21
- def initialize( opts = {} )
22
- super('stdout', STDOUT, opts)
21
+ def initialize( name = nil, opts = {} )
22
+ name ||= 'stdout'
23
+ STDOUT.sync = true
24
+ super(name, STDOUT, opts)
23
25
  end
24
- end # class StdOut
26
+ end # class Stdout
25
27
 
26
28
  #
27
29
  # This class provides an Appender that can write to STDERR.
28
30
  #
29
- class StdErr< ::Logging::Appenders::IO
31
+ class Stderr< ::Logging::Appenders::IO
30
32
 
31
33
  #
32
34
  # call-seq:
@@ -36,10 +38,12 @@ module Appenders
36
38
  # Creates a new StdErr Appender. The name 'stderr' will always be used for
37
39
  # this appender.
38
40
  #
39
- def initialize( opts = {} )
40
- super('stderr', STDERR, opts)
41
+ def initialize( name = nil, opts = {} )
42
+ name ||= 'stderr'
43
+ STDERR.sync = true
44
+ super(name, STDERR, opts)
41
45
  end
42
- end # class StdErr
46
+ end # class Stderr
43
47
 
44
48
  end # module Appenders
45
49
  end # module Logging
@@ -1,9 +1,8 @@
1
- # $Id: file.rb 2 2007-01-09 18:10:50Z tim_pease $
1
+ # $Id: file.rb 22 2007-01-29 16:20:54Z tim_pease $
2
2
 
3
3
  require 'logging/appenders/io'
4
4
 
5
- module Logging
6
- module Appenders
5
+ module Logging::Appenders
7
6
 
8
7
  #
9
8
  # This class provides an Appender that can write to a File.
@@ -12,34 +11,37 @@ module Appenders
12
11
 
13
12
  #
14
13
  # call-seq:
15
- # File.new( filename )
16
- # File.new( filename, :truncate => true )
17
- # File.new( filename, :layout => layout )
14
+ # File.new( name, :filename => 'file' )
15
+ # File.new( name, :filename => 'file', :truncate => true )
16
+ # File.new( name, :filename => 'file', :layout => layout )
18
17
  #
19
- # Creates a new File Appender that will use the given _filename_ as the
18
+ # Creates a new File Appender that will use the given filename as the
20
19
  # logging destination. If the file does not already exist it will be
21
- # created. If the :truncate option is set to +true+ then the file will be
22
- # truncated before writing begins; otherwise, log messages will be appened
23
- # to the file.
20
+ # created. If the :truncate option is set to +true+ then the file will
21
+ # be truncated before writing begins; otherwise, log messages will be
22
+ # appened to the file.
24
23
  #
25
- def initialize( filename, opts = {} )
26
- mode = opts.delete(:truncate) ? 'w' : 'a'
27
-
28
- if ::File.exist?(filename)
29
- if not ::File.file?(filename)
30
- raise StandardError, "#{filename} is not a regular file"
31
- elsif not ::File.writable?(filename)
32
- raise StandardError, "#{filename} is not writeable"
24
+ def initialize( name, opts = {} )
25
+ @fn = opts.delete(:filename) || opts.delete('filename')
26
+ raise ArgumentError, 'no filename was given' if @fn.nil?
27
+
28
+ mode = opts.delete(:truncate) || opts.delete('truncate')
29
+ mode = mode ? 'w' : 'a'
30
+
31
+ if ::File.exist?(@fn)
32
+ if not ::File.file?(@fn)
33
+ raise StandardError, "#{@fn} is not a regular file"
34
+ elsif not ::File.writable?(@fn)
35
+ raise StandardError, "#{@fn} is not writeable"
33
36
  end
34
- elsif not ::File.writable?(::File.dirname(filename))
35
- raise StandardError, "#{::File.dirname(filename)} is not writable"
37
+ elsif not ::File.writable?(::File.dirname(@fn))
38
+ raise StandardError, "#{::File.dirname(@fn)} is not writable"
36
39
  end
37
40
 
38
- super(filename, ::File.new(filename, mode), opts)
41
+ super(name, ::File.new(@fn, mode), opts)
39
42
  end
40
43
 
41
44
  end # class FileAppender
42
- end # module Appenders
43
- end # module Logging
45
+ end # module Logging::Appenders
44
46
 
45
47
  # EOF
@@ -1,4 +1,4 @@
1
- # $Id: io.rb 10 2007-01-12 18:57:07Z tim_pease $
1
+ # $Id: io.rb 21 2007-01-26 20:23:32Z tim_pease $
2
2
 
3
3
  require 'logging/appender'
4
4
 
@@ -25,8 +25,6 @@ module Appenders
25
25
  end
26
26
 
27
27
  @io = io
28
- @io.sync = true
29
-
30
28
  super(name, opts)
31
29
  end
32
30
 
@@ -41,11 +39,9 @@ module Appenders
41
39
  #
42
40
  def close( *args )
43
41
  return self if @io.nil?
44
- sync do
45
- super(*args)
46
- @io.close unless [STDIN, STDERR, STDOUT].include?(@io)
47
- @io = nil
48
- end
42
+ super(*args)
43
+ io, @io = @io, nil
44
+ io.close unless [STDIN, STDERR, STDOUT].include?(io)
49
45
  self
50
46
  end
51
47
 
@@ -0,0 +1,189 @@
1
+ # $Id: rolling_file.rb 22 2007-01-29 16:20:54Z tim_pease $
2
+
3
+ require 'logging/appenders/file'
4
+
5
+ module Logging::Appenders
6
+
7
+ #
8
+ # An appender that writes to a file and ensures that the file size or age
9
+ # never exceeds some user specified level.
10
+ #
11
+ # The goal of this class is to write log messages to a file. When the file
12
+ # age or size exceeds a given limit then the log file is closed, the name
13
+ # is changed to indicate it is an older log file, and a new log file is
14
+ # created.
15
+ #
16
+ # The name of the log file is changed by inserting the age of the log file
17
+ # (as a single number) between the log file name and the extension. If the
18
+ # file has no extension then the number is appended to the filename. Here
19
+ # is a simple example:
20
+ #
21
+ # /var/log/ruby.log => /var/log/ruby.1.log
22
+ #
23
+ # New log messages will be appended to a newly opened log file of the same
24
+ # name (<tt>/var/log/ruby.log</tt> in our example above). The age number for
25
+ # all older log files is incremented when the log file is rolled. The number
26
+ # of older log files to keep can be given, otherwise all the log files are
27
+ # kept.
28
+ #
29
+ # The actual process of rolling all the log file names can be expensive if
30
+ # there are many, many older log files to process.
31
+ #
32
+ class RollingFile < ::Logging::Appenders::File
33
+
34
+ #
35
+ # call-seq:
36
+ # RollingFile.new( name, opts )
37
+ #
38
+ # Creates a new Rolling File Appender. The _name_ is the unique Appender
39
+ # name used to retrieve this appender from the Appender hash. The only
40
+ # required option is the filename to use for creating log files.
41
+ #
42
+ # [:filename] The base filename to use when constructing new log
43
+ # filenames.
44
+ #
45
+ # The following options are optional:
46
+ #
47
+ # [:layout] The Layout that will be used by this appender. The Basic
48
+ # layout will be used if none is given.
49
+ # [:truncate] When set to true any existing log files will be rolled
50
+ # immediately and a new, empty log file will be created.
51
+ # [:max_size] The maximum allowed size (in bytes) of a log file before
52
+ # it is rolled.
53
+ # [:max_age] The maximum age (in seconds) of a log file before it is
54
+ # rolled.
55
+ # [:keep] The number of rolled log files to keep.
56
+ #
57
+ def initialize( name, opts = {} )
58
+ # raise an error if a filename was not given
59
+ @fn = opts[:filename] || opts['filename']
60
+ raise ArgumentError, 'no filename was given' if @fn.nil?
61
+
62
+ # grab the information we need to properly roll files
63
+ ext = ::File.extname(@fn)
64
+ bn = ::File.join(::File.dirname(@fn), ::File.basename(@fn, ext))
65
+ @rgxp = %r/\.(\d+)#{Regexp.escape(ext)}\z/
66
+ @glob = "#{bn}.*#{ext}"
67
+ @logname_fmt = "#{bn}.%d#{ext}"
68
+
69
+ # if the truncate flag was set to true, then roll
70
+ roll_now = opts.delete(:truncate) || opts.delete('truncate')
71
+ roll_files if roll_now
72
+
73
+ # grab out our options
74
+ @keep = opts.delete(:keep) || opts.delete('keep')
75
+ @max_size = opts.delete(:max_size) || opts.delete('max_size')
76
+ @max_age = opts.delete(:max_age) || opts.delete('max_age')
77
+
78
+ @keep = Integer(@keep) unless @keep.nil?
79
+ @max_size = Integer(@max_size) unless @max_size.nil?
80
+ unless @max_age.nil?
81
+ @max_age = Integer(@max_age)
82
+ @start_time = Time.now
83
+ end
84
+
85
+ @file_size = (::File.exist?(@fn) ? ::File.size(@fn) : 0)
86
+ super(name, opts)
87
+ end
88
+
89
+ private
90
+ #
91
+ # call-seq:
92
+ # write( str )
93
+ #
94
+ # Write the given string to the log file. The log file will be rolled
95
+ # if the maximum file size is exceeded or if the file is older than the
96
+ # maximum age.
97
+ #
98
+ def write( str )
99
+ super
100
+ @file_size += str.size # keep track of the size internally since
101
+ roll if roll_required? # the file IO stream is probably not being
102
+ end # flushed to disk immediately
103
+
104
+ #
105
+ # call-seq:
106
+ # roll
107
+ #
108
+ # Close the currently open log file, roll all the log files, and open a
109
+ # new log file.
110
+ #
111
+ def roll
112
+ begin; @io.close; rescue; end
113
+ roll_files
114
+ @io = ::File.new(@fn, 'w')
115
+ end
116
+
117
+ #
118
+ # call-seq:
119
+ # roll_required?
120
+ #
121
+ # Returns +true+ if the log file needs to be rolled.
122
+ #
123
+ def roll_required?
124
+ # check if max size has been exceeded
125
+ if @max_size and @file_size > @max_size
126
+ @file_size = 0
127
+ return true
128
+ end
129
+
130
+ # check if max age has been exceeded
131
+ if @max_age and (Time.now - @start_time) > @max_age
132
+ @start_time = Time.now
133
+ return true
134
+ end
135
+
136
+ false
137
+ end
138
+
139
+ #
140
+ # call-seq:
141
+ # roll_files
142
+ #
143
+ # Roll the log files. This is accomplished by renaming the log files
144
+ # starting with the oldest and working towards the youngest.
145
+ #
146
+ # test.10.log => deleted (we are only keeping 10)
147
+ # test.9.log => test.10.log
148
+ # test.8.log => test.9.log
149
+ # ...
150
+ # test.1.log => test.2.log
151
+ #
152
+ # Lastly the current log file is rolled to a numbered log file.
153
+ #
154
+ # test.log => test.1.log
155
+ #
156
+ # This method leaves no <tt>test.log</tt> file when it is done. This
157
+ # file will be created elsewhere.
158
+ #
159
+ def roll_files
160
+ return unless ::File.exist?(@fn)
161
+
162
+ files = Dir.glob(@glob).find_all {|fn| @rgxp =~ fn}
163
+ unless files.empty?
164
+ # sort the files in revese order based on their count number
165
+ files = files.sort do |a,b|
166
+ a = Integer(@rgxp.match(a)[1])
167
+ b = Integer(@rgxp.match(b)[1])
168
+ b <=> a
169
+ end
170
+
171
+ # for each file, roll its count number one higher
172
+ files.each do |fn|
173
+ cnt = Integer(@rgxp.match(fn)[1])
174
+ if @keep and cnt >= @keep
175
+ ::File.delete fn
176
+ next
177
+ end
178
+ ::File.rename fn, sprintf(@logname_fmt, cnt+1)
179
+ end
180
+ end
181
+
182
+ # finally reanme the base log file
183
+ ::File.rename(@fn, sprintf(@logname_fmt, 1))
184
+ end
185
+
186
+ end # class RollingFile
187
+ end # module Logging::Appenders
188
+
189
+ # EOF