log4rails 1.1.11

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 (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,28 @@
1
+ # :nodoc:
2
+ module Log4r
3
+
4
+ ##
5
+ # LogEvent wraps up all the miscellaneous data associated with a logging
6
+ # statement. It gets passed around to the varied components of Log4r and
7
+ # should be of interest to those creating extensions.
8
+ #
9
+ # Data contained:
10
+ #
11
+ # [level] The integer level of the log event. Use LNAMES[level]
12
+ # to get the actual level name.
13
+ # [tracer] The execution stack returned by <tt>caller</tt> at the
14
+ # log event. It is nil if the invoked Logger's trace is false.
15
+ # [data] The object that was passed into the logging method.
16
+ # [name] The name of the logger that was invoked.
17
+ # [fullname] The fully qualified name of the logger that was invoked.
18
+ #
19
+ # Note that creating timestamps is a task left to formatters.
20
+
21
+ class LogEvent
22
+ attr_reader :level, :tracer, :data, :name, :fullname
23
+ def initialize(level, logger, tracer, data)
24
+ @level, @tracer, @data = level, tracer, data
25
+ @name, @fullname = logger.name, logger.fullname
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,206 @@
1
+ # :include: rdoc/logger
2
+ #
3
+ # == Other Info
4
+ #
5
+ # Version:: $Id$
6
+ # Author:: Leon Torres <leon(at)ugcs.caltech.edu>
7
+
8
+ require "log4r/outputter/outputter"
9
+ require "log4r/repository"
10
+ require "log4r/loggerfactory"
11
+ require "log4r/staticlogger"
12
+
13
+ module Log4r
14
+
15
+ # See log4r/logger.rb
16
+ class Logger
17
+ attr_reader :name, :fullname, :path, :level, :parent
18
+ attr_reader :additive, :trace, :outputters
19
+
20
+ # Logger requires a name. The last 3 parameters are:
21
+ #
22
+ # level:: Do I have a level? (Otherwise, I'll inherit my parent's)
23
+ # additive:: Am I additive?
24
+ # trace:: Do I record the execution trace? (slows things a wee bit)
25
+
26
+ def initialize(_fullname, _level=nil, _additive=true, _trace=false)
27
+ # validation
28
+ raise ArgumentError, "Logger must have a name", caller if _fullname.nil?
29
+ Log4rTools.validate_level(_level) unless _level.nil?
30
+ validate_name(_fullname)
31
+
32
+ # create the logger
33
+ @fullname = _fullname
34
+ @outputters = []
35
+ @additive = _additive
36
+ deal_with_inheritance(_level)
37
+ LoggerFactory.define_methods(self)
38
+ self.trace = _trace
39
+ Repository[@fullname] = self
40
+ end
41
+
42
+ def validate_name(_fullname)
43
+ parts = _fullname.split Log4rConfig::LoggerPathDelimiter
44
+ for part in parts
45
+ raise ArgumentError, "Malformed path", caller[1..-1] if part.empty?
46
+ end
47
+ end
48
+ private :validate_name
49
+
50
+ # Parses name for location in heiarchy, sets the parent, and
51
+ # deals with level inheritance
52
+
53
+ def deal_with_inheritance(_level)
54
+ mypath = @fullname.split Log4rConfig::LoggerPathDelimiter
55
+ @name = mypath.pop
56
+ if mypath.empty? # then root is my daddy
57
+ @path = ""
58
+ # This is one of the guarantees that RootLogger gets created
59
+ @parent = Logger.root
60
+ else
61
+ @path = mypath.join(Log4rConfig::LoggerPathDelimiter)
62
+ @parent = Repository.find_ancestor(@path)
63
+ @parent = Logger.root if @parent.nil?
64
+ end
65
+ # inherit the level if no level defined
66
+ if _level.nil? then @level = @parent.level
67
+ else @level = _level end
68
+ Repository.reassign_any_children(self)
69
+ end
70
+ private :deal_with_inheritance
71
+
72
+ # Set the logger level dynamically. Does not affect children.
73
+ def level=(_level)
74
+ Log4rTools.validate_level(_level)
75
+ @level = _level
76
+ LoggerFactory.define_methods(self)
77
+ Logger.log_internal {"Logger '#{@fullname}' set to #{LNAMES[@level]}"}
78
+ @level
79
+ end
80
+
81
+ # Return array of defined levels.
82
+ def levels
83
+ LNAMES
84
+ end
85
+
86
+ # Set the additivity of the logger dynamically. True or false.
87
+ def additive=(_additive)
88
+ @additive = _additive
89
+ LoggerFactory.define_methods(self)
90
+ Logger.log_internal {"Logger '#{@fullname}' is additive"}
91
+ @additive
92
+ end
93
+
94
+ # Set whether the logger traces. Can be set dynamically. Defaults
95
+ # to false and understands the strings 'true' and 'false'.
96
+ def trace=(_trace)
97
+ @trace =
98
+ case _trace
99
+ when "true", true then true
100
+ else false end
101
+ LoggerFactory.define_methods(self)
102
+ Logger.log_internal {"Logger '#{@fullname}' is tracing"} if @trace
103
+ @trace
104
+ end
105
+
106
+ # Please don't reset the parent
107
+ def parent=(parent)
108
+ @parent = parent
109
+ end
110
+
111
+ # Set the Outputters dynamically by name or reference. Can be done any
112
+ # time.
113
+ def outputters=(_outputters)
114
+ @outputters.clear
115
+ add(*_outputters)
116
+ end
117
+
118
+ # Add outputters by name or by reference. Can be done any time.
119
+ def add(*_outputters)
120
+ for thing in _outputters
121
+ o = (thing.kind_of?(Outputter) ? thing : Outputter[thing])
122
+ # some basic validation
123
+ if not o.kind_of?(Outputter)
124
+ raise TypeError, "Expected kind of Outputter, got #{o.class}", caller
125
+ elsif o.nil?
126
+ raise TypeError, "Couldn't find Outputter '#{thing}'", caller
127
+ end
128
+ @outputters.push o
129
+ Logger.log_internal {"Added outputter '#{o.name}' to '#{@fullname}'"}
130
+ end
131
+ @outputters
132
+ end
133
+
134
+ # Remove outputters from this logger by name only. Can be done any time.
135
+ def remove(*_outputters)
136
+ for name in _outputters
137
+ o = Outputter[name]
138
+ @outputters.delete o
139
+ Logger.log_internal {"Removed outputter '#{o.name}' from '#{@fullname}'"}
140
+ end
141
+ end
142
+
143
+ def is_root?; false end
144
+
145
+ def ==(other)
146
+ return true if self.object_id == other.object_id
147
+ end
148
+
149
+ # fix for rails 4+
150
+ # <tk>
151
+ def formatter
152
+ nil
153
+ end
154
+ # </tk>
155
+ end
156
+
157
+
158
+ # RootLogger should be retrieved with Logger.root or Logger.global.
159
+ # It's supposed to be transparent.
160
+ #--
161
+ # We must guarantee the creation of RootLogger before any other Logger
162
+ # or Outputter gets their logging methods defined. There are two
163
+ # guarantees in the code:
164
+ #
165
+ # * Logger#deal_with_inheritance - calls RootLogger.instance when
166
+ # a new Logger is created without a parent. Parents must exist, therefore
167
+ # RootLogger is forced to be created.
168
+ #
169
+ # * OutputterFactory.create_methods - Calls Logger.root first. So if
170
+ # an Outputter is created, RootLogger is also created.
171
+ #
172
+ # When RootLogger is created, it calls
173
+ # Log4r.define_levels(*Log4rConfig::LogLevels). This ensures that the
174
+ # default levels are loaded if no custom ones are.
175
+
176
+ class RootLogger < Logger
177
+ include Singleton
178
+
179
+ def initialize
180
+ Log4r.define_levels(*Log4rConfig::LogLevels) # ensure levels are loaded
181
+ @level = ALL
182
+ @outputters = []
183
+ Repository['root'] = self
184
+ Repository['global'] = self
185
+ LoggerFactory.undefine_methods(self)
186
+ end
187
+
188
+ def is_root?; true end
189
+
190
+ # Set the global level. Any loggers defined thereafter will
191
+ # not log below the global level regardless of their levels.
192
+
193
+ def level=(alevel); @level = alevel end
194
+
195
+ # Does nothing
196
+ def outputters=(foo); end
197
+ # Does nothing
198
+ def trace=(foo); end
199
+ # Does nothing
200
+ def additive=(foo); end
201
+ # Does nothing
202
+ def add(*foo); end
203
+ # Does nothing
204
+ def remove(*foo); end
205
+ end
206
+ end
@@ -0,0 +1,89 @@
1
+ # :nodoc:
2
+ # Version:: $Id$
3
+
4
+ require "log4r/base"
5
+ require "log4r/repository"
6
+ require 'log4r/logevent'
7
+
8
+ module Log4r
9
+ class Logger
10
+ class LoggerFactory #:nodoc:
11
+
12
+ # we want to log iff root.lev <= lev && logger.lev <= lev
13
+ # BTW, root is guaranteed to be defined by this point
14
+ def self.define_methods(logger)
15
+ return if logger.is_root?
16
+ undefine_methods(logger)
17
+ globlev = Repository['root'].level
18
+ return if logger.level == OFF or globlev == OFF
19
+ toggle_methods(globlev, logger)
20
+ end
21
+
22
+ # set logging methods to null defaults
23
+ def self.undefine_methods(logger)
24
+ for lname in LNAMES
25
+ next if lname == 'OFF'|| lname == 'ALL'
26
+ unset_log(logger, lname)
27
+ set_false(logger, lname)
28
+ end
29
+ set_false(logger, 'all')
30
+ set_true(logger, 'off')
31
+ end
32
+
33
+ # toggle methods >= globlev that are also >= level
34
+ def self.toggle_methods(globlev, logger)
35
+ for lev in globlev...LEVELS # satisfies >= globlev
36
+ next if lev < logger.level # satisfies >= level
37
+ next if LNAMES[lev] == 'OFF'
38
+ next if LNAMES[lev] == 'ALL'
39
+ set_log(logger, LNAMES[lev])
40
+ set_true(logger, LNAMES[lev])
41
+ end
42
+ if logger.level == ALL
43
+ set_true(logger, 'all')
44
+ end
45
+ if logger.level != OFF && globlev != OFF
46
+ set_false(logger, 'off')
47
+ end
48
+ end
49
+
50
+ # And now, the weird dynamic method definitions! :)
51
+
52
+ def self.unset_log(logger, lname)
53
+ mstr="def logger.#{lname.downcase}(data=nil, propagated=false); end"
54
+ module_eval mstr
55
+ end
56
+
57
+ # Logger logging methods are defined here.
58
+ def self.set_log(logger, lname)
59
+ # invoke caller iff the logger invoked is tracing
60
+ tracercall = (logger.trace ? "caller" : "nil")
61
+ # maybe pass parent a logevent. second arg is the switch
62
+ if logger.additive && !logger.parent.is_root?
63
+ parentcall = "@parent.#{lname.downcase}(event, true)"
64
+ end
65
+ mstr = %-
66
+ def logger.#{lname.downcase}(data=nil, propagated=false)
67
+ if propagated then event = data
68
+ else
69
+ data = yield if block_given?
70
+ event = LogEvent.new(#{lname}, self, #{tracercall}, data)
71
+ end
72
+ @outputters.each {|o| o.#{lname.downcase}(event) }
73
+ #{parentcall}
74
+ end
75
+ -
76
+ module_eval mstr
77
+ end
78
+
79
+ def self.set_false(logger, lname)
80
+ module_eval "def logger.#{lname.downcase}?; false end"
81
+ end
82
+
83
+ def self.set_true(logger, lname)
84
+ module_eval "def logger.#{lname.downcase}?; true end"
85
+ end
86
+
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,28 @@
1
+ # :include: rdoc/logserver
2
+
3
+ require 'log4r/logger'
4
+ require 'log4r/lib/drbloader'
5
+
6
+ module Log4r
7
+ # See log4r/logserver.rb
8
+ class LogServer < Logger
9
+ attr_reader :uri
10
+
11
+ # A valid ROMP uri must be specified.
12
+ def initialize(_fullname, _uri, _level=nil,
13
+ _additive=true, _trace=false, &accept)
14
+ super(_fullname, _level, _additive, _trace)
15
+ @uri = _uri
16
+ start_server(_uri, accept)
17
+ Logger.log_internal {"LogServer started at #{@uri}"}
18
+ end
19
+
20
+ if HAVE_ROMP
21
+ include ROMPServer
22
+ else
23
+ def initialize(*args)
24
+ raise RuntimeError, "LogServer not supported. ROMP is required", caller
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,47 @@
1
+ require 'log4r/outputter/syslogoutputter'
2
+
3
+ module Log4r
4
+ class BufferedSyslogOutputter < SyslogOutputter
5
+
6
+ def initialize(*args)
7
+ super
8
+ @buff = {}
9
+ end
10
+
11
+ def flush
12
+ synch do
13
+ begin
14
+ @buff.each do |pri, message|
15
+ Syslog.open(@ident, @logopt, @facility) do |s|
16
+ s.log(pri, '%s', message.join("\t"))
17
+ end
18
+ end
19
+ ensure
20
+ @buff.clear
21
+ end
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def canonical_log(logevent)
28
+ begin
29
+ pri = SYSLOG_LEVELS_MAP[@levels_map[LNAMES[logevent.level]]]
30
+ rescue
31
+ pri = LOG_INFO
32
+ end
33
+
34
+ return if logevent.data.empty?
35
+
36
+ o = format(logevent)
37
+ msg = if o.is_a? Exception
38
+ "#{o.class} at (#{o.backtrace[0]}): #{o.message}"
39
+ elsif o.respond_to?(:to_str)
40
+ o.to_str
41
+ else
42
+ o.inspect
43
+ end
44
+ synch { @buff.has_key?(pri) ? @buff[pri].push(msg) : @buff[pri] = [msg] }
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,18 @@
1
+ # :nodoc:
2
+ require "log4r/outputter/iooutputter"
3
+
4
+ module Log4r
5
+ # Same as IOOutputter(name, $stdout)
6
+ class StdoutOutputter < IOOutputter
7
+ def initialize(_name, hash={})
8
+ super(_name, $stdout, hash)
9
+ end
10
+ end
11
+
12
+ # Same as IOOutputter(name, $stderr)
13
+ class StderrOutputter < IOOutputter
14
+ def initialize(_name, hash={})
15
+ super(_name, $stderr, hash)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,117 @@
1
+ # = DateFileOutputter
2
+ #
3
+ # Subclass of FileOutputter that changes the log file daily. When a new
4
+ # day begins, a new file is created with the date included in the name.
5
+ #
6
+ # == Usage
7
+ #
8
+ # df_out = DateFileOutputter.new('name',
9
+ # :dirname="/tmp", :date_pattern=>"%m-%d"
10
+ # )
11
+ #
12
+ # == Rate of Change
13
+ #
14
+ # A new logfile is created whenever the current time as formatted by the date
15
+ # pattern no longer matches the previous time. (This is a simple String
16
+ # comparison.) So, in order to change the frequency of the rollover, just
17
+ # alter the date pattern to match how fast the files should be generated.
18
+ # For instance, to generate files by the minute,
19
+ #
20
+ # df_out.date_pattern = "%M"
21
+ #
22
+ # This causes the following files to show up one minute apart, asuming the
23
+ # script starts at the 4th minute of the hour:
24
+ #
25
+ # file_04.rb
26
+ # file_05.rb
27
+ # file_06.rb
28
+ # ...
29
+ #
30
+ # The only limitation of this approach is that the precise time cannot be
31
+ # recorded as the smallest time interval equals the rollover period for this
32
+ # system.
33
+
34
+ require "log4r/outputter/fileoutputter"
35
+ require "log4r/staticlogger"
36
+
37
+ module Log4r
38
+
39
+ # Additional hash arguments are:
40
+ #
41
+ # [<tt>:dirname</tt>] Directory of the log file
42
+ # [<tt>:date_pattern</tt>] Time.strftime format string (default is "%Y-%m-%d")
43
+
44
+ class DateFileOutputter < FileOutputter
45
+ DEFAULT_DATE_FMT = "%Y-%m-%d"
46
+
47
+ def initialize(_name, hash={})
48
+ @DatePattern = (hash[:date_pattern] or hash['date_pattern'] or
49
+ DEFAULT_DATE_FMT)
50
+ @DateStamp = Time.now.strftime( @DatePattern);
51
+ _dirname = (hash[:dirname] or hash['dirname'])
52
+ # hash[:dirname] masks hash[:filename]
53
+ if _dirname
54
+ if not FileTest.directory?( _dirname)
55
+ raise StandardError, "'#{_dirname}' must be a valid directory", caller
56
+ end
57
+ end
58
+
59
+ _filename = (hash[:filename] or hash['filename'])
60
+ if _filename.nil?
61
+ @filebase = File.basename( $0, '.rb') + ".log"
62
+ else
63
+ @filebase = File.basename((hash[:filename] or hash['filename'] or ""))
64
+ end
65
+
66
+ # Get rid of the 'nil' in the path
67
+ path = [_dirname, @filebase.sub(/(\.\w*)$/, "_#{@DateStamp}" + '\1')].compact
68
+ hash[:filename] = hash['filename'] = File.join(path)
69
+
70
+ super(_name, hash)
71
+ end
72
+
73
+ #######
74
+ private
75
+ #######
76
+
77
+ # perform the write
78
+ def write(data)
79
+ change if requiresChange
80
+ super
81
+ end
82
+
83
+ # construct a new filename from the DateStamp
84
+ def makeNewFilename
85
+ @DateStamp = Time.now.strftime( @DatePattern);
86
+ @filename = File.join(File.dirname(@filename),
87
+ @filebase.sub(/(\.\w*)$/, "_#{@DateStamp}" + '\1'))
88
+ end
89
+
90
+ # does the file require a change?
91
+ def requiresChange
92
+ _DateStamp = Time.now.strftime( @DatePattern);
93
+ if not _DateStamp == @DateStamp
94
+ @DateStamp = _DateStamp
95
+ return true
96
+ end
97
+ false
98
+ end
99
+
100
+ # change the file
101
+ def change
102
+ begin
103
+ @out.close
104
+ rescue
105
+ Logger.log_internal {
106
+ "DateFileOutputter '#{@name}' could not close #{@filename}"
107
+ }
108
+ end
109
+ makeNewFilename
110
+ @out = File.new(@filename, (@trunc ? "wb" : "ab"))
111
+ Logger.log_internal {
112
+ "DateFileOutputter '#{@name}' now writing to #{@filename}"
113
+ }
114
+ end
115
+ end
116
+
117
+ end