Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updates to README file

  • Loading branch information...
commit 246a5ccad35e2208bd47097034582dc9d211f810 1 parent 7fddd59
@fhellwig authored
Showing with 22 additions and 44 deletions.
  1. +9 −6 README.md
  2. +13 −38 lib/Log.js
View
15 README.md
@@ -54,9 +54,9 @@ There are five corresponding log methods:
log.debug(message [,args]);
log.trace(message [,args]);
-Each of these takes a message string (or an Error object) as the first parameter. The message can contain optional placeholders that are replaced by the values of any additional arguments.
+Each of these takes a message string (or an object, such as an Error) as the first parameter. The message can contain optional placeholders that are replaced by the values of any additional arguments.
-- If the first argument is an Error object, then the log message is either `<errorType>: <message>` (if the error object has the `errorType` property) or `<name>: <message>` (if it does not have the `errorType` property). This supports frameworks that indicate the error description using the `errorType` property instead of the `name` property.
+- If the first argument is an object, then that object is converted to a string and becomes the error message.
- If the arguments following the `message` parameter are primitive values, then these values are accessed using numerical placeholders. For example, `{0}` is the first argument after the `message` parameter, `{1}` is the second argument after the `message` parameter, and so on.
@@ -88,14 +88,17 @@ Note that every log instance exports the levels as constants. Therefore, calling
The default log output is *stderr*. The log output can be set by calling the `setOutput({Object|String})` method or by setting the `STDLOG_OUTPUT` environment variable.
-If the argument is an object, then is must provide a `write` function. If the argument is a string, then the following rules apply:
+If the argument is an object, then is must provide a `write` function.
+
+If the argument is a string, then the following rules apply:
1. The string `stderr` is interpreted as the *stderr* stream.
2. The string `stdout` is interpreted as the *stdout* stream.
-3. A string beginning with a dot is resolved against the current working directory.
-4. A string *not* beginning with a dot is resolved against the package or module directory of the parent module (the one requiring the stdlog package).
+3. Otherwise, the string is the pathname of a log file subject to the following:
+ - A string beginning with a dot is resolved against the current working directory.
+ - A string *not* beginning with a dot is resolved against the package or module directory of the parent module (the one requiring the stdlog package).
-For the last two cases, a log file having the resolved name is created if it does not exist. Log messages are then appended to that file.
+In the case of a log file, a file having the resolved name is created if it does not exist. Any directory in the log file pathname must exist. Log messages are then appended to that file.
### Log Format
View
51 lib/Log.js
@@ -62,31 +62,6 @@ Log.prototype.DEBUG = DEBUG;
Log.prototype.TRACE = TRACE;
//-----------------------------------------------------------------------------
-// PRIVATE UTILITY METHODS
-//-----------------------------------------------------------------------------
-
-/**
- * Returns true if the argument is a non-null object.
- */
-function isObject(arg) {
- return (arg !== null) && (typeof arg === 'object');
-}
-
-/**
- * Returns true if the argument is a non-empty string.
- */
-function isString(arg) {
- return (typeof arg === 'string') && (arg.length !== 0);
-}
-
-/**
- * Returns true if the argument is an object with a filename string property.
- */
-function isModule(arg) {
- return isObject(arg) && isString(arg.filename);
-}
-
-//-----------------------------------------------------------------------------
// LOG METHODS
//-----------------------------------------------------------------------------
@@ -194,9 +169,12 @@ Log.prototype.setLevel = function (level) {
* Sets the log output. This can either be a stream or a string. If the string
* is 'stderr' or 'stdout', then that stream is used. Otherwise, it is assumed
* to be the pathname of the log file and messages are appended to that file.
+ *
+ * Note: We are liberal in what constitutes a stream. Any object having a write
+ * method is valid, thereby allowing writers that are not stream instances.
*/
Log.prototype.setOutput = function (output) {
- if (output instanceof stream) {
+ if (typeof output === 'object' && typeof output.write === 'function') {
this.output = output;
} else if (typeof output === 'string') {
if (output === 'stderr') {
@@ -242,20 +220,19 @@ Log.prototype.fullName = function () {
/**
- * Formats the message part of the log string. The first elements of the args
- * array must be a string or an Error object. Throws a TypeError if it is not.
+ * Formats the message part of the log string. Any embedded CRLF or LF line
+ * terminators are prefixed with the '> ' string so multi-line error messages
+ * can be parsed from the log.
*/
Log.prototype.formatMessage = function (args) {
+ var message;
var arg = args[0];
if (typeof arg === 'string') {
- return strformat.apply(null, args);
- } else if (arg instanceof Error) {
- // Some frameworks use errorType for the error description.
- var name = arg.errorType ? arg.errorType : arg.name;
- return strformat('{0}: {1}', name, arg.message);
+ message = strformat.apply(null, args);
} else {
- throw new TypeError(strformat('Invalid log argument: {0} (expected a string or an Error object)', arg));
+ message = '' + arg;
}
+ return message.replace(/\r?\n/g, os.EOL + '> ');
};
/**
@@ -265,16 +242,14 @@ Log.prototype.formatMessage = function (args) {
* can be parsed from the log.
*/
Log.prototype.write = function (level, args) {
- var message = this.formatMessage(args);
- message = message.replace(/\r?\n/g, os.EOL + '> ');
var rec = {
timestamp: (new Date()).toISOString(),
level: LEVELS[level],
pid: process.pid,
name: this.fullName(),
- message: message
+ message: this.formatMessage(args)
};
- message = strformat(this.format, rec) + os.EOL;
+ var message = strformat(this.format, rec) + os.EOL;
if (typeof this.output === 'string') {
fs.appendFileSync(this.output, message);
} else {
Please sign in to comment.
Something went wrong with that request. Please try again.