log4rails 1.1.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.bsd +12 -0
  3. data/README.md +37 -0
  4. data/lib/log4r/GDC.rb +41 -0
  5. data/lib/log4r/MDC.rb +59 -0
  6. data/lib/log4r/NDC.rb +86 -0
  7. data/lib/log4r/base.rb +74 -0
  8. data/lib/log4r/config.rb +9 -0
  9. data/lib/log4r/configurator.rb +224 -0
  10. data/lib/log4r/formatter/formatter.rb +105 -0
  11. data/lib/log4r/formatter/log4jxmlformatter.rb +65 -0
  12. data/lib/log4r/formatter/patternformatter.rb +145 -0
  13. data/lib/log4r/lib/drbloader.rb +52 -0
  14. data/lib/log4r/lib/xmlloader.rb +24 -0
  15. data/lib/log4r/log4r-rails.yaml +60 -0
  16. data/lib/log4r/logevent.rb +28 -0
  17. data/lib/log4r/logger.rb +206 -0
  18. data/lib/log4r/loggerfactory.rb +89 -0
  19. data/lib/log4r/logserver.rb +28 -0
  20. data/lib/log4r/outputter/bufferedsyslogoutputter.rb +47 -0
  21. data/lib/log4r/outputter/consoleoutputters.rb +18 -0
  22. data/lib/log4r/outputter/datefileoutputter.rb +117 -0
  23. data/lib/log4r/outputter/emailoutputter.rb +143 -0
  24. data/lib/log4r/outputter/fileoutputter.rb +57 -0
  25. data/lib/log4r/outputter/iooutputter.rb +55 -0
  26. data/lib/log4r/outputter/outputter.rb +134 -0
  27. data/lib/log4r/outputter/outputterfactory.rb +60 -0
  28. data/lib/log4r/outputter/remoteoutputter.rb +40 -0
  29. data/lib/log4r/outputter/rollingfileoutputter.rb +234 -0
  30. data/lib/log4r/outputter/scribeoutputter.rb +37 -0
  31. data/lib/log4r/outputter/staticoutputter.rb +30 -0
  32. data/lib/log4r/outputter/syslogoutputter.rb +126 -0
  33. data/lib/log4r/outputter/udpoutputter.rb +53 -0
  34. data/lib/log4r/railtie.rb +211 -0
  35. data/lib/log4r/rdoc/GDC +14 -0
  36. data/lib/log4r/rdoc/MDC +16 -0
  37. data/lib/log4r/rdoc/NDC +41 -0
  38. data/lib/log4r/rdoc/configurator +243 -0
  39. data/lib/log4r/rdoc/emailoutputter +103 -0
  40. data/lib/log4r/rdoc/formatter +39 -0
  41. data/lib/log4r/rdoc/log4jxmlformatter +21 -0
  42. data/lib/log4r/rdoc/log4r +89 -0
  43. data/lib/log4r/rdoc/logger +175 -0
  44. data/lib/log4r/rdoc/logserver +85 -0
  45. data/lib/log4r/rdoc/outputter +108 -0
  46. data/lib/log4r/rdoc/patternformatter +128 -0
  47. data/lib/log4r/rdoc/scribeoutputter +16 -0
  48. data/lib/log4r/rdoc/syslogoutputter +29 -0
  49. data/lib/log4r/rdoc/win32eventoutputter +7 -0
  50. data/lib/log4r/rdoc/yamlconfigurator +20 -0
  51. data/lib/log4r/repository.rb +88 -0
  52. data/lib/log4r/staticlogger.rb +49 -0
  53. data/lib/log4r/version.rb +4 -0
  54. data/lib/log4r/yamlconfigurator.rb +198 -0
  55. data/lib/log4rails.rb +22 -0
  56. metadata +97 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7fed18812138b6e4049cdde81a06f54d2c0e17f4
