[英]No winston log files are created during pre-run check
I have a typescript project using winston and winston-daily-rotate-file.我有一个使用 winston 和 winston-daily-rotate-file 的 typescript 项目。 At the start of the project I check for environment variables that are present.在项目开始时,我检查存在的环境变量。 If not, I want to log the missing variable using logger.error()
.如果没有,我想使用logger.error()
记录丢失的变量。 But for some reason the error log is never created.但由于某种原因,永远不会创建错误日志。 The logs do appear in my console.日志确实出现在我的控制台中。
The logger and function to check environment variables come from a custom npm module, because I want to reuse this logic for all other projects of mine.用于检查环境变量的记录器和 function 来自自定义 npm 模块,因为我想将此逻辑重用于我的所有其他项目。 So the logger is actually placed in node_modules/my-custom-project/util/logger.ts所以记录器实际上是放在 node_modules/my-custom-project/util/logger.ts
yarn run v1.22.19
$ ts-node src/index.ts
Debugger attached.
info: Starting project Test {"timestamp":"2023-01-19T07:49:53.342Z","type":"start-project"}
error: Missing environment variable DEFAULT_REQUIRED_VARIABLE {"timestamp":"2023-01-19T07:49:53.348Z"}
error: Exiting because of missing environment variables {"data":["DEFAULT_REQUIRED_VARIABLE"],"timestamp":"2023-01-19T07:50:05.447Z"}
import * as winston from "winston";
import DailyRotateFile from "winston-daily-rotate-file";
const infoTransport: DailyRotateFile = new DailyRotateFile({
level: "info",
filename: "./logs/%DATE%/combined.log",
datePattern: "YYYY-MM-DD-HH",
maxSize: "20m",
maxFiles: "14d",
utc: true,
});
const warnTransport: DailyRotateFile = new DailyRotateFile({
level: "warn",
filename: "./logs/%DATE%/warn.log",
datePattern: "YYYY-MM-DD-HH",
maxSize: "20m",
maxFiles: "14d",
utc: true,
});
const errorTransport: DailyRotateFile = new DailyRotateFile({
level: "error",
filename: "./logs/%DATE%/error.log",
datePattern: "YYYY-MM-DD-HH",
maxSize: "20m",
maxFiles: "14d",
utc: true,
});
const logger = winston.createLogger({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [infoTransport, warnTransport, errorTransport],
});
if (process.env.NODE_ENV !== "test") {
logger.add(
new winston.transports.Console({
format: winston.format.simple(),
})
);
}
export default logger;
export default (extraVariables: string[]): boolean => {
let success = false;
const missing: string[] = [],
requiredVariables = [
"DEFAULT_REQUIRED_VARIABLE",
...extraVariables,
];
for (let variable of requiredVariables) {
if (!(variable in process.env)) {
missing.push(variable);
logger.error(`Missing environment variable ${variable}`); // <-- no log file create, but log appears in my console?
}
}
if (missing.length > 0) {
handleError({
error: {
message: "Exiting because of missing environment variables",
data: missing,
},
...
});
} else {
success = true;
}
return success;
};
const run = async () => {
let log: Log = {
message: `Starting project ${process.env.PROJECT_NAME}`,
type: "start-project",
data: new Date().toISOString,
};
logger.info(log);
if (!requireEnvironmentVariables(['NON_DEFAULT_REQUIRED_VARIABLE']) process.exit();
...
};
run().catch((error) => handleError(error));
node_modules/my-custom-project/util/logger.ts
and node_modules/my-custom-project/util/requireEnvironmentVariables.ts
to my local project.将node_modules/my-custom-project/util/logger.ts
和node_modules/my-custom-project/util/requireEnvironmentVariables.ts
到我的本地项目。logger.info()
before checking the variables.在检查变量之前调用logger.info()
。 No log files are created.没有创建日志文件。logger.info()
is called AFTER this function has ran, it seems to work fine?如果所有环境变量都存在,并且在这个 function 运行之后调用第一个logger.info()
,它似乎工作正常?I found logger.on method , it can be used to listen to the finish event:我找到了 logger.on 方法,它可以用来监听 finish 事件:
logger.on('finish', (info) => {
// Still nog logs written here...
})
But the logs don't exist at that point.但此时日志不存在。 Also, the info parameter here is undefined and useless.此外,这里的 info 参数未定义且无用。
I eventually found out that this issue is hard to solve with the winston logger.我最终发现这个问题很难用 winston logger 解决。 It has an issue open on GitHub about this.它在 GitHub 上有一个关于此的问题。 I resorted to pino where I found this example about MultiStreams.我求助于pino ,在那里我找到了这个关于 MultiStreams 的例子。 Eventually this was my solution:最终这是我的解决方案:
import { createWriteStream, existsSync, mkdirSync } from "fs";
import path from "path";
import pino, { stdTimeFunctions } from "pino";
import pretty from "pino-pretty";
import getLogDir from "./getLogDir";
import getLogFileName from "./getLogFileName";
import LogSequence from "./LogSequence";
const logSequence = LogSequence.getInstance(),
logDir = getLogDir();
let nextSequenceNumberFound = false,
logFileName = getLogFileName(logSequence.sequence),
logFilePath = "";
// Create logs folder if it does not exist
if (!existsSync(logDir)) mkdirSync(logDir, { recursive: true });
// Decide filename with unique sequence, within every hour the sequence gets upped
while (nextSequenceNumberFound === false) {
logFilePath = path.join(logDir, logFileName);
// Try to find file with sequence number
let fileExists = existsSync(logFilePath);
// If it exists, try to find the next one
if (fileExists) {
logSequence.incrementSequence();
logFileName = getLogFileName(logSequence.sequence);
// Else, we know what to call the next file
} else nextSequenceNumberFound = true;
}
const fileStream = createWriteStream(logFilePath),
streams = [
{ stream: fileStream },
{
stream: pretty({
colorize: true,
translateTime: true,
ignore: "pid",
}),
},
];
const logger = pino(
{
enabled:
process.env.NODE_ENV !== "test" && process.env.NODE_ENV !== "production",
formatters: {
level(label) {
return { level: label };
},
},
level: "debug",
nestedKey: "payload",
timestamp: stdTimeFunctions.isoTime,
},
pino.multistream(streams)
);
export default logger;
Then for example in my tests I could do:然后例如在我的测试中我可以这样做:
beforeAll((done) => {
logger.info("Testing...");
logger.flush();
done();
});
test("getLog", () => {
fileStream.once("close", () => {
// Log files are available here
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.