如何将文件名传递给 winston logger?
how to pass a filename to winston logger?
我将 winston 设置为记录器,效果很好。
但是,我有几个进程要记录到不同的文件中。如何将文件名传递给记录器实例?
我用这个作为我的区块
'use strict';
const { createLogger, format, transports } = require('winston');
require('winston-daily-rotate-file');
const fs = require('fs');
const path = require('path');
const logDir = '/codeforge/log';
const dailyRotateFileTransport = new transports.DailyRotateFile({
filename: `${logDir}/%DATE%-engine.log`,
maxSize: "1g",
maxDays: "3d",
zippedArchive: true,
datePattern: 'YYYY-MM-DD'
});
const logger = createLogger({
// change level if in dev environment versus production
level: 'debug',
maxsize: '500m',
format: format.combine(
format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss'
}),
// for the log file
format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)
),
transports: [
new transports.Console({
level: 'info',
format: format.combine(
format.colorize(),
format.printf(
info => `${info.message}`
)
)
}),
dailyRotateFileTransport
]
});
module.exports = logger
我想传入一个文件名来替换“-engine”部分,以便为其创建或附加一个日志文件。
感谢任何提示。
将您的记录器变成您调用的函数
const log = require('logger')('myfilename');
log.info('happy logging')
代码:
'use strict';
const { createLogger, format, transports } = require('winston');
require('winston-daily-rotate-file');
const fs = require('fs');
const path = require('path');
const logDir = '/codeforge/log';
const dailyRotateFileTransport = filename => new transports.DailyRotateFile({
filename: `${logDir}/%DATE%-${filename}.log`,
maxSize: "1g",
maxDays: "3d",
zippedArchive: true,
datePattern: 'YYYY-MM-DD'
});
const logger = function(filename){
return createLogger({
// change level if in dev environment versus production
level: 'debug',
maxsize: '500m',
format: format.combine(
format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss'
}),
// for the log file
format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)
),
transports: [
new transports.Console({
level: 'info',
format: format.combine(
format.colorize(),
format.printf(
info => `${info.message}`
)
)
}),
dailyRotateFileTransport(filename)
]
});
}
module.exports = logger // is now a function
我不想多次创建或重新初始化 Logger 实例,我们可以通过 运行
检查
DEBUG=winston* yarn start
我正在使用 child logger ,这是我的打字稿记录器,
import winston from 'winston';
const { transports, format } = winston;
const { LOG_LEVEL, APP_ENV } = process.env;
const logFormatter = APP_ENV === 'dev'
? format.combine(
winston.format.timestamp(),
winston.format.colorize(),
winston.format.printf((meta: any) => {
const { level, message, timestamp, namespace, stack, ...restMeta } = meta;
const displayNamespace = namespace ? `[${namespace}] -` : '';
const stackMessage = stack ? `\n${stack}` : '';
const otherMetaMessage = Object.keys(restMeta).length > 0 ? `\n${JSON.stringify(restMeta)}` : '';
return `${timestamp} ${displayNamespace} ${level}: ${message} ${otherMetaMessage}${stackMessage}`;
})
)
: format.combine(winston.format.timestamp(), winston.format.json());
const logger = winston.createLogger({
level: LOG_LEVEL || 'debug',
format: logFormatter,
transports: [
new winston.transports.Console({
silent: APP_ENV === 'test',
}),
],
});
export const Logger = (namespace?: string) => {
if (namespace) {
return logger.child({ namespace });
}
return logger;
};
用法:
服务-abc.js
const LOGGER = Logger('service:abc');
export class serviceAbc{
doSomething(){
LOGGER.info("do something");
}
}
如果你正在使用 ES6 模块导入,这里有一个可行的建议:
logger.js
import winston from "winston";
import { resolve } from "path";
import { fileURLToPath } from "url";
const { format, transports, createLogger } = winston;
const { combine, timestamp, printf } = format;
export default (meta_url) => {
const root = resolve("./");
const file = fileURLToPath(new URL(meta_url));
const file_path = file.replace(root, "");
const customFormat = printf(({ level, message, timestamp, stack }) => {
return `${timestamp} [${level}] ${file_path}: ${stack || message}`;
});
const loggerInstance = createLogger({
level: "info",
format: combine(
timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
format.splat(),
format.errors({ stack: true }),
customFormat
),
defaultMeta: { service: "user-service" },
transports: [
new transports.File({ filename: "log/error.log", level: "error" }),
new transports.File({ filename: "log/common.log" }),
],
});
// Log also to console if not in production
if (process.env.NODE_ENV === "development") {
loggerInstance.add(
new transports.Console({
format: combine(colorize(), customFormat),
})
);
}
return loggerInstance;
};
server/index.js
import Logger from "../logger.js";
const logger = Logger(import.meta.url);
logger.info("App running on http://localhost:%i", 5000);
结果:
2021-12-17 15:09:38 [info] /server/index.js: App running on http://localhost:5000
工作原理:
在 logger.js 中,我们 return 一个包装函数,它接受文件的 import.meta.url
作为参数,然后 returns 记录器实例。
在记录器内部,我们简化了绝对路径,并将其传递给自定义记录器格式以进行输出。如果你不想美化路径,只需使用const file_path = fileURLToPath(new URL(meta_url))
我将 winston 设置为记录器,效果很好。 但是,我有几个进程要记录到不同的文件中。如何将文件名传递给记录器实例?
我用这个作为我的区块
'use strict';
const { createLogger, format, transports } = require('winston');
require('winston-daily-rotate-file');
const fs = require('fs');
const path = require('path');
const logDir = '/codeforge/log';
const dailyRotateFileTransport = new transports.DailyRotateFile({
filename: `${logDir}/%DATE%-engine.log`,
maxSize: "1g",
maxDays: "3d",
zippedArchive: true,
datePattern: 'YYYY-MM-DD'
});
const logger = createLogger({
// change level if in dev environment versus production
level: 'debug',
maxsize: '500m',
format: format.combine(
format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss'
}),
// for the log file
format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)
),
transports: [
new transports.Console({
level: 'info',
format: format.combine(
format.colorize(),
format.printf(
info => `${info.message}`
)
)
}),
dailyRotateFileTransport
]
});
module.exports = logger
我想传入一个文件名来替换“-engine”部分,以便为其创建或附加一个日志文件。
感谢任何提示。
将您的记录器变成您调用的函数
const log = require('logger')('myfilename');
log.info('happy logging')
代码:
'use strict';
const { createLogger, format, transports } = require('winston');
require('winston-daily-rotate-file');
const fs = require('fs');
const path = require('path');
const logDir = '/codeforge/log';
const dailyRotateFileTransport = filename => new transports.DailyRotateFile({
filename: `${logDir}/%DATE%-${filename}.log`,
maxSize: "1g",
maxDays: "3d",
zippedArchive: true,
datePattern: 'YYYY-MM-DD'
});
const logger = function(filename){
return createLogger({
// change level if in dev environment versus production
level: 'debug',
maxsize: '500m',
format: format.combine(
format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss'
}),
// for the log file
format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)
),
transports: [
new transports.Console({
level: 'info',
format: format.combine(
format.colorize(),
format.printf(
info => `${info.message}`
)
)
}),
dailyRotateFileTransport(filename)
]
});
}
module.exports = logger // is now a function
我不想多次创建或重新初始化 Logger 实例,我们可以通过 运行
检查DEBUG=winston* yarn start
我正在使用 child logger ,这是我的打字稿记录器,
import winston from 'winston';
const { transports, format } = winston;
const { LOG_LEVEL, APP_ENV } = process.env;
const logFormatter = APP_ENV === 'dev'
? format.combine(
winston.format.timestamp(),
winston.format.colorize(),
winston.format.printf((meta: any) => {
const { level, message, timestamp, namespace, stack, ...restMeta } = meta;
const displayNamespace = namespace ? `[${namespace}] -` : '';
const stackMessage = stack ? `\n${stack}` : '';
const otherMetaMessage = Object.keys(restMeta).length > 0 ? `\n${JSON.stringify(restMeta)}` : '';
return `${timestamp} ${displayNamespace} ${level}: ${message} ${otherMetaMessage}${stackMessage}`;
})
)
: format.combine(winston.format.timestamp(), winston.format.json());
const logger = winston.createLogger({
level: LOG_LEVEL || 'debug',
format: logFormatter,
transports: [
new winston.transports.Console({
silent: APP_ENV === 'test',
}),
],
});
export const Logger = (namespace?: string) => {
if (namespace) {
return logger.child({ namespace });
}
return logger;
};
用法: 服务-abc.js
const LOGGER = Logger('service:abc');
export class serviceAbc{
doSomething(){
LOGGER.info("do something");
}
}
如果你正在使用 ES6 模块导入,这里有一个可行的建议:
logger.js
import winston from "winston";
import { resolve } from "path";
import { fileURLToPath } from "url";
const { format, transports, createLogger } = winston;
const { combine, timestamp, printf } = format;
export default (meta_url) => {
const root = resolve("./");
const file = fileURLToPath(new URL(meta_url));
const file_path = file.replace(root, "");
const customFormat = printf(({ level, message, timestamp, stack }) => {
return `${timestamp} [${level}] ${file_path}: ${stack || message}`;
});
const loggerInstance = createLogger({
level: "info",
format: combine(
timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
format.splat(),
format.errors({ stack: true }),
customFormat
),
defaultMeta: { service: "user-service" },
transports: [
new transports.File({ filename: "log/error.log", level: "error" }),
new transports.File({ filename: "log/common.log" }),
],
});
// Log also to console if not in production
if (process.env.NODE_ENV === "development") {
loggerInstance.add(
new transports.Console({
format: combine(colorize(), customFormat),
})
);
}
return loggerInstance;
};
server/index.js
import Logger from "../logger.js";
const logger = Logger(import.meta.url);
logger.info("App running on http://localhost:%i", 5000);
结果:
2021-12-17 15:09:38 [info] /server/index.js: App running on http://localhost:5000
工作原理:
在 logger.js 中,我们 return 一个包装函数,它接受文件的 import.meta.url
作为参数,然后 returns 记录器实例。
在记录器内部,我们简化了绝对路径,并将其传递给自定义记录器格式以进行输出。如果你不想美化路径,只需使用const file_path = fileURLToPath(new URL(meta_url))