Logger (class)
Overview
Summary
The Logger class provides a simple object-oriented approach to logging information, both to the Output panel and to file, including basic templating and substitution of placeholder variables.
Contents
Concept
Overview
Often in applications, you will want to log or report some kind of information, e.g. the intention or perhaps result of an action. Doing this with traces to the Output panel is fine, but in more complex applications, sometimes more structure or consistency is necessary.
The Logger class has various features that make it suitable for such a task:
- It can log messages to both the Output panel and to file
- It uses a template into which log messages are formatted
- It allows the use of placeholder variables, such as {date} or {time}
- It has some file-specific methods that allow you to manage the log file
Template
The Logger constructor as its first argument takes a formatted string template, into which future log messages are formatted. A typical template string might look something like this:
> xjsfl: {message}
This allows you to assign a consistent format to all log messages, and only pass in the message (formatted into the message placeholder variable) instead of the whole string each time you log:
var log = new Logger('> xjsfl: {message}', 'c:/temp/xjsfl log.txt'); log.log('New message logged at {time}');
The above code would output to a file in the temp directory:
> xjsfl: New message logged at 14:34:15
Placeholder variables
Because Logger is based on a simple templating system, placholder variables allow you keep things simple, yet flexible.
As seen above, the main placeholder variable (and the default template, should you not supply one) is {message}:
{message} The message passed to the log() function, i.e. "Loading classes..."
The following standard placeholder variables are recalculated internally each time you log, and can be used in both the template string, or the logged message:
{timestamp} The current timestamp, i.e. "Fri, 03 Feb 2012 01:38:16 GMT" {date} The current date, i.e. "Fri, 03 Feb 2012" {time} The current time, i.e. "01:38:16" {millitime} The current time with milliseconds, i.e. "01:38:16:124" {count} An incremental count of the number of items logged since instantiation, i.e. "34"
The following placeholder variable can be used in both the template string or the logged message, but can be passed in via the log() method only:
{type} An optional log type, i.e. "INFO"
Finally, you can pass in any custom variables you like, which you supply via the log() method:
{foo} Must be passed in via log(), i.e. template.log('hello', {foo:'Dave'})
Usage
Template vs message variables
Standard variables in template:
template: '> xjsfl: "{message}" logged at {time}' log(): 'Hello there'
result: > xjsfl: "Hello there" logged at 14:34:15'
Standard variables in template and log():
template: '> xjsfl: "{message}"' log(): 'Hello there logged at {time}'
result: > xjsfl: "Hello there logged at 14:34:15"User variables in log():
template: '> xjsfl: "{message}" logged at {time} by {name}' log(): 'Hello there', {name:'Dave'}
result: > xjsfl: "Hello there" logged at 14:34:15 by Dave
See the SimpleTemplate class for further infomation on the templating functionality in the Logger class.
Debugging code
The logging class can be very useful when writing a complex application that crashes, or worse, hangs Flash. It's easy to add logging traces at key points in your code, then check the log file to see where the paper trail ends.
Whilst writing and testing the URI class, a test URI was causing Flash to hang. Using the logger class, it was fairly easy to trace the error to the section of code that resolved relative-parent folders:
// debug logger.log(' > correct() : doubleslashes'); // replace double-slashes path = path.replace(/\/+/g, '/'); // debug logger.log(' > correct() : ../'); // resolve ../ while(path.indexOf('../') > -1) { logger.log(' > correct() 1: ' + path); path = path.replace(/(^|\/)[^\/]+\/\.\.\//, "/"); logger.log(' > correct() 2: ' + path); } // debug logger.log(' > correct() : ./');
In the buggy version of the file, the RegEx that was supposed to be fully-resolving the ../ tokens was leaving one in, and so the while-loop never completed. The error log thus-contained many message of the same kind!
The output of the final log can be seen here: file-debugging-log.txt
API
Logger(template, uriOrPath, append)
Logger constructor
An Output panel logger (with no file logging) is created by supplying only an input pattern to the constructor.
var logger = new Logger('{timestamp} - {message}'; logger.log('Something happened');
Sun, 05 Feb 2012 00:41:47 GMT - Something happened
A file logger (with no output panel traces) is created by supplying both an input pattern, and a file path or URI:
var uri = '{user}temp/logs/user.txt'; var logger = new Logger('{timestamp} - {message}', uri); logger.log('Something happened');
Note that a file logger does not by default trace to the output panel. To trace to the output panel you need to pass a Boolean true in the log() call:
logger.log('This message was written to both the file and the output panel...', true);
It is also possible for multiple loggers to write to the same file:
var path = 'c:/temp/log.txt'; var logger1 = new Logger('> log1: {message}', path); var logger2 = new Logger('> log2: {message}', path); logger1.log('This is from log 1') logger2.log('And this is from log 2') logger1.log('And this is from log 1 again') logger1.open();
> log1: This is from log 1 > log2: And this is from log 2 > log1: And this is from log 1 again
Properties
template
The SimpleTemplate the Logger uses to create the log
file
The File object that contains the log data
count
An incremental count that can be used within the Template as {count}
Logging methods
log(message, $type, $params, $trace)
Log a message (note that the order of $ arguments may be swapped)
The log() method is the workhorse of the Logger class, and allows you to pass in a message, message type, and custom parameters should you wish. At its most basic level, you would simply log a message.
The following example logs a message to a file:
var logger = new Logger('{time} - {message}', '{user}temp/logs/user.txt'); logger.log('Something happened');
12:02:34 - Something happened
The following example logs a message to a file, along with a message type:
var logger = new Logger('{time} - {type} - {message}', '{user}temp/logs/user.txt'); logger.log('Something happened', 'INFO');
12:02:34 - INFO - Something happened
Note that you can also trigger callbacks by registering a certain log type using addtrigger().
The following example logs a message to a file, along with some custom variables:
var logger = new Logger('{time} - {a} {b} {c}', '{user}temp/logs/user.txt'); logger.log('Something happened', {a:1, b:2, c:3});
12:02:34 - 1 2 3
addTrigger(type, callback)
Add a callback function that should fire when a log with a certain type is logged
The log() method of the logger class allows you to pass in an additional string you may use to assign types to your log messages, such as "info", "warn", "error", etc. addTrigger() allows you to bind callbacks to these types, so if a message of a certain type is received, you can run some custom code, such as running a batch file that might send an email, or calling a panel that might connect to a server.
The following example demonstrates how to fire a custom action when a message of type "error" is logged:
/** * Callback function to handle log trigger * @param {Logger} logger The logger instance * @param {String} message The log message * @param {Object} data The data passed to the log */ function onError(logger, message, data) { alert('There is an error: ' + data.message); logger.open(); } // set up the logger var logger = new Logger('[{type}]\t{message}', '{user}temp/logs/new log.txt'); logger.addTrigger('error', onError) // start logging logger .log('Everything is fine...', 'info') // nothing will fire here, as "info" types are not registered .log('Oh dear!', 'error');
[info] Everything is fine...
[error] Oh dear!
File-related methods
write(message, trace)
Writes directly to the log file, if there is one
Usually, you will use the log() method to write to the log file or output panel, but there may be times when you wish to write directly to the log file or output panel.
The following example logs two messages with a divider between them:
var logger = new Logger('{time} - {message}'); logger .log('This is a message...') .write('\n------------------------------------------------------------\n') .log('...and this is another message');
12:32:51 - This is a message...
------------------------------------------------------------
12:32:51 - ...and this is another message
clear()
Clears the log file
The following example creates and clears an existing log file, then writes a new message to it:
var logger = new Logger(null, 'user/temp/logs/user.txt'); logger .log('You will never read this...') .clear() .log('...but you will read this!') .open();
...but you will read this!
open()
Opens the log file in a text editor, if there is one
The following example creates a log file, logs a message then opens the log in the user's default text editor:
var logger = new Logger(); logger .log('You should now be reading this') .open();
reveal()
Reveals the log file in the Explorer / Finder, if there is one
The following example creates a log file, logs a message then reveals the log file in the user's Explorer / Finder:
var logger = new Logger(null, 'user/temp/logs/user.txt'); logger .log('Hello there') .reveal();
remove()
Revoves the log file on disk, if there is one
The following example creates a log file, logs a message then deletes the log from the user's hard drive:
var logger = new Logger(null, 'user/temp/logs/user.txt'); logger .log('You will never read this!') .remove();
File-related accessors
contents
Get the contents of the log file Directly set the contents of the log file
Sometimes you will just want to manipulate the contents of the log file manually.
The following example creates a log file, then both reads and wrotes directly to the contents property:
var logger = new Logger('', 'user/temp/logs/user.txt'); logger.log('This is some content'); trace(logger.contents) logger.contents += 'This is some more content' trace(logger.contents)
This is some content This is some content This is some more content
Utility methods
toString()
Returns a String representation of the instance
The following example traces the string represnetation of the logger instance:
var logger = new Logger('', '../temp/logs/user.txt');
trace(logger);
[object Logger template="{message}" path="E:/Projects/xJSFL/user/temp/logs/user.txt"]
Comments are closed.