path-log4r 1.1.10

Sign up to get free protection for your applications and to get access to all the features.
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>