logging 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +1,21 @@
1
+ == 0.6.3 / 2008-02-08
2
+
3
+ 2 minor enhancements
4
+ - YAML configuration now supports multiple keys -- i.e. development
5
+ or production or whatever
6
+ - Reorganized a lot of files so that requiring files is cleaner and
7
+ more deterministic
8
+
1
9
  == 0.6.2 / 2008-02-06
2
10
 
3
- 2 bugfixes
11
+ 2 bug fixes
4
12
  - An extra e-mail was being pushed out when the e-mail
5
13
  appender was closed
6
14
  - Created an at_exit handler to close all appenders
7
15
 
8
16
  == 0.6.1 / 2008-01-01
9
17
 
10
- 1 bugfix
18
+ 1 bug fix
11
19
  - Fixed include order to avoid double loading when testing
12
20
 
13
21
  == 0.6.0 / 2007-12-26
@@ -40,8 +48,8 @@
40
48
 
41
49
  * Added a microsecond flag to the Pattern layout
42
50
  * All appenders write immediately upon receipt of a logging event
43
- * Added a basic logging method tha returns a logger object configured in the
44
- same manner as the standard Ruby logger
51
+ * Added a basic logging method that returns a logger object configured in
52
+ the same manner as the standard Ruby logger
45
53
  * Fixed a bug caused by nil log messages
46
54
 
47
55
  == 0.3.1 / 2007-02-08
@@ -55,7 +63,7 @@
55
63
  == 0.2.0 / 2007-01-29
56
64
 
57
65
  * The "once every four years" release
58
- * Storage and retrieveal of appenders by name
66
+ * Storage and retrieval of appenders by name
59
67
  * YAML configuration support
60
68
  * Rolling file appender
61
69
 
@@ -11,7 +11,6 @@ lib/logging/appenders/file.rb
11
11
  lib/logging/appenders/growl.rb
12
12
  lib/logging/appenders/io.rb
13
13
  lib/logging/appenders/rolling_file.rb
14
- lib/logging/appenders/static_appender.rb
15
14
  lib/logging/appenders/syslog.rb
16
15
  lib/logging/config/yaml_configurator.rb
17
16
  lib/logging/layout.rb
@@ -1,39 +1,23 @@
1
- # $Id: logging.rb 85 2008-02-06 17:59:00Z tim_pease $
2
-
3
- require 'logging/utils'
4
- require 'logging/log_event'
5
- require 'logging/logger'
6
- require 'logging/root_logger'
7
- require 'logging/repository'
8
- require 'logging/appender'
9
- require 'logging/layout'
10
-
11
- # require all appenders
12
- require 'logging/appenders/static_appender'
13
- require 'logging/appenders/io'
14
- require 'logging/appenders/console'
15
- require 'logging/appenders/email'
16
- require 'logging/appenders/file'
17
- require 'logging/appenders/growl'
18
- require 'logging/appenders/rolling_file'
19
- require 'logging/appenders/syslog'
20
-
21
- # require all layouts
22
- require 'logging/layouts/basic'
23
- require 'logging/layouts/pattern'
24
-
25
- # require all configurators
26
- require 'logging/config/yaml_configurator'
1
+ # $Id: logging.rb 90 2008-02-08 19:03:48Z tim_pease $
27
2
 
3
+ # Equivalent to a header guard in C/C++
4
+ # Used to prevent the class/module from being loaded more than once
5
+ unless defined? Logging
6
+
7
+ # TODO: internal logger for debugging
8
+ # TODO: Windows Log Service appender
28
9
 
29
10
  #
30
11
  #
31
12
  module Logging
32
13
 
33
- VERSION = '0.6.2' # :nodoc:
34
-
35
- LEVELS = {} # :nodoc:
36
- LNAMES = {} # :nodoc:
14
+ # :stopdoc:
15
+ VERSION = '0.6.3'
16
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
17
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
18
+ LEVELS = {}
19
+ LNAMES = {}
20
+ # :startdoc:
37
21
 
38
22
  class << self
39
23
 
@@ -44,10 +28,10 @@ module Logging
44
28
  # found in the given file. The file extension should be either '.yaml'
45
29
  # or '.yml' (XML configuration is not yet supported).
46
30
  #
47
- def configure( filename )
31
+ def configure( filename, *args )
48
32
  case File.extname(filename)
49
33
  when '.yaml', '.yml'
50
- ::Logging::Config::YamlConfigurator.load(filename)
34
+ ::Logging::Config::YamlConfigurator.load(filename, *args)
51
35
  else raise ArgumentError, 'unknown configuration file format' end
52
36
  end
53
37
 
@@ -232,8 +216,42 @@ module Logging
232
216
  module_eval "OBJ_FORMAT = :#{f}"
233
217
  end
234
218
 
235
- # :stopdoc:
219
+ # Returns the version string for the library.
220
+ #
221
+ def version
222
+ VERSION
223
+ end
236
224
 
