A factory class that returns Logger instances. Since each registry has its own logger factory, the logger factory must be separately instantiable.
| 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 ] |
| [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. |
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.
[ show source ]
# 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
Closes the logging device and makes this factory invalid for future accesses.
[ show source ]
# 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
Returns true if the factory has been closed.
[ show source ]
# File lib/needle/log-factory.rb, line 232
232: def closed?
233: @closed
234: end
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.
[ show source ]
# 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
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.
[ show source ]
# 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