Class: Loggability::Logger

Inherits:
Logger
  • Object
show all
Includes:
Constants, Logger::Severity
Defined in:
lib/loggability/logger.rb

Overview

A subclass of Logger that provides additional API for configuring outputters, formatters, etc.

Defined Under Namespace

Classes: ObjectNameProxy

Constant Summary collapse

DEFAULT_DEVICE =

Default log ‘device’

$stderr
DEFAULT_SHIFT_AGE =

Default ‘shift age’

0
DEFAULT_SHIFT_SIZE =

Default ‘shift size’

1048576

Constants included from Constants

Constants::LOG_LEVELS, Constants::LOG_LEVEL_NAMES

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(logdev = DEFAULT_DEVICE, *args) ⇒ Logger

Create a new Logger wrapper that will output to the specified logdev.



118
119
120
121
122
123
124
125
126
# File 'lib/loggability/logger.rb', line 118

def initialize( logdev=DEFAULT_DEVICE, *args )
	super( nil )

	self.level = if $DEBUG then :debug else :warn end
	self.output_to( logdev, *args )

	@created_from = caller( 3 ).first
	@default_formatter = Loggability::Formatter.create( :default )
end

Instance Attribute Details

#created_fromObject (readonly)

The line that caused this logger to be created.



135
136
137
# File 'lib/loggability/logger.rb', line 135

def created_from
  @created_from
end

#logdevObject

The raw log device



238
239
240
# File 'lib/loggability/logger.rb', line 238

def logdev
  @logdev
end

Class Method Details

.from_std_logger(logger) ⇒ Object

Return an equivalent Loggability::Logger object for the given logger.



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/loggability/logger.rb', line 100

def self::from_std_logger( logger )
	device = logger.instance_variable_get( :@logdev ) or
		raise ArgumentError, "%p doesn't appear to be a Logger (no @logdev)" % [ logger ]

	newlogger = self.new( device.dev )

	newlogger.level     = logger.level
	newlogger.formatter = logger.formatter

	return newlogger
end

Instance Method Details

#<<(message) ⇒ Object

Append operator – Override Logger’s append so log messages always have formatting, and are always appended at :debug level.



180
181
182
183
184
# File 'lib/loggability/logger.rb', line 180

def <<( message )
	unless self.logdev.nil?
		self.add( Logger::DEBUG, message )
	end
end

#add(severity, message = nil, progname = nil) ⇒ Object

Log a message if the severity is high enough. Overridden to account for the overridden #level.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/loggability/logger.rb', line 158

def add( severity, message=nil, progname=nil )
	return true if severity < self.sev_threshold
	progname ||= @progname

	unless message
		if block_given?
			message = yield
		else
			message = progname
			progname = @progname
		end
	end

	msg = self.format_message( self.format_severity(severity), Time.now, progname, message )
	self.logdev.write( msg )

	return true
end

#format_message(severity, datetime, progname, msg) ⇒ Object

Format a log message using the current formatter and return it.



275
276
277
# File 'lib/loggability/logger.rb', line 275

def format_message( severity, datetime, progname, msg )
	self.formatter.call( severity, datetime, progname, msg )
end

#format_severity(severity) ⇒ Object

Return the formatted name of the given severity.



281
282
283
284
# File 'lib/loggability/logger.rb', line 281

def format_severity( severity )
	name = LOG_LEVEL_NAMES[ severity ] || severity.to_s
	return name.upcase
end

#format_with(formatter = nil, &block) ⇒ Object Also known as: format_as, formatter=

Set a new formatter for the logger. If formatter is nil or :default, this causes the logger to fall back to its default formatter. If it’s a Symbol other than :default, it looks for a similarly-named formatter under loggability/formatter/ and uses that. If formatter is an object that responds to #call (e.g., a Proc or a Method object), that object is used directly.

Procs and methods should have the method signature: (severity, datetime, progname, msg).

# Load and use the HTML formatter
MyProject.logger.format_with( :html )

# Call self.format_logmsg(...) to format messages
MyProject.logger.format_with( self.method(:format_logmsg) )

# Reset to the default
MyProject.logger.format_with( :default )


304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/loggability/logger.rb', line 304

