mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-22 15:02:22 +00:00
8bb211e441
Change-type: patch
179 lines
4.8 KiB
TypeScript
179 lines
4.8 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2019-2020 Balena Ltd.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
import _ = require('lodash');
|
|
import { EOL as eol } from 'os';
|
|
import { StreamLogger } from 'resin-stream-logger';
|
|
import { getChalk } from './lazy';
|
|
|
|
enum Level {
|
|
BUILD = 'build',
|
|
INFO = 'info',
|
|
DEBUG = 'debug',
|
|
SUCCESS = 'success',
|
|
WARN = 'warn',
|
|
ERROR = 'error',
|
|
LOGS = 'logs',
|
|
LIVEPUSH = 'livepush',
|
|
}
|
|
|
|
interface LoggerAdapter {
|
|
debug: (msg: string) => void;
|
|
error: (msg: string) => void;
|
|
info: (msg: string) => void;
|
|
log: (msg: string) => void;
|
|
warn: (msg: string) => void;
|
|
}
|
|
|
|
/**
|
|
* General purpose logger class with support for log streams and colours.
|
|
* Call `Logger.getLogger()` to retrieve a global shared instance of this
|
|
* class. The `new Logger()` pattern is not recommended because it may lead
|
|
* to Node printing "MaxListenersExceededWarning" warning messages to the
|
|
* console.
|
|
*/
|
|
class Logger {
|
|
public static readonly Level = Level;
|
|
// `Logger.command` is currently set in `preparser.ts`
|
|
public static command: string; // CLI cmd, e.g. 'push', 'env add', ...
|
|
|
|
public streams: {
|
|
build: NodeJS.ReadWriteStream;
|
|
info: NodeJS.ReadWriteStream;
|
|
debug: NodeJS.ReadWriteStream;
|
|
success: NodeJS.ReadWriteStream;
|
|
warn: NodeJS.ReadWriteStream;
|
|
error: NodeJS.ReadWriteStream;
|
|
logs: NodeJS.ReadWriteStream;
|
|
livepush: NodeJS.ReadWriteStream;
|
|
};
|
|
|
|
public formatMessage: (name: string, message: string) => string;
|
|
|
|
protected deferredLogMessages: Array<[string, Level]>;
|
|
|
|
protected adapter: LoggerAdapter;
|
|
|
|
protected constructor() {
|
|
const logger = new StreamLogger();
|
|
const chalk = getChalk();
|
|
logger.addPrefix('build', chalk.blue('[Build]'));
|
|
logger.addPrefix('info', chalk.cyan('[Info]'));
|
|
logger.addPrefix('debug', chalk.magenta('[Debug]'));
|
|
logger.addPrefix('success', chalk.green('[Success]'));
|
|
logger.addPrefix('warn', chalk.yellow('[Warn]'));
|
|
logger.addPrefix('error', chalk.red('[Error]'));
|
|
logger.addPrefix('logs', chalk.green('[Logs]'));
|
|
logger.addPrefix('live', chalk.yellow('[Live]'));
|
|
|
|
this.streams = {
|
|
build: logger.createLogStream('build'),
|
|
info: logger.createLogStream('info'),
|
|
debug: logger.createLogStream('debug'),
|
|
success: logger.createLogStream('success'),
|
|
warn: logger.createLogStream('warn'),
|
|
error: logger.createLogStream('error'),
|
|
logs: logger.createLogStream('logs'),
|
|
livepush: logger.createLogStream('live'),
|
|
};
|
|
|
|
_.forEach(this.streams, function (stream, key) {
|
|
if (key !== 'debug') {
|
|
stream.pipe(process.stdout);
|
|
} else if (process.env.DEBUG) {
|
|
stream.pipe(process.stderr);
|
|
}
|
|
});
|
|
|
|
this.formatMessage = logger.formatWithPrefix.bind(logger);
|
|
|
|
this.deferredLogMessages = [];
|
|
|
|
this.adapter = {
|
|
debug: (msg: string) => this.logDebug(msg),
|
|
error: (msg: string) => this.logError(msg),
|
|
info: (msg: string) => this.logInfo(msg),
|
|
log: (msg: string) => this.logLogs(msg),
|
|
warn: (msg: string) => this.logWarn(msg),
|
|
};
|
|
}
|
|
|
|
protected static logger: Logger;
|
|
|
|
/** Retrieve a global shared instance of this class */
|
|
public static getLogger() {
|
|
if (!this.logger) {
|
|
this.logger = new Logger();
|
|
}
|
|
return this.logger;
|
|
}
|
|
|
|
public logInfo(msg: string) {
|
|
return this.streams.info.write(msg + eol);
|
|
}
|
|
|
|
public logDebug(msg: string) {
|
|
return this.streams.debug.write(msg + eol);
|
|
}
|
|
|
|
public logSuccess(msg: string) {
|
|
return this.streams.success.write(msg + eol);
|
|
}
|
|
|
|
public logWarn(msg: string) {
|
|
return this.streams.warn.write(msg + eol);
|
|
}
|
|
|
|
public logError(msg: string) {
|
|
return this.streams.error.write(msg + eol);
|
|
}
|
|
|
|
public logBuild(msg: string) {
|
|
return this.streams.build.write(msg + eol);
|
|
}
|
|
|
|
public logLogs(msg: string) {
|
|
return this.streams.logs.write(msg + eol);
|
|
}
|
|
|
|
public logLivepush(msg: string) {
|
|
return this.streams.livepush.write(msg + eol);
|
|
}
|
|
|
|
/**
|
|
* Log a message for output later, ignore duplicates.
|
|
*/
|
|
public deferredLog(msg: string, level: Level) {
|
|
if (!this.deferredLogMessages.find((entry) => entry[0] === msg)) {
|
|
this.deferredLogMessages.push([msg, level]);
|
|
}
|
|
}
|
|
|
|
/** Output any messages that have been queued for deferred output */
|
|
public outputDeferredMessages() {
|
|
this.deferredLogMessages.forEach((m) => {
|
|
this.streams[m[1]].write(m[0] + eol);
|
|
});
|
|
this.deferredLogMessages = [];
|
|
}
|
|
|
|
public getAdapter(): LoggerAdapter {
|
|
return this.adapter;
|
|
}
|
|
}
|
|
|
|
export = Logger;
|