225
+ # Returns the library path for the module. If any arguments are given,
226
+ # they will be joined to the end of the libray path using
227
+ # <tt>File.join</tt>.
228
+ #
229
+ def libpath( *args )
230
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, *args)
231
+ end
232
+
233
+ # Returns the lpath for the module. If any arguments are given,
234
+ # they will be joined to the end of the path using
235
+ # <tt>File.join</tt>.
236
+ #
237
+ def path( *args )
238
+ args.empty? ? PATH : ::File.join(PATH, *args)
239
+ end
240
+
241
+ # Utility method used to rquire all files ending in .rb that lie in the
242
+ # directory below this file that has the same name as the filename passed
243
+ # in. Optionally, a specific _directory_ name can be passed in such that
244
+ # the _filename_ does not have to be equivalent to the directory.
245
+ #
246
+ def require_all_libs_relative_to( fname, dir = nil )
247
+ dir ||= ::File.basename(fname, '.*')
248
+ search_me = ::File.expand_path(
249
+ ::File.join(::File.dirname(fname), dir, '*.rb'))
250
+
251
+ Dir.glob(search_me).sort.each {|rb| require rb}
252
+ end
253
+
254
+ # :stopdoc:
237
255
  # Convert the given level into a connaconical form - a lowercase string.
238
256
  def levelify( level )
239
257
  case level
@@ -252,9 +270,11 @@ module Logging
252
270
  end
253
271
  # :startdoc:
254
272
  end
255
-
256
273
  end # module Logging
257
274
 
275
+ Logging.require_all_libs_relative_to(__FILE__)
276
+ Logging.require_all_libs_relative_to(__FILE__, 'logging/config')
277
+
258
278
  # This exit handler will close all the appenders that exist in the system.
259
279
  # This is needed for closing IO streams and connections to the syslog server
260
280
  # or e-mail servers, etc.
@@ -265,4 +285,6 @@ at_exit {
265
285
  end
266
286
  }
267
287
 
288
+ end # unless defined?
289
+
268
290
  # EOF
@@ -1,203 +1,257 @@
1
- # $Id: appender.rb 85 2008-02-06 17:59:00Z tim_pease $
1
+ # $Id: appender.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
3
  require 'thread'
4
4
 
5
5
  module Logging
6
6
 
7
- # The +Appender+ class is provides methods for appending log events to a
8
- # logging destination. The log events are formatted into strings using a
9
- # Layout.
10
- #
11
- # All other Appenders inherit from this class which provides stub methods.
12
- # Each subclass should provide a +write+ method that will write log
13
- # messages to the logging destination.
14
- #
15
- # A private +sync+ method is provided for use by subclasses. It is used to
16
- # synchronize writes to the logging destination, and can be used by
17
- # subclasses to synchronize the closing or flushing of the logging
18
- # destination.
19
- #
20
- class Appender
7
+ # The +Appender+ class is provides methods for appending log events to a
8
+ # logging destination. The log events are formatted into strings using a
9
+ # Layout.
10
+ #
11
+ # All other Appenders inherit from this class which provides stub methods.
12
+ # Each subclass should provide a +write+ method that will write log
13
+ # messages to the logging destination.
14
+ #
15
+ # A private +sync+ method is provided for use by subclasses. It is used to
16
+ # synchronize writes to the logging destination, and can be used by
17
+ # subclasses to synchronize the closing or flushing of the logging
18
+ # destination.
19
+ #
20
+ class Appender
21
21
 
22
- attr_reader :name, :layout, :level
22
+ @appenders = Hash.new
23
+
24
+ class << self
23
25
 
24
26
  # call-seq:
25
- # Appender.new( name )
26
- # Appender.new( name, :layout => layout )
27
+ # Appender[name]
27
28
  #
28
- # Creates a new appender using the given name. If no Layout is specified,
29
- # then a Basic layout will be used. Any logging header supplied by the
30
- # layout will be written to the logging destination when the Appender is
31
- # created.
29
+ # Returns the appender instance stroed in the Appender hash under the
30
+ # key _name_, or +nil+ if no appender has been created using that name.
32
31
  #
33
- def initialize( name, opts = {} )
34
- @name = name.to_s
35
- @closed = false
36
-
37
- self.layout = opts.getopt(:layout, ::Logging::Layouts::Basic.new)
38
- self.level = opts.getopt(:level)
39
-
40
- @mutex = Mutex.new
41
- header = @layout.header
42
- sync {write(header)} unless header.nil? || header.empty?
43
-
44
- ::Logging::Appender[@name] = self
45
- end
32
+ def []( name ) @appenders[name] end
46
33
 
47
34
  # call-seq:
48
- # append( event )
35
+ # Appender[name] = appender
49
36
  #
50
- # Write the given _event_ to the logging destination. The log event will
51
- # be processed through the Layout associated with the Appender.
37
+ # Stores the given _appender_ instance in the Appender hash under the
38
+ # key _name_.
52
39
  #
53
- def append( event )
54
- if @closed
55
- raise RuntimeError,
56
- "appender '<#{self.class.name}: #{@name}>' is closed"
57
- end
58
-
59
- sync {write(event)} unless @level > event.level
60
- self
61
- end
40
+ def []=( name, val ) @appenders[name] = val end
62
41
 
63
42
  # call-seq:
64
- # appender << string
43
+ # Appenders.remove( name )
65
44
  #
66
- # Write the given _string_ to the logging destination "as is" -- no
67
- # layout formatting will be performed.
45
+ # Removes the appender instance stored in the Appender hash under the
46
+ # key _name_.
68
47
  #
69
- def <<( str )
70
- if @closed
71
- raise RuntimeError,
72
- "appender '<#{self.class.name}: #{@name}>' is closed"
73
- end
74
-
75
- sync {write(str)} unless @level >= ::Logging::LEVELS.length
76
- self
77
- end
48
+ def remove( name ) @appenders.delete(name) end
78
49
 
