[CLI] Readable logs on Windows with chalk colors (#15557) (#17636)

* [colors] try new cli colors

* [colors] try magentaBright instead of magenta

* [colors] try white for log text

* [colors] replace all remaining ansicolors with chalk

* [colors] try yellowBright instead of yellow

* remove ansicolors from package.json

* [tests] attempt to fix tests

* [tests] attempt to fix tests again

* [color] backgrounds, cleanup

* [color] update yarn.lock
This commit is contained in:
archana 2018-04-10 10:57:56 -05:00 committed by GitHub
parent 8cc5aed4ef
commit a03e37cb9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 54 additions and 59 deletions

View file

@ -108,6 +108,7 @@
"brace": "0.10.0",
"bunyan": "1.7.1",
"cache-loader": "1.0.3",
"chalk": "2.3.0",
"check-hash": "1.0.1",
"color": "1.0.3",
"commander": "2.8.1",
@ -224,7 +225,6 @@
"babel-eslint": "8.1.2",
"backport": "2.2.0",
"chai": "3.5.0",
"chalk": "2.0.1",
"chance": "1.0.6",
"cheerio": "0.22.0",
"chokidar": "1.6.0",

View file

@ -5,6 +5,7 @@ import { findIndex } from 'lodash';
import MockClusterFork from './_mock_cluster_fork';
import Worker from '../worker';
import Log from '../../log';
const workersToShutdown = [];
@ -70,7 +71,7 @@ describe('CLI cluster manager', function () {
describe('#shutdown', function () {
describe('after starting()', function () {
it('kills the worker and unbinds from message, online, and disconnect events', async function () {
const worker = setup();
const worker = setup({ log: new Log(false, true) });
await worker.start();
expect(worker).to.have.property('online', true);
const fork = worker.fork;
@ -97,27 +98,29 @@ describe('CLI cluster manager', function () {
describe('#parseIncomingMessage()', function () {
describe('on a started worker', function () {
it(`is bound to fork's message event`, async function () {
const worker = setup();
const worker = setup({ log: new Log(false, true) });
await worker.start();
sinon.assert.calledWith(worker.fork.on, 'message');
});
});
it('ignores non-array messsages', function () {
const worker = setup();
worker.parseIncomingMessage('some string thing');
worker.parseIncomingMessage(0);
worker.parseIncomingMessage(null);
worker.parseIncomingMessage(undefined);
worker.parseIncomingMessage({ like: 'an object' });
worker.parseIncomingMessage(/weird/);
});
describe('do after', function () {
it('ignores non-array messsages', function () {
const worker = setup();
worker.parseIncomingMessage('some string thing');
worker.parseIncomingMessage(0);
worker.parseIncomingMessage(null);
worker.parseIncomingMessage(undefined);
worker.parseIncomingMessage({ like: 'an object' });
worker.parseIncomingMessage(/weird/);
});
it('calls #onMessage with message parts', function () {
const worker = setup();
const stub = sinon.stub(worker, 'onMessage');
worker.parseIncomingMessage([10, 100, 1000, 10000]);
sinon.assert.calledWith(stub, 10, 100, 1000, 10000);
it('calls #onMessage with message parts', function () {
const worker = setup();
const stub = sinon.stub(worker, 'onMessage');
worker.parseIncomingMessage([10, 100, 1000, 10000]);
sinon.assert.calledWith(stub, 10, 100, 1000, 10000);
});
});
});
@ -156,7 +159,7 @@ describe('CLI cluster manager', function () {
describe('#start', function () {
describe('when not started', function () {
it('creates a fork and waits for it to come online', async function () {
const worker = setup();
const worker = setup({ log: new Log(false, true) });
sinon.spy(worker, 'on');
@ -167,7 +170,7 @@ describe('CLI cluster manager', function () {
});
it('listens for cluster and process "exit" events', async function () {
const worker = setup();
const worker = setup({ log: new Log(false, true) });
sinon.spy(process, 'on');
sinon.spy(cluster, 'on');

View file

@ -150,7 +150,7 @@ export default class Worker extends EventEmitter {
this.fork = cluster.fork(this.env);
this.forkBinder = new BinderFor(this.fork);
// when the fork sends a message, comes online, or looses it's connection, then react
// when the fork sends a message, comes online, or loses its connection, then react
this.forkBinder.on('message', msg => this.parseIncomingMessage(msg));
this.forkBinder.on('online', () => this.onOnline());
this.forkBinder.on('disconnect', () => this.onDisconnect());

View file

@ -1,6 +1,6 @@
import _ from 'lodash';
import ansicolors from 'ansicolors';
import chalk from 'chalk';
export const green = _.flow(ansicolors.black, ansicolors.bgGreen);
export const red = _.flow(ansicolors.white, ansicolors.bgRed);
export const yellow = _.flow(ansicolors.black, ansicolors.bgYellow);
export const green = _.flow(chalk.black, chalk.bgGreen);
export const red = _.flow(chalk.white, chalk.bgRed);
export const yellow = _.flow(chalk.black, chalk.bgYellow);

View file

@ -79,7 +79,7 @@ describe(`Server logging configuration`, function () {
function expectPlainTextLogLine(line) {
// assert
const tags = `[\u001b[32minfo\u001b[39m][\u001b[36mconfig\u001b[39m]`;
const tags = `[info][config]`;
const status = `Reloaded logging configuration due to SIGHUP.`;
const expected = `${tags} ${status}`;
const actual = line.slice(-expected.length);

View file

@ -1,7 +1,7 @@
import { format } from 'util';
import { PassThrough } from 'stream';
import { magenta, yellow, red, blue, green, dim } from 'chalk';
import { magentaBright, yellow, red, blue, green, dim } from 'chalk';
import { parseLogLevel } from './log_levels';
@ -20,7 +20,7 @@ export function createToolingLog(initialLogLevelName = 'silent') {
verbose(...args) {
if (!logLevel.flags.verbose) return;
this.write(' %s ', magenta('sill'), format(...args));
this.write(' %s ', magentaBright('sill'), format(...args));
}
debug(...args) {

View file

@ -2,7 +2,7 @@ import Stream from 'stream';
import moment from 'moment';
import { get, _ } from 'lodash';
import numeral from '@elastic/numeral';
import ansicolors from 'ansicolors';
import chalk from 'chalk';
import stringify from 'json-stringify-safe';
import querystring from 'querystring';
import applyFiltersToKeys from './apply_filters_to_keys';
@ -19,10 +19,10 @@ function serializeError(err = {}) {
}
const levelColor = function (code) {
if (code < 299) return ansicolors.green(code);
if (code < 399) return ansicolors.yellow(code);
if (code < 499) return ansicolors.magenta(code);
return ansicolors.red(code);
if (code < 299) return chalk.green(code);
if (code < 399) return chalk.yellow(code);
if (code < 499) return chalk.magentaBright(code);
return chalk.red(code);
};
@ -100,8 +100,8 @@ export default class TransformObjStream extends Stream.Transform {
data.message += ' ';
data.message += levelColor(data.res.statusCode);
data.message += ' ';
data.message += ansicolors.brightBlack(data.res.responseTime + 'ms');
data.message += ansicolors.brightBlack(' - ' + numeral(contentLength).format('0.0b'));
data.message += chalk.gray(data.res.responseTime + 'ms');
data.message += chalk.gray(' - ' + numeral(contentLength).format('0.0b'));
}
else if (data.type === 'ops') {
_.defaults(data, _.pick(event, [
@ -110,19 +110,19 @@ export default class TransformObjStream extends Stream.Transform {
'proc',
'load'
]));
data.message = ansicolors.brightBlack('memory: ');
data.message = chalk.gray('memory: ');
data.message += numeral(get(data, 'proc.mem.heapUsed')).format('0.0b');
data.message += ' ';
data.message += ansicolors.brightBlack('uptime: ');
data.message += chalk.gray('uptime: ');
data.message += numeral(get(data, 'proc.uptime')).format('00:00:00');
data.message += ' ';
data.message += ansicolors.brightBlack('load: [');
data.message += chalk.gray('load: [');
data.message += get(data, 'os.load', []).map(function (val) {
return numeral(val).format('0.00');
}).join(' ');
data.message += ansicolors.brightBlack(']');
data.message += chalk.gray(']');
data.message += ' ';
data.message += ansicolors.brightBlack('delay: ');
data.message += chalk.gray('delay: ');
data.message += numeral(get(data, 'proc.delay')).format('0.000');
}
else if (data.type === 'error') {

View file

@ -1,5 +1,5 @@
import _ from 'lodash';
import ansicolors from 'ansicolors';
import chalk from 'chalk';
import LogFormat from './log_format';
@ -14,7 +14,7 @@ const statuses = [
];
const typeColors = {
log: 'blue',
log: 'white',
req: 'green',
res: 'green',
ops: 'cyan',
@ -23,18 +23,18 @@ const typeColors = {
info: 'green',
error: 'red',
warning: 'red',
fatal: 'magenta',
status: 'yellow',
debug: 'brightBlack',
server: 'brightBlack',
fatal: 'magentaBright',
status: 'yellowBright',
debug: 'gray',
server: 'gray',
optmzr: 'white',
managr: 'green',
optimize: 'magenta',
listening: 'magenta'
optimize: 'magentaBright',
listening: 'magentaBright'
};
const color = _.memoize(function (name) {
return ansicolors[typeColors[name]] || _.identity;
return chalk[typeColors[name]] || _.identity;
});
const type = _.memoize(function (t) {

View file

@ -1,4 +1,4 @@
import { bgRed, white } from 'ansicolors';
import { bgRed, white } from 'chalk';
import { execSync } from 'child_process';
import { createInterface } from 'readline';

View file

@ -1,4 +1,4 @@
import { green, magenta } from 'ansicolors';
import { green, magentaBright } from 'chalk';
export function initVerboseRemoteLogging(log, server) {
const wrap = (original, httpMethod) => (path, requestData, pathParts) => {
@ -25,7 +25,7 @@ export function initVerboseRemoteLogging(log, server) {
message = err.message;
}
log.verbose(`[remote] < %s %s ${magenta('ERR')} %j`, httpMethod, url, message.split(/\r?\n/)[0]);
log.verbose(`[remote] < %s %s ${magentaBright('ERR')} %j`, httpMethod, url, message.split(/\r?\n/)[0]);
throw error;
});
};

View file

@ -2007,14 +2007,6 @@ chai@3.5.0, "chai@>=1.9.2 <4.0.0":
deep-eql "^0.1.3"
type-detect "^1.0.0"
chalk@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.0.1.tgz#dbec49436d2ae15f536114e76d14656cdbc0f44d"
dependencies:
ansi-styles "^3.1.0"
escape-string-regexp "^1.0.5"
supports-color "^4.0.0"
chalk@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e"