path-log4r 1.1.10

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.
Files changed (104) hide show
  1. data/INSTALL +11 -0
  2. data/LICENSE +90 -0
  3. data/LICENSE.LGPLv3 +165 -0
  4. data/README +95 -0
  5. data/Rakefile +74 -0
  6. data/TODO +2 -0
  7. data/doc/content/contact.html +22 -0
  8. data/doc/content/contribute.html +21 -0
  9. data/doc/content/index.html +90 -0
  10. data/doc/content/license.html +56 -0
  11. data/doc/content/manual.html +449 -0
  12. data/doc/dev/README.developers +55 -0
  13. data/doc/dev/checklist +23 -0
  14. data/doc/dev/things-to-do +5 -0
  15. data/doc/images/log4r-logo.png +0 -0
  16. data/doc/images/logo2.png +0 -0
  17. data/doc/log4r.css +111 -0
  18. data/doc/rdoc-log4r.css +696 -0
  19. data/doc/templates/main.html +147 -0
  20. data/examples/README +19 -0
  21. data/examples/ancestors.rb +53 -0
  22. data/examples/chainsaw_settings.xml +7 -0
  23. data/examples/customlevels.rb +34 -0
  24. data/examples/filelog.rb +25 -0
  25. data/examples/fileroll.rb +40 -0
  26. data/examples/gmail.rb +30 -0
  27. data/examples/gmail.yaml +95 -0
  28. data/examples/log4r_yaml.yaml +0 -0
  29. data/examples/logclient.rb +25 -0
  30. data/examples/logserver.rb +18 -0
  31. data/examples/moderate.xml +29 -0
  32. data/examples/moderateconfig.rb +66 -0
  33. data/examples/myformatter.rb +23 -0
  34. data/examples/outofthebox.rb +21 -0
  35. data/examples/rdoc-gen +2 -0
  36. data/examples/rrconfig.xml +63 -0
  37. data/examples/rrsetup.rb +42 -0
  38. data/examples/simpleconfig.rb +39 -0
  39. data/examples/syslogcustom.rb +52 -0
  40. data/examples/xmlconfig.rb +25 -0
  41. data/examples/yaml.rb +30 -0
  42. data/lib/log4r.rb +20 -0
  43. data/lib/log4r/GDC.rb +41 -0
  44. data/lib/log4r/MDC.rb +59 -0
  45. data/lib/log4r/NDC.rb +86 -0
  46. data/lib/log4r/base.rb +74 -0
  47. data/lib/log4r/config.rb +9 -0
  48. data/lib/log4r/configurator.rb +224 -0
  49. data/lib/log4r/formatter/formatter.rb +105 -0
  50. data/lib/log4r/formatter/log4jxmlformatter.rb +61 -0
  51. data/lib/log4r/formatter/patternformatter.rb +145 -0
  52. data/lib/log4r/lib/drbloader.rb +52 -0
  53. data/lib/log4r/lib/xmlloader.rb +24 -0
  54. data/lib/log4r/logevent.rb +28 -0
  55. data/lib/log4r/logger.rb +199 -0
  56. data/lib/log4r/loggerfactory.rb +89 -0
  57. data/lib/log4r/logserver.rb +28 -0
  58. data/lib/log4r/outputter/consoleoutputters.rb +18 -0
  59. data/lib/log4r/outputter/datefileoutputter.rb +117 -0
  60. data/lib/log4r/outputter/emailoutputter.rb +143 -0
  61. data/lib/log4r/outputter/fileoutputter.rb +56 -0
  62. data/lib/log4r/outputter/iooutputter.rb +55 -0
  63. data/lib/log4r/outputter/outputter.rb +134 -0
  64. data/lib/log4r/outputter/outputterfactory.rb +61 -0
  65. data/lib/log4r/outputter/remoteoutputter.rb +40 -0
  66. data/lib/log4r/outputter/rollingfileoutputter.rb +234 -0
  67. data/lib/log4r/outputter/scribeoutputter.rb +37 -0
  68. data/lib/log4r/outputter/staticoutputter.rb +30 -0
  69. data/lib/log4r/outputter/syslogoutputter.rb +130 -0
  70. data/lib/log4r/outputter/udpoutputter.rb +53 -0
  71. data/lib/log4r/rdoc/GDC +14 -0
  72. data/lib/log4r/rdoc/MDC +16 -0
  73. data/lib/log4r/rdoc/NDC +41 -0
  74. data/lib/log4r/rdoc/configurator +243 -0
  75. data/lib/log4r/rdoc/emailoutputter +103 -0
  76. data/lib/log4r/rdoc/formatter +39 -0
  77. data/lib/log4r/rdoc/log4r +89 -0
  78. data/lib/log4r/rdoc/logger +175 -0
  79. data/lib/log4r/rdoc/logserver +85 -0
  80. data/lib/log4r/rdoc/outputter +108 -0
  81. data/lib/log4r/rdoc/patternformatter +128 -0
  82. data/lib/log4r/rdoc/scribeoutputter +16 -0
  83. data/lib/log4r/rdoc/syslogoutputter +29 -0
  84. data/lib/log4r/rdoc/win32eventoutputter +7 -0
  85. data/lib/log4r/rdoc/yamlconfigurator +20 -0
  86. data/lib/log4r/repository.rb +88 -0
  87. data/lib/log4r/staticlogger.rb +49 -0
  88. data/lib/log4r/yamlconfigurator.rb +196 -0
  89. data/tests/README +10 -0
  90. data/tests/testGDC.rb +26 -0
  91. data/tests/testMDC.rb +42 -0
  92. data/tests/testNDC.rb +27 -0
  93. data/tests/testall.rb +6 -0
  94. data/tests/testbase.rb +49 -0
  95. data/tests/testchainsaw.rb +48 -0
  96. data/tests/testconf.xml +37 -0
  97. data/tests/testcustom.rb +27 -0
  98. data/tests/testformatter.rb +27 -0
  99. data/tests/testlogger.rb +196 -0
  100. data/tests/testoutputter.rb +132 -0
  101. data/tests/testpatternformatter.rb +78 -0
  102. data/tests/testthreads.rb +35 -0
  103. data/tests/testxmlconf.rb +45 -0
  104. metadata +184 -0