79
50
  # call-seq:
80
- # level = :all
81
- #
82
- # Set the level for this appender; log events below this level will be
83
- # ignored by this appender. The level can be either a +String+, a
84
- # +Symbol+, or a +Fixnum+. An +ArgumentError+ is raised if this is not
85
- # the case.
51
+ # Appender.stdout
86
52
  #
87
- # There are two special levels -- "all" and "off". The former will
88
- # enable recording of all log events. The latter will disable the
89
- # recording of all events.
53
+ # Returns an instance of the Stdout Appender. Unless the user explicitly
54
+ # creates a new Stdout Appender, the instance returned by this method
55
+ # will always be the same:
90
56
  #
91
- # Example:
57
+ # Appender.stdout.object_id == Appender.stdout.object_id #=> true
92
58
  #
93
- # appender.level = :debug
94
- # appender.level = "INFO"
95
- # appender.level = 4
96
- # appender.level = 'off'
97
- # appender.level = :all
59
+ def stdout( ) self['stdout'] || ::Logging::Appenders::Stdout.new end
60
+
61
+ # call-seq:
62
+ # Appender.stderr
98
63
  #
99
- # These prodcue an +ArgumentError+
64
+ # Returns an instance of the Stderr Appender. Unless the user explicitly
65
+ # creates a new Stderr Appender, the instance returned by this method
66
+ # will always be the same:
100
67
  #
101
- # appender.level = Object
102
- # appender.level = -1
103
- # appender.level = 1_000_000_000_000
68
+ # Appender.stderr.object_id == Appender.stderr.object_id #=> true
104
69
  #
105
- def level=( level )
106
- lvl = case level
107
- when String, Symbol; ::Logging::level_num(level)
108
- when Fixnum; level
109
- when nil; 0
110
- else
111
- raise ArgumentError,
112
- "level must be a String, Symbol, or Integer"
113
- end
114
- if lvl.nil? or lvl < 0 or lvl > ::Logging::LEVELS.length
115
- raise ArgumentError, "unknown level was given '#{level}'"
116
- end
117
-
118
- @level = lvl
70
+ def stderr( ) self['stderr'] || ::Logging::Appenders::Stderr.new end
71
+
72
+ end # class << self
73
+
74
+ attr_reader :name, :layout, :level
75
+
76
+ # call-seq:
77
+ # Appender.new( name )
78
+ # Appender.new( name, :layout => layout )
79
+ #
80
+ # Creates a new appender using the given name. If no Layout is specified,
81
+ # then a Basic layout will be used. Any logging header supplied by the
82
+ # layout will be written to the logging destination when the Appender is
83
+ # created.
84
+ #
85
+ def initialize( name, opts = {} )
86
+ @name = name.to_s
87
+ @closed = false
88
+
89
+ self.layout = opts.getopt(:layout, ::Logging::Layouts::Basic.new)
90
+ self.level = opts.getopt(:level)
91
+
92
+ @mutex = Mutex.new
93
+ header = @layout.header
94
+ sync {write(header)} unless header.nil? || header.empty?
95
+
96
+ ::Logging::Appender[@name] = self
97
+ end
98
+
99
+ # call-seq:
100
+ # append( event )
101
+ #
102
+ # Write the given _event_ to the logging destination. The log event will
103
+ # be processed through the Layout associated with the Appender.
104
+ #
105
+ def append( event )
106
+ if @closed
107
+ raise RuntimeError,
108
+ "appender '<#{self.class.name}: #{@name}>' is closed"
119
109
  end
120
110
 
121
- # call-seq
122
- # appender.layout = Logging::Layouts::Basic.new
123
- #
124
- # Sets the layout to be used by this appender.
125
- #
126
- def layout=( layout )
127
- unless layout.kind_of? ::Logging::Layout
128
- raise TypeError,
129
- "#{layout.inspect} is not a kind of 'Logging::Layout'"
130
- end
131
- @layout = layout
111
+ sync {write(event)} unless @level > event.level
112
+ self
113
+ end
114
+
115
+ # call-seq:
116
+ # appender << string
117
+ #
118
+ # Write the given _string_ to the logging destination "as is" -- no
119
+ # layout formatting will be performed.
120
+ #
121
+ def <<( str )
122
+ if @closed
123
+ raise RuntimeError,
124
+ "appender '<#{self.class.name}: #{@name}>' is closed"
132
125
  end
133
126
 
