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,53 @@
1
+ # :include: ../rdoc/outputter
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version:: $Id$
6
+ # Author:: Leon Torres <leon@ugcs.caltech.edu>
7
+
8
+ require "log4r/outputter/outputter"
9
+ require 'log4r/staticlogger'
10
+ require "socket"
11
+
12
+ module Log4r
13
+
14
+ class UDPOutputter < Outputter
15
+ attr_reader :host, :port
16
+ attr_accessor :udpsock
17
+
18
+ def initialize(_name, hash={})
19
+ super(_name, hash)
20
+ @host = (hash[:hostname] or hash["hostname"])
21
+ @port = (hash[:port] or hash["port"])
22
+
23
+ begin
24
+ Logger.log_internal {
25
+ "UDPOutputter will send to #{@host}:#{@port}"
26
+ }
27
+ @udpsock = UDPSocket.new
28
+ @udpsock.connect( @host, @port )
29
+ rescue Exception => e
30
+ Logger.log_internal(ERROR) {
31
+ "UDPOutputter failed to create UDP socket: #{e}"
32
+ }
33
+ Logger.log_internal {e}
34
+ self.level = OFF
35
+ raise e
36
+ end
37
+ end
38
+
39
+ #######
40
+ private
41
+ #######
42
+
43
+ def write(data)
44
+ @udpsock.send(data, 0)
45
+ rescue Exception => e
46
+ Logger.log_internal(ERROR) {
47
+ "UDPOutputter failed to send data to #{@host}:#{@port}, #{e}"
48
+ }
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,211 @@
1
+ # :nodoc:
2
+ # Version:: $Id$
3
+ # Author:: Mike Ho <i(at)bestmike007.com>
4
+ # How to configure log4r for rails in application.rb:
5
+ # config.log4rails.<option> = <value>
6
+ # config.log4rails.enabled = true # enable log4r integration
7
+ # config.log4rails.action_mht = 500 # maximum action handling time to log with level INFO, default: 500ms.
8
+ # config.log4rails.auto_reload = true # auto-reload log4r configuration file from config/log4r.yaml (or config/log4r-production.yaml in production environment)
9
+
10
+ require 'rails'
11
+ require 'log4r/yamlconfigurator'
12
+
13
+ module Log4r
14
+
15
+ class Railtie < Rails::Railtie
16
+
17
+ config.log4rails = ActiveSupport::OrderedOptions.new
18
+ # default values
19
+ config.log4rails.enabled = false
20
+ config.log4rails.action_mht = 500
21
+ config.log4rails.auto_reload = true
22
+
23
+ initializer "log4rails.pre_init", :before => :initialize_logger do |app|
24
+ if app.config.log4rails.enabled
25
+ Log4r::Railtie.load_config
26
+ Log4r::Railtie.pre_init(app, {:root => Rails.root.to_s, :env => Rails.env}.merge(app.config.log4rails))
27
+ end
28
+ end
29
+
30
+ initializer "log4rails.post_init", :after => :initialize_logger do |app|
31
+ if app.config.log4rails.enabled
32
+ Log4r::Railtie.post_init
33
+ end
34
+ end
35
+
36
+ initializer "log4rails.cache_logger", :after => :initialize_cache do |app|
37
+ if app.config.log4rails.enabled
38
+ class << Rails.cache
39
+ def logger
40
+ Log4r::Logger['rails::cache'] || Log4r::Logger.root
41
+ end
42
+ def logger=(l)
43
+ (l || logger).debug "Log4r is preventing set of logger for cache."
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ class << self
50
+
51
+ # remove rails default log subscriptions
52
+ # [ActiveRecord::LogSubscriber, ActionController::LogSubscriber, ActionView::LogSubscriber, ActionMailer::LogSubscriber]
53
+ unsubscribe = lambda { |component, subscriber|
54
+ events = subscriber.public_methods(false).reject { |method| method.to_s == 'call' }
55
+ events.each do |event|
56
+ ActiveSupport::Notifications.notifier.listeners_for("#{event}.#{component}").each do |listener|
57
+ if listener.instance_variable_get('@delegate') == subscriber
58
+ ActiveSupport::Notifications.unsubscribe listener
59
+ end
60
+ end
61
+ end
62
+ }
63
+ remove_existing_log_subscriptions = lambda {
64
+ ActiveSupport::LogSubscriber.log_subscribers.each do |subscriber|
65
+ case subscriber
66
+ when ActionView::LogSubscriber
67
+ unsubscribe.call(:action_view, subscriber)
68
+ when ActionController::LogSubscriber
69
+ unsubscribe.call(:action_controller, subscriber)
70
+ when ActiveRecord::LogSubscriber
71
+ unsubscribe.call(:active_record, subscriber)
72
+ when ActionMailer::LogSubscriber
73
+ unsubscribe.call(:action_mailler, subscriber)
74
+ end
75
+ end
76
+ }
77
+
78
+ config_time = Time.new 0
79
+ config_next_check = Time.now
80
+ config_path = nil
81
+ options = nil
82
+
83
+ define_method(:options) { options }
84
+
85
+ # load or reload config from RAILS_ROOT/config/log4r.yaml or RAILS_ROOT/config/log4r-production.yaml
86
+ define_method :load_config do
87
+ # auto reload config every 30 seconds.
88
+ return if Time.now < config_next_check
89
+ config_next_check = Time.now + 30
90
+ return if !config_path.nil? && (!File.file?(config_path) || File.mtime(config_path) == config_time)
91
+ config_path = File.join Rails.root, "config", "log4r.yaml"
92
+ begin
93
+ if Rails.env == 'production'
94
+ production_config = File.join Rails.root, "config", "log4r-production.yaml"
95
+ config_path = production_config if File.file?(production_config)
96
+ end
97
+ if File.file? config_path
98
+ YamlConfigurator.load_yaml_file config_path
99
+ config_path = config_path
100
+ config_time = File.mtime(config_path)
101
+ return
102
+ end
103
+ puts "Log4r Warning: Unable to find log4r config file for rails, using default config."
104
+ rescue Log4r::ConfigError => e
105
+ puts "Log4r Error: Unable to load config #{config_path}, error: #{e}. Using default config."
106
+ end
107
+ config_path = File.join File.dirname(__FILE__), 'log4r-rails.yaml'
108
+ YamlConfigurator.load_yaml_file config_path
109
+ end
110
+
111
+ define_method :pre_init do |app, opts|
112
+ options = opts
113
+ # silence default rails logger
114
+ app.config.log_level = :unknown
115
+ # define global logger
116
+ setup_logger Object, "root"
117
+ # define rails controller logger names
118
+ setup_logger ActionController::Base, "rails::controllers"
119
+ setup_logger ActiveRecord::Base, "rails::models"
120
+ setup_logger ActionMailer::Base, "rails::mailers"
121
+
122
+ remove_existing_log_subscriptions.call
123
+
124
+ ActiveSupport::Notifications.subscribe "process_action.action_controller" do |name, start, finish, id, payload|
125
+ Log4r::Railtie.load_config if Log4r::Railtie.options[:auto_reload]
126
+ Log4r::Railtie.controller_log({ duration: ((finish - start).to_f * 100000).round / 100.0 }.merge(payload))
127
+ end
128
+
129
+ ActiveSupport::Notifications.subscribe "sql.active_record" do |name, start, finish, id, payload|
130
+ Log4r::Railtie.load_config if Log4r::Railtie.options[:auto_reload]
131
+ logger = Log4r::Logger["rails::db"] || Log4r::Logger.root
132
+ logger.debug { "(#{((finish - start).to_f * 100000).round / 100.0 }) #{payload[:sql]}" }
133
+ end
134
+ end
135
+
136
+ def post_init
137
+ setup_logger Rails, "rails"
138
+ # disable rack development output, e.g. Started GET "/session/new" for 127.0.0.1 at 2012-09-26 14:51:42 -0700
139
+ if Rails.const_defined?(:Rack) && Rails::Rack.const_defined?(:Logger)
140
+ setup_logger Rails::Rack::Logger, "root"
141
+ end
142
+ # override DebugExceptions output
143
+ ActionDispatch::DebugExceptions.module_eval %-
144
+ def log_error(env, wrapper)
145
+ logger = Rails.logger
146
+ exception = wrapper.exception
147
+ # trace = wrapper.application_trace
148
+ # trace = wrapper.framework_trace if trace.empty?
149
+ logger.info "ActionDispatch Exception: \#{exception.class} (\#{exception.message})"
150
+ end
151
+ private :log_error
152
+ -
153
+ end
154
+
155
+ def controller_log(payload)
156
+ logger = Rails.logger
157
+ params_logger = Log4r::Logger["rails::params"] || Log4r::Logger.root
158
+
159
+ duration = payload[:duration]
160
+ unless payload[:exception].nil?
161
+ logger.warn {
162
+ db = (payload[:db_runtime] * 100).round/100.0 rescue "-"
163
+ view = (payload[:view_runtime] * 100).round/100.0 rescue "-"
164
+ "#{payload[:method]} #{payload[:path]} (TIMING[ms]: sum:#{duration} db:#{db} view:#{view}) EXCEPTION: #{payload[:exception]}"
165
+ }
166
+ params_logger.info { "request params: " + payload[:params].to_json }
167
+ return
168
+ end
169
+ if duration >= Log4r::Railtie.options[:action_mht]
170
+ logger.warn {
171
+ db = (payload[:db_runtime] * 100).round/100.0 rescue "-"
172
+ view = (payload[:view_runtime] * 100).round/100.0 rescue "-"
173
+ "#{payload[:method]} #{payload[:path]} (TIMING[ms]: sum:#{duration} db:#{db} view:#{view})"
174
+ }
175
+ else
176
+ logger.info {
177
+ db = (payload[:db_runtime] * 100).round/100.0 rescue "-"
178
+ view = (payload[:view_runtime] * 100).round/100.0 rescue "-"
179
+ "#{payload[:method]} #{payload[:path]} (TIMING[ms]: sum:#{duration} db:#{db} view:#{view})"
180
+ }
181
+ end
182
+ params_logger.info { "request params: " + payload[:params].to_json }
183
+ end
184
+
185
+ # convenient static method to setup logger for class and descendants.
186
+ def setup_logger(clazz, logger_name)
187
+ clazz.module_eval %(
188
+ class << self
189
+ custom_logger = nil
190
+ define_method :logger do
191
+ custom_logger || Log4r::Logger['#{logger_name}'] || Log4r::Logger.root
192
+ end
193
+ define_method :logger= do |l|
194
+ (l || custom_logger).debug "Log4rails is preventing set of logger. Use #custom_logger= if you really want it set."
195
+ end
196
+ define_method :custom_logger= do |l|
197
+ custom_logger = l
198
+ end
199
+ end
200
+
201
+ def logger
202
+ #{clazz.name}.logger
203
+ end
204
+ )
205
+ end
206
+
207
+ end
208
+
209
+ end # class Railtie
210
+
211
+ end # module Log4r
@@ -0,0 +1,14 @@
1
+ = GDC
2
+
3
+ The GDC class implements a copy of the Global Diagnostic Context, which
4
+ is not part of the Apache Log4j library, as of this writing (10 Jan 2009).
5
+
6
+ The GDC is like the NDC and MDC classes, only it is global to the
7
+ application (see NDC and MDC for details on those classes).
8
+
9
+ The GDC is local to the main thread, and any new threads will return
10
+ the value of the current GDC set in the main thread.
11
+
12
+ Only the main thread can set the GDC, any other threads that
13
+ attempt to will raise an exception.
14
+
@@ -0,0 +1,16 @@
1
+ = MDC
2
+
3
+ The MDC class implements a copy of the Mapped Diagnostic Context, which
4
+ is part of the Apache Log4j library. See the NDC documentation for
5
+ more details. MDCs are much like NDCs, but instead of a stack context
6
+ it uses a map for holding this information.
7
+
8
+ This allows for selection of information out of the map when
9
+ the log message is being created.
10
+
11
+ MDCs are thread safe, and are unique to each thread.
12
+
13
+ An important difference between MDCs in Log4r vs Log4j is that they
14
+ only inherit from the main thread. Ruby treats all new threads as
15
+ being the children of the main thread, even if they are started
16
+ from a thread that is not main.
@@ -0,0 +1,41 @@
1
+ = NDC
2
+
3
+ The NDC class implements a copy of the Nested Diagnostic Context, which
4
+ is part of the Apache Log4j library. Nested Diagnostic Contexts were
5
+ derived from Neil Harrison's article on "Patterns for Logging
6
+ Diagnostic Messages", part of the book "Pattern Languages of Program
7
+ Design 3" edited by Martin et al.
8
+
9
+ NDCs in Log4r are thread safe.
10
+
11
+ NDCs in log4r are close enough to NDCs in Log4j that I include its
12
+ documentation directly:
13
+
14
+ ...
15
+ A Nested Diagnostic Context, or NDC in short, is an instrument to
16
+ distinguish interleaved log output from different sources. Log output
17
+ is typically interleaved when a server handles multiple clients
18
+ near-simultaneously.
19
+
20
+ Interleaved log output can still be meaningful if each log entry from
21
+ different contexts had a distinctive stamp. This is where NDCs come into
22
+ play.
23
+
24
+ Note that NDCs are managed on a per thread basis. NDC operations such as
25
+ push, pop(), clear(), getDepth() and setMaxDepth(int) affect the NDC of
26
+ the current thread only. NDCs of other threads remain unaffected.
27
+ ...
28
+
29
+ An important difference between NDCs in Log4r vs Log4j is that you
30
+ do not have to called NDC.remove() when exiting a thread.
31
+
32
+ This class will automatically create Thread specific storage for the
33
+ current thread on the first call to any of its methods, i.e.
34
+
35
+ NDC.push( "client accept" );
36
+
37
+ New threads may inherit the NDC of the parent thread by making use of
38
+ the clone_stack() and inherit() methods. By default, the NDC is not
39
+ inherited automatically. This is unlike MDCs, which will inherit from
40
+ the main thread.
41
+
@@ -0,0 +1,243 @@
1
+ = Configuring Log4r with Log4r::Configurator
2
+
3
+ The Configurator class allows one to set up Log4r via XML.
4
+ Additionally, Configurator contains methods to configure any Log4r
5
+ defaults. In particular, Configurator provides a method to
6
+ customize the logging levels.
7
+
8
+ Log4r is also configurable using YAML. For that, there is
9
+ a class similar to Configurator called Log4r::YamlConfigurator. Please see
10
+ log4r/yamlconfigurator.rb for details.
11
+
12
+ REXML is required for XML configuration. Get REXML at
13
+ http://www.ruby-lang.org/en/raa-list.rhtml?name=REXML
14
+
15
+ To use the Configurator class,
16
+
17
+ require 'log4r/configurator'
18
+
19
+ == Custom Levels
20
+
21
+ Suppose you want the following levels and ranks:
22
+
23
+ Foo < Bar < Baz
24
+
25
+ This is easily accomplished:
26
+
27
+ Configurator.custom_levels('Foo', 'Bar', :Baz)
28
+
29
+ The method accepts strings or symbols. However, custom levels must have names
30
+ that are valid for Ruby constants. Also, custom levels should be set before
31
+ anything else is done with Log4r, otherwise the default levels will be loaded.
32
+
33
+ You can set custom levels in XML. That's covered in the following section.
34
+
35
+ == XML Configuration
36
+
37
+ If you have REXML, you can configure Log4r with XML.
38
+ To do this, first write an XML configuration (which you can learn by
39
+ studying this document and the examples provided in the distribution)
40
+ and then load up the XML from within your program as follows:
41
+
42
+ Configurator.load_xml_file('/path/to/file.xml')
43
+
44
+ The Log4r XML configuration system is very flexible and powerful. In fact,
45
+ it is somewhat preferable to configuring Log4r in Ruby. In order to take
46
+ full advantage of this feature, there are several concepts one must know.
47
+ They are covered in the following three sections.
48
+
49
+ === Concept: XML Directives
50
+
51
+ The expressive power of Ruby has enabled a feature I call
52
+ <i>XML directives</i>. An XML directive is a name-value pair belonging to
53
+ some element. It
54
+ may be represented as an attribute (name="value") of the element, or
55
+ as a child (<name>value</name>) of the element. Therefore, you are
56
+ free to specify information about an object as either an attribute
57
+ or an element. An example should clarify:
58
+
59
+ <object data="value"/>
60
+
61
+ Is equivalent to:
62
+
63
+ <object>
64
+ <data>value</data>
65
+ </object>
66
+
67
+ You can assume this behavior except where noted elsewhere in the API.
68
+
69
+ === Concept: XML Parameters
70
+
71
+ A scheme which I call <i>XML parameters</i> enables one to utilize the XML
72
+ configuratin system for custom Outputters and Formatters.
73
+ This requires <b>no</b> extra work on your part, so long as your objects
74
+ are set up using hash arguments and can decode string values. That is, once
75
+ you've written a custom Outputter, it is automatically configurable in XML
76
+ without having to write any extra code.
77
+
78
+ An XML parameter is analogous to a hash argument to some object's <tt>new</tt>
79
+ method. Consider these hash arguments to FileOutputter:
80
+
81
+ :filename => '/path/to/logs/my.log'
82
+ :trunc => 'true'
83
+
84
+ We can specify them in XML like this:
85
+
86
+ <outputter type="FileOutputter" trunc="true">
87
+ <filename>/path/to/logs/my.log</filename>
88
+ ...
89
+
90
+ The name of the element/attribute is just the name of the parameter. Note that
91
+ the input will be a string, thus it's wise to convert the data in from
92
+ strings in any custom classes (to_i for integers, etc). Now let's suppose you
93
+ have defined a custom Outputter named MyOutputter with the following
94
+ additional hash args:
95
+
96
+ :myarg1 => 'foo'
97
+ :myarg2 => 123
98
+
99
+ Automagically, you can configure your Outputter like so:
100
+
101
+ <outputter type="MyOutputter" myarg2="123">
102
+ <myarg1>foo</myarg1>
103
+ ...
104
+
105
+ Isn't that nice? <tt>:-)</tt>
106
+
107
+ === Concept: Variable Substitution
108
+
109
+ To kill the need for preprocessors, Configurator provides a means of variable
110
+ substitution for XML parameters at runtime. If you specify
111
+ <tt>#{foo}</tt> in an XML parameter value, Configurator will replace it with
112
+ the value of 'foo' in its parameter hashtable. The primary idea is that you
113
+ can figure stuff out in your program,
114
+ say the log path, and relay that information to the XML while it's being
115
+ loaded. Secondarily, it is a way to have aliases within an XML document.
116
+
117
+ There are two ways to tell Configurator about these variables. The first
118
+ method we'll cover is done within a Ruby program with Configurator[].
119
+
120
+ Configurator['logpath'] = '/path/to/logs'
121
+
122
+ Thereafter, any occurence of <tt>#{logpath}</tt> in each and every XML
123
+ parameter will be substituted with '/path/to/logs'. For example:
124
+
125
+ <filename>#{logpath}/mylog.log</filename>
126
+
127
+ Becomes,
128
+
129
+ <filename>/path/to/logs/mylog.log</filename>
130
+
131
+ Aside from Configurator[], another way to define XML parameter variables
132
+ is to define <tt>parameters</tt> under the <tt><pre_config></tt> element
133
+ of an XML configuration:
134
+
135
+ <pre_config>
136
+ <parameter name="logpath" value="/path/to/logs'/>
137
+ <parameter name="other" value="somethingelse'/>
138
+ ...
139
+ </pre_config>
140
+
141
+ Alternatively,
142
+
143
+ <pre_config>
144
+ <parameters>
145
+ <logpath>/path/to/logs</logpath>
146
+ <other>somethingelse</other>
147
+ ...
148
+ </parameters>
149
+ ...
150
+
151
+ The end result is the same as using Configurator[]. However, this method
152
+ is not dynamic. Configurator[] should be used when you want to set variables
153
+ from within Ruby.
154
+
155
+ = XML Grammar
156
+
157
+ And now, here's the XML grammar we use to configure Log4r.
158
+
159
+ == Root Element
160
+
161
+ The root element is <tt><log4r_config></tt>. It can be embedded as a node of
162
+ any other element in an XML file. For instance:
163
+
164
+ <my-xml-thing>
165
+ <customize-libraries>
166
+ <log4r_config>
167
+ <!-- log4r configuratin goes here -->
168
+ </log4r_config>
169
+ ...
170
+
171
+ == Pre-config element
172
+
173
+ The pre_config element is a child of log4r_config and contains:
174
+
175
+ * 'custom_levels' element
176
+ * 'global' element
177
+ * 'parameters' element
178
+ * any number of 'parameter' elements
179
+
180
+ === Pre_config: Custom Levels
181
+
182
+ The custom_levels element is not an <i>XML directive</i> of pre_config. It
183
+ <b>must</b> be specified like this:
184
+
185
+ <custom_levels>Foo, Bar, Baz</custom_levels>
186
+
187
+ And <b>not</b> like this:
188
+
189
+ <!-- NOT SUPPORTED -->
190
+ <custom_levels levels="Foo, Bar, Baz"/>
191
+
192
+ === Pre_config: Global Level
193
+
194
+ <global level="DEBUG"/>
195
+
196
+ or
197
+
198
+ <global><level>DEBUG</level></global>
199
+
200
+ Here, level is an XML directive of global.
201
+
202
+ === Pre_config: Parameters
203
+
204
+ Parameters are variables that will be substituted later on. Please
205
+ see the <b>Concept: Variable Substitution</b> section above. Parameters
206
+ are <i>XML Directives</i>, which means they can be expressed using elements
207
+ or attributes. Here is an example:
208
+
209
+ <parameter name="param name 1" value="param value 1">
210
+ <parameter name="param name 2" value="param value 2">
211
+ ...
212
+ <parameters>
213
+ <param3>value3</param3>
214
+ <param4>value3</param4>
215
+ ...
216
+
217
+ === Pre_config: Complete Example
218
+
219
+ <log4r_config>
220
+
221
+ <pre_config>
222
+ <custom_levels>
223
+ Foo,Bar, Baz
224
+ </custom_levels>
225
+ <global level="Bar"/>
226
+ <parameters>
227
+ <logpath>/var/log/foo</logpath>
228
+ <mypattern>%l [%d] %m</mypattern>
229
+ </parameters>
230
+ </pre_config>
231
+
232
+ <!-- define some outputters and loggers -->
233
+
234
+ </log4r_config>
235
+
236
+ == Configuring Log4r Objects
237
+
238
+ The XML configuration grammar for Loggers, Outputters and the like are
239
+ covered in the usage guidelines for those classes.
240
+
241
+ == Order Doesn't Matter
242
+
243
+ You can (it is hoped) define any of the XML objects in any order desired.