sml-log4r 1.0.6

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 (77) hide show
  1. data/doc/content/contact.html +22 -0
  2. data/doc/content/contribute.html +21 -0
  3. data/doc/content/index.html +90 -0
  4. data/doc/content/license.html +56 -0
  5. data/doc/content/manual.html +449 -0
  6. data/doc/dev/README.developers +40 -0
  7. data/doc/dev/checklist +14 -0
  8. data/doc/dev/things-to-do +2 -0
  9. data/doc/images/crush/logo2.png +0 -0
  10. data/doc/images/log4r-logo.png +0 -0
  11. data/doc/images/logo2.png +0 -0
  12. data/doc/log4r.css +111 -0
  13. data/doc/old/manual.html +348 -0
  14. data/doc/templates/main.html +147 -0
  15. data/examples/README +19 -0
  16. data/examples/customlevels.rb +34 -0
  17. data/examples/fileroll.rb +40 -0
  18. data/examples/log4r_yaml.yaml +0 -0
  19. data/examples/logclient.rb +25 -0
  20. data/examples/logserver.rb +18 -0
  21. data/examples/moderate.xml +29 -0
  22. data/examples/moderateconfig.rb +66 -0
  23. data/examples/myformatter.rb +23 -0
  24. data/examples/outofthebox.rb +21 -0
  25. data/examples/rrconfig.xml +63 -0
  26. data/examples/rrsetup.rb +42 -0
  27. data/examples/simpleconfig.rb +39 -0
  28. data/examples/xmlconfig.rb +25 -0
  29. data/examples/yaml.rb +30 -0
  30. data/src/log4r.rb +17 -0
  31. data/src/log4r/base.rb +74 -0
  32. data/src/log4r/config.rb +9 -0
  33. data/src/log4r/configurator.rb +224 -0
  34. data/src/log4r/formatter/formatter.rb +105 -0
  35. data/src/log4r/formatter/patternformatter.rb +108 -0
  36. data/src/log4r/lib/drbloader.rb +52 -0
  37. data/src/log4r/lib/xmlloader.rb +24 -0
  38. data/src/log4r/logevent.rb +28 -0
  39. data/src/log4r/logger.rb +194 -0
  40. data/src/log4r/loggerfactory.rb +89 -0
  41. data/src/log4r/logserver.rb +28 -0
  42. data/src/log4r/outputter/consoleoutputters.rb +18 -0
  43. data/src/log4r/outputter/datefileoutputter.rb +110 -0
  44. data/src/log4r/outputter/emailoutputter.rb +115 -0
  45. data/src/log4r/outputter/fileoutputter.rb +49 -0
  46. data/src/log4r/outputter/iooutputter.rb +55 -0
  47. data/src/log4r/outputter/outputter.rb +132 -0
  48. data/src/log4r/outputter/outputterfactory.rb +59 -0
  49. data/src/log4r/outputter/remoteoutputter.rb +40 -0
  50. data/src/log4r/outputter/rollingfileoutputter.rb +126 -0
  51. data/src/log4r/outputter/staticoutputter.rb +30 -0
  52. data/src/log4r/outputter/syslogoutputter.rb +75 -0
  53. data/src/log4r/rdoc/configurator +243 -0
  54. data/src/log4r/rdoc/emailoutputter +103 -0
  55. data/src/log4r/rdoc/formatter +39 -0
  56. data/src/log4r/rdoc/log4r +89 -0
  57. data/src/log4r/rdoc/logger +175 -0
  58. data/src/log4r/rdoc/logserver +85 -0
  59. data/src/log4r/rdoc/outputter +108 -0
  60. data/src/log4r/rdoc/patternformatter +128 -0
  61. data/src/log4r/rdoc/syslogoutputter +29 -0
  62. data/src/log4r/rdoc/yamlconfigurator +20 -0
  63. data/src/log4r/repository.rb +65 -0
  64. data/src/log4r/staticlogger.rb +49 -0
  65. data/src/log4r/yamlconfigurator.rb +0 -0
  66. data/tests/include.rb +7 -0
  67. data/tests/runtest.rb +6 -0
  68. data/tests/testbase.rb +45 -0
  69. data/tests/testcustom.rb +33 -0
  70. data/tests/testdefault.rb +25 -0
  71. data/tests/testformatter.rb +29 -0
  72. data/tests/testlogger.rb +198 -0
  73. data/tests/testoutputter.rb +112 -0
  74. data/tests/testpatternformatter.rb +26 -0
  75. data/tests/testxmlconf.rb +51 -0
  76. data/tests/xml/testconf.xml +37 -0
  77. metadata +140 -0