134
- # call-seq:
135
- # close( footer = true )
136
- #
137
- # Close the appender and writes the layout footer to the logging
138
- # destination if the _footer_ flag is set to +true+. Log events will
139
- # no longer be written to the logging destination after the appender
140
- # is closed.
141
- #
142
- def close( footer = true )
143
- return self if @closed
144
- ::Logging::Appender.remove(@name)
145
- @closed = true
146
- if footer
147
- footer = @layout.footer
148
- sync {write(footer)} unless footer.nil? || footer.empty?
149
- end
150
- self
127
+ sync {write(str)} unless @level >= ::Logging::LEVELS.length
128
+ self
129
+ end
130
+
131
+ # call-seq:
132
+ # level = :all
133
+ #
134
+ # Set the level for this appender; log events below this level will be
135
+ # ignored by this appender. The level can be either a +String+, a
136
+ # +Symbol+, or a +Fixnum+. An +ArgumentError+ is raised if this is not
137
+ # the case.
138
+ #
139
+ # There are two special levels -- "all" and "off". The former will
140
+ # enable recording of all log events. The latter will disable the
141
+ # recording of all events.
142
+ #
143
+ # Example:
144
+ #
145
+ # appender.level = :debug
146
+ # appender.level = "INFO"
147
+ # appender.level = 4
148
+ # appender.level = 'off'
149
+ # appender.level = :all
150
+ #
151
+ # These prodcue an +ArgumentError+
152
+ #
153
+ # appender.level = Object
154
+ # appender.level = -1
155
+ # appender.level = 1_000_000_000_000
156
+ #
157
+ def level=( level )
158
+ lvl = case level
159
+ when String, Symbol; ::Logging::level_num(level)
160
+ when Fixnum; level
161
+ when nil; 0
162
+ else
163
+ raise ArgumentError,
164
+ "level must be a String, Symbol, or Integer"
165
+ end
166
+ if lvl.nil? or lvl < 0 or lvl > ::Logging::LEVELS.length
167
+ raise ArgumentError, "unknown level was given '#{level}'"
151
168
  end
152
169
 
153
- # call-seq:
154
- # closed?
155
- #
156
- # Returns +true+ if the appender has been closed; returns +false+
157
- # otherwise. When an appender is closed, no more log events can be
158
- # written to the logging destination.
159
- #
160
- def closed?
161
- @closed
170
+ @level = lvl
171
+ end
172
+
173
+ # call-seq
174
+ # appender.layout = Logging::Layouts::Basic.new
175
+ #
176
+ # Sets the layout to be used by this appender.
177
+ #
178
+ def layout=( layout )
179
+ unless layout.kind_of? ::Logging::Layout
180
+ raise TypeError,
181
+ "#{layout.inspect} is not a kind of 'Logging::Layout'"
162
182
  end
183
+ @layout = layout
184
+ end
163
185
 
164
- # call-seq:
165
- # flush
166
- #
167
- # Call +flush+ to force an appender to write out any buffered log events.
168
- # Similar to IO#flush, so use in a similar fashion.
169
- #
170
- def flush
171
- self
186
+ # call-seq:
187
+ # close( footer = true )
188
+ #
189
+ # Close the appender and writes the layout footer to the logging
190
+ # destination if the _footer_ flag is set to +true+. Log events will
191
+ # no longer be written to the logging destination after the appender
192
+ # is closed.
193
+ #
194
+ def close( footer = true )
195
+ return self if @closed
196
+ ::Logging::Appender.remove(@name)
197
+ @closed = true
198
+ if footer
199
+ footer = @layout.footer
200
+ sync {write(footer)} unless footer.nil? || footer.empty?
172
201
  end
202
+ self
203
+ end
173
204
 
205
+ # call-seq:
206
+ # closed?
207
+ #
208
+ # Returns +true+ if the appender has been closed; returns +false+
209
+ # otherwise. When an appender is closed, no more log events can be
210
+ # written to the logging destination.
211
+ #
212
+ def closed?
213
+ @closed
214
+ end
174
215
 
175
- private
216
+ # call-seq:
217
+ # flush
218
+ #
219
+ # Call +flush+ to force an appender to write out any buffered log events.
220
+ # Similar to IO#flush, so use in a similar fashion.
221
+ #
222
+ def flush
223
+ self
224
+ end
176
225
 
177
- # call-seq:
178
- # write( event )
179
- #
180
- # Writes the given _event_ to the logging destination. Subclasses should
181
- # provide an implementation of this method. The _event_ can be either a
182
- # LogEvent or a String. If a LogEvent, then it will be formatted using
183
- # the layout given to the appender when it was created.
184
- #
185
- def write( event )
186
- nil
187
- end
188
226
 
189
- # call-seq:
190
- # sync { block }
191
- #
192
- # Obtains an exclusive lock, runs the block, and releases the lock when
193
- # the block completes. This method is re-entrant so that a single thread
194
- # can call +sync+ multiple times without hanging the thread.
195
- #
196
- def sync
197
- @mutex.synchronize {yield}
198
- end
227
+ private
228
+
229
+ # call-seq:
230
+ # write( event )
231
+ #
232
+ # Writes the given _event_ to the logging destination. Subclasses should
233
+ # provide an implementation of this method. The _event_ can be either a
234
+ # LogEvent or a String. If a LogEvent, then it will be formatted using
235
+ # the layout given to the appender when it was created.
236
+ #
237
+ def write( event )
238
+ nil
239
+ end
199
240
 
200
- end # class Appender
241
+ # call-seq:
242
+ # sync { block }
243
+ #
244
+ # Obtains an exclusive lock, runs the block, and releases the lock when
245
+ # the block completes. This method is re-entrant so that a single thread
246
+ # can call +sync+ multiple times without hanging the thread.
247
+ #
248
+ def sync
249
+ @mutex.synchronize {yield}
250
+ end
251
+
252
+ end # class Appender
201
253
  end # module Logging
202
254
 
255
+ Logging.require_all_libs_relative_to(__FILE__, 'appenders')
256
+
203
257
  # EOF
@@ -1,4 +1,6 @@
1
- # $Id: console.rb 77 2007-12-30 02:21:33Z tim_pease $
1
+ # $Id: console.rb 88 2008-02-08 18:47:36Z tim_pease $
2
+
3
+ require Logging.libpath(*%w[logging appenders io])
2
4
 
