sml-log4r 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
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,105 @@
1
+ # :include: ../rdoc/formatter
2
+ #
3
+ # Version:: $Id: formatter.rb,v 1.7 2003/09/01 22:33:20 cepheus Exp $
4
+
5
+ require "singleton"
6
+
7
+ require "log4r/base"
8
+
9
+ module Log4r
10
+
11
+ # Formatter is an abstract class and a null object
12
+ class Formatter
13
+ def initialize(hash={})
14
+ end
15
+ # Define this method in a subclass to format data.
16
+ def format(logevent)
17
+ end
18
+ end
19
+
20
+ # SimpleFormatter produces output like this:
21
+ #
22
+ # WARN loggername> Danger, Will Robinson, danger!
23
+ #
24
+ # Does not write traces and does not inspect objects.
25
+
26
+ class SimpleFormatter < Formatter
27
+ def format(event)
28
+ sprintf("%*s %s> %s\n", MaxLevelLength, LNAMES[event.level],
29
+ event.name, event.data)
30
+ end
31
+ end
32
+
33
+ # BasicFormatter produces output like this:
34
+ #
35
+ # WARN loggername: I dropped my Wookie!
36
+ #
37
+ # Or like this if trace is on:
38
+ #
39
+ # WARN loggername(file.rb at 12): Hot potato!
40
+ #
41
+ # Also, it will pretty-print any Exception it gets and
42
+ # +inspect+ everything else.
43
+ #
44
+ # Hash arguments include:
45
+ #
46
+ # +depth+:: How many lines of the stacktrace to display.
47
+
48
+ class BasicFormatter < SimpleFormatter
49
+ @@basicformat = "%*s %s"
50
+
51
+ def initialize(hash={})
52
+ @depth = (hash[:depth] or hash['depth'] or 7).to_i
53
+ end
54
+
55
+ def format(event)
56
+ buff = sprintf(@@basicformat, MaxLevelLength, LNAMES[event.level],
57
+ event.name)
58
+ buff += (event.tracer.nil? ? "" : "(#{event.tracer[0]})") + ": "
59
+ buff += format_object(event.data) + "\n"
60
+ buff
61
+ end
62
+
63
+ # Formats data according to its class:
64
+ #
65
+ # String:: Prints it out as normal.
66
+ # Exception:: Produces output similar to command-line exceptions.
67
+ # Object:: Prints the type of object, then the output of
68
+ # +inspect+. An example -- Array: [1, 2, 3]
69
+
70
+ def format_object(obj)
71
+ if obj.kind_of? Exception
72
+ return "Caught #{obj.class}: #{obj.message}\n\t" +\
73
+ obj.backtrace[0...@depth].join("\n\t")
74
+ elsif obj.kind_of? String
75
+ return obj
76
+ else # inspect the object
77
+ return "#{obj.class}: #{obj.inspect}"
78
+ end
79
+ end
80
+ end
81
+
82
+ # Formats objects the same way irb does:
83
+ #
84
+ # loggername:foo.rb in 12>
85
+ # [1, 3, 4]
86
+ # loggername:foo.rb in 13>
87
+ # {1=>"1"}
88
+ #
89
+ # Strings don't get inspected. just printed. The trace is optional.
90
+
91
+ class ObjectFormatter < Formatter
92
+ def format(event)
93
+ buff = event.logger.name
94
+ buff += (event.tracer.nil? ? "" : ":#{event.tracer[0]}") + ">\n"
95
+ buff += (event.data.kind_of?(String) ? event.data : event.data.inspect)
96
+ buff += "\n"
97
+ end
98
+ end
99
+
100
+ # Outputters that don't define a Formatter will get this, which
101
+ # is currently BasicFormatter
102
+ class DefaultFormatter < BasicFormatter
103
+ end
104
+
105
+ end
@@ -0,0 +1,108 @@
1
+ # :include: ../rdoc/patternformatter
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version:: $Id: patternformatter.rb,v 1.2 2002/01/28 16:05:05 cepheus Exp $
6
+ # Author:: Leon Torres <leon@ugcs.caltech.edu>
7
+
8
+ require "log4r/formatter/formatter"
9
+
10
+ module Log4r
11
+ # See log4r/formatter/patternformatter.rb
12
+ class PatternFormatter < BasicFormatter
13
+
14
+ # Arguments to sprintf keyed to directive letters
15
+ DirectiveTable = {
16
+ "c" => 'event.name',
17
+ "C" => 'event.fullname',
18
+ "d" => 'format_date',
19
+ "t" => 'event.tracer[0]',
20
+ "m" => 'event.data',
21
+ "M" => 'format_object(event.data)',
22
+ "l" => 'LNAMES[event.level]',
23
+ "%" => '"%"'
24
+ }
25
+
26
+ # Matches the first directive encountered and the stuff around it.
27
+ #
28
+ # * $1 is the stuff before directive or "" if not applicable
29
+ # * $2 is the directive group or nil if there's none
30
+ # * $3 is the %#.# match within directive group
31
+ # * $4 is the .# match which we don't use (it's there to match properly)
32
+ # * $5 is the directive letter
33
+ # * $6 is the stuff after the directive or "" if not applicable
34
+
35
+ DirectiveRegexp = /([^%]*)((%-?\d*(\.\d+)?)([cCdtmMl%]))?(.*)/
36
+
37
+ # default date format
38
+ ISO8601 = "%Y-%m-%d %H:%M:%S"
39
+
40
+ attr_reader :pattern, :date_pattern, :date_method
41
+
42
+ # Accepts the following hash arguments (either a string or a symbol):
43
+ #
44
+ # [<tt>pattern</tt>] A pattern format string.
45
+ # [<tt>date_pattern</tt>] A Time#strftime format string. See the
46
+ # Ruby Time class for details.
47
+ # [+date_method+]
48
+ # As an option to date_pattern, specify which
49
+ # Time.now method to call. For
50
+ # example, +usec+ or +to_s+.
51
+ # Specify it as a String or Symbol.
52
+ #
53
+ # The default date format is ISO8601, which looks like this:
54
+ #
55
+ # yyyy-mm-dd hh:mm:ss => 2001-01-12 13:15:50
56
+
57
+ def initialize(hash={})
58
+ super(hash)
59
+ @pattern = (hash['pattern'] or hash[:pattern] or nil)
60
+ @date_pattern = (hash['date_pattern'] or hash[:date_pattern] or nil)
61
+ @date_method = (hash['date_method'] or hash[:date_method] or nil)
62
+ @date_pattern = ISO8601 if @date_pattern.nil? and @date_method.nil?
63
+ PatternFormatter.create_format_methods(self)
64
+ end
65
+
66
+ # PatternFormatter works by dynamically defining a <tt>format</tt> method
67
+ # based on the supplied pattern format. This method contains a call to
68
+ # Kernel#sptrintf with arguments containing the data requested in
69
+ # the pattern format.
70
+ #
71
+ # How is this magic accomplished? First, we visit each directive
72
+ # and change the %#.# component to %#.#s. The directive letter is then
73
+ # used to cull an appropriate entry from the DirectiveTable for the
74
+ # sprintf argument list. After assembling the method definition, we
75
+ # run module_eval on it, and voila.
76
+
77
+ def PatternFormatter.create_format_methods(pf) #:nodoc:
78
+ # first, define the format_date method
79
+ if pf.date_method
80
+ module_eval "def pf.format_date; Time.now.#{pf.date_method}; end"
81
+ else
82
+ module_eval <<-EOS
83
+ def pf.format_date
84
+ Time.now.strftime "#{pf.date_pattern}"
85
+ end
86
+ EOS
87
+ end
88
+ # and now the main format method
89
+ ebuff = "def pf.format(event)\n sprintf(\""
90
+ _pattern = pf.pattern.dup
91
+ args = [] # the args to sprintf which we'll append to ebuff lastly
92
+ while true # work on each match in turn
93
+ match = DirectiveRegexp.match _pattern
94
+ ebuff += match[1] unless match[1].empty?
95
+ break if match[2].nil?
96
+ # deal with the directive by inserting a %#.#s where %#.# is copied
97
+ # directy from the match
98
+ ebuff += match[3] + "s"
99
+ args << DirectiveTable[match[5]] # cull the data for our argument list
100
+ break if match[6].empty?
101
+ _pattern = match[6]
102
+ end
103
+ ebuff += '\n", ' + args.join(', ') + ")\n"
104
+ ebuff += "end\n"
105
+ module_eval ebuff
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,52 @@
1
+ #:nodoc:
2
+ module Log4r
3
+ begin
4
+ require 'romp'
5
+ HAVE_ROMP = true
6
+ rescue LoadError
7
+ HAVE_ROMP = false
8
+ end
9
+
10
+ if HAVE_ROMP
11
+
12
+ module ROMPServer #:nodoc:
13
+ private
14
+ def start_server(_uri, accept)
15
+ @server = ROMP::Server.new(_uri, accept) # what if accept is nil?
16
+ @server.bind(self, "Log4r::LogServer")
17
+ end
18
+ end
19
+
20
+ module ROMPClient #:nodoc:
21
+ private
22
+ def connect
23
+ begin
24
+ @client = ROMP::Client.new(@uri, false)
25
+ @remote_logger = @client.resolve("Log4r::LogServer")
26
+ rescue Exception => e
27
+ Logger.log_internal(-2) {
28
+ "RemoteOutputter '#{@name}' failed to connect to #{@uri}!"
29
+ }
30
+ Logger.log_internal {e}
31
+ self.level = OFF
32
+ end
33
+ end
34
+ # we use propagated = true
35
+ def send_buffer
36
+ begin
37
+ @buff.each {|levent|
38
+ lname = LNAMES[levent.level].downcase
39
+ @remote_logger.oneway(lname, levent, true)
40
+ }
41
+ rescue Exception => e
42
+ Logger.log_internal(-2) {"RemoteOutputter '#{@name}' can't log!"}
43
+ Logger.log_internal {e}
44
+ self.level = OFF
45
+ ensure @buff.clear
46
+ end
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,24 @@
1
+ #:nodoc:
2
+ module Log4r
3
+ begin
4
+ require 'rexml/document'
5
+ HAVE_REXML = true
6
+ rescue LoadError
7
+ HAVE_REXML = false
8
+ end
9
+ end
10
+
11
+ if Log4r::HAVE_REXML
12
+ module REXML #:nodoc: all
13
+ class Element
14
+ def value_of(elmt)
15
+ val = attributes[elmt]
16
+ if val.nil?
17
+ sub = elements[elmt]
18
+ val = sub.text unless sub.nil?
19
+ end
20
+ val
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ # :nodoc:
2
+ module Log4r
3
+
4
+ ##
5
+ # LogEvent wraps up all the miscellaneous data associated with a logging
6
+ # statement. It gets passed around to the varied components of Log4r and
7
+ # should be of interest to those creating extensions.
8
+ #
9
+ # Data contained:
10
+ #
11
+ # [level] The integer level of the log event. Use LNAMES[level]
12
+ # to get the actual level name.
13
+ # [tracer] The execution stack returned by <tt>caller</tt> at the
14
+ # log event. It is nil if the invoked Logger's trace is false.
15
+ # [data] The object that was passed into the logging method.
16
+ # [name] The name of the logger that was invoked.
17
+ # [fullname] The fully qualified name of the logger that was invoked.
18
+ #
19
+ # Note that creating timestamps is a task left to formatters.
20
+
21
+ class LogEvent
22
+ attr_reader :level, :tracer, :data, :name, :fullname
23
+ def initialize(level, logger, tracer, data)
24
+ @level, @tracer, @data = level, tracer, data
25
+ @name, @fullname = logger.name, logger.fullname
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,194 @@
1
+ # :include: rdoc/logger
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version:: $Id: logger.rb,v 1.24 2004/03/17 19:13:07 fando Exp $
6
+ # Author:: Leon Torres <leon(at)ugcs.caltech.edu>
7
+
8
+ require "log4r/outputter/outputter"
9
+ require "log4r/repository"
10
+ require "log4r/loggerfactory"
11
+ require "log4r/staticlogger"
12
+
13
+ module Log4r
14
+
15
+ # See log4r/logger.rb
16
+ class Logger
17
+ attr_reader :name, :fullname, :path, :level, :parent
18
+ attr_reader :additive, :trace, :outputters
19
+
20
+ # Logger requires a name. The last 3 parameters are:
21
+ #
22
+ # level:: Do I have a level? (Otherwise, I'll inherit my parent's)
23
+ # additive:: Am I additive?
24
+ # trace:: Do I record the execution trace? (slows things a wee bit)
25
+
26
+ def initialize(_fullname, _level=nil, _additive=true, _trace=false)
27
+ # validation
28
+ raise ArgumentError, "Logger must have a name", caller if _fullname.nil?
29
+ Log4rTools.validate_level(_level) unless _level.nil?
30
+ validate_name(_fullname)
31
+
32
+ # create the logger
33
+ @fullname = _fullname
34
+ @outputters = []
35
+ @additive = _additive
36
+ deal_with_inheritance(_level)
37
+ LoggerFactory.define_methods(self)
38
+ self.trace = _trace
39
+ Repository[@fullname] = self
40
+ end
41
+
42
+ def validate_name(_fullname)
43
+ parts = _fullname.split Log4rConfig::LoggerPathDelimiter
44
+ for part in parts
45
+ raise ArgumentError, "Malformed path", caller[1..-1] if part.empty?
46
+ end
47
+ end
48
+ private :validate_name
49
+
50
+ # Parses name for location in heiarchy, sets the parent, and
51
+ # deals with level inheritance
52
+
53
+ def deal_with_inheritance(_level)
54
+ mypath = @fullname.split Log4rConfig::LoggerPathDelimiter
55
+ @name = mypath.pop
56
+ if mypath.empty? # then root is my daddy
57
+ @path = ""
58
+ # This is one of the guarantees that RootLogger gets created
59
+ @parent = Logger.root
60
+ else
61
+ @path = mypath.join(Log4rConfig::LoggerPathDelimiter)
62
+ @parent = Repository.find_ancestor(@path)
63
+ @parent = Logger.root if @parent.nil?
64
+ end
65
+ # inherit the level if no level defined
66
+ if _level.nil? then @level = @parent.level
67
+ else @level = _level end
68
+ Repository.reassign_any_children(self)
69
+ end
70
+ private :deal_with_inheritance
71
+
72
+ # Set the logger level dynamically. Does not affect children.
73
+ def level=(_level)
74
+ Log4rTools.validate_level(_level)
75
+ @level = _level
76
+ LoggerFactory.define_methods(self)
77
+ Logger.log_internal {"Logger '#{@fullname}' set to #{LNAMES[@level]}"}
78
+ @level
79
+ end
80
+
81
+ # Set the additivity of the logger dynamically. True or false.
82
+ def additive=(_additive)
83
+ @additive = _additive
84
+ LoggerFactory.define_methods(self)
85
+ Logger.log_internal {"Logger '#{@fullname}' is additive"}
86
+ @additive
87
+ end
88
+
89
+ # Set whether the logger traces. Can be set dynamically. Defaults
90
+ # to false and understands the strings 'true' and 'false'.
91
+ def trace=(_trace)
92
+ @trace =
93
+ case _trace
94
+ when "true", true then true
95
+ else false end
96
+ LoggerFactory.define_methods(self)
97
+ Logger.log_internal {"Logger '#{@fullname}' is tracing"} if @trace
98
+ @trace
99
+ end
100
+
101
+ # Please don't reset the parent
102
+ def parent=(parent)
103
+ @parent = parent
104
+ end
105
+
106
+ # Set the Outputters dynamically by name or reference. Can be done any
107
+ # time.
108
+ def outputters=(_outputters)
109
+ @outputters.clear
110
+ add(*_outputters)
111
+ end
112
+
113
+ # Add outputters by name or by reference. Can be done any time.
114
+ def add(*_outputters)
115
+ for thing in _outputters
116
+ o = (thing.kind_of?(Outputter) ? thing : Outputter[thing])
117
+ # some basic validation
118
+ if not o.kind_of?(Outputter)
119
+ raise TypeError, "Expected kind of Outputter, got #{o.class}", caller
120
+ elsif o.nil?
121
+ raise TypeError, "Couldn't find Outputter '#{thing}'", caller
122
+ end
123
+ @outputters.push o
124
+ Logger.log_internal {"Added outputter '#{o.name}' to '#{@fullname}'"}
125
+ end
126
+ @outputters
127
+ end
128
+
129
+ # Remove outputters from this logger by name only. Can be done any time.
130
+ def remove(*_outputters)
131
+ for name in _outputters
132
+ o = Outputter[name]
133
+ @outputters.delete o
134
+ Logger.log_internal {"Removed outputter '#{o.name}' from '#{@fullname}'"}
135
+ end
136
+ end
137
+
138
+ def is_root?; false end
139
+
140
+ def ==(other)
141
+ return true if object_id == other.object_id
142
+ end
143
+ end
144
+
145
+
146
+ # RootLogger should be retrieved with Logger.root or Logger.global.
147
+ # It's supposed to be transparent.
148
+ #--
149
+ # We must guarantee the creation of RootLogger before any other Logger
150
+ # or Outputter gets their logging methods defined. There are two
151
+ # guarantees in the code:
152
+ #
153
+ # * Logger#deal_with_inheritance - calls RootLogger.instance when
154
+ # a new Logger is created without a parent. Parents must exist, therefore
155
+ # RootLogger is forced to be created.
156
+ #
157
+ # * OutputterFactory.create_methods - Calls Logger.root first. So if
158
+ # an Outputter is created, RootLogger is also created.
159
+ #
160
+ # When RootLogger is created, it calls
161
+ # Log4r.define_levels(*Log4rConfig::LogLevels). This ensures that the
162
+ # default levels are loaded if no custom ones are.
163
+
164
+ class RootLogger < Logger
165
+ include Singleton
166
+
167
+ def initialize
168
+ Log4r.define_levels(*Log4rConfig::LogLevels) # ensure levels are loaded
169
+ @level = ALL
170
+ @outputters = []
171
+ Repository['root'] = self
172
+ Repository['global'] = self
173
+ LoggerFactory.undefine_methods(self)
174
+ end
175
+
176
+ def is_root?; true end
177
+
178
+ # Set the global level. Any loggers defined thereafter will
179
+ # not log below the global level regardless of their levels.
180
+
181
+ def level=(alevel); @level = alevel end
182
+
183
+ # Does nothing
184
+ def outputters=(foo); end
185
+ # Does nothing
186
+ def trace=(foo); end
187
+ # Does nothing
188
+ def additive=(foo); end
189
+ # Does nothing
190
+ def add(*foo); end
191
+ # Does nothing
192
+ def remove(*foo); end
193
+ end
194
+ end