mtn_log4r 1.1.11

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 (106) hide show
  1. checksums.yaml +15 -0
  2. data/doc/content/contact.html +22 -0
  3. data/doc/content/contribute.html +21 -0
  4. data/doc/content/index.html +90 -0
  5. data/doc/content/license.html +56 -0
  6. data/doc/content/manual.html +449 -0
  7. data/doc/dev/README.developers +55 -0
  8. data/doc/dev/checklist +23 -0
  9. data/doc/dev/things-to-do +5 -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/rdoc-log4r.css +696 -0
  14. data/doc/templates/main.html +147 -0
  15. data/examples/README +19 -0
  16. data/examples/ancestors.rb +53 -0
  17. data/examples/chainsaw_settings.xml +7 -0
  18. data/examples/customlevels.rb +34 -0
  19. data/examples/filelog.rb +25 -0
  20. data/examples/fileroll.rb +40 -0
  21. data/examples/gmail.rb +30 -0
  22. data/examples/gmail.yaml +95 -0
  23. data/examples/log4r_yaml.yaml +0 -0
  24. data/examples/logclient.rb +25 -0
  25. data/examples/logserver.rb +18 -0
  26. data/examples/moderate.xml +29 -0
  27. data/examples/moderateconfig.rb +66 -0
  28. data/examples/myformatter.rb +23 -0
  29. data/examples/outofthebox.rb +21 -0
  30. data/examples/rdoc-gen +2 -0
  31. data/examples/rrconfig.xml +63 -0
  32. data/examples/rrsetup.rb +42 -0
  33. data/examples/simpleconfig.rb +39 -0
  34. data/examples/syslogcustom.rb +52 -0
  35. data/examples/xmlconfig.rb +25 -0
  36. data/examples/yaml.rb +30 -0
  37. data/lib/log4r/GDC.rb +41 -0
  38. data/lib/log4r/MDC.rb +59 -0
  39. data/lib/log4r/NDC.rb +86 -0
  40. data/lib/log4r/base.rb +74 -0
  41. data/lib/log4r/config.rb +9 -0
  42. data/lib/log4r/configurator.rb +224 -0
  43. data/lib/log4r/formatter/formatter.rb +109 -0
  44. data/lib/log4r/formatter/log4jxmlformatter.rb +65 -0
  45. data/lib/log4r/formatter/patternformatter.rb +145 -0
  46. data/lib/log4r/lib/drbloader.rb +52 -0
  47. data/lib/log4r/lib/xmlloader.rb +24 -0
  48. data/lib/log4r/logevent.rb +28 -0
  49. data/lib/log4r/logger.rb +199 -0
  50. data/lib/log4r/loggerfactory.rb +89 -0
  51. data/lib/log4r/logserver.rb +28 -0
  52. data/lib/log4r/outputter/consoleoutputters.rb +18 -0
  53. data/lib/log4r/outputter/datefileoutputter.rb +117 -0
  54. data/lib/log4r/outputter/emailoutputter.rb +143 -0
  55. data/lib/log4r/outputter/fileoutputter.rb +56 -0
  56. data/lib/log4r/outputter/iooutputter.rb +55 -0
  57. data/lib/log4r/outputter/outputter.rb +134 -0
  58. data/lib/log4r/outputter/outputterfactory.rb +61 -0
  59. data/lib/log4r/outputter/rabbitoutputter.rb +70 -0
  60. data/lib/log4r/outputter/remoteoutputter.rb +40 -0
  61. data/lib/log4r/outputter/rollingfileoutputter.rb +234 -0
  62. data/lib/log4r/outputter/scribeoutputter.rb +37 -0
  63. data/lib/log4r/outputter/staticoutputter.rb +30 -0
  64. data/lib/log4r/outputter/syslogoutputter.rb +130 -0
  65. data/lib/log4r/outputter/udpoutputter.rb +53 -0
  66. data/lib/log4r/rdoc/GDC +14 -0
  67. data/lib/log4r/rdoc/MDC +16 -0
  68. data/lib/log4r/rdoc/NDC +41 -0
  69. data/lib/log4r/rdoc/configurator +243 -0
  70. data/lib/log4r/rdoc/emailoutputter +103 -0
  71. data/lib/log4r/rdoc/formatter +39 -0
  72. data/lib/log4r/rdoc/log4jxmlformatter +21 -0
  73. data/lib/log4r/rdoc/log4r +89 -0
  74. data/lib/log4r/rdoc/logger +175 -0
  75. data/lib/log4r/rdoc/logserver +85 -0
  76. data/lib/log4r/rdoc/outputter +108 -0
  77. data/lib/log4r/rdoc/patternformatter +128 -0
  78. data/lib/log4r/rdoc/scribeoutputter +16 -0
  79. data/lib/log4r/rdoc/syslogoutputter +29 -0
  80. data/lib/log4r/rdoc/win32eventoutputter +7 -0
  81. data/lib/log4r/rdoc/yamlconfigurator +20 -0
  82. data/lib/log4r/repository.rb +88 -0
  83. data/lib/log4r/staticlogger.rb +49 -0
  84. data/lib/log4r/version.rb +4 -0
  85. data/lib/log4r/yamlconfigurator.rb +198 -0
  86. data/lib/log4r.rb +18 -0
  87. data/tests/README +10 -0
  88. data/tests/testGDC.rb +24 -0
  89. data/tests/testMDC.rb +40 -0
  90. data/tests/testNDC.rb +25 -0
  91. data/tests/test_helper.rb +12 -0
  92. data/tests/testall.rb +6 -0
  93. data/tests/testbase.rb +48 -0
  94. data/tests/testchainsaw.rb +42 -0
  95. data/tests/testconf.xml +37 -0
  96. data/tests/testcustom.rb +30 -0
  97. data/tests/testformatter.rb +31 -0
  98. data/tests/testlogger.rb +200 -0
  99. data/tests/testoutputter.rb +143 -0
  100. data/tests/testpatternformatter.rb +76 -0
  101. data/tests/testthreads.rb +31 -0
  102. data/tests/testxmlconf.rb +48 -0
  103. data/tests/testyaml.rb +39 -0
  104. data/tests/testyaml_arrays.yaml +25 -0
  105. data/tests/testyaml_injection.yaml +22 -0
  106. metadata +193 -0