3
5
  module Logging::Appenders
4
6
 
@@ -1,4 +1,4 @@
1
- # $Id: yaml_configurator.rb 77 2007-12-30 02:21:33Z tim_pease $
1
+ # $Id: yaml_configurator.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
3
  require 'yaml'
4
4
 
@@ -15,44 +15,54 @@ module Config
15
15
  class << self
16
16
 
17
17
  # call-seq:
18
- # YamlConfigurator.load( file )
18
+ # YamlConfigurator.load( file, key = 'logging_config' )
19
19
  #
20
20
  # Load the given YAML _file_ and use it to configure the Logging
21
21
  # framework. The file can be either a filename, and open File, or an
22
22
  # IO object. If it is the latter two, the File / IO object will not be
23
23
  # closed by this method.
24
24
  #
25
- def load( file )
25
+ # The configuration will be loaded from the given _key_ in the YAML
26
+ # stream.
27
+ #
28
+ def load( file, key = 'logging_config' )
26
29
  io, close = nil, false
27
30
  case file
28
31
  when String
29
32
  io = File.open(file, 'r')
30
33
  close = true
31
- when IO; io = file
32
- else raise Error, 'expecting a filename or a File' end
34
+ when IO
35
+ io = file
36
+ else
37
+ raise Error, 'expecting a filename or a File'
38
+ end
33
39
 
34
- begin new(io).load; ensure; io.close if close end
40
+ begin
41
+ new(io, key).load
42
+ ensure
43
+ io.close if close
44
+ end
35
45
  nil
36
46
  end
37
47
  end # class << self
38
48
 
39
49
  # call-seq:
40
- # YamlConfigurator.new( io )
50
+ # YamlConfigurator.new( io, key )
41
51
  #
42
52
  # Creates a new YAML configurator that will load the Logging
43
- # configuration from the given _io_ stream.
53
+ # configuration from the given _io_ stream. The configuration will be
54
+ # loaded from the given _key_ in the YAML stream.
44
55
  #
45
- def initialize( io )
56
+ def initialize( io, key )
46
57
  YAML.load_documents(io) do |doc|
47
- @config = doc['logging_config']
58
+ @config = doc[key]
48
59
  break if @config.instance_of?(Hash)
49
60
  end
50
61
 
51
62
  unless @config.instance_of?(Hash)
52
- raise Error, "Key 'logging_config' not defined in YAML configuration"
63
+ raise Error, "Key '#{key}' not defined in YAML configuration"
53
64
  end
54
65
  end
55
- private :initialize
56
66
 
57
67
  # call-seq:
58
68
  # load
@@ -1,101 +1,103 @@
1
- # $Id: layout.rb 77 2007-12-30 02:21:33Z tim_pease $
1
+ # $Id: layout.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
3
  require 'yaml'
4
4
 
5
5
  module Logging
6
6
 
7
- # The +Layout+ class provides methods for formatting log events into a
8
- # string representation. Layouts are used by Appenders to format log
9
- # events before writing them to the logging destination.
7
+ # The +Layout+ class provides methods for formatting log events into a
8
+ # string representation. Layouts are used by Appenders to format log
9
+ # events before writing them to the logging destination.
10
+ #
11
+ # All other Layouts inherit from this class which provides stub methods.
12
+ # Each subclass should provide a +format+ method. A layout can be used by
13
+ # more than one +Appender+ so all the methods need to be thread safe.
14
+ #
15
+ class Layout
16
+
17
+ # call-seq:
18
+ # Layout.new( :format_as => :string )
19
+ #
20
+ # Creates a new layout that will format objecs as strings using the
21
+ # given <tt>:format_as</tt> style. This can be one of <tt>:string</tt>,
22
+ # <tt>:inspect</tt>, or <tt>:yaml</tt>. These formatting commands map to
23
+ # the following object methods:
10
24
  #
11
- # All other Layouts inherit from this class which provides stub methods.
12
- # Each subclass should provide a +format+ method. A layout can be used by
13
- # more than one +Appender+ so all the methods need to be thread safe.
25
+ # * :string => to_s
26
+ # * :inspect => inspect
27
+ # * :yaml => to_yaml
14
28
  #
15
- class Layout
29
+ # If the format is not specified then the global object format is used
30
+ # (see Logging#format_as). If the global object format is not specified
31
+ # then <tt>:string</tt> is used.
32
+ #
33
+ def initialize( opts = {} )
34
+ default = ::Logging.const_defined?('OBJ_FORMAT') ?
35
+ ::Logging::OBJ_FORMAT : nil
16
36
 
17
- # call-seq:
18
- # Layout.new( :format_as => :string )
19
- #
20
- # Creates a new layout that will format objecs as strings using the
21
- # given <tt>:format_as</tt> style. This can be one of <tt>:string</tt>,
22
- # <tt>:inspect</tt>, or <tt>:yaml</tt>. These formatting commands map to
23
- # the following object methods:
24
- #
25
- # * :string => to_s
26
- # * :inspect => inspect
27
- # * :yaml => to_yaml
28
- #
29
- # If the format is not specified then the global object format is used
30
- # (see Logging#format_as). If the global object format is not specified
31
- # then <tt>:string</tt> is used.
32
- #
33
- def initialize( opts = {} )
34
- default = ::Logging.const_defined?('OBJ_FORMAT') ?
35
- ::Logging::OBJ_FORMAT : nil
37
+ f = opts.getopt(:format_as, default)
38
+ f = f.intern if f.instance_of? String
36
39
 
