Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node: configurable util.inspect() options #327

Merged
merged 6 commits into from
Dec 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions Readme.md → README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,36 @@ Then, run the program to be debugged as usual.

## Conventions

If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".

## Wildcards

The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.

You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:".

## Environment Variables

When running through Node.js, you can set a few environment variables that will
change the behavior of the debug logging:

| Name | Purpose |
|-----------|-------------------------------------------------|
| `DEBUG` | Enables/disabled specific debugging namespaces. |
| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |
| `DEBUG_FD`| File descriptor to output debug logs to. Defaults to stderr. |
| `DEBUG_DEPTH` | Object inspection depth. |
| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |


__Note:__ The environment variables beginning with `DEBUG_` end up being
converted into an Options object that gets used with `%o`/`%O` formatters.
See the Node.js documentation for
[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
for the complete list.

__Note:__ Certain IDEs (such as WebStorm) don't support colors on stderr. In these cases you must set `DEBUG_COLORS` to `1` and additionally change `DEBUG_FD` to `1`.

## Formatters


Expand Down Expand Up @@ -191,12 +213,6 @@ Example:
$ DEBUG_FD=3 node your-app.js 3> whatever.log
```

### Terminal colors

By default colors will only be used in a TTY. However this can be overridden by setting the environment variable `DEBUG_COLORS` to `1`.

Note: Certain IDEs (such as WebStorm) don't support colors on stderr. In these cases you must set `DEBUG_COLORS` to `1` and additionally change `DEBUG_FD` to `1`.

## Authors

- TJ Holowaychuk
Expand Down
7 changes: 2 additions & 5 deletions browser.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/**
* This is the web browser implementation of `debug()`.
*
Expand Down Expand Up @@ -69,8 +68,7 @@ exports.formatters.j = function(v) {
* @api public
*/

function formatArgs() {
var args = arguments;
function formatArgs(args) {
var useColors = this.useColors;

args[0] = (useColors ? '%c' : '')
Expand Down Expand Up @@ -101,7 +99,6 @@ function formatArgs() {
});

args.splice(lastC, 0, c);
return args;
}

/**
Expand Down Expand Up @@ -172,7 +169,7 @@ exports.enable(load());
* @api private
*/

function localstorage(){
function localstorage() {
try {
return window.localStorage;
} catch (e) {}
Expand Down
40 changes: 19 additions & 21 deletions debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Expose `debug()` as the module.
*/

exports = module.exports = debug.debug = debug;
exports = module.exports = createDebug.debug = createDebug.default = createDebug;
exports.coerce = coerce;
exports.disable = disable;
exports.enable = enable;
Expand All @@ -23,7 +23,7 @@ exports.skips = [];
/**
* Map of special "%n" handling functions, for the debug "format" argument.
*
* Valid key names are a single, lowercased letter, i.e. "n".
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
*/

exports.formatters = {};
Expand Down Expand Up @@ -66,17 +66,13 @@ function selectColor(namespace) {
* @api public
*/

function debug(namespace) {
function createDebug(namespace) {

// define the `disabled` version
function disabled() {
}
disabled.enabled = false;

// define the `enabled` version
function enabled() {
function debug() {
// disabled?
if (!debug.enabled) return;

var self = enabled;
var self = debug;

// set `diff` timestamp
var curr = +new Date();
Expand All @@ -86,10 +82,7 @@ function debug(namespace) {
self.curr = curr;
prevTime = curr;

// add the `color` if not set
if (null == self.useColors) self.useColors = exports.useColors();
if (null == self.color && self.useColors) self.color = selectColor(namespace);

// turn the `arguments` into a proper Array
var args = new Array(arguments.length);
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i];
Expand Down Expand Up @@ -120,19 +113,24 @@ function debug(namespace) {
return match;
});

// apply env-specific formatting
args = exports.formatArgs.apply(self, args);
// apply env-specific formatting (colors, etc.)
exports.formatArgs.call(self, args);

var logFn = enabled.log || exports.log || console.log.bind(console);
logFn.apply(self, args);
}
enabled.enabled = true;

var fn = exports.enabled(namespace) ? enabled : disabled;
debug.namespace = namespace;
debug.enabled = exports.enabled(namespace);
debug.useColors = exports.useColors();
debug.color = selectColor(namespae);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

namespae typo here!!!


fn.namespace = namespace;
// env-specific initialization logic for debug instances
if ('function' === typeof exports.init) {
exports.init(debug);
}

return fn;
return debug;
}

/**
Expand Down
88 changes: 54 additions & 34 deletions node.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/**
* Module dependencies.
*/
Expand All @@ -13,6 +12,7 @@ var util = require('util');
*/

exports = module.exports = require('./debug');
exports.init = init;
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
Expand All @@ -25,6 +25,32 @@ exports.useColors = useColors;

exports.colors = [6, 2, 3, 4, 5, 1];

/**
* Build up the default `inspectOpts` object from the environment variables.
*
* $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
*/

exports.inspectOpts = Object.keys(process.env).filter(function (key) {
return /^debug_/i.test(key);
}).reduce(function (obj, key) {
// camel-case
var prop = key
.substring(6)
.toLowerCase()
.replace(/_([a-z])/, function (_, k) { return k.toUpperCase() });

// coerce string value into JS value
var val = process.env[key];
if (/^(yes|on|true|enabled)$/i.test(val)) val = true;
else if (/^(no|off|false|disabled)$/i.test(val)) val = false;
else if (val === 'null') val = null;
else val = Number(val);

obj[prop] = val;
return obj;
}, {});

/**
* The file descriptor to write the `debug()` calls to.
* Set the `DEBUG_FD` env variable to override with another value. i.e.:
Expand All @@ -42,39 +68,28 @@ var stream = 1 === fd ? process.stdout :
*/

function useColors() {
var debugColors = (process.env.DEBUG_COLORS || '').trim().toLowerCase();
if (0 === debugColors.length) {
return tty.isatty(fd);
} else {
return '0' !== debugColors
&& 'no' !== debugColors
&& 'false' !== debugColors
&& 'disabled' !== debugColors;
}
return 'colors' in exports.inspectOpts
? Boolean(exports.inspectOpts.colors)
: tty.isatty(fd);
}

/**
* Map %o to `util.inspect()`, since Node doesn't do that out of the box.
* Map %o to `util.inspect()`, all on a single line.
*/

var inspect = (4 === util.inspect.length ?
// node <= 0.8.x
function (v, colors) {
return util.inspect(v, void 0, void 0, colors);
} :
// node > 0.8.x
function (v, colors) {
return util.inspect(v, { colors: colors });
}
);

exports.formatters.o = function(v) {
return inspect(v, this.useColors)
this.inspectOpts.colors = this.useColors;
return util.inspect(v, this.inspectOpts)
.replace(/\s*\n\s*/g, ' ');
};

/**
* Map %o to `util.inspect()`, allowing multiple lines if needed.
*/

exports.formatters.O = function(v) {
return inspect(v, this.useColors);
this.inspectOpts.colors = this.useColors;
return util.inspect(v, this.inspectOpts);
};

/**
Expand All @@ -83,14 +98,9 @@ exports.formatters.O = function(v) {
* @api public
*/

function formatArgs() {
var len = arguments.length;
var args = new Array(len);
var useColors = this.useColors;
function formatArgs(args) {
var name = this.namespace;
for (var i = 0; i < len; i++) {
args[i] = arguments[i];
}
var useColors = this.useColors;

if (useColors) {
var c = this.color;
Expand All @@ -102,15 +112,14 @@ function formatArgs() {
args[0] = new Date().toUTCString()
+ ' ' + name + ' ' + args[0];
}
return args;
}

/**
* Invokes `console.error()` with the specified arguments.
* Invokes `util.format()` with the specified arguments and writes to `stream`.
*/

function log() {
return stream.write(util.format.apply(this, arguments) + '\n');
return stream.write(util.format.apply(util, arguments) + '\n');
}

/**
Expand Down Expand Up @@ -209,6 +218,17 @@ function createWritableStdioStream (fd) {
return stream;
}

/**
* Init logic for `debug` instances.
*
* Create a new `inspectOpts` object in case `useColors` is set
* differently for a particular `debug` instance.
*/

function init (debug) {
debug.inspectOpts = util._extend({}, exports.inspectOpts);
}

/**
* Enable namespaces listed in `process.env.DEBUG` initially.
*/
Expand Down