path-log4r 1.1.10

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 (104) hide show
  1. data/INSTALL +11 -0
  2. data/LICENSE +90 -0
  3. data/LICENSE.LGPLv3 +165 -0
  4. data/README +95 -0
  5. data/Rakefile +74 -0
  6. data/TODO +2 -0
  7. data/doc/content/contact.html +22 -0
  8. data/doc/content/contribute.html +21 -0
  9. data/doc/content/index.html +90 -0
  10. data/doc/content/license.html +56 -0
  11. data/doc/content/manual.html +449 -0
  12. data/doc/dev/README.developers +55 -0
  13. data/doc/dev/checklist +23 -0
  14. data/doc/dev/things-to-do +5 -0
  15. data/doc/images/log4r-logo.png +0 -0
  16. data/doc/images/logo2.png +0 -0
  17. data/doc/log4r.css +111 -0
  18. data/doc/rdoc-log4r.css +696 -0
  19. data/doc/templates/main.html +147 -0
  20. data/examples/README +19 -0
  21. data/examples/ancestors.rb +53 -0
  22. data/examples/chainsaw_settings.xml +7 -0
  23. data/examples/customlevels.rb +34 -0
  24. data/examples/filelog.rb +25 -0
  25. data/examples/fileroll.rb +40 -0
  26. data/examples/gmail.rb +30 -0
  27. data/examples/gmail.yaml +95 -0
  28. data/examples/log4r_yaml.yaml +0 -0
  29. data/examples/logclient.rb +25 -0
  30. data/examples/logserver.rb +18 -0
  31. data/examples/moderate.xml +29 -0
  32. data/examples/moderateconfig.rb +66 -0
  33. data/examples/myformatter.rb +23 -0
  34. data/examples/outofthebox.rb +21 -0
  35. data/examples/rdoc-gen +2 -0
  36. data/examples/rrconfig.xml +63 -0
  37. data/examples/rrsetup.rb +42 -0
  38. data/examples/simpleconfig.rb +39 -0
  39. data/examples/syslogcustom.rb +52 -0
  40. data/examples/xmlconfig.rb +25 -0
  41. data/examples/yaml.rb +30 -0
  42. data/lib/log4r.rb +20 -0
  43. data/lib/log4r/GDC.rb +41 -0
  44. data/lib/log4r/MDC.rb +59 -0
  45. data/lib/log4r/NDC.rb +86 -0
  46. data/lib/log4r/base.rb +74 -0
  47. data/lib/log4r/config.rb +9 -0
  48. data/lib/log4r/configurator.rb +224 -0
  49. data/lib/log4r/formatter/formatter.rb +105 -0
  50. data/lib/log4r/formatter/log4jxmlformatter.rb +61 -0
  51. data/lib/log4r/formatter/patternformatter.rb +145 -0
  52. data/lib/log4r/lib/drbloader.rb +52 -0
  53. data/lib/log4r/lib/xmlloader.rb +24 -0
  54. data/lib/log4r/logevent.rb +28 -0
  55. data/lib/log4r/logger.rb +199 -0
  56. data/lib/log4r/loggerfactory.rb +89 -0
  57. data/lib/log4r/logserver.rb +28 -0
  58. data/lib/log4r/outputter/consoleoutputters.rb +18 -0
  59. data/lib/log4r/outputter/datefileoutputter.rb +117 -0
  60. data/lib/log4r/outputter/emailoutputter.rb +143 -0
  61. data/lib/log4r/outputter/fileoutputter.rb +56 -0
  62. data/lib/log4r/outputter/iooutputter.rb +55 -0
  63. data/lib/log4r/outputter/outputter.rb +134 -0
  64. data/lib/log4r/outputter/outputterfactory.rb +61 -0
  65. data/lib/log4r/outputter/remoteoutputter.rb +40 -0
  66. data/lib/log4r/outputter/rollingfileoutputter.rb +234 -0
  67. data/lib/log4r/outputter/scribeoutputter.rb +37 -0
  68. data/lib/log4r/outputter/staticoutputter.rb +30 -0
  69. data/lib/log4r/outputter/syslogoutputter.rb +130 -0
  70. data/lib/log4r/outputter/udpoutputter.rb +53 -0
  71. data/lib/log4r/rdoc/GDC +14 -0
  72. data/lib/log4r/rdoc/MDC +16 -0
  73. data/lib/log4r/rdoc/NDC +41 -0
  74. data/lib/log4r/rdoc/configurator +243 -0
  75. data/lib/log4r/rdoc/emailoutputter +103 -0
  76. data/lib/log4r/rdoc/formatter +39 -0
  77. data/lib/log4r/rdoc/log4r +89 -0
  78. data/lib/log4r/rdoc/logger +175 -0
  79. data/lib/log4r/rdoc/logserver +85 -0
  80. data/lib/log4r/rdoc/outputter +108 -0
  81. data/lib/log4r/rdoc/patternformatter +128 -0
  82. data/lib/log4r/rdoc/scribeoutputter +16 -0
  83. data/lib/log4r/rdoc/syslogoutputter +29 -0
  84. data/lib/log4r/rdoc/win32eventoutputter +7 -0
  85. data/lib/log4r/rdoc/yamlconfigurator +20 -0
  86. data/lib/log4r/repository.rb +88 -0
  87. data/lib/log4r/staticlogger.rb +49 -0
  88. data/lib/log4r/yamlconfigurator.rb +196 -0
  89. data/tests/README +10 -0
  90. data/tests/testGDC.rb +26 -0
  91. data/tests/testMDC.rb +42 -0
  92. data/tests/testNDC.rb +27 -0
  93. data/tests/testall.rb +6 -0
  94. data/tests/testbase.rb +49 -0
  95. data/tests/testchainsaw.rb +48 -0
  96. data/tests/testconf.xml +37 -0
  97. data/tests/testcustom.rb +27 -0
  98. data/tests/testformatter.rb +27 -0
  99. data/tests/testlogger.rb +196 -0
  100. data/tests/testoutputter.rb +132 -0
  101. data/tests/testpatternformatter.rb +78 -0
  102. data/tests/testthreads.rb +35 -0
  103. data/tests/testxmlconf.rb +45 -0
  104. metadata +184 -0