37
- f = opts.getopt(:format_as, default)
38
- f = f.intern if f.instance_of? String
40
+ @obj_format = case f
41
+ when :inspect, :yaml; f
42
+ else :string end
43
+ end
39
44
 
40
- @obj_format = case f
41
- when :inspect, :yaml; f
42
- else :string end
43
- end
44
-
45
- # call-seq:
46
- # format( event )
47
- #
48
- # Returns a string representation of the given loggging _event_. It is
49
- # up to subclasses to implement this method.
50
- #
51
- def format( event ) nil end
45
+ # call-seq:
46
+ # format( event )
47
+ #
48
+ # Returns a string representation of the given loggging _event_. It is
49
+ # up to subclasses to implement this method.
50
+ #
51
+ def format( event ) nil end
52
52
 
53
- # call-seq:
54
- # header
55
- #
56
- # Returns a header string to be used at the beginning of a logging
57
- # appender.
58
- #
59
- def header( ) '' end
53
+ # call-seq:
54
+ # header
55
+ #
56
+ # Returns a header string to be used at the beginning of a logging
57
+ # appender.
58
+ #
59
+ def header( ) '' end
60
60
 
61
- # call-seq:
62
- # footer
63
- #
64
- # Returns a footer string to be used at the end of a logging appender.
65
- #
66
- def footer( ) '' end
61
+ # call-seq:
62
+ # footer
63
+ #
64
+ # Returns a footer string to be used at the end of a logging appender.
65
+ #
66
+ def footer( ) '' end
67
67
 
68
68
 
69
- protected
69
+ protected
70
70
 
71
- # call-seq:
72
- # format_obj( obj )
73
- #
74
- # Return a string representation of the given object. Depending upon
75
- # the configuration of the logger system the format will be an +inspect+
76
- # based represenation or a +yaml+ based representation.
77
- #
78
- def format_obj( obj )
79
- case obj
80
- when String; obj
81
- when Exception
82
- str = "<#{obj.class.name}> #{obj.message}"
83
- unless obj.backtrace.nil?
84
- str << "\n\t" << obj.backtrace.join("\n\t")
85
- end
86
- str
87
- when nil; "<#{obj.class.name}> nil"
88
- else
89
- str = "<#{obj.class.name}> "
90
- str << case @obj_format
91
- when :inspect; obj.inspect
92
- when :yaml; "\n#{obj.to_yaml}"
93
- else obj.to_s end
94
- str
71
+ # call-seq:
72
+ # format_obj( obj )
73
+ #
74
+ # Return a string representation of the given object. Depending upon
75
+ # the configuration of the logger system the format will be an +inspect+
76
+ # based represenation or a +yaml+ based representation.
77
+ #
78
+ def format_obj( obj )
79
+ case obj
80
+ when String; obj
81
+ when Exception
82
+ str = "<#{obj.class.name}> #{obj.message}"
83
+ unless obj.backtrace.nil?
84
+ str << "\n\t" << obj.backtrace.join("\n\t")
95
85
  end
86
+ str
87
+ when nil; "<#{obj.class.name}> nil"
88
+ else
89
+ str = "<#{obj.class.name}> "
90
+ str << case @obj_format
91
+ when :inspect; obj.inspect
92
+ when :yaml; "\n#{obj.to_yaml}"
93
+ else obj.to_s end
94
+ str
96
95
  end
96
+ end
97
97
 
98
- end # class Layout
98
+ end # class Layout
99
99
  end # module Logging
100
100
 
101
+ Logging.require_all_libs_relative_to(__FILE__, 'layouts')
102
+
101
103
  # EOF
@@ -1,27 +1,19 @@
1
- # $Id$
1
+ # $Id: annotations.rake 87 2008-02-08 17:21:07Z tim_pease $
2
2
 
3
3
  if HAVE_BONES
4
4
 
5
5
  desc "Enumerate all annotations"
6
6
  task :notes do
7
7
  Bones::AnnotationExtractor.enumerate(
8
- PROJ, "OPTIMIZE|FIXME|TODO", :tag => true)
8
+ PROJ, PROJ.annotation_tags.join('|'), :tag => true)
9
9
  end
10
10
 
11
11
  namespace :notes do
12
- desc "Enumerate all OPTIMIZE annotations"
13
- task :optimize do
14
- Bones::AnnotationExtractor.enumerate(PROJ, "OPTIMIZE")
15
- end
16
-
17
- desc "Enumerate all FIXME annotations"
18
- task :fixme do
19
- Bones::AnnotationExtractor.enumerate(PROJ, "FIXME")
20
- end
21
-
22
- desc "Enumerate all TODO annotations"
23
- task :todo do
24
- Bones::AnnotationExtractor.enumerate(PROJ, "TODO")
12
+ PROJ.annotation_tags.each do |tag|
13
+ desc "Enumerate all #{tag} annotations"
14
+ task tag.downcase.to_sym do
15
+ Bones::AnnotationExtractor.enumerate(PROJ, tag)
16
+ end
25
17
  end
26
18
  end
27
19
 
