2023-07-27 07:31:52 +02:00
|
|
|
/*
|
|
|
|
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
|
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
2022-02-27 03:07:39 +01:00
|
|
|
import cluster from 'node:cluster';
|
2024-01-16 14:13:35 +01:00
|
|
|
import { pino } from 'pino';
|
2022-12-04 07:03:09 +01:00
|
|
|
import { bindThis } from '@/decorators.js';
|
2022-09-17 20:27:08 +02:00
|
|
|
import { envOption } from './env.js';
|
2023-06-25 14:13:15 +02:00
|
|
|
import type { KEYWORD } from 'color-convert/conversions.js';
|
2019-03-02 10:51:59 +01:00
|
|
|
|
2023-08-17 14:20:58 +02:00
|
|
|
// eslint-disable-next-line import/no-default-export
|
2019-03-02 10:51:59 +01:00
|
|
|
export default class Logger {
|
2024-01-16 14:13:35 +01:00
|
|
|
private readonly domain: string;
|
|
|
|
private logger: pino.Logger;
|
2019-03-02 10:51:59 +01:00
|
|
|
|
2024-01-16 14:13:35 +01:00
|
|
|
constructor(domain: string, _color?: KEYWORD, _store = true, parentLogger?: Logger) {
|
|
|
|
if (parentLogger) {
|
|
|
|
this.domain = parentLogger.domain + '.' + domain;
|
|
|
|
} else {
|
|
|
|
this.domain = domain;
|
2024-01-08 12:26:39 +01:00
|
|
|
}
|
|
|
|
|
2024-01-16 14:13:35 +01:00
|
|
|
this.logger = pino({
|
|
|
|
name: this.domain,
|
|
|
|
level: envOption.verbose ? 'debug' : 'info',
|
|
|
|
depthLimit: 8,
|
|
|
|
edgeLimit: 128,
|
|
|
|
redact: ['context.password', 'context.token'],
|
|
|
|
enabled: !envOption.quiet || envOption.logJson,
|
|
|
|
timestamp: envOption.withLogTime || envOption.logJson ? pino.stdTimeFunctions.isoTime : false,
|
|
|
|
messageKey: 'message',
|
|
|
|
errorKey: 'error',
|
|
|
|
mixin: () => ({ cluster: cluster.isPrimary ? 'primary' : `worker#${cluster.worker!.id}` }),
|
|
|
|
transport: !envOption.logJson ? {
|
|
|
|
target: 'pino-pretty',
|
|
|
|
options: {
|
|
|
|
levelFirst: false,
|
|
|
|
levelKey: 'level',
|
|
|
|
timestampKey: 'time',
|
|
|
|
messageKey: 'message',
|
|
|
|
errorLikeObjectKeys: ['e', 'err', 'error'],
|
|
|
|
ignore: 'pid,hostname,cluster,important',
|
|
|
|
messageFormat: '@{cluster} | {message}',
|
|
|
|
},
|
|
|
|
} : undefined,
|
|
|
|
});
|
|
|
|
}
|
2024-01-11 03:41:20 +01:00
|
|
|
|
2024-01-16 14:13:35 +01:00
|
|
|
@bindThis
|
|
|
|
public createSubLogger(domain: string, _color?: KEYWORD, _store = true): Logger {
|
|
|
|
return new Logger(domain, undefined, false, this);
|
2019-03-02 10:51:59 +01:00
|
|
|
}
|
|
|
|
|
2022-12-04 07:03:09 +01:00
|
|
|
@bindThis
|
2024-01-16 14:13:35 +01:00
|
|
|
public error(x: string | Error, context?: Record<string, any> | null, important = false): void { // 実行を継続できない状況で使う
|
|
|
|
if (context === null) context = undefined;
|
|
|
|
|
2019-03-02 10:51:59 +01:00
|
|
|
if (x instanceof Error) {
|
2024-01-16 14:13:35 +01:00
|
|
|
context = context ?? {};
|
|
|
|
context.error = x;
|
2024-01-11 03:41:20 +01:00
|
|
|
|
2024-01-16 14:13:35 +01:00
|
|
|
if (important) this.logger.fatal({ context, important }, x.toString());
|
|
|
|
else this.logger.error({ context, important }, x.toString());
|
2021-02-27 09:39:55 +01:00
|
|
|
} else if (typeof x === 'object') {
|
2024-01-16 14:13:35 +01:00
|
|
|
context = context ?? {};
|
|
|
|
context.error = context.error ?? x;
|
2024-01-11 03:41:20 +01:00
|
|
|
|
2024-01-16 14:13:35 +01:00
|
|
|
if (important) this.logger.fatal({ context, important }, `${(x as any).message ?? (x as any).name ?? x}`);
|
|
|
|
else this.logger.error({ context, important }, `${(x as any).message ?? (x as any).name ?? x}`);
|
2019-03-02 10:51:59 +01:00
|
|
|
} else {
|
2024-01-16 14:13:35 +01:00
|
|
|
if (important) this.logger.fatal({ context, important }, x);
|
|
|
|
else this.logger.error({ context, important }, x);
|
2019-03-02 10:51:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-04 07:03:09 +01:00
|
|
|
@bindThis
|
2024-01-16 14:13:35 +01:00
|
|
|
public warn(x: string | Error, context?: Record<string, any> | null, important = false): void { // 実行を継続できるが改善すべき状況で使う
|
|
|
|
if (context === null) context = undefined;
|
|
|
|
|
2024-01-11 03:41:20 +01:00
|
|
|
if (x instanceof Error) {
|
2024-01-16 14:13:35 +01:00
|
|
|
context = context ?? {};
|
|
|
|
context.error = x;
|
2024-01-11 03:41:20 +01:00
|
|
|
|
2024-01-16 14:13:35 +01:00
|
|
|
this.logger.warn({ context, important }, x.toString());
|
2024-01-11 03:41:20 +01:00
|
|
|
} else if (typeof x === 'object') {
|
2024-01-16 14:13:35 +01:00
|
|
|
context = context ?? {};
|
|
|
|
context.error = context.error ?? x;
|
2024-01-11 03:41:20 +01:00
|
|
|
|
2024-01-16 14:13:35 +01:00
|
|
|
this.logger.warn({ context, important }, `${(x as any).message ?? (x as any).name ?? x}`);
|
2024-01-11 03:41:20 +01:00
|
|
|
} else {
|
2024-01-16 14:13:35 +01:00
|
|
|
this.logger.warn({ context, important }, x);
|
2024-01-11 03:41:20 +01:00
|
|
|
}
|
2019-03-02 10:51:59 +01:00
|
|
|
}
|
|
|
|
|
2022-12-04 07:03:09 +01:00
|
|
|
@bindThis
|
2024-01-16 14:13:35 +01:00
|
|
|
public succ(message: string, context?: Record<string, any> | null, important = false): void { // 何かに成功した状況で使う
|
|
|
|
if (context === null) context = undefined;
|
|
|
|
|
|
|
|
this.logger.trace({ context, important }, message);
|
2019-03-02 10:51:59 +01:00
|
|
|
}
|
|
|
|
|
2022-12-04 07:03:09 +01:00
|
|
|
@bindThis
|
2024-01-16 14:13:35 +01:00
|
|
|
public debug(message: string, context?: Record<string, any> | null, important = false): void { // デバッグ用に使う(開発者に必要だが利用者に不要な情報)
|
|
|
|
if (context === null) context = undefined;
|
|
|
|
|
|
|
|
this.logger.debug({ context, important }, message);
|
2019-03-02 10:51:59 +01:00
|
|
|
}
|
|
|
|
|
2022-12-04 07:03:09 +01:00
|
|
|
@bindThis
|
2024-01-16 14:13:35 +01:00
|
|
|
public info(message: string, context?: Record<string, any> | null, important = false): void { // それ以外
|
|
|
|
if (context === null) context = undefined;
|
|
|
|
|
|
|
|
this.logger.info({ context, important }, message);
|
2019-03-02 10:51:59 +01:00
|
|
|
}
|
|
|
|
}
|