def format_with( formatter=nil, &block ) # :yield: severity, datetime, progname, msg
	formatter ||= block

	if formatter.nil? || formatter == :default
		@formatter = nil

	elsif formatter.respond_to?( :call )
		@formatter = formatter

	elsif formatter.respond_to?( :to_sym )
		@formatter = Loggability::Formatter.create( formatter )

	else
		raise ArgumentError, "don't know what to do with a %p formatter (%p)" %
			[ formatter.class, formatter ]
	end
end

#formatterObject

Return the current formatter used to format log messages.



269
270
271
# File 'lib/loggability/logger.rb', line 269

def formatter
	return ( @formatter || @default_formatter )
end

#inspectObject

Return a human-readable representation of the object suitable for debugging.



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/loggability/logger.rb', line 139

def inspect
	dev = if self.logdev.respond_to?( :dev )
			self.logdev.dev.class
		else
			self.logdev
		end

	return "#<%p:%#x severity: %s, formatter: %s, outputting to: %p>" % [
		self.class,
		self.object_id * 2,
		self.level,
		self.formatter.class.name.sub( /.*::/, '' ).downcase,
		dev,
	]
end

#levelObject

Return the logger’s level as a Symbol.



219
220
221
# File 'lib/loggability/logger.rb', line 219

def level
	return LOG_LEVEL_NAMES[ self.sev_threshold ]
end

#level=(newlevel) ⇒ Object

Set the logger level to newlevel, which can be a numeric level (e.g., Logger::DEBUG, etc.), or a symbolic level (e.g., :debug, :info, etc.)



226
227
228
229
230
# File 'lib/loggability/logger.rb', line 226

def level=( newlevel )
	newlevel = LOG_LEVELS[ newlevel.to_sym ] if
		newlevel.respond_to?( :to_sym ) && LOG_LEVELS.key?( newlevel.to_sym )
	super( newlevel )
end

#output_to(target, *args) ⇒ Object Also known as: write_to

Change the log device to log to target instead of what it was before. Any additional args are passed to the LogDevice’s constructor. In addition to Logger’s support for logging to IO objects and files (given a filename in a String), this method can also set up logging to any object that responds to #<<.



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/loggability/logger.rb', line 245

def output_to( target, *args )
	if target.is_a?( Logger::LogDevice ) || target.is_a?( Loggability::LogDevice )
		self.logdev = target
	elsif target.respond_to?( :write ) || target.is_a?( String )
		opts = { :shift_age => args.shift || 0, :shift_size => args.shift || 1048576 }
		self.logdev = Logger::LogDevice.new( target, **opts )
	elsif target.respond_to?( :any? ) && target.any?( Loggability::LogDevice )
		self.logdev = MultiDevice.new( target )
	elsif target.respond_to?( :<< )
		self.logdev = Loggability::LogDevice.create( :appending, target )
	elsif target.is_a?( Symbol )
		self.logdev = Loggability::LogDevice.create( target, *args )
	else
		raise ArgumentError, "don't know how to output to %p (a %p)" % [ target, target.class ]
	end
end

#proxy_for(object) ⇒ Object

Create a logging proxy for object that will include its name as the ‘progname’ of each message.



335
336
337
# File 'lib/loggability/logger.rb', line 335

def proxy_for( object )
	return ObjectNameProxy.new( self, object )
end

#restore_settings(settings) ⇒ Object

Restore the level, logdev, and formatter from the given settings.



207
208
209
210
211
# File 'lib/loggability/logger.rb', line 207

def restore_settings( settings )
	self.level = settings[:level]            if settings[ :level ]
	self.output_to( settings[:logdev] )      if settings[ :logdev ]
	self.format_with( settings[:formatter] ) if settings[ :formatter ]
end

#settingsObject

Return a Hash that contains its settings suitable for restoration via #restore_settings later.



197
198
199
200
201
202
203
# File 'lib/loggability/logger.rb', line 197

def settings
	return {
		level:     self.level,
		logdev:    self.logdev,
		formatter: self.formatter,
	}
end

#write(message) ⇒ Object

Rack::CommonLogger compatibility method – append a message at ‘info’ level.



188
189
190
191
192
# File 'lib/loggability/logger.rb', line 188

def write( message )
	unless self.logdev.nil?
		self.add( Logger::INFO, message )
	end
end