@@ -1,4 +1,4 @@
1
- # $Id: post_load.rake 85 2008-02-06 17:59:00Z tim_pease $
1
+ # $Id$
2
2
 
3
3
  # This file does not define any rake tasks. It is used to load some project
4
4
  # settings if they are not defined by the user.
@@ -1,4 +1,4 @@
1
- # $Id: setup.rb 85 2008-02-06 17:59:00Z tim_pease $
1
+ # $Id: setup.rb 87 2008-02-08 17:21:07Z tim_pease $
2
2
 
3
3
  require 'rubygems'
4
4
  require 'rake'
@@ -57,8 +57,9 @@ PROJ.need_tar = true
57
57
  PROJ.need_zip = false
58
58
 
59
59
  # File Annotations
60
- PROJ.annotation_exclude = []
60
+ PROJ.annotation_exclude = %w(^tasks/setup.rb$)
61
61
  PROJ.annotation_extensions = %w(.txt .rb .erb) << ''
62
+ PROJ.annotation_tags = %w(FIXME OPTIMIZE TODO)
62
63
 
63
64
  # Subversion Repository
64
65
  PROJ.svn = false
@@ -1,6 +1,6 @@
1
- # $Id: test_console.rb 17 2007-01-20 18:47:43Z tim_pease $
1
+ # $Id: test_console.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
4
 
5
5
  module TestLogging
6
6
  module TestAppenders
@@ -1,6 +1,6 @@
1
- # $Id: test_email.rb 69 2007-12-26 20:53:33Z tim_pease $
1
+ # $Id: test_email.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
4
  require 'flexmock'
5
5
 
6
6
  module TestLogging
@@ -1,7 +1,6 @@
1
- # $Id: test_file.rb 72 2007-12-26 21:59:58Z tim_pease $
1
+ # $Id: test_file.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
4
- require 'fileutils'
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
5
4
 
6
5
  module TestLogging
7
6
  module TestAppenders
@@ -1,6 +1,6 @@
1
- # $Id: test_growl.rb 69 2007-12-26 20:53:33Z tim_pease $
1
+ # $Id: test_growl.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
4
  require 'flexmock'
5
5
 
6
6
  module TestLogging
@@ -1,7 +1,6 @@
1
- # $Id: test_io.rb 67 2007-12-26 16:27:06Z tim_pease $
1
+ # $Id: test_io.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
4
- require 'stringio'
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
5
4
 
6
5
  module TestLogging
7
6
  module TestAppenders
@@ -1,7 +1,6 @@
1
- # $Id: test_rolling_file.rb 72 2007-12-26 21:59:58Z tim_pease $
1
+ # $Id: test_rolling_file.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
4
- require 'fileutils'
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
5
4
 
6
5
  module TestLogging
7
6
  module TestAppenders
@@ -1,6 +1,6 @@
1
- # $Id: test_syslog.rb 72 2007-12-26 21:59:58Z tim_pease $
1
+ # $Id: test_syslog.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
4
 
5
5
  if HAVE_SYSLOG
6
6
 
@@ -1,8 +1,6 @@
1
- # $Id: test_yaml_configurator.rb 72 2007-12-26 21:59:58Z tim_pease $
1
+ # $Id: test_yaml_configurator.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'stringio'
4
- require 'yaml'
5
- require 'test/setup.rb'
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
6
4
 
7
5
  module TestLogging
8
6
  module TestConfig
@@ -31,7 +29,7 @@ module TestConfig
31
29
  io.seek 0
32
30
 
33
31
  assert_raise(::Logging::Config::YamlConfigurator::Error) {
34
- ::Logging::Config::YamlConfigurator.new(io)
32
+ ::Logging::Config::YamlConfigurator.new(io, :meh)
35
33
  }
36
34
  end
37
35
 
@@ -1,6 +1,6 @@
1
- # $Id: test_basic.rb 53 2007-11-28 00:21:33Z tim_pease $
1
+ # $Id: test_basic.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
4
 
5
5
  module TestLogging
6
6
  module TestLayouts
@@ -1,6 +1,6 @@
1
- # $Id: test_pattern.rb 53 2007-11-28 00:21:33Z tim_pease $
1
+ # $Id: test_pattern.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
4
 
5
5
  module TestLogging
6
6
  module TestLayouts
@@ -1,13 +1,20 @@
1
- # $Id: setup.rb 77 2007-12-30 02:21:33Z tim_pease $
1
+ # $Id: setup.rb 88 2008-02-08 18:47:36Z tim_pease $
2
+
3
+ # Equivalent to a header guard in C/C++
4
+ # Used to prevent the class/module from being loaded more than once
5
+ unless defined? LOGGING_TEST_SETUP
6
+ LOGGING_TEST_SETUP = true
2
7
 
3
8
  require 'test/unit'
9
+ require 'fileutils'
10
+ require 'stringio'
4
11
 
5
12
  # This line is needed for Ruby 1.9 -- hashes throw a "KeyError" in 1.9
6
13
  # whereas they throw an "IndexError" in 1.8
7
14
  #
8
15
  KeyError = IndexError if not defined? KeyError
9
16
 
10
- require File.join(File.dirname(__FILE__), '..', 'lib', 'logging')
17
+ require File.join(File.dirname(__FILE__), %w[.. lib logging])
11
18
 
12
19
  begin
13
20
  require 'turn'
@@ -59,4 +66,6 @@ module LoggingTestCase
59
66
  end # module LoggingTestCase
