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.
- data/doc/content/contact.html +22 -0
- data/doc/content/contribute.html +21 -0
- data/doc/content/index.html +90 -0
- data/doc/content/license.html +56 -0
- data/doc/content/manual.html +449 -0
- data/doc/dev/README.developers +55 -0
- data/doc/dev/checklist +23 -0
- data/doc/dev/things-to-do +5 -0
- data/doc/images/log4r-logo.png +0 -0
- data/doc/images/logo2.png +0 -0
- data/doc/log4r.css +111 -0
- data/doc/templates/main.html +147 -0
- data/examples/README +19 -0
- data/examples/customlevels.rb +34 -0
- data/examples/fileroll.rb +40 -0
- data/examples/log4r_yaml.yaml +0 -0
- data/examples/logclient.rb +25 -0
- data/examples/logserver.rb +18 -0
- data/examples/moderate.xml +29 -0
- data/examples/moderateconfig.rb +66 -0
- data/examples/myformatter.rb +23 -0
- data/examples/outofthebox.rb +21 -0
- data/examples/rrconfig.xml +63 -0
- data/examples/rrsetup.rb +42 -0
- data/examples/simpleconfig.rb +39 -0
- data/examples/xmlconfig.rb +25 -0
- data/examples/yaml.rb +30 -0
- data/src/log4r.rb +17 -0
- data/src/log4r/base.rb +74 -0
- data/src/log4r/config.rb +9 -0
- data/src/log4r/configurator.rb +224 -0
- data/src/log4r/formatter/formatter.rb +105 -0
- data/src/log4r/formatter/patternformatter.rb +107 -0
- data/src/log4r/lib/drbloader.rb +52 -0
- data/src/log4r/lib/xmlloader.rb +24 -0
- data/src/log4r/logevent.rb +28 -0
- data/src/log4r/logger.rb +194 -0
- data/src/log4r/loggerfactory.rb +89 -0
- data/src/log4r/logserver.rb +28 -0
- data/src/log4r/outputter/consoleoutputters.rb +18 -0
- data/src/log4r/outputter/datefileoutputter.rb +110 -0
- data/src/log4r/outputter/emailoutputter.rb +116 -0
- data/src/log4r/outputter/fileoutputter.rb +49 -0
- data/src/log4r/outputter/iooutputter.rb +55 -0
- data/src/log4r/outputter/outputter.rb +132 -0
- data/src/log4r/outputter/outputterfactory.rb +59 -0
- data/src/log4r/outputter/remoteoutputter.rb +40 -0
- data/src/log4r/outputter/rollingfileoutputter.rb +126 -0
- data/src/log4r/outputter/staticoutputter.rb +30 -0
- data/src/log4r/outputter/syslogoutputter.rb +75 -0
- data/src/log4r/rdoc/configurator +243 -0
- data/src/log4r/rdoc/emailoutputter +103 -0
- data/src/log4r/rdoc/formatter +39 -0
- data/src/log4r/rdoc/log4r +89 -0
- data/src/log4r/rdoc/logger +175 -0
- data/src/log4r/rdoc/logserver +85 -0
- data/src/log4r/rdoc/outputter +108 -0
- data/src/log4r/rdoc/patternformatter +128 -0
- data/src/log4r/rdoc/syslogoutputter +29 -0
- data/src/log4r/rdoc/yamlconfigurator +20 -0
- data/src/log4r/repository.rb +65 -0
- data/src/log4r/staticlogger.rb +49 -0
- data/src/log4r/yamlconfigurator.rb +0 -0
- data/tests/README +10 -0
- data/tests/testall.rb +6 -0
- data/tests/testbase.rb +49 -0
- data/tests/testconf.xml +37 -0
- data/tests/testcustom.rb +27 -0
- data/tests/testformatter.rb +27 -0
- data/tests/testlogger.rb +196 -0
- data/tests/testoutputter.rb +111 -0
- data/tests/testpatternformatter.rb +21 -0
- data/tests/testxmlconf.rb +45 -0
- metadata +127 -0
data/src/log4r/config.rb
ADDED
@@ -0,0 +1,224 @@
|
|
1
|
+
# :include: rdoc/configurator
|
2
|
+
#
|
3
|
+
# == Other Info
|
4
|
+
#
|
5
|
+
# Version:: $Id: configurator.rb,v 1.1.1.1 2004/03/19 03:31:06 fando Exp $
|
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,105 @@
|
|
1
|
+
# :include: ../rdoc/formatter
|
2
|
+
#
|
3
|
+
# Version:: $Id: formatter.rb,v 1.2 2009/09/19 05:16:43 colbygk 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,107 @@
|
|
1
|
+
# :include: ../rdoc/patternformatter
|
2
|
+
#
|
3
|
+
# == Other Info
|
4
|
+
#
|
5
|
+
# Version:: $Id: patternformatter.rb,v 1.3 2009/09/19 05:16:43 colbygk Exp $
|
6
|
+
|
7
|
+
require "log4r/formatter/formatter"
|
8
|
+
|
9
|
+
module Log4r
|
10
|
+
# See log4r/formatter/patternformatter.rb
|
11
|
+
class PatternFormatter < BasicFormatter
|
12
|
+
|
13
|
+
# Arguments to sprintf keyed to directive letters
|
14
|
+
DirectiveTable = {
|
15
|
+
"c" => 'event.name',
|
16
|
+
"C" => 'event.fullname',
|
17
|
+
"d" => 'format_date',
|
18
|
+
"t" => '(event.tracer.nil? ? "no trace" : event.tracer[0])',
|
19
|
+
"m" => 'event.data',
|
20
|
+
"M" => 'format_object(event.data)',
|
21
|
+
"l" => 'LNAMES[event.level]',
|
22
|
+
"%" => '"%"'
|
23
|
+
}
|
24
|
+
|
25
|
+
# Matches the first directive encountered and the stuff around it.
|
26
|
+
#
|
27
|
+
# * $1 is the stuff before directive or "" if not applicable
|
28
|
+
# * $2 is the directive group or nil if there's none
|
29
|
+
# * $3 is the %#.# match within directive group
|
30
|
+
# * $4 is the .# match which we don't use (it's there to match properly)
|
31
|
+
# * $5 is the directive letter
|
32
|
+
# * $6 is the stuff after the directive or "" if not applicable
|
33
|
+
|
34
|
+
DirectiveRegexp = /([^%]*)((%-?\d*(\.\d+)?)([cCdtmMl%]))?(.*)/
|
35
|
+
|
36
|
+
# default date format
|
37
|
+
ISO8601 = "%Y-%m-%d %H:%M:%S"
|
38
|
+
|
39
|
+
attr_reader :pattern, :date_pattern, :date_method
|
40
|
+
|
41
|
+
# Accepts the following hash arguments (either a string or a symbol):
|
42
|
+
#
|
43
|
+
# [<tt>pattern</tt>] A pattern format string.
|
44
|
+
# [<tt>date_pattern</tt>] A Time#strftime format string. See the
|
45
|
+
# Ruby Time class for details.
|
46
|
+
# [+date_method+]
|
47
|
+
# As an option to date_pattern, specify which
|
48
|
+
# Time.now method to call. For
|
49
|
+
# example, +usec+ or +to_s+.
|
50
|
+
# Specify it as a String or Symbol.
|
51
|
+
#
|
52
|
+
# The default date format is ISO8601, which looks like this:
|
53
|
+
#
|
54
|
+
# yyyy-mm-dd hh:mm:ss => 2001-01-12 13:15:50
|
55
|
+
|
56
|
+
def initialize(hash={})
|
57
|
+
super(hash)
|
58
|
+
@pattern = (hash['pattern'] or hash[:pattern] or nil)
|
59
|
+
@date_pattern = (hash['date_pattern'] or hash[:date_pattern] or nil)
|
60
|
+
@date_method = (hash['date_method'] or hash[:date_method] or nil)
|
61
|
+
@date_pattern = ISO8601 if @date_pattern.nil? and @date_method.nil?
|
62
|
+
PatternFormatter.create_format_methods(self)
|
63
|
+
end
|
64
|
+
|
65
|
+
# PatternFormatter works by dynamically defining a <tt>format</tt> method
|
66
|
+
# based on the supplied pattern format. This method contains a call to
|
67
|
+
# Kernel#sptrintf with arguments containing the data requested in
|
68
|
+
# the pattern format.
|
69
|
+
#
|
70
|
+
# How is this magic accomplished? First, we visit each directive
|
71
|
+
# and change the %#.# component to %#.#s. The directive letter is then
|
72
|
+
# used to cull an appropriate entry from the DirectiveTable for the
|
73
|
+
# sprintf argument list. After assembling the method definition, we
|
74
|
+
# run module_eval on it, and voila.
|
75
|
+
|
76
|
+
def PatternFormatter.create_format_methods(pf) #:nodoc:
|
77
|
+
# first, define the format_date method
|
78
|
+
if pf.date_method
|
79
|
+
module_eval "def pf.format_date; Time.now.#{pf.date_method}; end"
|
80
|
+
else
|
81
|
+
module_eval <<-EOS
|
82
|
+
def pf.format_date
|
83
|
+
Time.now.strftime "#{pf.date_pattern}"
|
84
|
+
end
|
85
|
+
EOS
|
86
|
+
end
|
87
|
+
# and now the main format method
|
88
|
+
ebuff = "def pf.format(event)\n sprintf(\""
|
89
|
+
_pattern = pf.pattern.dup
|
90
|
+
args = [] # the args to sprintf which we'll append to ebuff lastly
|
91
|
+
while true # work on each match in turn
|
92
|
+
match = DirectiveRegexp.match _pattern
|
93
|
+
ebuff << match[1] unless match[1].empty?
|
94
|
+
break if match[2].nil?
|
95
|
+
# deal with the directive by inserting a %#.#s where %#.# is copied
|
96
|
+
# directy from the match
|
97
|
+
ebuff << match[3] + "s"
|
98
|
+
args << DirectiveTable[match[5]] # cull the data for our argument list
|
99
|
+
break if match[6].empty?
|
100
|
+
_pattern = match[6]
|
101
|
+
end
|
102
|
+
ebuff << '\n", ' + args.join(', ') + ")\n"
|
103
|
+
ebuff << "end\n"
|
104
|
+
module_eval ebuff
|
105
|
+
end
|
106
|
+
end
|
107
|
+
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
|