@@ -0,0 +1,196 @@
1
+ # :include: rdoc/yamlconfigurator
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version: $Id$
6
+
7
+ require "log4r/logger"
8
+ require "log4r/outputter/staticoutputter"
9
+ require "log4r/logserver"
10
+ require "log4r/outputter/remoteoutputter"
11
+
12
+ require 'yaml'
13
+
14
+ module Log4r
15
+ # Gets raised when Configurator encounters bad YAML.
16
+ class ConfigError < Exception
17
+ end
18
+
19
+ # See log4r/yamlconfigurator.rb
20
+ class YamlConfigurator
21
+ @@params = Hash.new
22
+
23
+ # Get a parameter's value
24
+ def self.[](param); @@params[param] end
25
+ # Define a parameter with a value
26
+ def self.[]=(param, value); @@params[param] = value end
27
+
28
+
29
+ def self.custom_levels( levels)
30
+ return Logger.root if levels.size == 0
31
+ for i in 0...levels.size
32
+ name = levels[i].to_s
33
+ if name =~ /\s/ or name !~ /^[A-Z]/
34
+ raise TypeError, "#{name} is not a valid Ruby Constant name", caller
35
+ end
36
+ end
37
+ Log4r.define_levels *levels
38
+ end
39
+
40
+ # Given a filename, loads the YAML configuration for Log4r.
41
+ def self.load_yaml_file( filename)
42
+ actual_load( File.open( filename))
43
+ end
44
+
45
+ # You can load a String YAML configuration instead of a file.
46
+ def self.load_yaml_string( string)
47
+ actual_load( string)
48
+ end
49
+
50
+ #######
51
+ private
52
+ #######
53
+
54
+ def self.actual_load( yaml_docs)
55
+ log4r_config = nil
56
+ YAML.load_documents( yaml_docs){ |doc|
57
+ doc.has_key?( 'log4r_config') and log4r_config = doc['log4r_config'] and break
58
+ }
59
+ if log4r_config.nil?
60
+ raise ConfigError,
61
+ "Key 'log4r_config:' not defined in yaml documents", caller[1..-1]
62
+ end
63
+ decode_yaml( log4r_config)
64
+ end
65
+
66
+ def self.decode_yaml( cfg)
67
+ decode_pre_config( cfg['pre_config'])
68
+ cfg['outputters'].each{ |op| decode_outputter( op)}
69
+ cfg['loggers'].each{ |lo| decode_logger( lo)}
70
+ cfg['logserver'].each{ |lo| decode_logserver( lo)} unless cfg['logserver'].nil?
71
+ end
72
+
73
+ def self.decode_pre_config( pre)
74
+ return Logger.root if pre.nil?
75
+ decode_custom_levels( pre['custom_levels'])
76
+ global_config( pre['global'])
77
+ global_config( pre['root'])
78
+ decode_parameters( pre['parameters'])
79
+ end
80
+
81
+ def self.decode_custom_levels( levels)
82
+ return Logger.root if levels.nil?
83
+ begin custom_levels( levels)
84
+ rescue TypeError => te
85
+ raise ConfigError, te.message, caller[1..-4]
86
+ end
87
+ end
88
+
89
+ def self.global_config( e)
90
+ return if e.nil?
91
+ globlev = e['level']
92
+ return if globlev.nil?
93
+ lev = LNAMES.index(globlev) # find value in LNAMES
94
+ Log4rTools.validate_level(lev, 4) # choke on bad level
95
+ Logger.global.level = lev
96
+ end
97
+
98
+ def self.decode_parameters( params)
99
+ params.each{ |p| @@params[p['name']] = p['value']} unless params.nil?
100
+ end
101
+
102
+ def self.decode_outputter( op)
103
+ # fields
104
+ name = op['name']
105
+ type = op['type']
106
+ level = op['level']
107
+ only_at = op['only_at']
108
+ # validation
109
+ raise ConfigError, "Outputter missing name", caller[1..-3] if name.nil?
110
+ raise ConfigError, "Outputter missing type", caller[1..-3] if type.nil?
111
+ Log4rTools.validate_level(LNAMES.index(level)) unless level.nil?
112
+ only_levels = []
113
+ unless only_at.nil?
114
+ for lev in only_at
115
+ alev = LNAMES.index(lev)
116
+ Log4rTools.validate_level(alev, 3)
117
+ only_levels.push alev
118
+ end
119
+ end
120
+
121
+ formatter = decode_formatter( op['formatter'])
122
+ # build the eval string
123
+ buff = "Outputter[name] = #{type}.new name"
124
+ buff += ",:level=>#{LNAMES.index(level)}" unless level.nil?
125
+ buff += ",:formatter=>formatter" unless formatter.nil?
126
+ params = decode_hash_params( op)
127
+ buff += "," + params.join(',') if params.size > 0
128
+ begin eval buff
129
+ rescue Exception => ae
130
+ raise ConfigError,
131
+ "Problem creating outputter: #{ae.message}", caller[1..-3]
132
+ end
133
+ Outputter[name].only_at( *only_levels) if only_levels.size > 0
134
+ Outputter[name]
135
+ end
136
+
137
+ def self.decode_formatter( fo)
138
+ return nil if fo.nil?
139
+ type = fo['type']
140
+ raise ConfigError, "Formatter missing type", caller[1..-4] if type.nil?
141
+ buff = "#{type}.new " + decode_hash_params( fo).join(',')
142
+ begin return eval( buff)
143
+ rescue Exception => ae
144
+ raise ConfigError,
145
+ "Problem creating outputter: #{ae.message}", caller[1..-4]
146
+ end
147
+ end
148
+
149
+ ExcludeParams = %w{formatter level name type only_at}
150
+
151
+ # Does the fancy parameter to hash argument transformation
152
+ def self.decode_hash_params( ph)
153
+ buff = []
154
+ ph.each{ |name, value|
155
+ next if ExcludeParams.include? name
156
+ buff << ":" + name + "=>" + paramsub( value)
157
+ }
158
+ buff
159
+ end
160
+
161
+ # Substitues any #{foo} in the YAML with Parameter['foo']
162
+ def self.paramsub( str)
163
+ return nil if str.nil?
164
+ return nil if str.class != String
165
+ @@params.each {|param, value|
166
+ str.sub!( '#{' + param + '}', value)
167
+ }
168
+ "'" + str + "'"
169
+ end
170
+
171
+ def self.decode_logger( lo)
172
+ l = Logger.new lo['name']
173
+ decode_logger_common( l, lo)
174
+ end
175
+
176
+ def self.decode_logserver( lo)
177
+ name = lo['name']
178
+ uri = lo['uri']
179
+ l = LogServer.new name, uri
180
+ decode_logger_common(l, lo)
181
+ end
182
+
183
+ def self.decode_logger_common( l, lo)
184
+ level = lo['level']
185
+ additive = lo['additive']
186
+ trace = lo['trace']
187
+ l.level = LNAMES.index( level) unless level.nil?
188
+ l.additive = additive unless additive.nil?
189
+ l.trace = trace unless trace.nil?
190
+ # and now for outputters
191
+ outs = lo['outputters']
192
+ outs.each {|n| l.add n.strip} unless outs.nil?
193
+ end
194
+ end
195
+ end
196
+
@@ -0,0 +1,10 @@
1
+ The unit tests are currently out of date. The examples actually provide
2
+ a decent test suite for log4r. But the unit tests are still very important
3
+ because of bounds-checking and a quicker turnaround for bug discovery.
4
+ The unit files need to be converted to the new 'test/unit' paradigm.
5
+
6
+ Because Log4r dynamically defines constants according to user preferences,
7
+ the unit testing can't all be done in one instance of ruby. It is planned
8
+ to use popen to run each test that needs a clean ruby instance.
9
+
10
+ The logs/ directory is where these tests dump generated log files.
@@ -0,0 +1,26 @@
1
+ $: << File.join("..","lib")
2
+ require "test/unit"
3
+ require "log4r"
4
+ include Log4r
5
+
6
+ class TestGDC < Test::Unit::TestCase
7
+
8
+ def test_gdc_default
9
+ assert(GDC.get() == "testGDC.rb", "Expected 'testGDC.rb' got '#{GDC.get()}'" )
10
+ end
11
+
12
+ def test_gdc_set
13
+ assert_nothing_raised() { GDC.set("testGDCset") }
14
+ assert(GDC.get() == "testGDCset", "Expected 'testGDCset' got '#{GDC.get()}'" )
15
+ end
16
+
17
+ def test_gdc_threaded
18
+ assert_nothing_raised() { GDC.set("testGDCset") }
19
+ t = Thread.new("test GDC thread") do |name|
20
+ assert_raise(RuntimeError) { GDC.set("somethingelse") }
21
+ end
22
+ t.join
23
+ assert(GDC.get() == "testGDCset", "Expected 'testGDCset' got '#{GDC.get()}'" )
24
+ end
25
+
26
+ end
@@ -0,0 +1,42 @@
1
+ $: << File.join("..","lib")
2
+ require "test/unit"
3
+ require "log4r"
4
+ include Log4r
5
+
6
+ class TestMDC < Test::Unit::TestCase
7
+
8
+ def test_multithread_copy
9
+ Log4r::MDC.put("user","colbygk")
10
+ t = Thread.new("test first copy") do |name|
11
+ assert(Log4r::MDC.get("user") == "colbygk",
12
+ "Did not get back expected value, '#{MDC.get("user")}'")
13
+ Log4r::MDC.put("user","unique")
14
+ assert(Log4r::MDC.get("user") == "unique",
15
+ "Did not get back expected value, '#{MDC.get("user")}'")
16
+ end
17
+ t.join
18
+ assert(Log4r::MDC.get("user") == "colbygk",
19
+ "Did not get back expected value, '#{MDC.get("user")}'")
20
+ end
21
+
22
+ def test_MDCoutput
23
+ Log4r::MDC.put(:user, "symbol")
24
+ Log4r::MDC.put("string", "string")
25
+ Log4r::MDC.put(5, "number")
26
+ l = Logger.new 'test'
27
+ o = StdoutOutputter.new 'test'
28
+ l.add o
29
+ assert_nothing_raised {
30
+ f = PatternFormatter.new :pattern=> "%l user: %X{:user} %X{strng} %X{5}"
31
+ Outputter['test'].formatter = f
32
+ l.debug "And this?"
33
+ l.info "How's this?"
34
+ l.error "and a really freaking huge line which we hope will be trimmed?"
35
+ e = ArgumentError.new("something barfed")
36
+ e.set_backtrace Array.new(5, "trace junk at thisfile.rb 154")
37
+ l.fatal e
38
+ l.info [1, 3, 5]
39
+ }
40
+
41
+ end
42
+ end
@@ -0,0 +1,27 @@
1
+ $: << File.join("..","lib")
2
+ require "test/unit"
3
+ require "log4r"
4
+ include Log4r
5
+
6
+ class TestNDC < Test::Unit::TestCase
7
+
8
+ def test_ndc_remove_push
9
+ NDC.remove()
10
+ NDC.push("ndc")
11
+ assert(Log4r::NDC.get() == "ndc", "Expected 'ndc' got '#{NDC.get()}'" )
12
+ NDC.push("ndc")
13
+ assert(Log4r::NDC.get() == "ndc ndc", "Expected 'ndc ndc' got '#{NDC.get()}'" )
14
+ end
15
+
16
+ def test_ndc_remove_push_clone_and_inherit
17
+ NDC.remove()
18
+ NDC.push("ndc")
19
+ NDC.push("ndc")
20
+ a = NDC.clone_stack()
21
+ NDC.remove()
22
+ assert(NDC.get() == "", "Expected '' got '#{NDC.get()}'" )
23
+ NDC.inherit(a)
24
+ assert(NDC.get() == "ndc ndc", "Expected 'ndc ndc' got '#{NDC.get()}'" )
25
+ end
26
+
27
+ end
@@ -0,0 +1,6 @@
1
+ $: << File.join("..", "lib")
2
+
3
+ # because constants are dynamically defined, some tests need to
4
+ # be opened in a fresh instance of Ruby, hence the popens
5
+
6
+ IO.popen("date") { |f| puts f.gets }
@@ -0,0 +1,49 @@
1
+ $: << File.join("..","lib")
2
+ require "test/unit"
3
+ require "log4r"
4
+ include Log4r
5
+
6
+ class TestBase < Test::Unit::TestCase
7
+ # check that LNAMES loads properly (it uses an eval to load)
8
+ def test_default_levels
9
+ Logger.root # doing this loads the default levels
10
+ assert_equal(ALL,0)
11
+ assert_equal(DEBUG,1)
12
+ assert_equal(INFO,2)
13
+ assert_equal(WARN,3)
14
+ assert_equal(ERROR,4)
15
+ assert_equal(FATAL,5)
16
+ assert_equal(OFF,6)
17
+ assert_equal(LEVELS, 7)
18
+ assert_equal(LNAMES.size, 7)
19
+ end
20
+ # check bad input and bounds for validate_level
21
+ def test_validate_level
22
+ 7.times{|i| assert_nothing_raised {Log4rTools.validate_level(i)} }
23
+ assert_raises(ArgumentError) {Log4rTools.validate_level(-1)}
24
+ assert_raises(ArgumentError) {Log4rTools.validate_level(LEVELS)}
25
+ assert_raises(ArgumentError) {Log4rTools.validate_level(String)}
26
+ assert_raises(ArgumentError) {Log4rTools.validate_level("bogus")}
27
+ end
28
+ # decode_bool turns a string 'true' into true and so on
29
+ def test_decode_bool
30
+ # when the key is a symbol :data
31
+ assert(Log4rTools.decode_bool({:data=> 'true'} ,:data,false) == true)
32
+ assert(Log4rTools.decode_bool({:data=> true} ,:data,false) == true)
33
+ assert(Log4rTools.decode_bool({:data=> 'false'} ,:data,true) == false)
34
+ assert(Log4rTools.decode_bool({:data=> false} ,:data,true) == false)
35
+ assert(Log4rTools.decode_bool({:data=> nil} ,:data,true) == true)
36
+ assert(Log4rTools.decode_bool({:data=> nil} ,:data,false) == false)
37
+ assert(Log4rTools.decode_bool({:data=> String} ,:data,true) == true)
38
+ assert(Log4rTools.decode_bool({:data=> String} ,:data,false) == false)
39
+ # now the key is a string 'data'
40
+ assert(Log4rTools.decode_bool({'data'=> 'true'} ,:data,false) == true)
41
+ assert(Log4rTools.decode_bool({'data'=> true} ,:data,false) == true)
42
+ assert(Log4rTools.decode_bool({'data'=> 'false'} ,:data,true) == false)
43
+ assert(Log4rTools.decode_bool({'data'=> false} ,:data,true) == false)
44
+ assert(Log4rTools.decode_bool({'data'=> nil} ,:data,true) == true)
45
+ assert(Log4rTools.decode_bool({'data'=> nil} ,:data,false) == false)
46
+ assert(Log4rTools.decode_bool({'data'=> String} ,:data,true) == true)
47
+ assert(Log4rTools.decode_bool({'data'=> String} ,:data,false) == false)
48
+ end
49
+ end
@@ -0,0 +1,48 @@
1
+ $: << File.join("..", "lib")
2
+
3
+ require 'log4r'
4
+ require 'log4r/staticlogger'
5
+ require 'log4r/formatter/log4jxmlformatter'
6
+ require 'log4r/outputter/udpoutputter'
7
+ require 'log4r/outputter/consoleoutputters'
8
+
9
+ include Log4r
10
+
11
+ log4r = Logger.new 'log4r'
12
+ log4r.trace = true
13
+ log4r.outputters = StdoutOutputter.new 'log4r'
14
+ log4r.level = ALL
15
+
16
+ formatter = Log4jXmlFormatter.new
17
+ outputter = UDPOutputter.new 'udp', :hostname => "localhost", :port => 8071
18
+ outputter.formatter = formatter
19
+
20
+ mylog = Logger.new 'mylog'
21
+ mylog.trace = true
22
+ mylog.outputters = [outputter]
23
+
24
+ # Log4r::Formatter throws when formatting
25
+ # an excpetion with a nil backtrace (line 73).
26
+ def get_exception(msg)
27
+ begin
28
+ raise msg
29
+ rescue Exception => e
30
+ e
31
+ end
32
+ end
33
+
34
+ NDC.push "saw test"
35
+
36
+ MDC.put "clientip", %q{10.33.33.33}
37
+
38
+ def do_log(log)
39
+ log.debug "This is a message with level DEBUG"
40
+ log.info "This is a message with level INFO"
41
+ log.warn "This is a message with level WARN"
42
+ log.error "This is a message with level ERROR"
43
+ log.fatal "This is a message with level FATAL"
44
+
45
+ log.fatal get_exception( "This is an exception" )
46
+ end
47
+
48
+ do_log(mylog)
@@ -0,0 +1,37 @@
1
+ <test>
2
+ <log4r_config>
3
+
4
+ <pre_config>
5
+ <custom_levels>Foo, Bar,Baz, Bing</custom_levels>
6
+ <global level="Foo"/>
7
+ <parameters>
8
+ <mypattern>[%l] %d %t - %m</mypattern>
9
+ </parameters>
10
+ <parameter name="datem" value="usec"/>
11
+ </pre_config>
12
+
13
+ <!-- level and formatter are optional, -->
14
+ <outputter name="SO" type="StdoutOutputter">
15
+ <level>Foo</level>
16
+ <formatter type="Log4r::PatternFormatter">
17
+ <pattern>%d %c %l&gt; %m</pattern>
18
+ <date_method>#{datem}</date_method>
19
+ </formatter>
20
+ </outputter>
21
+ <outputter name="SE" type="StderrOutputter" level="Baz">
22
+ <formatter type="PatternFormatter" pattern="#{mypattern}">
23
+ <date_pattern>%H:%S</date_pattern>
24
+ </formatter>
25
+ </outputter>
26
+ <outputter name="F" type="FileOutputter">
27
+ <filename>#{logpath}/junk/foo.log</filename>
28
+ <trunc>true</trunc>
29
+ <only_at>Foo, Bar, Bing</only_at>
30
+ </outputter>
31
+ <!-- optional level, additive and outputters -->
32
+ <logger name="first::second" level="Bar" additive="false">
33
+ <trace>true</trace>
34
+ <outputters>SO, SE, F, stdout, stderr</outputters>
35
+ </logger>
36
+ </log4r_config>
37
+ </test>