4
+ data.tar.gz: f83b7d97ecd7d1a0a97b990454b1062544b9abf8
5
+ SHA512:
6
+ metadata.gz: 84e32f8e38727c3eb481f3e34aa844c2fcda0bc20c1a1251803d54a9e78e34ab6558440a156516be3464e54c427d03114407c93c4d4fdaf516d1427fb9aca8ac
7
+ data.tar.gz: aa9d042d2dd722afe2c4c6d27184656b4235d420a7143e9293a5bb2a0819d018b507b45fcfb3804ac8af61cb4bfa1382d0340d75124f0a511b70b359c633b222
@@ -0,0 +1,12 @@
1
+ Copyright (c) 2014, Colby Gutierrez-Kraybill, bestmike007.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+
6
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
+
8
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9
+
10
+ 3. Neither the name of ShrewdRaven Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,37 @@
1
+ Log4r - A flexible logging library for Ruby
2
+ Log4rails - A better log4r especially for rails
3
+
4
+ ```
5
+ gem install log4rails
6
+ ```
7
+
8
+ DO NOT USE THIS TOGETHER WITH `log4r`!
9
+
10
+ ``` ruby
11
+ config.log4rails.<option> = <value>
12
+ # enable log4rails integration
13
+ config.log4rails.enabled = true
14
+ # maximum action handling time to log with level INFO, default: 500ms.
15
+ config.log4rails.action_mht = 500
16
+ # auto-reload log4r configuration file from config/log4r.yaml (or config/log4r-production.yaml in production environment)
17
+ config.log4rails.auto_reload = true
18
+ ```
19
+
20
+ ## Why this fork
21
+
22
+ Log4r seems not to be actively maintained. And also I need these features:
23
+
24
+ + Integrate with the latest rails
25
+ + Reload the configuration file in production mode in order to switch ON/OFF logs
26
+ + Better RollingFileOutputter, etc.
27
+
28
+ ## TODO
29
+
30
+ + Better integrate with rails
31
+ + Write more tests
32
+ + Document is important, especially since rubyforge is dead
33
+ + Refactor
34
+ + Fix issues for general usage
35
+ + Improve extensibility
36
+
37
+ You're welcome to contribute!
@@ -0,0 +1,41 @@
1
+ # :include: rdoc/GDC
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version:: $Id$
6
+ # Author:: Colby Gutierrez-Kraybill <colby(at)astro.berkeley.edu>
7
+
8
+ require 'monitor'
9
+
10
+ module Log4r
11
+ GDCNAME = "log4rGDC"
12
+ $globalGDCLock = Monitor.new
13
+
14
+ # See log4r/GDC.rb
15
+ class GDC < Monitor
16
+ private_class_method :new
17
+
18
+ def self.clear()
19
+ Thread.main[GDCNAME] = ""
20
+ end
21
+
22
+ def self.get()
23
+ $globalGDCLock.synchronize do
24
+ if ( Thread.main[GDCNAME] == nil ) then
25
+ Thread.main[GDCNAME] = $0
26
+ end
27
+ end
28
+ return Thread.main[GDCNAME]
29
+ end
30
+
31
+ def self.set( a_name )
32
+ if ( Thread.current != Thread.main ) then
33
+ raise "Can only initialize Global Diagnostic Context from Thread.main"
34
+ end
35
+ $globalGDCLock.synchronize do
36
+ Thread.main[GDCNAME] = a_name
37
+ end
38
+ end
39
+ end
40
+ end
41
+
@@ -0,0 +1,59 @@
1
+ # :include: rdoc/MDC
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version:: $Id$
6
+ # Author:: Colby Gutierrez-Kraybill <colby(at)astro.berkeley.edu>
7
+
8
+ require 'monitor'
9
+
10
+ module Log4r
11
+ MDCNAME = "log4rMDC"
12
+ MDCNAMEMAXDEPTH = "log4rMDCMAXDEPTH"
13
+ $globalMDCLock = Monitor.new
14
+
15
+ # See log4r/MDC.rb
16
+ class MDC < Monitor
17
+ private_class_method :new
18
+
19
+ def self.check_thread_instance()
20
+ # need to interlock here, so that if
21
+ # another thread is entering this section
22
+ # of code before the main thread does,
23
+ # then the main thread copy of the MDC
24
+ # is setup before then attempting to clone
25
+ # it off
26
+ if ( Thread.current[MDCNAME] == nil ) then
27
+ $globalMDCLock.synchronize do
28
+ if ( Thread.main[MDCNAME] == nil ) then
29
+ Thread.main[MDCNAME] = Hash.new
30
+ end
31
+ if ( Thread.current != Thread.main ) then
32
+ Thread.current[MDCNAME] = Hash.new
33
+ Thread.main[MDCNAME].each{ |k,v| Thread.current[MDCNAME][k] = v }
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def self.get( a_key )
40
+ self.check_thread_instance()
41
+ Thread.current[MDCNAME].fetch(a_key, "");
42
+ end
43
+
44
+ def self.get_context()
45
+ self.check_thread_instance()
46
+ return Thread.current[MDCNAME].clone
47
+ end
48
+
49
+ def self.put( a_key, a_value )
50
+ self.check_thread_instance()
51
+ Thread.current[MDCNAME][a_key] = a_value
52
+ end
53
+
54
+ def self.remove( a_key )
55
+ self.check_thread_instance()
56
+ Thread.current[MDCNAME].delete( a_key )
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,86 @@
1
+ # :include: rdoc/NDC
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version:: $Id$
6
+ # Author:: Colby Gutierrez-Kraybill <colby(at)astro.berkeley.edu>
7
+
8
+ module Log4r
9
+ NDCNAME = "log4rNDC"
10
+ NDCNAMEMAXDEPTH = "log4rNDCMAXDEPTH"
11
+ NDCDEFAULTMAXDEPTH = 256
12
+
13
+ # See log4r/NDC.rb
14
+ class NDC
15
+ private_class_method :new
16
+
17
+ def self.check_thread_instance()
18
+ if ( Thread.current[NDCNAME] == nil ) then
19
+ Thread.current[NDCNAME] = Array.new
20
+ Thread.current[NDCNAMEMAXDEPTH] = NDCDEFAULTMAXDEPTH
21
+ end
22
+ end
23
+
24
+ def self.clear()
25
+ self.check_thread_instance()
26
+ Thread.current[NDCNAME].clear
27
+ end
28
+
29
+ def self.clone_stack()
30
+ self.check_thread_instance()
31
+ return Thread.current[NDCNAME].clone
32
+ end
33
+
34
+ def self.get_depth()
35
+ self.check_thread_instance()
36
+ return Thread.current[NDCNAME].length
37
+ end
38
+
39
+ def self.inherit( a_stack )
40
+ if ( a_stack.class == Array ) then
41
+ if ( Thread.current[NDCNAME] != nil ) then
42
+ Thread.current[NDCNAME].clear
43
+ Thread.current[NDCNAME] = nil
44
+ end
45
+ Thread.current[NDCNAME] = a_stack
46
+ else
47
+ raise "Expecting Array in NDC.inherit"
48
+ end
49
+ end
50
+
51
+ def self.get()
52
+ self.check_thread_instance
53
+ return Thread.current[NDCNAME] * " "
54
+ end
55
+
56
+ def self.peek()
57
+ self.check_thread_instance()
58
+ return Thread.current[NDCNAME].last
59
+ end
60
+
61
+ def self.pop()
62
+ self.check_thread_instance()
63
+ return Thread.current[NDCNAME].pop
64
+ end
65
+
66
+ def self.push( value )
67
+ self.check_thread_instance()
68
+ if ( Thread.current[NDCNAME].length < Thread.current[NDCNAMEMAXDEPTH] ) then
69
+ Thread.current[NDCNAME].push( value )
70
+ end
71
+ end
72
+
73
+ def self.remove()
74
+ self.check_thread_instance()
75
+ Thread.current[NDCNAME].clear
76
+ Thread.current[NDCNAMEMAXDEPTH] = nil
77
+ Thread.current[NDCNAME] = nil
78
+ end
79
+
80
+ def self.set_max_depth( max_depth )
81
+ self.check_thread_instance()
82
+ Thread.current[NDCNAMEMAXDEPTH] = max_depth
83
+ end
84
+ end
85
+ end
86
+
@@ -0,0 +1,74 @@
1
+ # :nodoc:
2
+ require "log4r/config"
3
+
4
+ module Log4r
5
+ ALL = 0
6
+ LNAMES = ['ALL']
7
+
8
+ # Defines the log levels of the Log4r module at runtime. It is given
9
+ # either the default level spec (when root logger is created) or the
10
+ # user-specified level spec (when Logger.custom_levels is called).
11
+ #
12
+ # The last constant defined by this method is OFF. Other level-sensitive
13
+ # parts of the code check to see if OFF is defined before deciding what
14
+ # to do. The typical action would be to force the creation of RootLogger
15
+ # so that the custom levels get loaded and business can proceed as usual.
16
+ #
17
+ # For purposes of formatting, a constant named MaxLevelLength is defined
18
+ # in this method. It stores the max level name string size.
19
+
20
+ def Log4r.define_levels(*levels) #:nodoc:
21
+ return if const_defined? :OFF
22
+ for i in 0...levels.size
23
+ name = levels[i].to_s
24
+ module_eval "#{name} = #{i} + 1; LNAMES.push '#{name}'"
25
+ end
26
+ module_eval %{
27
+ LNAMES.push 'OFF'
28
+ LEVELS = LNAMES.size
29
+ OFF = LEVELS - 1
30
+ MaxLevelLength = Log4rTools.max_level_str_size
31
+ }
32
+ end
33
+
34
+ # Some common functions
35
+ class Log4rTools
36
+ # Raises ArgumentError if level argument is an invalid level. Depth
37
+ # specifies how many trace entries to remove.
38
+ def self.validate_level(level, depth=0)
39
+ unless valid_level?(level)
40
+ raise ArgumentError, "Log level must be in 0..#{LEVELS}",
41
+ caller[1..-(depth + 1)]
42
+ end
43
+ end
44
+
45
+ def self.valid_level?(lev)
46
+ not lev.nil? and lev.kind_of?(Numeric) and lev >= ALL and lev <= OFF
47
+ end
48
+
49
+ def self.max_level_str_size #:nodoc:
50
+ size = 0
51
+ LNAMES.each {|i| size = i.length if i.length > size}
52
+ size
53
+ end
54
+
55
+ # Shortcut for decoding 'true', 'false', true, false or nil into a bool
56
+ # from a hash parameter. E.g., it looks for true/false values for
57
+ # the keys 'symbol' and :symbol.
58
+
59
+ def self.decode_bool(hash, symbol, default)
60
+ data = hash[symbol]
61
+ data = hash[symbol.to_s] if data.nil?
62
+ return case data
63
+ when 'true',true then true
64
+ when 'false',false then false
65
+ else default
66
+ end
67
+ end
68
+
69
+ # Splits comma-delimited lists with arbitrary \s padding
70
+ def self.comma_split(string)
71
+ string.split(/\s*,\s*/).collect {|s| s.strip}
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,9 @@
1
+ # :nodoc:
2
+ # Version:: $Id$
3
+
4
+ module Log4r
5
+ module Log4rConfig #:nodoc:
6
+ LogLevels = ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']
7
+ LoggerPathDelimiter = '::'
8
+ end
9
+ end
@@ -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