@@ -0,0 +1,89 @@
1
+ # :nodoc:
2
+ # Version:: $Id: loggerfactory.rb,v 1.11 2002/01/28 16:05:05 cepheus Exp $
3
+
4
+ require "log4r/base"
5
+ require "log4r/repository"
6
+ require 'log4r/logevent'
7
+
8
+ module Log4r
9
+ class Logger
10
+ class LoggerFactory #:nodoc:
11
+
12
+ # we want to log iff root.lev <= lev && logger.lev <= lev
13
+ # BTW, root is guaranteed to be defined by this point
14
+ def self.define_methods(logger)
15
+ return if logger.is_root?
16
+ undefine_methods(logger)
17
+ globlev = Repository['root'].level
18
+ return if logger.level == OFF or globlev == OFF
19
+ toggle_methods(globlev, logger)
20
+ end
21
+
22
+ # set logging methods to null defaults
23
+ def self.undefine_methods(logger)
24
+ for lname in LNAMES
25
+ next if lname == 'OFF'|| lname == 'ALL'
26
+ unset_log(logger, lname)
27
+ set_false(logger, lname)
28
+ end
29
+ set_false(logger, 'all')
30
+ set_true(logger, 'off')
31
+ end
32
+
33
+ # toggle methods >= globlev that are also >= level
34
+ def self.toggle_methods(globlev, logger)
35
+ for lev in globlev...LEVELS # satisfies >= globlev
36
+ next if lev < logger.level # satisfies >= level
37
+ next if LNAMES[lev] == 'OFF'
38
+ next if LNAMES[lev] == 'ALL'
39
+ set_log(logger, LNAMES[lev])
40
+ set_true(logger, LNAMES[lev])
41
+ end
42
+ if logger.level == ALL
43
+ set_true(logger, 'all')
44
+ end
45
+ if logger.level != OFF && globlev != OFF
46
+ set_false(logger, 'off')
47
+ end
48
+ end
49
+
50
+ # And now, the weird dynamic method definitions! :)
51
+
52
+ def self.unset_log(logger, lname)
53
+ mstr="def logger.#{lname.downcase}(data=nil, propagated=false); end"
54
+ module_eval mstr
55
+ end
56
+
57
+ # Logger logging methods are defined here.
58
+ def self.set_log(logger, lname)
59
+ # invoke caller iff the logger invoked is tracing
60
+ tracercall = (logger.trace ? "caller" : "nil")
61
+ # maybe pass parent a logevent. second arg is the switch
62
+ if logger.additive && !logger.parent.is_root?
63
+ parentcall = "@parent.#{lname.downcase}(event, true)"
64
+ end
65
+ mstr = %-
66
+ def logger.#{lname.downcase}(data=nil, propagated=false)
67
+ if propagated then event = data
68
+ else
69
+ data = yield if block_given?
70
+ event = LogEvent.new(#{lname}, self, #{tracercall}, data)
71
+ end
72
+ @outputters.each {|o| o.#{lname.downcase}(event) }
73
+ #{parentcall}
74
+ end
75
+ -
76
+ module_eval mstr
77
+ end
78
+
79
+ def self.set_false(logger, lname)
80
+ module_eval "def logger.#{lname.downcase}?; false end"
81
+ end
82
+
83
+ def self.set_true(logger, lname)
84
+ module_eval "def logger.#{lname.downcase}?; true end"
85
+ end
86
+
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,28 @@
1
+ # :include: rdoc/logserver
2
+
3
+ require 'log4r/logger'
4
+ require 'log4r/lib/drbloader'
5
+
6
+ module Log4r
7
+ # See log4r/logserver.rb
8
+ class LogServer < Logger
9
+ attr_reader :uri
10
+
11
+ # A valid ROMP uri must be specified.
12
+ def initialize(_fullname, _uri, _level=nil,
13
+ _additive=true, _trace=false, &accept)
14
+ super(_fullname, _level, _additive, _trace)
15
+ @uri = _uri
16
+ start_server(_uri, accept)
17
+ Logger.log_internal {"LogServer started at #{@uri}"}
18
+ end
19
+
20
+ if HAVE_ROMP
21
+ include ROMPServer
22
+ else
23
+ def initialize(*args)
24
+ raise RuntimeError, "LogServer not supported. ROMP is required", caller
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ # :nodoc:
2
+ require "log4r/outputter/iooutputter"
3
+
4
+ module Log4r
5
+ # Same as IOOutputter(name, $stdout)
6
+ class StdoutOutputter < IOOutputter
7
+ def initialize(_name, hash={})
8
+ super(_name, $stdout, hash)
9
+ end
10
+ end
11
+
12
+ # Same as IOOutputter(name, $stderr)
13
+ class StderrOutputter < IOOutputter
14
+ def initialize(_name, hash={})
15
+ super(_name, $stderr, hash)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,110 @@
1
+ # = DateFileOutputter
2
+ #
3
+ # Subclass of FileOutputter that changes the log file daily. When a new
4
+ # day begins, a new file is created with the date included in the name.
5
+ #
6
+ # == Usage
7
+ #
8
+ # df_out = DateFileOutputter.new('name',
9
+ # :dirname="/tmp", :date_pattern=>"%m-%d"
10
+ # )
11
+ #
12
+ # == Rate of Change
13
+ #
14
+ # A new logfile is created whenever the current time as formatted by the date
15
+ # pattern no longer matches the previous time. (This is a simple String
16
+ # comparison.) So, in order to change the frequency of the rollover, just
17
+ # alter the date pattern to match how fast the files should be generated.
18
+ # For instance, to generate files by the minute,
19
+ #
20
+ # df_out.date_pattern = "%M"
21
+ #
22
+ # This causes the following files to show up one minute apart, asuming the
23
+ # script starts at the 4th minute of the hour:
24
+ #
25
+ # file_04.rb
26
+ # file_05.rb
27
+ # file_06.rb
28
+ # ...
29
+ #
30
+ # The only limitation of this approach is that the precise time cannot be
31
+ # recorded as the smallest time interval equals the rollover period for this
32
+ # system.
33
+
34
+ require "log4r/outputter/fileoutputter"
35
+ require "log4r/staticlogger"
36
+
37
+ module Log4r
38
+
39
+ # Additional hash arguments are:
40
+ #
41
+ # [<tt>:dirname</tt>] Directory of the log file
42
+ # [<tt>:date_pattern</tt>] Time.strftime format string (default is "%Y-%m-%d")
43
+
44
+ class DateFileOutputter < FileOutputter
45
+ DEFAULT_DATE_FMT = "%Y-%m-%d"
46
+
47
+ def initialize(_name, hash={})
48
+ @DatePattern = (hash[:date_pattern] or hash['date_pattern'] or
49
+ DEFAULT_DATE_FMT)
50
+ @DateStamp = Time.now.strftime( @DatePattern);
51
+ _dirname = (hash[:dirname] or hash['dirname'])
52
+ # hash[:dirname] masks hash[:filename]
53
+ if _dirname
54
+ if not FileTest.directory?( _dirname)
55
+ raise StandardError, "'#{_dirname}' must be a valid directory", caller
56
+ end
57
+ @filebase = File.basename( $0, '.rb') + ".log"
58
+ else
59
+ @filebase = File.basename((hash[:filename] or hash['filename'] or ""))
60
+ end
61
+ hash['filename'] = File.join(_dirname,
62
+ @filebase.sub(/(\.\w*)$/, "_#{@DateStamp}" + '\1'))
63
+ super(_name, hash)
64
+ end
65
+
66
+ #######
67
+ private
68
+ #######
69
+
70
+ # perform the write
71
+ def write(data)
72
+ change if requiresChange
73
+ super
74
+ end
75
+
76
+ # construct a new filename from the DateStamp
77
+ def makeNewFilename
78
+ @DateStamp = Time.now.strftime( @DatePattern);
79
+ @filename = File.join(File.dirname(@filename),
80
+ @filebase.sub(/(\.\w*)$/, "_#{@DateStamp}" + '\1'))
81
+ end
82
+
83
+ # does the file require a change?
84
+ def requiresChange
85
+ _DateStamp = Time.now.strftime( @DatePattern);
86
+ if not _DateStamp == @DateStamp
87
+ @DateStamp = _DateStamp
88
+ return true
89
+ end
90
+ false
91
+ end
92
+
93
+ # change the file
94
+ def change
95
+ begin
96
+ @out.close
97
+ rescue
98
+ Logger.log_internal {
99
+ "DateFileOutputter '#{@name}' could not close #{@filename}"
100
+ }
101
+ end
102
+ makeNewFilename
103
+ @out = File.new(@filename, (@trunc ? "w" : "a"))
104
+ Logger.log_internal {
105
+ "DateFileOutputter '#{@name}' now writing to #{@filename}"
106
+ }
107
+ end
108
+ end
109
+
110
+ end
@@ -0,0 +1,115 @@
1
+ # :include: ../rdoc/emailoutputter
2
+
3
+ require 'log4r/outputter/outputter'
4
+ require 'log4r/staticlogger'
5
+ require 'net/smtp'
6
+
7
+ module Log4r
8
+
9
+ class EmailOutputter < Outputter
10
+ attr_reader :server, :port, :domain, :acct, :authtype, :subject
11
+
12
+ def initialize(_name, hash={})
13
+ super(_name, hash)
14
+ validate(hash)
15
+ @buff = []
16
+ begin
17
+ @smtp = Net::SMTP.start(*@params)
18
+ Logger.log_internal {
19
+ "EmailOutputter '#{@name}' running SMTP client on #{@server}:#{@port}"
20
+ }
21
+ rescue Exception => e
22
+ Logger.log_internal(-2) {
23
+ "EmailOutputter '#{@name}' failed to start SMTP client!"
24
+ }
25
+ Logger.log_internal {e}
26
+ self.level = OFF
27
+ end
28
+ end
29
+
30
+ # send out an email with the current buffer
31
+ def flush
32
+ synch { send_mail }
33
+ Logger.log_internal {"Flushed EmailOutputter '#{@name}'"}
34
+ end
35
+
36
+ private
37
+
38
+ def validate(hash)
39
+ @buffsize = (hash[:buffsize] or hash['buffsize'] or 100).to_i
40
+ @formatfirst = Log4rTools.decode_bool(hash, :formatfirst, false)
41
+ decode_immediate_at(hash)
42
+ validate_smtp_params(hash)
43
+ end
44
+
45
+ def decode_immediate_at(hash)
46
+ @immediate = Hash.new
47
+ _at = (hash[:immediate_at] or hash['immediate_at'])
48
+ return if _at.nil?
49
+ Log4rTools.comma_split(_at).each {|lname|
50
+ level = LNAMES.index(lname)
51
+ if level.nil?
52
+ Logger.log_internal(-2) do
53
+ "EmailOutputter: skipping bad immediate_at level name '#{lname}'"
54
+ end
55
+ next
56
+ end
57
+ @immediate[level] = true
58
+ }
59
+ end
60
+
61
+ def validate_smtp_params(hash)
62
+ @from = (hash[:from] or hash['from'])
63
+ raise ArgumentError, "Must specify from address" if @from.nil?
64
+ _to = (hash[:to] or hash['to'] or "")
65
+ @to = Log4rTools.comma_split(_to)
66
+ raise ArgumentError, "Must specify recepients" if @to.empty?
67
+ @server = (hash[:server] or hash['server'] or 'localhost')
68
+ @port = (hash[:port] or hash['port'] or 25).to_i
69
+ @domain = (hash[:domain] or hash['domain'] or ENV['HOSTNAME'])
70
+ @acct = (hash[:acct] or hash['acct'])
71
+ @passwd = (hash[:passwd] or hash['passwd'])
72
+ @authtype = (hash[:authtype] or hash['authtype'] or :cram_md5).to_s.intern
73
+ @subject = (hash[:subject] or hash['subject'] or "Message of #{$0}")
74
+ @params = [@server, @port, @domain, @acct, @passwd, @authtype]
75
+ end
76
+
77
+ def canonical_log(event)
78
+ synch {
79
+ @buff.push case @formatfirst
80
+ when true then @formatter.format event
81
+ else event
82
+ end
83
+ send_mail if @buff.size >= @buffsize or @immediate[event.level]
84
+ }
85
+ end
86
+
87
+ def send_mail
88
+ msg =
89
+ case @formatfirst
90
+ when true then @buff.join
91
+ else @buff.collect{|e| @formatter.format e}.join
92
+ end
93
+
94
+ ### build a mail header for RFC 822
95
+ rfc822msg =
96
+ "From: #{@from}\n" +
97
+ "To: #{@to}\n" +
98
+ "Subject: #{@subject}\n" +
99
+ "Date: #{Time.now.strftime( "%a, %d %b %Y %H:%M:%S %z %Z")}\n" +
100
+ "Message-Id: <#{"%.8f" % Time.now.to_f}@#{@domain}>\n\n" +
101
+ "#{msg}"
102
+
103
+ ### send email
104
+ begin @smtp.sendmail(rfc822msg, @from, @to)
105
+ rescue Exception => e
106
+ Logger.log_internal(-2) {
107
+ "EmailOutputter '#{@name}' couldn't send email!"
108
+ }
109
+ Logger.log_internal {e}
110
+ self.level = OFF
111
+ ensure @buff.clear
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,49 @@
1
+ # :nodoc:
2
+ # Version:: $Id: fileoutputter.rb,v 1.5 2003/09/12 23:55:43 fando Exp $
3
+
4
+ require "log4r/outputter/iooutputter"
5
+ require "log4r/staticlogger"
6
+
7
+ module Log4r
8
+
9
+ # Convenience wrapper for File. Additional hash arguments are:
10
+ #
11
+ # [<tt>:filename</tt>] Name of the file to log to.
12
+ # [<tt>:trunc</tt>] Truncate the file?
13
+ class FileOutputter < IOOutputter
14
+ attr_reader :trunc, :filename
15
+
16
+ def initialize(_name, hash={})
17
+ super(_name, nil, hash)
18
+
19
+ @trunc = Log4rTools.decode_bool(hash, :trunc, true)
20
+ _filename = (hash[:filename] or hash['filename'])
21
+
22
+ if _filename.class != String
23
+ raise TypeError, "Argument 'filename' must be a String", caller
24
+ end
25
+
26
+ # file validation
27
+ if FileTest.exist?( _filename )
28
+ if not FileTest.file?( _filename )
29
+ raise StandardError, "'#{_filename}' is not a regular file", caller
30
+ elsif not FileTest.writable?( _filename )
31
+ raise StandardError, "'#{_filename}' is not writable!", caller
32
+ end
33
+ else # ensure directory is writable
34
+ dir = File.dirname( _filename )
35
+ if not FileTest.writable?( dir )
36
+ raise StandardError, "'#{dir}' is not writable!"
37
+ end
38
+ end
39
+
40
+ @filename = _filename
41
+ @out = File.new(@filename, (@trunc ? "w" : "a"))
42
+ Logger.log_internal {
43
+ "FileOutputter '#{@name}' writing to #{@filename}"
44
+ }
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -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