@@ -0,0 +1,224 @@
1
+ # :include: rdoc/configurator
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version:: $Id$
6
+
7
+ require "log4r/logger"
8
+ require "log4r/outputter/staticoutputter"
9
+ require "log4r/lib/xmlloader"
10
+ require "log4r/logserver"
11
+ require "log4r/outputter/remoteoutputter"
12
+
13
+ # TODO: catch unparsed parameters #{FOO} and die
14
+ module Log4r
15
+ # Gets raised when Configurator encounters bad XML.
16
+ class ConfigError < Exception
17
+ end
18
+
19
+ # See log4r/configurator.rb
20
+ class Configurator
21
+ include REXML if HAVE_REXML
22
+ @@params = Hash.new
23
+
24
+ # Get a parameter's value
25
+ def self.[](param); @@params[param] end
26
+ # Define a parameter with a value
27
+ def self.[]=(param, value); @@params[param] = value end
28
+
29
+ # Sets the custom levels. This method accepts symbols or strings.
30
+ #
31
+ # Configurator.custom_levels('My', 'Custom', :Levels)
32
+ #
33
+ # Alternatively, you can specify custom levels in XML:
34
+ #
35
+ # <log4r_config>
36
+ # <pre_config>
37
+ # <custom_levels>
38
+ # My, Custom, Levels
39
+ # </custom_levels>
40
+ # ...
41
+
42
+ def self.custom_levels(*levels)
43
+ return Logger.root if levels.size == 0
44
+ for i in 0...levels.size
45
+ name = levels[i].to_s
46
+ if name =~ /\s/ or name !~ /^[A-Z]/
47
+ raise TypeError, "#{name} is not a valid Ruby Constant name", caller
48
+ end
49
+ end
50
+ Log4r.define_levels *levels
51
+ end
52
+
53
+ # Given a filename, loads the XML configuration for Log4r.
54
+ def self.load_xml_file(filename)
55
+ detect_rexml
56
+ actual_load Document.new(File.new(filename))
57
+ end
58
+
59
+ # You can load a String XML configuration instead of a file.
60
+ def self.load_xml_string(string)
61
+ detect_rexml
62
+ actual_load Document.new(string)
63
+ end
64
+
65
+ #######
66
+ private
67
+ #######
68
+
69
+ def self.detect_rexml
70
+ unless HAVE_REXML
71
+ raise LoadError,
72
+ "Need REXML to load XML configuration", caller[1..-1]
73
+ end
74
+ end
75
+
76
+ def self.actual_load(doc)
77
+ confignode = doc.elements['//log4r_config']
78
+ if confignode.nil?
79
+ raise ConfigError,
80
+ "<log4r_config> element not defined", caller[1..-1]
81
+ end
82
+ decode_xml(confignode)
83
+ end
84
+
85
+ def self.decode_xml(doc)
86
+ decode_pre_config(doc.elements['pre_config'])
87
+ doc.elements.each('outputter') {|e| decode_outputter(e)}
88
+ doc.elements.each('logger') {|e| decode_logger(e)}
89
+ doc.elements.each('logserver') {|e| decode_logserver(e)}
90
+ end
91
+
92
+ def self.decode_pre_config(e)
93
+ return Logger.root if e.nil?
94
+ decode_custom_levels(e.elements['custom_levels'])
95
+ global_config(e.elements['global'])
96
+ global_config(e.elements['root'])
97
+ decode_parameters(e.elements['parameters'])
98
+ e.elements.each('parameter') {|p| decode_parameter(p)}
99
+ end
100
+
101
+ def self.decode_custom_levels(e)
102
+ return Logger.root if e.nil? or e.text.nil?
103
+ begin custom_levels *Log4rTools.comma_split(e.text)
104
+ rescue TypeError => te
105
+ raise ConfigError, te.message, caller[1..-4]
106
+ end
107
+ end
108
+
109
+ def self.global_config(e)
110
+ return if e.nil?
111
+ globlev = e.value_of 'level'
112
+ return if globlev.nil?
113
+ lev = LNAMES.index(globlev) # find value in LNAMES
114
+ Log4rTools.validate_level(lev, 4) # choke on bad level
115
+ Logger.global.level = lev
116
+ end
117
+
118
+ def self.decode_parameters(e)
119
+ e.elements.each{|p| @@params[p.name] = p.text} unless e.nil?
120
+ end
121
+
122
+ def self.decode_parameter(e)
123
+ @@params[e.value_of('name')] = e.value_of 'value'
124
+ end
125
+
126
+ def self.decode_outputter(e)
127
+ # fields
128
+ name = e.value_of 'name'
129
+ type = e.value_of 'type'
130
+ level = e.value_of 'level'
131
+ only_at = e.value_of 'only_at'
132
+ # validation
133
+ raise ConfigError, "Outputter missing name", caller[1..-3] if name.nil?
134
+ raise ConfigError, "Outputter missing type", caller[1..-3] if type.nil?
135
+ Log4rTools.validate_level(LNAMES.index(level)) unless level.nil?
136
+ only_levels = []
137
+ unless only_at.nil?
138
+ for lev in Log4rTools.comma_split(only_at)
139
+ alev = LNAMES.index(lev)
140
+ Log4rTools.validate_level(alev, 3)
141
+ only_levels.push alev
142
+ end
143
+ end
144
+ formatter = decode_formatter(e.elements['formatter'])
145
+ # build the eval string
146
+ buff = "Outputter[name] = #{type}.new name"
147
+ buff += ",:level=>#{LNAMES.index(level)}" unless level.nil?
148
+ buff += ",:formatter=>formatter" unless formatter.nil?
149
+ params = decode_hash_params(e)
150
+ buff += "," + params.join(',') if params.size > 0
151
+ begin eval buff
152
+ rescue Exception => ae
153
+ raise ConfigError,
154
+ "Problem creating outputter: #{ae.message}", caller[1..-3]
155
+ end
156
+ Outputter[name].only_at *only_levels if only_levels.size > 0
157
+ Outputter[name]
158
+ end
159
+
160
+ def self.decode_formatter(e)
161
+ return nil if e.nil?
162
+ type = e.value_of 'type'
163
+ raise ConfigError, "Formatter missing type", caller[1..-4] if type.nil?
164
+ buff = "#{type}.new " + decode_hash_params(e).join(',')
165
+ begin return eval(buff)
166
+ rescue Exception => ae
167
+ raise ConfigError,
168
+ "Problem creating outputter: #{ae.message}", caller[1..-4]
169
+ end
170
+ end
171
+
172
+ ExcludeParams = %w{formatter level name type}
173
+
174
+ # Does the fancy parameter to hash argument transformation
175
+ def self.decode_hash_params(e)
176
+ buff = []
177
+ e.attributes.each_attribute {|p|
178
+ next if ExcludeParams.include? p.name
179
+ buff << ":" + p.name + "=>" + paramsub(p.value)
180
+ }
181
+ e.elements.each {|p|
182
+ next if ExcludeParams.include? p.name
183
+ buff << ":" + p.name + "=>" + paramsub(p.text)
184
+ }
185
+ buff
186
+ end
187
+
188
+ # Substitues any #{foo} in the XML with Parameter['foo']
189
+ def self.paramsub(str)
190
+ return nil if str.nil?
191
+ @@params.each {|param, value| str.sub! '#{'+param+'}', value}
192
+ "'" + str + "'"
193
+ end
194
+
195
+ def self.decode_logger(e)
196
+ l = Logger.new e.value_of('name')
197
+ decode_logger_common(l, e)
198
+ end
199
+
200
+ def self.decode_logserver(e)
201
+ return unless HAVE_REXML
202
+ name = e.value_of 'name'
203
+ uri = e.value_of 'uri'
204
+ l = LogServer.new name, uri
205
+ decode_logger_common(l, e)
206
+ end
207
+
208
+ def self.decode_logger_common(l, e)
209
+ level = e.value_of 'level'
210
+ additive = e.value_of 'additive'
211
+ trace = e.value_of 'trace'
212
+ l.level = LNAMES.index(level) unless level.nil?
213
+ l.additive = additive unless additive.nil?
214
+ l.trace = trace unless trace.nil?
215
+ # and now for outputters
216
+ outs = e.value_of 'outputters'
217
+ Log4rTools.comma_split(outs).each {|n| l.add n.strip} unless outs.nil?
218
+ e.elements.each('outputter') {|e|
219
+ name = (e.value_of 'name' or e.text)
220
+ l.add Outputter[name]
221
+ }
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,109 @@
1
+ # :include: ../rdoc/formatter
2
+ #
3
+ # Version:: $Id$
4
+
5
+ require "singleton"
6
+ require 'json'
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
+ klass = obj.class
72
+ case
73
+ when klass == Exception
74
+ return "Caught #{obj.class}: #{obj.message}\n\t" +\
75
+ (obj.backtrace.nil? ? [] : obj.backtrace[0...@depth]).join("\n\t").gsub('"','\\\\"')
76
+ when klass == Hash
77
+ return obj.to_json.gsub('"','\\\\"')
78
+ when klass == String
79
+ return obj.gsub('"','\\\\"')
80
+ else # inspect the object
81
+ return "#{obj.class}: #{obj.inspect}".gsub('"','\\\\"')
82
+ end
83
+ end
84
+ end
85
+
86
+ # Formats objects the same way irb does:
87
+ #
88
+ # loggername:foo.rb in 12>
89
+ # [1, 3, 4]
90
+ # loggername:foo.rb in 13>
91
+ # {1=>"1"}
92
+ #
93
+ # Strings don't get inspected. just printed. The trace is optional.
94
+
95
+ class ObjectFormatter < Formatter
96
+ def format(event)
97
+ buff = event.logger.name
98
+ buff << (event.tracer.nil? ? "" : ":#{event.tracer[0]}") + ">\n"
99
+ buff << (event.data.kind_of?(String) ? event.data : event.data.inspect)
100
+ buff << "\n"
101
+ end
102
+ end
103
+
104
+ # Outputters that don't define a Formatter will get this, which
105
+ # is currently BasicFormatter
106
+ class DefaultFormatter < BasicFormatter
107
+ end
108
+
109
+ end
@@ -0,0 +1,65 @@
1
+ # :include: ../rdoc/log4jxmlformatter
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version:: $Id$
6
+
7
+ require "log4r/formatter/formatter"
8
+
9
+ require "rubygems"
10
+ begin
11
+ require "builder"
12
+ rescue LoadError
13
+ puts "builder gem is required to use log4jxmlformatter, i.e. gem install builder"
14
+ end
15
+
16
+ module Log4r
17
+
18
+ class Log4jXmlFormatter < BasicFormatter
19
+
20
+ def format(logevent)
21
+ logger = logevent.fullname.gsub('::', '.')
22
+ timestamp = (Time.now.to_f * 1000).to_i
23
+ level = LNAMES[logevent.level]
24
+ message = format_object(logevent.data)
25
+ exception = message if logevent.data.kind_of? Exception
26
+ file, line, method = parse_caller(logevent.tracer[0]) if logevent.tracer
27
+
28
+ builder = Builder::XmlMarkup.new
29
+ xml = builder.log4j :event, :logger => logger,
30
+ :timestamp => timestamp,
31
+ :level => level,
32
+ :thread => '' do |e|
33
+ e.log4j :NDC, NDC.get
34
+ e.log4j :message, message
35
+ e.log4j :throwable, exception if exception
36
+ e.log4j :locationInfo, :class => '',
37
+ :method => method,
38
+ :file => file,
39
+ :line => line
40
+ e.log4j :properties do |p|
41
+ MDC.get_context.each do |key, value|
42
+ p.log4j :data, :name => key, :value => value
43
+ end
44
+ end
45
+ end
46
+ xml
47
+ end
48
+
49
+ #######
50
+ private
51
+ #######
52
+
53
+ def parse_caller(line)
54
+ if /^(.+?):(\d+)(?::in `(.*)')?/ =~ line
55
+ file = Regexp.last_match[1]
56
+ line = Regexp.last_match[2].to_i
57
+ method = Regexp.last_match[3]
58
+ [file, line, method]
59
+ else
60
+ []
61
+ end
62
+ end
63
+ end
64
+
65
+ end
@@ -0,0 +1,145 @@
1
+ # :include: ../rdoc/patternformatter
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version:: $Id$
6
+
7
+ require "log4r/formatter/formatter"
8
+ require "log4r/GDC"
9
+ require "log4r/MDC"
10
+ require "log4r/NDC"
11
+
12
+ module Log4r
13
+ # See log4r/formatter/patternformatter.rb
14
+ class PatternFormatter < BasicFormatter
15
+
16
+ # Arguments to sprintf keyed to directive letters<br>
17
+ # %c - event short name<br>
18
+ # %C - event fullname<br>
19
+ # %d - date<br>
20
+ # %g - Global Diagnostic Context (GDC)<br>
21
+ # %t - trace<br>
22
+ # %m - message<br>
23
+ # %h - thread name<br>
24
+ # %p - process ID aka PID<br>
25
+ # %M - formatted message<br>
26
+ # %l - Level in string form<br>
27
+ # %x - Nested Diagnostic Context (NDC)<br>
28
+ # %X - Mapped Diagnostic Context (MDC), syntax is "%X{key}"<br>
29
+ # %% - Insert a %<br>
30
+ DirectiveTable = {
31
+ "c" => 'event.name',
32
+ "C" => 'event.fullname',
33
+ "d" => 'format_date',
34
+ "g" => 'Log4r::GDC.get()',
35
+ "t" => '(event.tracer.nil? ? "no trace" : event.tracer[0])',
36
+ "T" => '(event.tracer.nil? ? "no trace" : event.tracer[0].split(File::SEPARATOR)[-1])',
37
+ "m" => 'event.data',
38
+ "h" => '(Thread.current[:name] or Thread.current.to_s)',
39
+ "p" => 'Process.pid.to_s',
40
+ "M" => 'format_object(event.data)',
41
+ "l" => 'LNAMES[event.level]',
42
+ "x" => 'Log4r::NDC.get()',
43
+ "X" => 'Log4r::MDC.get("DTR_REPLACE")',
44
+ "%" => '"%"'
45
+ }
46
+
47
+ # Matches the first directive encountered and the stuff around it.
48
+ #
49
+ # * $1 is the stuff before directive or "" if not applicable
50
+ # * $2 is the directive group or nil if there's none
51
+ # * $3 is the %#.# match within directive group
52
+ # * $4 is the .# match which we don't use (it's there to match properly)
53
+ # * $5 is the directive letter
54
+ # * $6 is the stuff after the directive or "" if not applicable
55
+ # * $7 is the remainder
56
+
57
+ DirectiveRegexp = /([^%]*)((%-?\d*(\.\d+)?)([cCdgtTmhpMlxX%]))?(\{.+?\})?(.*)/
58
+
59
+ # default date format
60
+ ISO8601 = "%Y-%m-%d %H:%M:%S"
61
+
62
+ attr_reader :pattern, :date_pattern, :date_method
63
+
64
+ # Accepts the following hash arguments (either a string or a symbol):
65
+ #
66
+ # [<tt>pattern</tt>] A pattern format string.
67
+ # [<tt>date_pattern</tt>] A Time#strftime format string. See the
68
+ # Ruby Time class for details.
69
+ # [+date_method+]
70
+ # As an option to date_pattern, specify which
71
+ # Time.now method to call. For
72
+ # example, +usec+ or +to_s+.
73
+ # Specify it as a String or Symbol.
74
+ #
75
+ # The default date format is ISO8601, which looks like this:
76
+ #
77
+ # yyyy-mm-dd hh:mm:ss => 2001-01-12 13:15:50
78
+
79
+ def initialize(hash={})
80
+ super(hash)
81
+ @pattern = (hash['pattern'] or hash[:pattern] or nil)
82
+ @date_pattern = (hash['date_pattern'] or hash[:date_pattern] or nil)
83
+ @date_method = (hash['date_method'] or hash[:date_method] or nil)
84
+ @date_pattern = ISO8601 if @date_pattern.nil? and @date_method.nil?
85
+ PatternFormatter.create_format_methods(self)
86
+ end
87
+
88
+ # PatternFormatter works by dynamically defining a <tt>format</tt> method
89
+ # based on the supplied pattern format. This method contains a call to
90
+ # Kernel#sptrintf with arguments containing the data requested in
91
+ # the pattern format.
92
+ #
93
+ # How is this magic accomplished? First, we visit each directive
94
+ # and change the %#.# component to %#.#s. The directive letter is then
95
+ # used to cull an appropriate entry from the DirectiveTable for the
96
+ # sprintf argument list. After assembling the method definition, we
97
+ # run module_eval on it, and voila.
98
+
99
+ def PatternFormatter.create_format_methods(pf) #:nodoc:
100
+ # first, define the format_date method
101
+ if pf.date_method
102
+ module_eval "def pf.format_date; Time.now.#{pf.date_method}; end"
103
+ else
104
+ module_eval <<-EOS
105
+ def pf.format_date
106
+ Time.now.strftime "#{pf.date_pattern}"
107
+ end
108
+ EOS
109
+ end
110
+ # and now the main format method
111
+ ebuff = "def pf.format(event)\n sprintf(\""
112
+ _pattern = pf.pattern.dup
113
+ args = [] # the args to sprintf which we'll append to ebuff lastly
114
+ while true # work on each match in turn
115
+ match = DirectiveRegexp.match _pattern
116
+ ebuff << match[1] unless match[1].empty?
117
+ break if match[2].nil?
118
+ # deal with the directive by inserting a %#.#s where %#.# is copied
119
+ # directy from the match
120
+ ebuff << match[3] + "s"
121
+
122
+ if ( match[5] == 'X' && match[6] != nil ) then
123
+
124
+ # MDC matches, need to be able to handle String, Symbol or Number
125
+ match6sub = /[\{\}\"]/
126
+ mdcmatches = match[6].match /\{(:?)(\d*)(.*)\}/
127
+
128
+ if ( mdcmatches[1] == "" && mdcmatches[2] == "" )
129
+ match6sub = /[\{\}]/ # don't remove surrounding "'s if String
130
+ end
131
+
132
+ args <<
133
+ DirectiveTable[match[5]].gsub("DTR_REPLACE", match[6]).gsub(match6sub,'')
134
+ else
135
+ args << DirectiveTable[match[5]] # cull the data for our argument list
136
+ end
137
+ break if match[7].empty?
138
+ _pattern = match[7]
139
+ end
140
+ ebuff << '\n", ' + args.join(', ') + ")\n"
141
+ ebuff << "end\n"
142
+ module_eval ebuff
143
+ end
144
+ end
145
+ 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