Skip to content

Commit

Permalink
feat: add --use-colors option (fixes #2)
Browse files Browse the repository at this point in the history
  • Loading branch information
gajus committed Jun 5, 2019
1 parent acf19b1 commit 3143558
Showing 1 changed file with 106 additions and 93 deletions.
199 changes: 106 additions & 93 deletions src/bin/commands/pretty-print.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow

import split from 'split2';
import chalk from 'chalk';
import {constructor as Chalk} from 'chalk';
import prettyjson from 'prettyjson';
import type {
MessageType
Expand All @@ -12,12 +12,14 @@ import {

type ArgvType = {|
+excludeOrphans: boolean,
+includeContext: boolean
+includeContext: boolean,
+useColors: boolean
|};

type LogFormatterConfigurationType = {|
+includeContext: boolean,
+excludeOrphans: boolean
+excludeOrphans: boolean,
+useColors: boolean
|};

/* eslint-disable quote-props */
Expand All @@ -31,118 +33,129 @@ const logLevels = {
};
/* eslint-enable */

const logLevelColorMap = {
DEBUG: chalk.gray,
ERROR: chalk.red,
FATAL: chalk.red,
INFO: chalk.cyan,
TRACE: chalk.gray,
WARN: chalk.yellow
};
export const command = 'pretty-print';
export const desc = 'Format logs for user-inspection.';

const getLogLevelName = (logLevel: number): string => {
return logLevels[logLevel] || 'INFO';
// eslint-disable-next-line flowtype/no-weak-types
export const builder = (yargs: Object) => {
return yargs
.options({
'exclude-orphans': {
default: false,
description: 'Excludes messages that cannot be recognized as Roarr log message.',
type: 'boolean'
},
'include-context': {
default: true,
description: 'Includes message context payload.',
type: 'boolean'
},
'use-colors': {
default: true,
description: 'Toggle use of colors in the output.',
type: 'boolean'
}
});
};

const formatMessage = (configuration: LogFormatterConfigurationType, message: MessageType): string => {
let formattedMessage = '';
export const handler = (argv: ArgvType) => {
const chalk = new Chalk({
enabled: argv.useColors
});

formattedMessage = '[' + new Date(message.time).toISOString() + ']';
const logLevelColorMap = {
DEBUG: chalk.gray,
ERROR: chalk.red,
FATAL: chalk.red,
INFO: chalk.cyan,
TRACE: chalk.gray,
WARN: chalk.yellow
};

if (message.context.logLevel && typeof message.context.logLevel === 'number') {
const logLevelName = getLogLevelName(message.context.logLevel);
const getLogLevelName = (logLevel: number): string => {
return logLevels[logLevel] || 'INFO';
};

const logLevelColorName = logLevelColorMap[logLevelName];
const formatMessage = (configuration: LogFormatterConfigurationType, message: MessageType): string => {
let formattedMessage = '';

if (!logLevelColorName) {
throw new Error('Unexpected state.');
}
formattedMessage = '[' + new Date(message.time).toISOString() + ']';

formattedMessage += ' ' + logLevelColorName(logLevelName + ' (' + String(message.context.logLevel) + ')');
}

if (message.context.package) {
formattedMessage += ' (@' + String(message.context.package) + ')';
}

if (message.context.namespace) {
formattedMessage += ' (#' + String(message.context.namespace) + ')';
}

formattedMessage += ': ' + message.message + '\n';

if (configuration.includeContext && message.context) {
/* eslint-disable no-unused-vars */
const {
application: termporary0,
hostname: termporary1,
instanceId: termporary2,
logLevel: termporary3,
namespace: termporary4,
package: termporary5,
package: termporary6,
...rest
} = message.context;

/* eslint-enable */

if (Object.keys(rest).length) {
// eslint-disable-next-line no-console
formattedMessage += prettyjson.render(rest) + '\n\n';
}
}
if (message.context.logLevel && typeof message.context.logLevel === 'number') {
const logLevelName = getLogLevelName(message.context.logLevel);

return formattedMessage;
};
const logLevelColorName = logLevelColorMap[logLevelName];

const formatInvalidInputMessage = (error: Error, input: string): string => {
return chalk.red('Cannot parse presumed Roarr log message as JSON [' + error.name + ': ' + error.message + ']') +
'\n' + chalk.gray('---INVALID INPUT START---') +
'\n' + input +
'\n' + chalk.gray('---INVALID INPUT END---');
};
if (!logLevelColorName) {
throw new Error('Unexpected state.');
}

const createLogFormatter = (configuration: LogFormatterConfigurationType) => {
const stream = split((line) => {
if (!isRoarrLine(line)) {
return configuration.excludeOrphans ? '' : line + '\n';
formattedMessage += ' ' + logLevelColorName(logLevelName + ' (' + String(message.context.logLevel) + ')');
}

let parsedMessage;
if (message.context.package) {
formattedMessage += ' (@' + String(message.context.package) + ')';
}

try {
parsedMessage = JSON.parse(line);
} catch (error) {
return formatInvalidInputMessage(error, line);
if (message.context.namespace) {
formattedMessage += ' (#' + String(message.context.namespace) + ')';
}

return formatMessage(configuration, parsedMessage);
});
formattedMessage += ': ' + message.message + '\n';

if (configuration.includeContext && message.context) {
/* eslint-disable no-unused-vars */
const {
application: termporary0,
hostname: termporary1,
instanceId: termporary2,
logLevel: termporary3,
namespace: termporary4,
package: termporary5,
package: termporary6,
...rest
} = message.context;

/* eslint-enable */

if (Object.keys(rest).length) {
// eslint-disable-next-line no-console
formattedMessage += prettyjson.render(rest, {
noColor: !argv.useColors
}) + '\n\n';
}
}

return stream;
};
return formattedMessage;
};

export const command = 'pretty-print';
export const desc = 'Format logs for user-inspection.';
const formatInvalidInputMessage = (error: Error, input: string): string => {
return chalk.red('Cannot parse presumed Roarr log message as JSON [' + error.name + ': ' + error.message + ']') +
'\n' + chalk.gray('---INVALID INPUT START---') +
'\n' + input +
'\n' + chalk.gray('---INVALID INPUT END---');
};

// eslint-disable-next-line flowtype/no-weak-types
export const builder = (yargs: Object) => {
return yargs
.options({
'exclude-orphans': {
default: false,
description: 'Excludes messages that cannot be recognized as Roarr log message.',
type: 'boolean'
},
'include-context': {
default: true,
description: 'Includes message context payload.',
type: 'boolean'
const createLogFormatter = (configuration: LogFormatterConfigurationType) => {
const stream = split((line) => {
if (!isRoarrLine(line)) {
return configuration.excludeOrphans ? '' : line + '\n';
}

let parsedMessage;

try {
parsedMessage = JSON.parse(line);
} catch (error) {
return formatInvalidInputMessage(error, line);
}

return formatMessage(configuration, parsedMessage);
});
};

export const handler = (argv: ArgvType) => {
return stream;
};

process.stdin
.pipe(createLogFormatter(argv))
.pipe(process.stdout);
Expand Down

0 comments on commit 3143558

Please sign in to comment.