Files
js-logging/src/log-message.ts

90 lines
2.2 KiB
TypeScript

import { omit } from "./util";
export enum LogLevel {
ALL = 0,
TRACE,
DEBUG,
LOG,
INFO,
WARN,
ERROR,
FATAL,
}
export function parseLogLevel(
str: string,
defaultLevel = LogLevel.INFO,
): LogLevel {
if (str in LogLevel) {
return LogLevel[str as keyof typeof LogLevel] as LogLevel;
} else {
return defaultLevel;
}
}
export interface LogMessage {
scope: string;
level: LogLevel;
msg: string | Record<string, unknown>;
stacktrace?: string;
err?: Error;
ts: Date;
}
export type FlattenedLogMessage = Record<string, unknown>;
/**
* Flatten a log message to a plain object in preparation for emission to an
* appender.
*
* In general, the *message* field can be either a string or an object. In the
* case of an object message, the LogMessage should be flattened before being
* emitted by an appender, promoting the object's fields to the top level of
* the message. Fields defined on the *LogMessage* interface are reserved and
* should not be used as keys in the message object (and will be ignored if
* they are).
*
* So, for example:
*
* ```typescript
* const logger = logService.getLogger('example');
* logger.info({ foo: 'bar', baz: 'qux', ts: 'today', level: LogLevel.WARN });
* ```
*
* Will result in a structured log message after flattening like:
* ```json
* {"scope":"example","level":"INFO","foo":"bar","baz":"qux","ts":"2020-01-01T00:00:00.000Z"}
* ```
*/
export function flattenMessage(logMsg: LogMessage): FlattenedLogMessage {
if (typeof logMsg.msg === "string") {
return { ...logMsg, level: LogLevel[logMsg.level] };
} else {
const { msg, ...rest } = logMsg;
return {
...omit(msg, [
"scope",
"level",
"stacktrace",
"err",
"ts",
]),
...rest,
level: LogLevel[logMsg.level],
};
}
}
export type LogMessageFormatter = (
msg: LogMessage,
) => string | FlattenedLogMessage;
export function structuredLogMessageFormatter(msg: LogMessage): string {
return JSON.stringify(flattenMessage(msg));
}
export function simpleTextLogMessageFormatter(msg: LogMessage): string {
return `[${msg.scope}] - ${msg.level}: ${msg.msg}`;
}
export default LogMessage;