60
67
  end # module TestLogging
61
68
 
69
+ end # unless defined?
70
+
62
71
  # EOF
@@ -1,6 +1,6 @@
1
- # $Id: test_appender.rb 85 2008-02-06 17:59:00Z tim_pease $
1
+ # $Id: test_appender.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
3
+ require File.join(File.dirname(__FILE__), %w[setup])
4
4
 
5
5
  module TestLogging
6
6
 
@@ -1,6 +1,6 @@
1
- # $Id: test_layout.rb 53 2007-11-28 00:21:33Z tim_pease $
1
+ # $Id: test_layout.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
3
+ require File.join(File.dirname(__FILE__), %w[setup])
4
4
 
5
5
  module TestLogging
6
6
 
@@ -1,6 +1,6 @@
1
- # $Id: test_log_event.rb 25 2007-01-30 20:19:12Z tim_pease $
1
+ # $Id: test_log_event.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
3
+ require File.join(File.dirname(__FILE__), %w[setup])
4
4
 
5
5
  module TestLogging
6
6
 
@@ -1,7 +1,6 @@
1
- # $Id: test_logger.rb 53 2007-11-28 00:21:33Z tim_pease $
1
+ # $Id: test_logger.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
4
- require 'stringio'
3
+ require File.join(File.dirname(__FILE__), %w[setup])
5
4
 
6
5
  module TestLogging
7
6
 
@@ -1,7 +1,6 @@
1
- # $Id: test_logging.rb 72 2007-12-26 21:59:58Z tim_pease $
1
+ # $Id: test_logging.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
4
- require 'fileutils'
3
+ require File.join(File.dirname(__FILE__), %w[setup])
5
4
 
6
5
  module TestLogging
7
6
 
@@ -1,6 +1,6 @@
1
- # $Id: test_repository.rb 53 2007-11-28 00:21:33Z tim_pease $
1
+ # $Id: test_repository.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
3
+ require File.join(File.dirname(__FILE__), %w[setup])
4
4
 
5
5
  module TestLogging
6
6
 
@@ -1,7 +1,6 @@
1
- # $Id: test_root_logger.rb 22 2007-01-29 16:20:54Z tim_pease $
1
+ # $Id: test_root_logger.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
4
- require 'stringio'
3
+ require File.join(File.dirname(__FILE__), %w[setup])
5
4
 
6
5
  module TestLogging
7
6
 
@@ -1,7 +1,6 @@
1
- # $Id: test_utils.rb 65 2007-12-23 04:48:55Z tim_pease $
1
+ # $Id: test_utils.rb 88 2008-02-08 18:47:36Z tim_pease $
2
2
 
3
- require 'test/setup.rb'
4
- require 'stringio'
3
+ require File.join(File.dirname(__FILE__), %w[setup])
5
4
 
6
5
  module TestLogging
7
6
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logging
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Pease
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-02-06 00:00:00 -07:00
12
+ date: 2008-02-08 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -53,7 +53,6 @@ files:
53
53
  - lib/logging/appenders/growl.rb
54
54
  - lib/logging/appenders/io.rb
55
55
  - lib/logging/appenders/rolling_file.rb
56
- - lib/logging/appenders/static_appender.rb
57
56
  - lib/logging/appenders/syslog.rb
58
57
  - lib/logging/config/yaml_configurator.rb
59
58
  - lib/logging/layout.rb
@@ -1,60 +0,0 @@
1
- # $Id: static_appender.rb 85 2008-02-06 17:59:00Z tim_pease $
2
-
3
- module Logging
4
- class Appender
5
-
6
- @appenders = Hash.new
7
-
8
- class << self
9
-
10
- # call-seq:
11
- # Appender[name]
12
- #
13
- # Returns the appender instance stroed in the Appender hash under the
14
- # key _name_, or +nil+ if no appender has been created using that name.
15
- #
16
- def []( name ) @appenders[name] end
17
-
18
- # call-seq:
19
- # Appender[name] = appender
20
- #
21
- # Stores the given _appender_ instance in the Appender hash under the
22
- # key _name_.
23
- #
24
- def []=( name, val ) @appenders[name] = val end
25
-
26
- # call-seq:
27
- # Appenders.remove( name )
28
- #
29
- # Removes the appender instance stored in the Appender hash under the
30
- # key _name_.
31
- #
32
- def remove( name ) @appenders.delete(name) end
33
-
34
- # call-seq:
35
- # Appender.stdout
36
- #
37
- # Returns an instance of the Stdout Appender. Unless the user explicitly
38
- # creates a new Stdout Appender, the instance returned by this method
39
- # will always be the same:
40
- #
41
- # Appender.stdout.object_id == Appender.stdout.object_id #=> true
42
- #
43
- def stdout( ) self['stdout'] || ::Logging::Appenders::Stdout.new end
44
-
45
- # call-seq:
46
- # Appender.stderr
47
- #
48
- # Returns an instance of the Stderr Appender. Unless the user explicitly
49
- # creates a new Stderr Appender, the instance returned by this method
50
- # will always be the same:
51
- #
52
- # Appender.stderr.object_id == Appender.stderr.object_id #=> true
53
- #
54
- def stderr( ) self['stderr'] || ::Logging::Appenders::Stderr.new end
55
-
56
- end # class << self
57
- end # class Appender
58
- end # module Logging
59
-
60
- # EOF