revolutionhealth-log4r 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/LICENSE +20 -0
  2. data/README +37 -0
  3. data/Rakefile +62 -0
  4. data/TODO +4 -0
  5. data/config/log4r.xml +59 -0
  6. data/lib/log4r.rb +29 -0
  7. data/lib/log4r/base.rb +74 -0
  8. data/lib/log4r/config.rb +9 -0
  9. data/lib/log4r/configurator.rb +229 -0
  10. data/lib/log4r/formatter/formatter.rb +105 -0
  11. data/lib/log4r/formatter/patternformatter.rb +110 -0
  12. data/lib/log4r/lib/drbloader.rb +52 -0
  13. data/lib/log4r/lib/xmlloader.rb +24 -0
  14. data/lib/log4r/logevent.rb +28 -0
  15. data/lib/log4r/logger.rb +194 -0
  16. data/lib/log4r/loggerfactory.rb +89 -0
  17. data/lib/log4r/logserver.rb +28 -0
  18. data/lib/log4r/outputter/consoleoutputters.rb +18 -0
  19. data/lib/log4r/outputter/datefileoutputter.rb +110 -0
  20. data/lib/log4r/outputter/emailoutputter.rb +115 -0
  21. data/lib/log4r/outputter/fileoutputter.rb +49 -0
  22. data/lib/log4r/outputter/iooutputter.rb +55 -0
  23. data/lib/log4r/outputter/outputter.rb +132 -0
  24. data/lib/log4r/outputter/outputterfactory.rb +59 -0
  25. data/lib/log4r/outputter/remoteoutputter.rb +40 -0
  26. data/lib/log4r/outputter/rollingfileoutputter.rb +171 -0
  27. data/lib/log4r/outputter/staticoutputter.rb +30 -0
  28. data/lib/log4r/outputter/syslogoutputter.rb +122 -0
  29. data/lib/log4r/repository.rb +65 -0
  30. data/lib/log4r/staticlogger.rb +77 -0
  31. data/lib/log4r/yamlconfigurator.rb +0 -0
  32. data/lib/log4r_logging.rb +21 -0
  33. data/lib/rails_patch_for_migrations.rb +20 -0
  34. data/lib/test/log_sql_per_test.rb +43 -0
  35. data/log4r_original_LICENSE +47 -0
  36. data/test/log4r_test.rb +188 -0
  37. data/test/orig_tests/include.rb +7 -0
  38. data/test/orig_tests/runtest.rb +6 -0
  39. data/test/orig_tests/testbase.rb +45 -0
  40. data/test/orig_tests/testcustom.rb +33 -0
  41. data/test/orig_tests/testdefault.rb +25 -0
  42. data/test/orig_tests/testformatter.rb +29 -0
  43. data/test/orig_tests/testlogger.rb +198 -0
  44. data/test/orig_tests/testoutputter.rb +112 -0
  45. data/test/orig_tests/testpatternformatter.rb +26 -0
  46. data/test/orig_tests/testxmlconf.rb +51 -0
  47. data/test/orig_tests/xml/testconf.xml +37 -0
  48. data/test/test_helper.rb +11 -0
  49. metadata +110 -0
