Akos Kitta 807b2ad424 Support of the CLI config.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2020-04-09 08:55:38 +02:00

136 lines
4.3 KiB
TypeScript

import { ILogger, LogLevel } from '@theia/core/lib/common/logger';
export interface DaemonLog {
readonly time: string;
readonly level: DaemonLog.Level;
readonly msg: string;
}
export namespace DaemonLog {
export interface Url {
readonly Scheme: string;
readonly Host: string;
readonly Path: string;
}
export namespace Url {
export function is(arg: any | undefined): arg is Url {
return !!arg
&& typeof arg.Scheme === 'string'
&& typeof arg.Host === 'string'
&& typeof arg.Path === 'string';
}
export function toString(url: Url): string {
const { Scheme, Host, Path } = url;
return `${Scheme}://${Host}${Path}`;
}
}
export interface System {
readonly os: string;
// readonly Resource: Resource;
}
export namespace System {
export function toString(system: System): string {
return `OS: ${system.os}`
}
}
export interface Tool {
readonly version: string;
readonly systems: System[];
}
export namespace Tool {
export function is(arg: any | undefined): arg is Tool {
return !!arg && typeof arg.version === 'string' && 'systems' in arg;
}
export function toString(tool: Tool): string {
const { version, systems } = tool;
return `Version: ${version}${!!systems ? ` Systems: [${tool.systems.map(System.toString).join(', ')}]` : ''}`;
}
}
export type Level = 'trace' | 'debug' | 'info' | 'warning' | 'error';
export function is(arg: any | undefined): arg is DaemonLog {
return !!arg
&& typeof arg.time === 'string'
&& typeof arg.level === 'string'
&& typeof arg.msg === 'string'
}
export function toLogLevel(log: DaemonLog): LogLevel {
const { level } = log;
switch (level) {
case 'trace': return LogLevel.TRACE;
case 'debug': return LogLevel.DEBUG;
case 'info': return LogLevel.INFO;
case 'warning': return LogLevel.WARN;
case 'error': return LogLevel.ERROR;
default: return LogLevel.INFO;
}
}
export function log(logger: ILogger, logMessages: string): void {
const parsed = parse(logMessages);
for (const log of parsed) {
const logLevel = toLogLevel(log);
const message = toMessage(log, { omitLogLevel: true });
logger.log(logLevel, message);
}
}
function parse(toLog: string): DaemonLog[] {
const messages = toLog.trim().split('\n');
const result: DaemonLog[] = [];
for (let i = 0; i < messages.length; i++) {
try {
const maybeDaemonLog = JSON.parse(messages[i]);
if (DaemonLog.is(maybeDaemonLog)) {
result.push(maybeDaemonLog);
continue;
}
} catch { /* NOOP */ }
result.push({
time: new Date().toString(),
level: 'info',
msg: messages[i]
});
}
return result;
}
export function toPrettyString(logMessages: string): string {
const parsed = parse(logMessages);
return parsed.map(log => toMessage(log)).join('\n') + '\n';
}
function toMessage(log: DaemonLog, options: { omitLogLevel: boolean } = { omitLogLevel: false }): string {
const details = Object.keys(log).filter(key => key !== 'msg' && key !== 'level' && key !== 'time').map(key => toDetails(log, key)).join(', ');
const logLevel = options.omitLogLevel ? '' : `[${log.level.toUpperCase()}] `;
return `${logLevel}${log.msg}${!!details ? ` [${details}]` : ''}`
}
function toDetails(log: DaemonLog, key: string): string {
let value = (log as any)[key];
if (DaemonLog.Url.is(value)) {
value = DaemonLog.Url.toString(value);
} else if (DaemonLog.Tool.is(value)) {
value = DaemonLog.Tool.toString(value);
} else if (typeof value === 'object') {
value = JSON.stringify(value).replace(/\"([^(\")"]+)\":/g, '$1:'); // Remove the quotes from the property keys.
}
return `${key.toLowerCase()}: ${value}`;
}
}