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

feat!: Highlight timestamp as util.inspect hightlights Dates #23

Merged
merged 5 commits into from
Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,39 @@ log.error('oh no!');
### `log(msg...)`

Logs the message as if you called `console.log` but prefixes the output with the
current time in HH:MM:ss format.
current time in HH:mm:ss format.

### `log.error(msg...)`

Logs the message as if you called `console.error` but prefixes the output with the
current time in HH:MM:ss format.
current time in HH:mm:ss format.

### `log.warn(msg...)`

Logs the message as if you called `console.warn` but prefixes the output with the
current time in HH:MM:ss format.
current time in HH:mm:ss format.

### `log.info(msg...)`

Logs the message as if you called `console.info` but prefixes the output with the
current time in HH:MM:ss format.
current time in HH:mm:ss format.

### `log.dir(msg...)`

Logs the message as if you called `console.dir` but prefixes the output with the
current time in HH:MM:ss format.
current time in HH:mm:ss format.

## Styling

If the terminal that you are logging to supports colors, the timestamp will be formatted as though it were a `Date` being formatted by `util.inspect()`. This means that it will be formatted as magenta by default but can be adjusted following node's [Customizing util.inspect colors](https://nodejs.org/dist/latest-v10.x/docs/api/util.html#util_customizing_util_inspect_colors) documentation.

For example, this will cause the logged timestamps (and other dates) to display in red:

```js
var utils = require('utils');
phated marked this conversation as resolved.
Show resolved Hide resolved

util.inspect.styles.date = 'red';
```

## License

Expand Down
24 changes: 16 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use strict';

var util = require('util');
var Console = require('console').Console;
var gray = require('ansi-gray');
var timestamp = require('time-stamp');
var supportsColor = require('color-support');