@@ -0,0 +1,132 @@
1
+ # :include: ../rdoc/outputter
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version:: $Id: outputter.rb,v 1.6 2003/09/12 23:55:43 fando Exp $
6
+ # Author:: Leon Torres <leon@ugcs.caltech.edu>
7
+
8
+ require "thread"
9
+
10
+ require "log4r/outputter/outputterfactory"
11
+ require "log4r/formatter/formatter"
12
+ require "log4r/staticlogger"
13
+
14
+ module Log4r
15
+
16
+ class Outputter
17
+ attr_reader :name, :level, :formatter
18
+ @@outputters = Hash.new
19
+
20
+ # An Outputter needs a name. RootLogger will be loaded if not already
21
+ # done. The hash arguments are as follows:
22
+ #
23
+ # [<tt>:level</tt>] Logger level. Optional, defaults to root level
24
+ # [<tt>:formatter</tt>] A Formatter. Defaults to DefaultFormatter
25
+
26
+ def initialize(_name, hash={})
27
+ if _name.nil?
28
+ raise ArgumentError, "Bad arguments. Name and IO expected.", caller
29
+ end
30
+ @name = _name
31
+ validate_hash(hash)
32
+ @@outputters[@name] = self
33
+ end
34
+
35
+ # dynamically change the level
36
+ def level=(_level)
37
+ Log4rTools.validate_level(_level)
38
+ @level = _level
39
+ OutputterFactory.create_methods(self)
40
+ Logger.log_internal {"Outputter '#{@name}' level is #{LNAMES[_level]}"}
41
+ end
42
+
43
+ # Set the levels to log. All others will be ignored
44
+ def only_at(*levels)
45
+ raise ArgumentError, "Gimme some levels!", caller if levels.empty?
46
+ raise ArgumentError, "Can't log only_at ALL", caller if levels.include? ALL
47
+ levels.each {|level| Log4rTools.validate_level(level)}
48
+ @level = levels.sort.first
49
+ OutputterFactory.create_methods self, levels
50
+ Logger.log_internal {
51
+ "Outputter '#{@name}' writes only on " +\
52
+ levels.collect{|l| LNAMES[l]}.join(", ")
53
+ }
54
+ end
55
+
56
+ # Dynamically change the formatter. You can just specify a Class
57
+ # object and the formatter will invoke +new+ or +instance+
58
+ # on it as appropriate.
59
+
60
+ def formatter=(_formatter)
61
+ if _formatter.kind_of?(Formatter)
62
+ @formatter = _formatter
63
+ elsif _formatter.kind_of?(Class) and _formatter <= Formatter
64
+ if _formatter.respond_to? :instance
65
+ @formatter = _formatter.instance
66
+ else
67
+ @formatter = _formatter.new
68
+ end
69
+ else
70
+ raise TypeError, "Argument was not a Formatter!", caller
71
+ end
72
+ Logger.log_internal {"Outputter '#{@name}' using #{@formatter.class}"}
73
+ end
74
+
75
+ # Call flush to force an outputter to write out any buffered
76
+ # log events. Similar to IO#flush, so use in a similar fashion.
77
+
78
+ def flush
79
+ end
80
+
81
+ #########
82
+ protected
83
+ #########
84
+
85
+ # Validates the common hash arguments. For now, that would be
86
+ # +:level+, +:formatter+ and the string equivalents
87
+ def validate_hash(hash)
88
+ @mutex = Mutex.new
89
+ # default to root level and DefaultFormatter
90
+ if hash.empty?
91
+ self.level = Logger.root.level
92
+ @formatter = DefaultFormatter.new
93
+ return
94
+ end
95
+ self.level = (hash[:level] or hash['level'] or Logger.root.level)
96
+ self.formatter = (hash[:formatter] or hash['formatter'] or DefaultFormatter.new)
97
+ end
98
+
99
+ #######
100
+ private
101
+ #######
102
+
103
+ # This method handles all log events passed to a typical Outputter.
104
+ # Overload this to change the overall behavior of an outputter. Make
105
+ # sure that the new behavior is thread safe.
106
+
107
+ def canonical_log(logevent)
108
+ synch { write(format(logevent)) }
109
+ end
110
+
111
+ # Common method to format data. All it does is call the resident
112
+ # formatter's format method. If a different formatting behavior is
113
+ # needed, then overload this method.
114
+
115
+ def format(logevent)
116
+ # @formatter is guaranteed to be DefaultFormatter if no Formatter
117
+ # was specified
118
+ @formatter.format(logevent)
119
+ end
120
+
121
+ # Abstract method to actually write the data to a destination.
122
+ # Custom outputters should overload this to specify how the
123
+ # formatted data should be written and to where.
124
+
125
+ def write(data)
126
+ end
127
+
128
+ def synch; @mutex.synchronize { yield } end
129
+
130
+ end
131
+
132
+ end
@@ -0,0 +1,59 @@
1
+ # :nodoc:
2
+ # Version: $Id: outputterfactory.rb,v 1.3 2002/01/28 16:05:05 cepheus Exp $
3
+
4
+ require "log4r/base"
5
+ require "log4r/repository"
6
+ require "log4r/logger"
7
+
8
+ module Log4r
9
+ class Outputter
10
+
11
+ class OutputterFactory #:nodoc:
12
+ include Singleton
13
+
14
+ # handles two cases: logging above a level (no second arg specified)
15
+ # or logging a set of levels (passed into the second argument)
16
+ def self.create_methods(out, levels=nil)
17
+ Logger.root # force levels to be loaded
18
+
19
+ # first, undefine all the log levels
20
+ for mname in LNAMES
21
+ undefine_log(mname.downcase, out)
22
+ end
23
+ if not levels.nil? and levels.include? OFF
24
+ raise TypeError, "Can't log only_at OFF", caller[1..-1]
25
+ end
26
+ return out if out.level == OFF
27
+
28
+ if levels.nil? # then define the log methods for lev >= outlev
29
+ for lev in out.level...LEVELS
30
+ define_log(LNAMES[lev].downcase, lev, out)
31
+ end
32
+ else # define the logs only for assigned levels
33
+ for lev in levels
34
+ define_log(LNAMES[lev].downcase, lev, out)
35
+ end
36
+ end
37
+ return out
38
+ end
39
+
40
+ # we need to synch the actual write/format for thread safteyness
41
+ def self.define_log(mname, level, out)
42
+ return if mname == 'off' || mname == 'all'
43
+ mstr = %-
44
+ def out.#{mname}(logevent)
45
+ canonical_log(logevent)
46
+ end
47
+ -
48
+ module_eval mstr
49
+ end
50
+
51
+ def self.undefine_log(mname, out)
52
+ return if mname == 'off' || mname == 'all'
53
+ mstr = "def out.#{mname}(logevent); end"
54
+ module_eval mstr
55
+ end
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,40 @@
1
+ # :nodoc:
2
+ require 'log4r/lib/drbloader'
3
+ require 'log4r/outputter/outputter'
4
+
5
+ module Log4r
6
+ # See log4r/logserver.rb
7
+ class RemoteOutputter < Outputter
8
+
9
+ def initialize(_name, hash={})
10
+ super(_name, hash)
11
+ @uri = (hash[:uri] or hash['uri'])
12
+ @buffsize = (hash[:buffsize] or hash['buffsize'] or 1).to_i
13
+ @buff = []
14
+ connect
15
+ end
16
+
17
+ if HAVE_ROMP
18
+ include ROMPClient
19
+ else
20
+ def initialize(*args)
21
+ raise RuntimeError, "LogServer not supported. ROMP is required", caller
22
+ end
23
+ end
24
+
25
+
26
+ # Call flush to send any remaining LogEvents to the remote server.
27
+ def flush
28
+ synch { send_buffer }
29
+ end
30
+
31
+ private
32
+
33
+ def canonical_log(logevent)
34
+ synch {
35
+ @buff.push logevent
36
+ send_buffer if @buff.size >= @buffsize
37
+ }
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,171 @@
1
+
2
+ # :nodoc:
3
+ # Version:: $Id: rollingfileoutputter.rb,v 1.4 2003/09/12 23:55:43 fando Exp $
4
+
5
+ require "log4r/outputter/fileoutputter"
6
+ require "log4r/staticlogger"
7
+
8
+ module Log4r
9
+
10
+ # RollingFileOutputter - subclass of FileOutputter that rolls files on size
11
+ # or time. Additional hash arguments are:
12
+ #
13
+ # [<tt>:maxsize</tt>] Maximum size of the file in bytes.
14
+ # [<tt>:trunc</tt>] Maximum age of the file in seconds.
15
+ class RollingFileOutputter < FileOutputter
16
+
17
+ attr_reader :count, :maxsize, :maxtime, :startTime, :maxBackupIndex #,i:baseFilename
18
+
19
+ def initialize(_name, hash={})
20
+ @count = 0
21
+ @max_backup_index = 10
22
+ super(_name, hash)
23
+ set_maxsize(hash)
24
+ if hash.has_key?(:maxtime) || hash.has_key?('maxtime')
25
+ _maxtime = (hash[:maxtime] or hash['maxtime']).to_i
26
+ if _maxtime.class != Fixnum
27
+ raise TypeError, "Argument 'maxtime' must be an Fixnum", caller
28
+ end
29
+ if _maxtime == 0
30
+ raise TypeError, "Argument 'maxtime' must be > 0", caller
31
+ end
32
+ @maxtime = _maxtime
33
+ @startTime = Time.now
34
+ end
35
+ if hash.has_key?(:maxBackupIndex) || hash.has_key?('maxBackupIndex')
36
+ _max_backup_index = (hash[:maxBackupIndex] or hash['maxBackupIndex']).to_i
37
+ if _max_backup_index.class != Fixnum
38
+ raise TypeError, "Argument 'maxsize' must be an Fixnum", caller
39
+ end
40
+ if _max_backup_index == 0
41
+ raise TypeError, "Argument 'maxsize' must be > 0", caller
42
+ end
43
+ @max_backup_index = _max_backup_index
44
+ end
45
+ @baseFilename = File.basename(@filename)
46
+ # roll immediately so all files are of the form "000001-@baseFilename"
47
+ roll if file_size_requires_roll?
48
+ # initialize the file size counter
49
+ @datasize = 0
50
+ end
51
+
52
+ #######
53
+ private
54
+ #######
55
+
56
+ def set_maxsize(options)
57
+ if options.has_key?(:maxsize) || options.has_key?('maxsize')
58
+ maxsize = (options[:maxsize] or options['maxsize'])
59
+
60
+ multiplier = 1
61
+ if (maxsize =~ /\d+KB/)
62
+ multiplier = 1024
63
+ elsif (maxsize =~ /\d+MB/)
64
+ multiplier = 1024 * 1024
65
+ elsif (maxsize =~ /\d+GB/)
66
+ multiplier = 1024 * 1024 * 1024
67
+ end
68
+
69
+ _maxsize = maxsize.to_i * multiplier
70
+
71
+ if _maxsize.class != Fixnum and _maxsize.class != Bignum
72
+ raise TypeError, "Argument 'maxsize' must be an Fixnum", caller
73
+ end
74
+ if _maxsize == 0
75
+ raise TypeError, "Argument 'maxsize' must be > 0", caller
76
+ end
77
+ @maxsize = _maxsize
78
+ end
79
+ end
80
+
81
+ # perform the write
82
+ def write(data)
83
+ # we have to keep track of the file size ourselves - File.size doesn't
84
+ # seem to report the correct size when the size changes rapidly
85
+ @datasize += data.size + 1 # the 1 is for newline
86
+ super
87
+ roll if requiresRoll
88
+ end
89
+
90
+ # construct a new filename from the count and baseFilname
91
+ def makeNewFilename
92
+ # note use of hard coded 6 digit counter width - is this enough files?
93
+ pad = "0" * (6 - @count.to_s.length) + count.to_s
94
+ newbase = @baseFilename.sub(/(\.\w*)$/, pad + '\1')
95
+ @filename = File.join(File.dirname(@filename), newbase)
96
+ Logger.log_internal {"File #{@filename} created"}
97
+ end
98
+
99
+ # does the file require a roll?
100
+ def requiresRoll
101
+ if !@maxsize.nil? && @datasize > @maxsize
102
+ @datasize = 0
103
+ return true
104
+ end
105
+ if !@maxtime.nil? && (Time.now - @startTime) > @maxtime
106
+ @startTime = Time.now
107
+ return true
108
+ end
109
+ false
110
+ end
111
+
112
+ def indexed_filename(index)
113
+ @filename + ".#{index}"
114
+ end
115
+
116
+ # more expensive, only for startup
117
+ def file_size_requires_roll?
118
+ (@maxsize.to_i > 0 and (File.size?(@filename).to_i >= @maxsize.to_i))
119
+ end
120
+
121
+ # roll the file
122
+ def roll
123
+ begin
124
+ @out.close
125
+ rescue
126
+ Logger.log_internal {
127
+ "RollingFileOutputter '#{@name}' could not close #{@filename}"
128
+ }
129
+ end
130
+ @count += 1
131
+
132
+ @max_backup_index.times do |x|
133
+ index = @max_backup_index - x - 1
134
+ if File.exists?(indexed_filename(index)) and index != 0
135
+ FileUtils.mv(indexed_filename(index), indexed_filename(index + 1))
136
+ elsif index == 0 and File.exists?(@filename)
137
+ FileUtils.mv(@filename, indexed_filename(index + 1))
138
+ end
139
+ end
140
+
141
+ @out = File.new(@filename, (@trunc ? "w" : "a"))
142
+ end
143
+
144
+ end
145
+
146
+ end
147
+
148
+ # this can be found in examples/fileroll.rb as well
149
+ if __FILE__ == $0
150
+ require 'log4r'
151
+ include Log4r
152
+
153
+
154
+ timeLog = Logger.new 'WbExplorer'
155
+ timeLog.outputters = RollingFileOutputter.new("WbExplorer", { "filename" => "TestTime.log", "maxtime" => 10, "trunc" => true })
156
+ timeLog.level = DEBUG
157
+
158
+ 100.times { |t|
159
+ timeLog.info "blah #{t}"
160
+ sleep(1.0)
161
+ }
162
+
163
+ sizeLog = Logger.new 'WbExplorer'
164
+ sizeLog.outputters = RollingFileOutputter.new("WbExplorer", { "filename" => "TestSize.log", "maxsize" => 16000, "trunc" => true })
165
+ sizeLog.level = DEBUG
166
+
167
+ 10000.times { |t|
168
+ sizeLog.info "blah #{t}"
169
+ }
170
+
171
+ end
@@ -0,0 +1,30 @@
1
+ # :nodoc:
2
+ module Log4r
3
+
4
+ class Outputter
5
+ # Retrieve an outputter.
6
+ def self.[](name)
7
+ out = @@outputters[name]
8
+ if out.nil?
9
+ return case name
10
+ when 'stdout' then StdoutOutputter.new 'stdout'
11
+ when 'stderr' then StderrOutputter.new 'stderr'
12
+ else nil end
13
+ end
14
+ out
15
+ end
16
+ def self.stdout; Outputter['stdout'] end
17
+ def self.stderr; Outputter['stderr'] end
18
+ # Set an outputter.
19
+ def self.[]=(name, outputter)
20
+ @@outputters[name] = outputter
21
+ end
22
+ # Yields each outputter's name and reference.
23
+ def self.each
24
+ @@outputters.each {|name, outputter| yield name, outputter}
25
+ end
26
+ def self.each_outputter
27
+ @@outputters.each_value {|outputter| yield outputter}
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,122 @@
1
+ # :include: ../rdoc/syslogoutputter
2
+ #
3
+ # Version:: $Id: syslogoutputter.rb,v 1.5 2004/03/17 20:18:00 fando Exp $
4
+ # Author:: Steve Lumos
5
+ # Author:: Leon Torres
6
+
7
+ begin
8
+ require 'syslog'
9
+
10
+ module Log4r
11
+
12
+ class SyslogOutputter < Outputter
13
+ include Syslog::Constants
14
+
15
+ # This is the mapping of syslog levels to integers
16
+ #(7 = debug, 6 = info, 5 = notice, 4 = warning, 3 = err, 2 = crit, 1 = alert, 0 = emerg, x = nothing)
17
+
18
+ SYSLOG_LOGGER_MAP = {
19
+ 0 => LOG_DEBUG,
20
+ 1 => LOG_DEBUG,
21
+ 2 => LOG_INFO,
22
+ 3 => LOG_WARNING,
23
+ 4 => LOG_ERR,
24
+ 5 => LOG_CRIT,
25
+ 6 => LOG_CRIT
26
+ }
27
+
28
+ # There are 3 hash arguments
29
+ #
30
+ # [<tt>:ident</tt>] syslog ident, defaults to _name
31
+ # [<tt>:logopt</tt>] syslog logopt, defaults to LOG_PID | LOG_CONS
32
+ # [<tt>:facility</tt>] syslog facility, defaults to LOG_USER
33
+ def initialize(_name, hash={})
34
+ super(_name, hash)
35
+ ident = (hash[:ident] or _name)
36
+ logopt = (hash[:logopt] or LOG_PID | LOG_CONS).to_i
37
+ facility = Syslog::Constants.const_get(hash[:facility]) if hash[:facility] != nil and Syslog::Constants.const_defined?(hash[:facility])
38
+ facility ||= Syslog::LOG_LOCAL0
39
+ @syslog = Syslog.open(ident, logopt, facility)
40
+ end
41
+
42
+ def closed?
43
+ return !@syslog.opened?
44
+ end
45
+
46
+ def close
47
+ @syslog.close unless @syslog.nil?
48
+ @level = OFF
49
+ OutputterFactory.create_methods(self)
50
+ Logger.log_internal {"Outputter '#{@name}' closed Syslog and set to OFF"}
51
+ end
52
+
53
+ private
54
+
55
+ def canonical_log(logevent)
56
+ pri = SYSLOG_LOGGER_MAP[logevent.level]
57
+ o = logevent.data
58
+ msg = format(logevent)
59
+ @syslog.log(pri, '%s', msg)
60
+ end
61
+ end
62
+ end
63
+
64
+ rescue Exception => detail
65
+ module Log4r
66
+ class SyslogOutputter < Outputter
67
+ def initialize(_name, hash={})
68
+ super(_name, hash)
69
+ end
70
+
71
+ ##########
72
+ # constants from syslog.c, just bogus values for windows
73
+ LOG_PID = 0
74
+ LOG_CONS = 1
75
+ LOG_ODELAY = 2
76
+ LOG_NDELAY = 3
77
+ LOG_NOWAIT = 4
78
+ LOG_PERROR = 5
79
+ LOG_AUTH = 6
80
+ LOG_AUTHPRIV = 7
81
+ LOG_CONSOLE = 8
82
+ LOG_CRON = 9
83
+ LOG_DAEMON = 10
84
+ LOG_FTP = 11
85
+ LOG_KERN = 12
86
+ LOG_LPR = 13
87
+ LOG_MAIL = 14
88
+ LOG_NEWS = 15
89
+ LOG_NTP = 16
90
+ LOG_SECURITY = 17
91
+ LOG_SYSLOG = 18
92
+ LOG_USER = 19
93
+ LOG_UUCP = 20
94
+ LOG_LOCAL0 = 21
95
+ LOG_LOCAL1 = 22
96
+ LOG_LOCAL2 = 23
97
+ LOG_LOCAL3 = 24
98
+ LOG_LOCAL4 = 25
99
+ LOG_LOCAL5 = 26
100
+ LOG_LOCAL6 = 27
101
+ LOG_LOCAL7 = 28
102
+ LOG_EMERG = 29
103
+ LOG_ALERT = 30
104
+ LOG_CRIT = 31
105
+ LOG_ERR = 32
106
+ LOG_WARNING = 33
107
+ LOG_NOTICE = 34
108
+ LOG_INFO = 35
109
+ LOG_DEBUG = 36
110
+
111
+
112
+ def closed?
113
+ @level == OFF
114
+ end
115
+
116
+ def close
117
+ @level = OFF
118
+ OutputterFactory.create_methods(self)
119
+ end
120
+ end
121
+ end
122
+ end