mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-19 08:02:55 +00:00
207 lines
5.4 KiB
TypeScript
207 lines
5.4 KiB
TypeScript
/*
|
|
* Copyright (C) 2018, 2019 StApps
|
|
* This program is free software: you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation, version 3.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
import chalk from 'chalk';
|
|
import {stringify} from 'flatted';
|
|
import {isNodeEnvironment, isProductiveNodeEnvironment} from './common';
|
|
import {Transport} from './Transport';
|
|
|
|
/**
|
|
* Logger with colors, loglevel and transport
|
|
*
|
|
* Log level can be defined by setting the environment variable STAPPS_LOG_LEVEL to a valid log level. Log levels are
|
|
* set in a binary way. For example STAPPS_LOG_LEVEL=12 does result in logs only for `Logger.warn` and `Logger.error`.
|
|
*
|
|
* Log levels in that order are:
|
|
* ```
|
|
* INFO: 1
|
|
* LOG: 2
|
|
* WARN: 4
|
|
* ERROR: 8
|
|
* OK: 16
|
|
* ```
|
|
*/
|
|
export class Logger {
|
|
/**
|
|
* Log levels
|
|
*/
|
|
private static logLevels = [
|
|
'INFO',
|
|
'LOG',
|
|
'WARN',
|
|
'ERROR',
|
|
'OK',
|
|
];
|
|
|
|
/**
|
|
* Transport for errors
|
|
*/
|
|
private static transport?: Transport;
|
|
|
|
/**
|
|
* Check if intended log level is allowed in environment log level
|
|
*
|
|
* @param logLevel
|
|
*/
|
|
private static checkLogLevel(logLevel: string): boolean {
|
|
const logLevelNumber = Math.pow(2, Logger.logLevels.indexOf(logLevel) + 1) - 1;
|
|
|
|
/* tslint:disable-next-line:no-bitwise */
|
|
return !!(Logger.getLogLevel() & logLevelNumber);
|
|
}
|
|
|
|
/**
|
|
* Return log level from environment
|
|
*/
|
|
private static getLogLevel(): number {
|
|
if (isNodeEnvironment() && typeof process.env.STAPPS_LOG_LEVEL !== 'undefined') {
|
|
// Node.js environment exists
|
|
return parseInt(process.env.STAPPS_LOG_LEVEL, 10);
|
|
} else if (typeof window !== 'undefined' && typeof (window as any).STAPPS_LOG_LEVEL === 'number') {
|
|
// browser environment exists
|
|
return (window as any).STAPPS_LOG_LEVEL;
|
|
}
|
|
|
|
// Log everything
|
|
return 31;
|
|
}
|
|
|
|
/**
|
|
* Log an error
|
|
*
|
|
* @param args Arguments to log
|
|
*/
|
|
public static async error(...args: any[]): Promise<string | void> {
|
|
if (!Logger.checkLogLevel('ERROR')) {
|
|
return;
|
|
}
|
|
|
|
/* tslint:disable-next-line:no-console */
|
|
console.error(chalk.bold.red(`[ERROR] ${Logger.stringifyArguments(...args)}`));
|
|
|
|
if (isProductiveNodeEnvironment()) {
|
|
if (typeof Logger.transport !== 'undefined') {
|
|
return Logger.transport.send('Error', Logger.stringifyArguments(...args));
|
|
} else if (!process.env.ALLOW_NO_TRANSPORT) {
|
|
throw new Error(`Error couldn't be transported! Please set a transport or set ALLOW_NO_TRANSPORT='true'.`);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Log an information
|
|
*
|
|
* @param args Arguments to log
|
|
*/
|
|
public static info(...args: any[]): void {
|
|
if (!Logger.checkLogLevel('INFO')) {
|
|
return;
|
|
}
|
|
|
|
/* tslint:disable-next-line:no-console */
|
|
console.info(chalk.cyan(`[INFO] ${Logger.stringifyArguments(args)}`));
|
|
}
|
|
|
|
/**
|
|
* Check if the logger is initialized correctly
|
|
*/
|
|
public static initialized(): void {
|
|
if (isProductiveNodeEnvironment() && typeof Logger.transport === 'undefined') {
|
|
if (!process.env.ALLOW_NO_TRANSPORT) {
|
|
throw new Error(`Productive environment doesn't set a transport for error notifications.`);
|
|
} else {
|
|
/* tslint:disable-next-line:no-console */
|
|
console.warn(chalk.yellow(`Productive environment doesn't set a transport for error notifications.`));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Log something
|
|
*
|
|
* @param args Arguments to log
|
|
*/
|
|
public static log(...args: any[]): void {
|
|
if (!this.checkLogLevel('LOG')) {
|
|
return;
|
|
}
|
|
|
|
/* tslint:disable-next-line:no-console */
|
|
console.log(chalk.white(`[LOG] ${Logger.stringifyArguments(args)}`));
|
|
}
|
|
|
|
/**
|
|
* Log something successful
|
|
*
|
|
* @param args Arguments to log
|
|
*/
|
|
public static ok(...args: any[]): void {
|
|
if (!this.checkLogLevel('OK')) {
|
|
return;
|
|
}
|
|
|
|
/* tslint:disable-next-line:no-console */
|
|
console.log(chalk.bold.green(`[OK] ${Logger.stringifyArguments(args)}`));
|
|
}
|
|
|
|
/**
|
|
* Set a transport
|
|
*
|
|
* @param transport Transport to set
|
|
*/
|
|
public static setTransport(transport?: Transport) {
|
|
Logger.transport = transport;
|
|
}
|
|
|
|
/**
|
|
* Stringify a list of arguments
|
|
*
|
|
* @param args Arguments to stringify
|
|
*/
|
|
public static stringifyArguments(...args: any[]): string {
|
|
const result: string[] = [];
|
|
|
|
args.forEach((argument) => {
|
|
const type = typeof argument;
|
|
|
|
if (['string', 'number'].indexOf(type) !== -1) {
|
|
result.push(argument);
|
|
} else if (argument instanceof Error) {
|
|
result.push(argument.message);
|
|
if (typeof argument.stack !== 'undefined') {
|
|
result.push(argument.stack);
|
|
}
|
|
} else {
|
|
result.push(stringify(argument, null, 2));
|
|
}
|
|
});
|
|
|
|
return result.join(', ');
|
|
}
|
|
|
|
/**
|
|
* Log a warning
|
|
*
|
|
* @param args Arguments to log
|
|
*/
|
|
public static warn(...args: any[]): void {
|
|
if (!this.checkLogLevel('WARN')) {
|
|
return;
|
|
}
|
|
|
|
/* tslint:disable-next-line:no-console */
|
|
console.warn(chalk.yellow(`[WARN] ${Logger.stringifyArguments(args)}`));
|
|
}
|
|
}
|