var console = new Console({
Expand All @@ -15,24 +14,33 @@ function hasFlag(flag) {
return process.argv.indexOf('--' + flag) !== -1;
}

function addColor(str) {
function hasColors() {
if (hasFlag('no-color')) {
return str;
return false;
}

if (hasFlag('color')) {
return gray(str);
return true;
}

if (supportsColor()) {
return gray(str);
return true;
}

return str;
return false;
}

function Timestamp() {
this.now = new Date();
}

Timestamp.prototype[util.inspect.custom] = function (depth, opts) {
var timestamp = this.now.toLocaleTimeString('en', { hour12: false });
return '[' + opts.stylize(timestamp, 'date') + ']';
}

function getTimestamp() {
return '[' + addColor(timestamp('HH:mm:ss')) + ']';
return util.inspect(new Timestamp(), { colors: hasColors() });
}

function log() {
Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@
"test": "nyc mocha --async-only"
},
"dependencies": {
"ansi-gray": "^0.1.1",
"color-support": "^1.1.3",
"time-stamp": "^2.2.0"
"color-support": "^1.1.3"
},
"devDependencies": {
"eslint": "^7.32.0",
Expand Down
82 changes: 56 additions & 26 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,60 @@ var nodeVersion = require('parse-node-version')(process.version);
var isLessThanNode12 = nodeVersion.major < 12;

var util = require('util');
var inspect = util.inspect;

var expect = require('expect');
var sinon = require('sinon');
var gray = require('ansi-gray');
var timestamp = require('time-stamp');

/* eslint-disable node/no-unsupported-features/es-syntax */
// Reference: https://github.com/nodejs/node/blob/4e2ceba/lib/internal/util/inspect.js#L267-L274
function stylizeWithColor(str, styleType) {
const style = inspect.styles[styleType];
if (style !== undefined) {
const color = inspect.colors[style];

return `\u001b[${color[0]}m${str}\u001b[${color[1]}m`;
}
return str;
}
/* eslint-enable node/no-unsupported-features/es-syntax */

function withColor(str) {
return stylizeWithColor(str, 'date');
}

var log = require('../');

var stdoutSpy = sinon.spy(process.stdout, 'write');
var stderrSpy = sinon.spy(process.stderr, 'write');

function expectCloseTo(arg, needsColor) {
var now = new Date();
var time;
var maxAttempts = 5;
for (var attempts = 1; attempts < maxAttempts; attempts++) {
try {
time = now.toLocaleTimeString('en', { hour12: false });
if (needsColor) {
expect(arg).toEqual('[' + withColor(time) + '] ');
} else {
expect(arg).toEqual('[' + time + '] ');
}
// Return on a success
return;
} catch (err) {
if (attempts === maxAttempts) {
throw err;
} else {
now.setSeconds(now.getSeconds() - 1);
}
}
}
}

describe('log()', function () {
this.timeout(5000);

var term = process.env.TERM;
var colorterm = process.env.COLORTERM;

Expand All @@ -35,8 +77,7 @@ describe('log()', function () {

it('should work i guess', function (done) {
log(1, 2, 3, 4, 'five');
var time = timestamp('HH:mm:ss');
expect(stdoutSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
expectCloseTo(stdoutSpy.args[0][0], true);
if (isLessThanNode12) {
expect(stdoutSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
} else {
Expand All @@ -48,8 +89,7 @@ describe('log()', function () {

it('should accept formatting', function (done) {
log('%s %d %j', 'something', 0.1, { key: 'value' });
var time = timestamp('HH:mm:ss');
expect(stdoutSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
expectCloseTo(stdoutSpy.args[0][0], true);
expect(stdoutSpy.args[1][0]).toEqual('something 0.1 {"key":"value"}\n');

done();
Expand All @@ -59,8 +99,7 @@ describe('log()', function () {
process.argv.push('--no-color');

log(1, 2, 3, 4, 'five');
var time = timestamp('HH:mm:ss');
expect(stdoutSpy.args[0][0]).toEqual('[' + time + '] ');
expectCloseTo(stdoutSpy.args[0][0], false);
if (isLessThanNode12) {
expect(stdoutSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
} else {
Expand All @@ -76,8 +115,7 @@ describe('log()', function () {
process.argv.push('--color');

log(1, 2, 3, 4, 'five');
var time = timestamp('HH:mm:ss');
expect(stdoutSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
expectCloseTo(stdoutSpy.args[0][0], true);
if (isLessThanNode12) {
expect(stdoutSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
} else {
Expand All @@ -94,8 +132,7 @@ describe('log()', function () {
delete process.env.COLORTERM;

log(1, 2, 3, 4, 'five');
var time = timestamp('HH:mm:ss');
expect(stdoutSpy.args[0][0]).toEqual('[' + time + '] ');
expectCloseTo(stdoutSpy.args[0][0], false);
if (isLessThanNode12) {
expect(stdoutSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
} else {
Expand All @@ -117,8 +154,7 @@ describe('log.info()', function () {

it('should work i guess', function (done) {
log.info(1, 2, 3, 4, 'five');
var time = timestamp('HH:mm:ss');
expect(stdoutSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
expectCloseTo(stdoutSpy.args[0][0], true);
if (isLessThanNode12) {
expect(stdoutSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
} else {
Expand All @@ -130,8 +166,7 @@ describe('log.info()', function () {

it('should accept formatting', function (done) {
log.info('%s %d %j', 'something', 0.1, { key: 'value' });
var time = timestamp('HH:mm:ss');
expect(stdoutSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
expectCloseTo(stdoutSpy.args[0][0], true);
expect(stdoutSpy.args[1][0]).toEqual('something 0.1 {"key":"value"}\n');

done();
Expand All @@ -146,8 +181,7 @@ describe('log.dir()', function () {

it('should format an object with util.inspect', function (done) {
log.dir({ key: 'value' });
var time = timestamp('HH:mm:ss');
expect(stdoutSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
expectCloseTo(stdoutSpy.args[0][0], true);
expect(stdoutSpy.args[1][0]).toEqual(util.inspect({ key: 'value' }) + '\n');

done();
Expand All @@ -162,8 +196,7 @@ describe('log.warn()', function () {

it('should work i guess', function (done) {
log.warn(1, 2, 3, 4, 'five');
var time = timestamp('HH:mm:ss');
expect(stderrSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
expectCloseTo(stdoutSpy.args[0][0], true);
if (isLessThanNode12) {
expect(stderrSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
} else {
Expand All @@ -175,8 +208,7 @@ describe('log.warn()', function () {

it('should accept formatting', function (done) {
log.warn('%s %d %j', 'something', 0.1, { key: 'value' });
var time = timestamp('HH:mm:ss');
expect(stderrSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
expectCloseTo(stdoutSpy.args[0][0], true);
expect(stderrSpy.args[1][0]).toEqual('something 0.1 {"key":"value"}\n');

done();
Expand All @@ -191,8 +223,7 @@ describe('log.error()', function () {

it('should work i guess', function (done) {
log.error(1, 2, 3, 4, 'five');
var time = timestamp('HH:mm:ss');
expect(stderrSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
expectCloseTo(stdoutSpy.args[0][0], true);
if (isLessThanNode12) {
expect(stderrSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
} else {
Expand All @@ -204,8 +235,7 @@ describe('log.error()', function () {

it('should accept formatting', function (done) {
log.error('%s %d %j', 'something', 0.1, { key: 'value' });
var time = timestamp('HH:mm:ss');
expect(stderrSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
expectCloseTo(stdoutSpy.args[0][0], true);
expect(stderrSpy.args[1][0]).toEqual('something 0.1 {"key":"value"}\n');

done();
Expand Down