@@ -0,0 +1,55 @@
1
+ # :nodoc:
2
+ require "log4r/outputter/outputter"
3
+ require "log4r/staticlogger"
4
+
5
+ module Log4r
6
+
7
+ ##
8
+ # IO Outputter invokes print then flush on the wrapped IO
9
+ # object. If the IO stream dies, IOOutputter sets itself to OFF
10
+ # and the system continues on its merry way.
11
+ #
12
+ # To find out why an IO stream died, create a logger named 'log4r'
13
+ # and look at the output.
14
+
15
+ class IOOutputter < Outputter
16
+
17
+ # IOOutputter needs an IO object to write to.
18
+ def initialize(_name, _out, hash={})
19
+ super(_name, hash)
20
+ @out = _out
21
+ end
22
+
23
+ def closed?
24
+ @out.closed?
25
+ end
26
+
27
+ # Close the IO and sets level to OFF
28
+ def close
29
+ @out.close unless @out.nil?
30
+ @level = OFF
31
+ OutputterFactory.create_methods(self)
32
+ Logger.log_internal {"Outputter '#{@name}' closed IO and set to OFF"}
33
+ end
34
+
35
+ #######
36
+ private
37
+ #######
38
+
39
+ # perform the write
40
+ def write(data)
41
+ begin
42
+ @out.print data
43
+ @out.flush
44
+ rescue IOError => ioe # recover from this instead of crash
45
+ Logger.log_internal {"IOError in Outputter '#{@name}'!"}
46
+ Logger.log_internal {ioe}
47
+ close
48
+ rescue NameError => ne
49
+ Logger.log_internal {"Outputter '#{@name}' IO is #{@out.class}!"}
50
+ Logger.log_internal {ne}
51
+ close
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,134 @@
1
+ # :include: ../rdoc/outputter
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version:: $Id$
6
+ # Author:: Leon Torres <leon@ugcs.caltech.edu>
7
+
8
+ require "thread"
9
+
10
+ require "log4r/outputter/outputterfactory"
11
+ require "log4r/formatter/formatter"
12
+ require "log4r/staticlogger"
13
+
14
+ require 'monitor'
15
+
16
+ module Log4r
17
+
18
+ class Outputter < Monitor
19
+ attr_reader :name, :level, :formatter
20
+ @@outputters = Hash.new
21
+
22
+ # An Outputter needs a name. RootLogger will be loaded if not already
23
+ # done. The hash arguments are as follows:
24
+ #
25
+ # [<tt>:level</tt>] Logger level. Optional, defaults to root level
26
+ # [<tt>:formatter</tt>] A Formatter. Defaults to DefaultFormatter
27
+
28
+ def initialize(_name, hash={})
29
+ super()
30
+ if _name.nil?
31
+ raise ArgumentError, "Bad arguments. Name and IO expected.", caller
32
+ end
33
+ @name = _name
34
+ validate_hash(hash)
35
+ @@outputters[@name] = self
36
+ end
37
+
38
+ # dynamically change the level
39
+ def level=(_level)
40
+ Log4rTools.validate_level(_level)
41
+ @level = _level
42
+ OutputterFactory.create_methods(self)
43
+ Logger.log_internal {"Outputter '#{@name}' level is #{LNAMES[_level]}"}
44
+ end
45
+
46
+ # Set the levels to log. All others will be ignored
47
+ def only_at(*levels)
48
+ raise ArgumentError, "Gimme some levels!", caller if levels.empty?
49
+ raise ArgumentError, "Can't log only_at ALL", caller if levels.include? ALL
50
+ levels.each {|level| Log4rTools.validate_level(level)}
51
+ @level = levels.sort.first
52
+ OutputterFactory.create_methods self, levels
53
+ Logger.log_internal {
54
+ "Outputter '#{@name}' writes only on " +\
55
+ levels.collect{|l| LNAMES[l]}.join(", ")
56
+ }
57
+ end
58
+
59
+ # Dynamically change the formatter. You can just specify a Class
60
+ # object and the formatter will invoke +new+ or +instance+
61
+ # on it as appropriate.
62
+
63
+ def formatter=(_formatter)
64
+ if _formatter.kind_of?(Formatter)
65
+ @formatter = _formatter
66
+ elsif _formatter.kind_of?(Class) and _formatter <= Formatter
67
+ if _formatter.respond_to? :instance
68
+ @formatter = _formatter.instance
69
+ else
70
+ @formatter = _formatter.new
71
+ end
72
+ else
73
+ raise TypeError, "Argument was not a Formatter!", caller
74
+ end
75
+ Logger.log_internal {"Outputter '#{@name}' using #{@formatter.class}"}
76
+ end
77
+
78
+ # Call flush to force an outputter to write out any buffered
79
+ # log events. Similar to IO#flush, so use in a similar fashion.
80
+
81
+ def flush
82
+ end
83
+
84
+ #########
85
+ protected
86
+ #########
87
+
88
+ # Validates the common hash arguments. For now, that would be
89
+ # +:level+, +:formatter+ and the string equivalents
90
+ def validate_hash(hash)
91
+ # default to root level and DefaultFormatter
92
+ if hash.empty?
93
+ self.level = Logger.root.level
94
+ @formatter = DefaultFormatter.new
95
+ return
96
+ end
97
+ self.level = (hash[:level] or hash['level'] or Logger.root.level)
98
+ self.formatter = (hash[:formatter] or hash['formatter'] or DefaultFormatter.new)
99
+ end
100
+
101
+ #######
102
+ private
103
+ #######
104
+
105
+ # This method handles all log events passed to a typical Outputter.
106
+ # Overload this to change the overall behavior of an outputter. Make
107
+ # sure that the new behavior is thread safe.
108
+
109
+ def canonical_log(logevent)
110
+ synch { write(format(logevent)) }
111
+ end
112
+
113
+ # Common method to format data. All it does is call the resident
114
+ # formatter's format method. If a different formatting behavior is
115
+ # needed, then overload this method.
116
+
117
+ def format(logevent)
118
+ # @formatter is guaranteed to be DefaultFormatter if no Formatter
119
+ # was specified
120
+ @formatter.format(logevent)
121
+ end
122
+
123
+ # Abstract method to actually write the data to a destination.
124
+ # Custom outputters should overload this to specify how the
125
+ # formatted data should be written and to where.
126
+
127
+ def write(data)
128
+ end
129
+
130
+ def synch; synchronize { yield } end
131
+
132
+ end
133
+
134
+ end
@@ -0,0 +1,61 @@
1
+ # :nodoc:
2
+ # Version: $Id$
3
+
4
+ require "log4r/base"
5
+ require "log4r/repository"
6
+ require "log4r/logger"
7
+
8
+ require 'monitor'
9
+
10
+ module Log4r
11
+ class Outputter < Monitor
12
+
13
+ class OutputterFactory #:nodoc:
14
+ include Singleton
15
+
16
+ # handles two cases: logging above a level (no second arg specified)
17
+ # or logging a set of levels (passed into the second argument)
18
+ def self.create_methods(out, levels=nil)
19
+ Logger.root # force levels to be loaded
20
+
21
+ # first, undefine all the log levels
22
+ for mname in LNAMES
23
+ undefine_log(mname.downcase, out)
24
+ end
25
+ if not levels.nil? and levels.include? OFF
26
+ raise TypeError, "Can't log only_at OFF", caller[1..-1]
27
+ end
28
+ return out if out.level == OFF
29
+
30
+ if levels.nil? # then define the log methods for lev >= outlev
31
+ for lev in out.level...LEVELS
32
+ define_log(LNAMES[lev].downcase, lev, out)
33
+ end
34
+ else # define the logs only for assigned levels
35
+ for lev in levels
36
+ define_log(LNAMES[lev].downcase, lev, out)
37
+ end
38
+ end
39
+ return out
40
+ end
41
+
42
+ # we need to synch the actual write/format for thread safteyness
43
+ def self.define_log(mname, level, out)
44
+ return if mname == 'off' || mname == 'all'
45
+ mstr = %-
46
+ def out.#{mname}(logevent)
47
+ canonical_log(logevent)
48
+ end
49
+ -
50
+ module_eval mstr
51
+ end
52
+
53
+ def self.undefine_log(mname, out)
54
+ return if mname == 'off' || mname == 'all'
55
+ mstr = "def out.#{mname}(logevent); end"
56
+ module_eval mstr
57
+ end
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,40 @@
1
+ # :nodoc:
2
+ require 'log4r/lib/drbloader'
3
+ require 'log4r/outputter/outputter'
4
+
5
+ module Log4r
6
+ # See log4r/logserver.rb
7
+ class RemoteOutputter < Outputter
8
+
9
+ def initialize(_name, hash={})
10
+ super(_name, hash)
11
+ @uri = (hash[:uri] or hash['uri'])
12
+ @buffsize = (hash[:buffsize] or hash['buffsize'] or 1).to_i
13
+ @buff = []
14
+ connect
15
+ end
16
+
17
+ if HAVE_ROMP
18
+ include ROMPClient
19
+ else
20
+ def initialize(*args)
21
+ raise RuntimeError, "LogServer not supported. ROMP is required", caller
22
+ end
23
+ end
24
+
25
+
26
+ # Call flush to send any remaining LogEvents to the remote server.
27
+ def flush
28
+ synch { send_buffer }
29
+ end
30
+
31
+ private
32
+
33
+ def canonical_log(logevent)
34
+ synch {
35
+ @buff.push logevent
36
+ send_buffer if @buff.size >= @buffsize
37
+ }
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,234 @@
1
+
2
+ # :nodoc:
3
+ # Version:: $Id: rollingfileoutputter.rb,v 1.2 2009/09/29 18:13:13 colbygk Exp $
4
+
5
+ require "log4r/outputter/fileoutputter"
6
+ require "log4r/staticlogger"
7
+
8
+ require 'fileutils'
9
+
10
+ module Log4r
11
+
12
+ # RollingFileOutputter - subclass of FileOutputter that rolls files on size
13
+ # or time. So, given a filename of "error.log", the first log file will be "error000001.log".
14
+ # When its check condition is exceeded, it'll create and log to "error000002.log", etc.
15
+ #
16
+ # Additional hash arguments are:
17
+ #
18
+ # [<tt>:maxsize</tt>] Maximum size of the file in bytes.
19
+ # [<tt>:maxtime</tt>] Maximum age of the file in seconds.
20
+ # [<tt>:max_backups</tt>] Maxium number of prior log files to maintain. If max_backups is a positive number,
21
+ # then each time a roll happens, RollingFileOutputter will delete the oldest backup log files in excess
22
+ # of this number (if any). So, if max_backups is 10, then a maximum of 11 files will be maintained (the current
23
+ # log, plus 10 backups). If max_backups is 0, no backups will be kept. If it is negative (the default),
24
+ # there will be no limit on the number of files created. Note that the sequence numbers will continue to escalate;
25
+ # old sequence numbers are not reused.
26
+ # [<tt>:trunc</tt>] If true, deletes ALL existing log files (based on :filename) upon initialization,
27
+ # and the sequence numbering will start over at 000001. Otherwise continues logging where it left off
28
+ # last time (i.e. either to the file with the highest sequence number, or a new file, as appropriate).
29
+ class RollingFileOutputter < FileOutputter
30
+
31
+ attr_reader :current_sequence_number, :maxsize, :maxtime, :start_time, :max_backups
32
+
33
+ def initialize(_name, hash={})
34
+ super( _name, hash.merge({:create => false}) )
35
+ if hash.has_key?(:maxsize) || hash.has_key?('maxsize')
36
+ _maxsize = (hash[:maxsize] or hash['maxsize']).to_i
37
+ if _maxsize.class != Fixnum
38
+ raise TypeError, "Argument 'maxsize' must be an Fixnum", caller
39
+ end
40
+ if _maxsize == 0
41
+ raise TypeError, "Argument 'maxsize' must be > 0", caller
42
+ end
43
+ @maxsize = _maxsize
44
+ end
45
+ if hash.has_key?(:maxtime) || hash.has_key?('maxtime')
46
+ _maxtime = (hash[:maxtime] or hash['maxtime']).to_i
47
+ if _maxtime.class != Fixnum
48
+ raise TypeError, "Argument 'maxtime' must be an Fixnum", caller
49
+ end
50
+ if _maxtime == 0
51
+ raise TypeError, "Argument 'maxtime' must be > 0", caller
52
+ end
53
+ @maxtime = _maxtime
54
+ end
55
+ if hash.has_key?(:max_backups) || hash.has_key?('max_backups')
56
+ _max_backups = (hash[:max_backups] or hash['max_backups']).to_i
57
+ if _max_backups.class != Fixnum
58
+ raise TypeError, "Argument 'max_backups' must be an Fixnum", caller
59
+ end
60
+ @max_backups = _max_backups
61
+ else
62
+ @max_backups = -1
63
+ end
64
+ # @filename starts out as the file (including path) provided by the user, e.g. "\usr\logs\error.log".
65
+ # It will get assigned the current log file (including sequence number)
66
+ # @log_dir is the directory in which we'll log, e.g. "\usr\logs"
67
+ # @file_extension is the file's extension (if any) including any period, e.g. ".log"
68
+ # @core_file_name is the part of the log file's name, sans sequence digits or extension, e.g. "error"
69
+ @log_dir = File.dirname(@filename)
70
+ @file_extension = File.extname(@filename) # Note: the File API doc comment states that this doesn't include the period, but its examples and behavior do include it. We'll depend on the latter.
71
+ @core_file_name = File.basename(@filename, @file_extension)
72
+ if (@trunc)
73
+ purge_log_files(0)
74
+ end
75
+ @current_sequence_number = get_current_sequence_number()
76
+ makeNewFilename
77
+ # Now @filename points to a properly sequenced filename, which may or may not yet exist.
78
+ open_log_file('a')
79
+
80
+ # Note: it's possible we're already in excess of our time or size constraint for the current file;
81
+ # no worries -- if a new file needs to be started, it'll happen during the write() call.
82
+ end
83
+
84
+ #######
85
+ private
86
+ #######
87
+
88
+ # Delete all but the latest number_to_keep log files.
89
+ def purge_log_files(number_to_keep)
90
+ Dir.chdir(@log_dir) do
91
+ # Make a list of the log files to delete. Start with all of the matching log files...
92
+ glob = "#{@core_file_name}[0-9][0-9][0-9][0-9][0-9][0-9]#{@file_extension}"
93
+ files = Dir.glob(glob)
94
+
95
+ # ... if there are fewer than our threshold, just return...
96
+ if (files.size() <= number_to_keep )
97
+ # Logger.log_internal {"No log files need purging."}
98
+ return
99
+ end
100
+ # ...then remove those that we want to keep (i.e. the most recent #{number_to_keep} files).
101
+ files.sort!().slice!(-number_to_keep, number_to_keep)
102
+
103
+ # Delete the files. We use force (rm_f), so in case any files can't be deleted (e.g. someone's got one
104
+ # open in an editor), we'll swallow the error and keep going.
105
+ FileUtils.rm_f(files)
106
+ Logger.log_internal { "Purged #{files.length} log files: #{files}" }
107
+ end
108
+ end
109
+
110
+ # Get the highest existing log file sequence number, or 1 if there are no existing log files.
111
+ def get_current_sequence_number()
112
+ max_seq_no = 0
113
+ Dir.foreach(@log_dir) do |child|
114
+ if child =~ /^#{@core_file_name}(\d+)#{@file_extension}$/
115
+ seq_no = $1.to_i
116
+ if (seq_no > max_seq_no)
117
+ max_seq_no = seq_no
118
+ end
119
+ end
120
+ end
121
+ return [max_seq_no, 1].max
122
+ end
123
+
124
+ # perform the write
125
+ def write(data)
126
+ # we have to keep track of the file size ourselves - File.size doesn't
127
+ # seem to report the correct size when the size changes rapidly
128
+ @datasize += data.size + 1 # the 1 is for newline
129
+ roll if requiresRoll
130
+ super
131
+ end
132
+
133
+ # Constructs a new filename from the @current_sequence_number, @core_file_name, and @file_extension,
134
+ # and assigns it to @filename
135
+ def makeNewFilename
136
+ # note use of hard coded 6 digit sequence width - is this enough files?
137
+ padded_seq_no = "0" * (6 - @current_sequence_number.to_s.length) + @current_sequence_number.to_s
138
+ newbase = "#{@core_file_name}#{padded_seq_no}#{@file_extension}"
139
+ @filename = File.join(@log_dir, newbase)
140
+ end
141
+
142
+ # Open @filename with the given mode:
143
+ # 'a' - appends to the end of the file if it exists; otherwise creates it.
144
+ # 'w' - truncates the file to zero length if it exists, otherwise creates it.
145
+ # Re-initializes @datasize and @startime appropriately.
146
+ def open_log_file(mode)
147
+ # It appears that if a file has been recently deleted then recreated, calls like
148
+ # File.ctime can return the erstwhile creation time. File.size? can similarly return
149
+ # old information. So instead of simply doing ctime and size checks after File.new, we
150
+ # do slightly more complicated checks beforehand:
151
+ if (mode == 'w' || !File.exists?(@filename))
152
+ @start_time = Time.now()
153
+ @datasize = 0
154
+ else
155
+ @start_time = File.ctime(@filename)
156
+ @datasize = File.size?(@filename) || 0 # File.size? returns nil even if the file exists but is empty; we convert it to 0.
157
+ end
158
+ @out = File.new(@filename, mode)
159
+ Logger.log_internal {"File #{@filename} opened with mode #{mode}"}
160
+ end
161
+
162
+ # does the file require a roll?
163
+ def requiresRoll
164
+ if !@maxsize.nil? && @datasize > @maxsize
165
+ Logger.log_internal { "Rolling because #{@filename} (#{@datasize} bytes) has exceded the maxsize limit (#{@maxsize} bytes)." }
166
+ return true
167
+ end
168
+ if !@maxtime.nil? && (Time.now - @start_time) > @maxtime
169
+ Logger.log_internal { "Rolling because #{@filename} (created: #{@start_time}) has exceded the maxtime age (#{@maxtime} seconds)." }
170
+ return true
171
+ end
172
+ false
173
+ end
174
+
175
+ # roll the file
176
+ def roll
177
+ begin
178
+ # If @baseFilename == @filename, then this method is about to
179
+ # try to close out a file that is not actually opened because
180
+ # fileoutputter has been called with the parameter roll=true
181
+ # TODO: Is this check valid any more? I suspect not. Am commenting out...:
182
+ #if ( @baseFilename != @filename ) then
183
+ @out.close
184
+ #end
185
+ rescue
186
+ Logger.log_internal {
187
+ "RollingFileOutputter '#{@name}' could not close #{@filename}"
188
+ }
189
+ end
190
+
191
+ # Prepare the next file. (Note: if max_backups is zero, we can skip this; we'll
192
+ # just overwrite the existing log file)
193
+ if (@max_backups != 0)
194
+ @current_sequence_number += 1
195
+ makeNewFilename
196
+ end
197
+
198
+ open_log_file('w')
199
+
200
+ # purge any excess log files (unless max_backups is negative, which means don't purge).
201
+ if (@max_backups >= 0)
202
+ purge_log_files(@max_backups + 1)
203
+ end
204
+
205
+ end
206
+
207
+ end
208
+
209
+ end
210
+
211
+ # this can be found in examples/fileroll.rb as well
212
+ if __FILE__ == $0
213
+ require 'log4r'
214
+ include Log4r
215
+
216
+
217
+ timeLog = Logger.new 'WbExplorer'
218
+ timeLog.outputters = RollingFileOutputter.new("WbExplorer", { "filename" => "TestTime.log", "maxtime" => 10, "trunc" => true })
219
+ timeLog.level = DEBUG
220
+
221
+ 100.times { |t|
222
+ timeLog.info "blah #{t}"
223
+ sleep(1.0)
224
+ }
225
+
226
+ sizeLog = Logger.new 'WbExplorer'
227
+ sizeLog.outputters = RollingFileOutputter.new("WbExplorer", { "filename" => "TestSize.log", "maxsize" => 16000, "trunc" => true })
228
+ sizeLog.level = DEBUG
229
+
230
+ 10000.times { |t|
231
+ sizeLog.info "blah #{t}"
232
+ }
233
+
234
+ end