A factory class that returns Logger instances. Since each registry has its own logger factory, the logger factory must be separately instantiable.

Methods
Constants
DEFAULT_LOG_FILENAME = "./needle.log"
  The default name of the log file to write to.
DEFAULT_MESSAGE_FORMAT = "[%-5p] %d -- %C: %m"
  The default format of the log messages (see Logger for more info)
LEVEL_TRANSLATOR = { "DEBUG" => Logger::DEBUG, "INFO" => Logger::INFO, "WARN" => Logger::WARN, "ERROR" => Logger::ERROR, "FATAL" => Logger::FATAL, "UNKNOWN" => Logger::UNKNOWN
  Translate names of levels to their actual values.
VALID_OPTIONS = [ :device, :filename, :roll_age, :roll_frequency, :roll_size, :default_date_format, :default_message_format, :default_level, :levels ]
VALID_LEVEL_OPTIONS = [ :level, :date_format, :message_format ]
Attributes
[R] default_date_format The default date format string to use when logging.
[R] default_level The default log level to use for logs that are created.
[R] default_message_format The default message format string to use when logging.
[R] device The device that logs will write to.
Public Class methods
new( opts={} )

Create a new LogFactory using the given initialization parameters. The valid options are:

  • :device: the device (pseudo-IO object) to write log messages to. Either this, or :filename must be specified.
  • :filename: the filename of the log to write to.
  • :roll_age: the number of days before the log should be rolled.
  • :roll_frequency: either ‘daily’, ‘weekly’, or ‘monthly’.
  • :roll_size: the maximum size of a log file.
  • :default_date_format: the default date format string for the log.
  • :default_message_format: the default message format string for the log.
  • :default_level: the default log level for the log.
  • :levels: a hash of patterns that map to a hash of ‘level’ ‘date_format’, and ‘message_format’ keys, specifying the log level, date format, and message format for any log whose name matches the key.
     # File lib/needle/log-factory.rb, line 80
 80:     def initialize( opts={} )
 81:       opts = convert_keys_to_symbols( opts )
 82:       bad = opts.keys - VALID_OPTIONS
 83:       raise ArgumentError,
 84:         "invalid option(s) to LogFactory (#{bad.inspect})" unless bad.empty?
 85: 
 86:       if opts[:device]
 87:         @device = opts[:device]
 88:       else
 89:         filename = opts[:filename] || DEFAULT_LOG_FILENAME
 90:         roll_age = opts[:roll_age ] || opts[:roll_frequency] || 0
 91:         roll_size = opts[:roll_size] || 0
 92:         @device = Logger::LogDevice.new( filename,
 93:           :shift_age=>roll_age, :shift_size=>roll_size )
 94:       end
 95: 
 96:       @default_date_format = opts[:default_date_format]
 97:       @default_message_format = opts[:default_message_format] ||
 98:         DEFAULT_MESSAGE_FORMAT
 99:       @default_level = opts[:default_level]
100: 
101:       if @default_level.is_a?( String ) || @default_level.is_a?( Symbol )
102:         @default_level = LEVEL_TRANSLATOR[@default_level.to_s.upcase]
103:         if @default_level.nil?
104:           raise ArgumentError,
105:             "invalid logging level (#{@default_level.inspect})"
106:         end
107:       end
108: 
109:       @levels = Hash.new :level => nil, :date_format => nil,
110:         :message_format => nil
111: 
112:       ( opts[:levels] || {} ).each_pair do |key, value|
113:         key = Regexp.new( "^" + key.gsub( /\./, "\\." ).gsub( /\*/, ".*" ) )
114: 
115:         if value.is_a?( String ) || value.is_a?( Symbol )
116:           value = { :level => value.to_s }
117:         else
118:           value = convert_keys_to_symbols( value )
119:         end
120: 
121:         bad = value.keys - VALID_LEVEL_OPTIONS
122:         raise ArgumentError, 
123:           "invalid log level option(s) #{bad.inspect}" unless bad.empty?
124: 
125:         value[ :level ] = LEVEL_TRANSLATOR[ value[:level].to_s.upcase ]
126:         if value[:level].nil?
127:           raise ArgumentError,
128:             "invalid logging level (#{value[:level].inspect})"
129:         end
130: 
131:         @levels[ key ] = value
132:       end
133: 
134:       @loggers = Hash.new
135:       @mutex = Mutex.new
136:       @closed = false
137:     end
Public Instance methods
close()

Closes the logging device and makes this factory invalid for future accesses.

     # File lib/needle/log-factory.rb, line 218
218:     def close
219:       @mutex.synchronize do
220:         return if @closed
221: 
222:         if @device
223:           @device.close unless [ $stdout, $stderr ].include?( @device )
224:         end
225: 
226:         @loggers = nil
227:         @closed = true
228:       end
229:     end
closed?()

Returns true if the factory has been closed.

     # File lib/needle/log-factory.rb, line 232
232:     def closed?
233:       @closed
234:     end
get( name )

Retrieves the logger with the given name. If no such log has been created, the log will be created and initialized. Otherwise, the log with the given name is returned.

If name responds to either fullname or name, then the result of invoking that message on name will be used as the name.

     # File lib/needle/log-factory.rb, line 184
184:     def get( name )
185:       name = name.fullname if name.respond_to?( :fullname )
186:       name = name.name if name.respond_to?( :name )
187:       name = name.to_s
188: 
189:       # the common case first, outside the synchronize, for speed
190:       return @loggers[ name ] if @loggers[ name ]
191: 
192:       @mutex.synchronize do
193:         # check again, inside the synchronize, to avoid race conditions
194:         return @loggers[ name ] if @loggers[ name ]
195: 
196:         definition = find_definition( name )
197: 
198:         level = definition[ :level ] || @default_level
199:         date_format = definition[ :date_format ] || @default_date_format
200:         message_format = definition[ :message_format ] ||
201:           @default_message_format
202: 
203:         level = LEVEL_TRANSLATOR[ level.to_s.upcase ] || level
204: 
205:         logger = Needle::Logger.new( @device )
206:         logger.level = level if level
207:         logger.progname = name
208:         logger.datetime_format = date_format if date_format
209:         logger.message_format = message_format if message_format
210: 
211:         @loggers[ name ] = logger
212:         return logger
213:       end
214:     end
write_to( device, shift_age = 0, shift_size = 1048576 )

Changes the device that the loggers write to. Every log that was created by this log factory will be changed to use the given device.

     # File lib/needle/log-factory.rb, line 141
141:     def write_to( device, shift_age = 0, shift_size = 1048576 )
142:       saved_critical = Thread.critical
143:       Thread.critical = true
144: 
145:       @device.close if @device unless [ $stdout, $stderr ].include?( @device )
146:       if device.respond_to?( :write ) && device.respond_to?( :close )
147:         @device = device
148:       else
149:         @device = Logger::LogDevice.new( device.to_str,
150:           :shift_age => shift_age, 
151:           :shift_size => shift_size )
152:       end
153: 
154:       @loggers.each_value { |logger| logger.write_to( @device ) }
155:       device
156: 
157:     ensure
158:       Thread.critical = saved_critical
159:     end