From 8dd85bd74243baca0cf3d00afdee5eb59e3eef9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E6=82=9F=E5=85=83?= <88357633+SunWuyuan@users.noreply.github.com> Date: Sat, 23 Nov 2024 21:49:12 +0800 Subject: [PATCH 1/3] Add centralized logging mechanism using Winston Introduce a centralized logging mechanism using the Winston library for structured logging. * **Add `server/logger.js`**: Configure and export a Winston logger instance to log to both console and file with different logging levels (info, warn, error). * **Modify `app.js`**: Import the Winston logger and replace all `console.log` statements with `logger.info` and `console.error` statements with `logger.error`. * **Modify `server/configManager.js`**: Import the Winston logger and replace all `console.error` statements with `logger.error`. * **Modify `server/lib/global.js`**: Import the Winston logger and replace all `console.log` statements with `logger.info` and `console.error` statements with `logger.error`. * **Modify `server/router_project.js`**: Import the Winston logger and replace all `console.log` statements with `logger.info` and `console.error` statements with `logger.error`. Update error handling to use the new logging mechanism. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/ZeroCatDev/zerocat-backend?shareId=XXXX-XXXX-XXXX-XXXX). --- app.js | 45 ++++++++---------------------------- server/configManager.js | 49 ++++++++++++++++++++-------------------- server/lib/global.js | 17 +++++++------- server/logger.js | 22 ++++++++++++++++++ server/router_project.js | 22 ++++++++++++------ 5 files changed, 79 insertions(+), 76 deletions(-) create mode 100644 server/logger.js diff --git a/app.js b/app.js index 574e78d..dea0057 100644 --- a/app.js +++ b/app.js @@ -3,36 +3,9 @@ var app = express(); const jwt = require("jsonwebtoken"); const configManager = require("./server/configManager.js"); +const logger = require("./server/logger.js"); require("dotenv").config({ override: true }); -//console.log(global.config); -// 日志部分 -/* -const opentelemetry = require("@opentelemetry/sdk-node"); -const { - getNodeAutoInstrumentations, -} = require("@opentelemetry/auto-instrumentations-node"); -const { - OTLPTraceExporter, -} = require("@opentelemetry/exporter-trace-otlp-proto"); -const { BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base"); -const { Resource } = require("@opentelemetry/resources"); -const { - SemanticResourceAttributes, -} = require("@opentelemetry/semantic-conventions"); -const traceExporter = new OTLPTraceExporter({ url: "https://api.axiom.co/v1/traces", headers: { Authorization: `Bearer ${process.env.AXIOM_TOKEN}`, "X-Axiom-Dataset": process.env.AXIOM_DATASET, }, }); -const resource = new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: "node traces", -}); -const sdk = new opentelemetry.NodeSDK({ - spanProcessor: new BatchSpanProcessor(traceExporter), - resource: resource, - instrumentations: [getNodeAutoInstrumentations()], -}); -sdk.start(); -*/ - -// 路由处理... var morganlogger = require("morgan"); morganlogger.token("colored-status", (req, res) => { @@ -65,7 +38,7 @@ var corsOptions = { if (!origin || corslist.indexOf(new URL(origin).hostname) !== -1) { callback(null, true); } else { - console.log(origin); + logger.info(origin); callback(new Error("Not allowed by CORS")); } }, @@ -125,7 +98,7 @@ app.all("*", async function (req, res, next) { (req.body && req.body.token) || (req.headers && req.headers["token"]) || (req.query && req.query.token); - console.log(token); + logger.info(token); // Continue with the token verification if (token) { jwt.verify(token, zcjwttoken, (err, decodedToken) => { @@ -141,7 +114,7 @@ app.all("*", async function (req, res, next) { is_admin: 0, usertoken: "", }; - //console.log("JWT验证失败: " + err.message); + logger.error("JWT验证失败: " + err.message); } else { // If verification succeeds, store user info let userInfo = decodedToken; @@ -155,8 +128,8 @@ app.all("*", async function (req, res, next) { is_admin: 0, usertoken: token, }; - //console.log("JWT验证成功: " + userInfo.email); - //console.log("调试用户信息(session): " + JSON.stringify(res.locals)); + logger.info("JWT验证成功: " + userInfo.email); + logger.info("调试用户信息(session): " + JSON.stringify(res.locals)); } next(); @@ -173,7 +146,7 @@ app.all("*", async function (req, res, next) { is_admin: 0, usertoken: "", }; - console.log("未找到JWT Token"); + logger.info("未找到JWT Token"); next(); } }); @@ -226,12 +199,12 @@ app.get("/check", function (req, res, next) { }); process.on("uncaughtException", function (err) { - console.log("Caught exception: " + err); + logger.error("Caught exception: " + err); }); // Centralized error-handling middleware function app.use((err, req, res, next) => { - console.error(err.stack); + logger.error(err.stack); res.status(500).send({ status: "error", message: "Something went wrong!", diff --git a/server/configManager.js b/server/configManager.js index f8a5037..69d3c07 100644 --- a/server/configManager.js +++ b/server/configManager.js @@ -1,5 +1,5 @@ -// configManager.js const { PrismaClient } = require("@prisma/client"); +const logger = require("./logger"); class ConfigManager { constructor() { @@ -8,38 +8,36 @@ class ConfigManager { async loadConfigsFromDB() { try { - // Fetch all configurations from the database - const configs = await this.prisma.ow_config.findMany(); + // Fetch all configurations from the database + const configs = await this.prisma.ow_config.findMany(); - // Internal configurations - global.config = {}; - configs.forEach(({ key, value }) => { - global.config[key] = value; - }); + // Internal configurations + global.config = {}; + configs.forEach(({ key, value }) => { + global.config[key] = value; + }); - // Public configurations - global.publicconfig = {}; - configs.forEach(({ key, value, is_public }) => { - if (is_public == 1) { - global.publicconfig[key] = value; - } - }); + // Public configurations + global.publicconfig = {}; + configs.forEach(({ key, value, is_public }) => { + if (is_public == 1) { + global.publicconfig[key] = value; + } + }); - // Configuration information - global.configinfo = configs; - } catch (error) { - console.error("Error loading configs from database:", error); - } - //console.log(global.configinfo); // Log the updated config info + // Configuration information + global.configinfo = configs; + } catch (error) { + logger.error("Error loading configs from database:", error); + } } async getConfig(key) { // Check if the value is already cached - if (global.config && global.config[key]!=null) { + if (global.config && global.config[key] != null) { return global.config[key]; } var config = await this.prisma.ow_config.findFirst({ where: { key: key } }); - //console.log(config); if (config == null) { return null; } @@ -59,8 +57,9 @@ class ConfigManager { if (global.publicconfig && global.publicconfig[key]) { return global.publicconfig[key]; } - var config = await this.prisma.ow_config.findFirst({ where: { key: key, is_public: 1 } }); - //console.log(config); + var config = await this.prisma.ow_config.findFirst({ + where: { key: key, is_public: 1 }, + }); if (config == null) { return null; } diff --git a/server/lib/global.js b/server/lib/global.js index 3180f56..b13f869 100644 --- a/server/lib/global.js +++ b/server/lib/global.js @@ -1,4 +1,5 @@ const configManager = require("../configManager"); +const logger = require("../logger"); const crypto = require("crypto"); const jwt = require("jsonwebtoken"); // 确保安装了 jsonwebtoken 库 @@ -35,7 +36,7 @@ let s3config; }, }; } catch (error) { - console.error("Error retrieving S3 config:", error); + logger.error("Error retrieving S3 config:", error); } finally { // Optionally disconnect Prisma client if needed // await configManager.prisma.$disconnect(); @@ -56,12 +57,12 @@ exports.S3update = async function (name, file) { }); const data = await s3.send(command); - console.log(data); - console.log( + logger.info(data); + logger.info( `成功上传了文件 ${await configManager.getConfig("s3.bucket")}/${name}` ); } catch (err) { - console.error("S3 update Error:", err); + logger.error("S3 update Error:", err); } }; @@ -98,7 +99,7 @@ exports.randomPassword = (len = 12) => { // JWT 生成与校验 exports.jwt = (data) => { const token = jwt.sign(data, "test"); - console.log(token); + logger.info(token); return token; }; @@ -107,7 +108,7 @@ exports.GenerateJwt = async (json) => { try { // Retrieve the JWT secret from config const secret = await configManager.getConfig("security.jwttoken"); -console.log(secret) +logger.info(secret) // Check if the secret is defined if (!secret) { throw new Error('JWT secret is not defined in the configuration'); @@ -116,7 +117,7 @@ console.log(secret) // Generate and return the JWT return jwt.sign(json, secret); } catch (error) { - console.error('Error generating JWT:', error); + logger.error('Error generating JWT:', error); throw error; // Rethrow or handle as needed } }; @@ -128,7 +129,7 @@ exports.isJSON = (str) => { const obj = JSON.parse(str); return obj && typeof obj === "object"; } catch (e) { - console.error("error:", str, e); + logger.error("error:", str, e); return false; } }; diff --git a/server/logger.js b/server/logger.js new file mode 100644 index 0000000..b7a443e --- /dev/null +++ b/server/logger.js @@ -0,0 +1,22 @@ +const { createLogger, format, transports } = require('winston'); +const { combine, timestamp, printf, errors } = format; + +const logFormat = printf(({ level, message, timestamp, stack }) => { + return `${timestamp} ${level}: ${stack || message}`; +}); + +const logger = createLogger({ + level: 'info', + format: combine( + timestamp(), + errors({ stack: true }), + logFormat + ), + transports: [ + new transports.Console(), + new transports.File({ filename: 'logs/error.log', level: 'error' }), + new transports.File({ filename: 'logs/combined.log' }) + ] +}); + +module.exports = logger; diff --git a/server/router_project.js b/server/router_project.js index a1ce991..86bbfb1 100644 --- a/server/router_project.js +++ b/server/router_project.js @@ -1,11 +1,11 @@ const configManager = require("./configManager"); - const express = require("express"); const router = express.Router(); const crypto = require("crypto"); const DB = require("./lib/database.js"); const I = require("./lib/global.js"); const default_project = require("./lib/default_project.js"); +const logger = require("./logger.js"); // 中间件,确保所有请求均经过该处理 router.all("*", (req, res, next) => next()); @@ -28,6 +28,7 @@ router.post("/", async (req, res, next) => { const result = await I.prisma.ow_projects.create({ data: outputJson }); res.status(200).send({ status: "1", msg: "保存成功", id: result.id }); } catch (err) { + logger.error("Error creating new project:", err); next(err); } }); @@ -62,6 +63,7 @@ router.post("/:id/fork", async (req, res, next) => { res.status(403).send({ status: "0", msg: "改编失败" }); } } catch (err) { + logger.error("Error forking project:", err); next(err); } }); @@ -73,7 +75,7 @@ router.put("/:id/source", async (req, res, next) => { } try { - console.log(req.body); + logger.info(req.body); const sha256 = setProjectFile(req.body); const projectId = Number(req.params.id); const userId = Number(res.locals.userid); @@ -93,6 +95,7 @@ router.put("/:id/source", async (req, res, next) => { res.status(200).send({ status: "1", msg: "保存成功" }); } catch (err) { + logger.error("Error saving source code:", err); next(err); } }); @@ -111,6 +114,7 @@ router.put("/:id", async (req, res, next) => { }); res.status(200).send({ status: "1", msg: "保存成功" }); } catch (err) { + logger.error("Error updating project information:", err); next(err); } }); @@ -156,6 +160,7 @@ router.post("/:id/push", async (req, res, next) => { res.status(200).send({ status: "1", msg: "推送成功" }); } catch (err) { + logger.error("Error pushing project:", err); next(err); } }); @@ -182,6 +187,7 @@ router.get("/:id", async (req, res, next) => { project.author = author; res.status(200).send(project); } catch (err) { + logger.error("Error fetching project information:", err); next(err); } }); @@ -209,6 +215,7 @@ router.get("/:id/source/:env?", async (req, res, next) => { res.status(403).send({ status: "0", msg: "无权访问此项目" }); } } catch (err) { + logger.error("Error fetching project source code:", err); next(err); } }); @@ -221,6 +228,7 @@ router.delete("/:id", async (req, res, next) => { }); res.status(200).send({ status: "1", msg: "删除成功" }); } catch (err) { + logger.error("Error deleting project:", err); next(err); } }); @@ -255,7 +263,7 @@ function isJson(str) { // 工具函数:设置项目文件 function setProjectFile(source) { - console.log(source); + logger.info(source); let sourcedata if (isJson(source)) { sourcedata =String(JSON.stringify(JSON.parse(source))) @@ -263,11 +271,11 @@ function setProjectFile(source) { sourcedata = String(source) } const sha256 = crypto.createHash("sha256").update(sourcedata).digest("hex"); - console.log("sha256:", sha256); - console.log(sourcedata); + logger.info("sha256:", sha256); + logger.info(sourcedata); I.prisma.ow_projects_file .create({ data: { sha256, source:sourcedata } }) - .catch(console.error); + .catch(logger.error); return sha256; } @@ -281,7 +289,7 @@ async function getProjectFile(sha256) { // 工具函数:处理错误响应 function handleError(res, err, msg) { - console.error(err); + logger.error(err); res.status(500).send({ status: "0", msg, error: err }); } From 905a31248d99762f122152e22c9499d470022523 Mon Sep 17 00:00:00 2001 From: SunWuyuan <1847261658@qq.com> Date: Sun, 24 Nov 2024 11:10:17 +0800 Subject: [PATCH 2/3] 1 --- app.js | 50 ++++---- package.json | 5 +- pnpm-lock.yaml | 270 +++++++++++++++++++++++++++++++++++++++ server/lib/global.js | 8 +- server/logger.js | 74 +++++++++-- server/router_project.js | 8 +- 6 files changed, 371 insertions(+), 44 deletions(-) diff --git a/app.js b/app.js index dea0057..5255598 100644 --- a/app.js +++ b/app.js @@ -7,23 +7,21 @@ const logger = require("./server/logger.js"); require("dotenv").config({ override: true }); -var morganlogger = require("morgan"); -morganlogger.token("colored-status", (req, res) => { - const status = res.statusCode; - let color; - if (status >= 500) { - color = "\x1b[31m"; // 红色 - } else if (status >= 400) { - color = "\x1b[33m"; // 黄色 - } else if (status >= 300) { - color = "\x1b[36m"; // 青色 - } else { - color = "\x1b[32m"; // 绿色 - } - return color + status + "\x1b[0m"; // 重置颜色 -}); + + +expressWinston = require("express-winston"); + app.use( - morganlogger(":method :colored-status :response-time ms :remote-addr :url") + expressWinston.logger({ + winstonInstance: logger, // 使用外部定义的logger + meta: true, // optional: control whether you want to log the meta data about the request (default to true). + msg: "HTTP {{req.method}} {{res.statusCode}} {{res.responseTime}}ms {{req.url}} {{req.ip}}", // optional: customize the default logging message. Eg. "{{res.statusCode}} {{req.method}} {{res.responseTime}}ms {{req.url}}" + colorize: false, // Color the text and status code, using the Express/morgan color palette (text: gray, status: default green, 3XX cyan, 4XX yellow, 5XX red). + ignoreRoute: function (req, res) { + return false; + }, // optional: allows to skip some loggin. It is passed the http request and http response objects, should return true to skip the request logging. + level: "info", // 记录所有请求为info级别 + }) ); // cors配置 @@ -38,7 +36,7 @@ var corsOptions = { if (!origin || corslist.indexOf(new URL(origin).hostname) !== -1) { callback(null, true); } else { - logger.info(origin); + logger.debug(origin); callback(new Error("Not allowed by CORS")); } }, @@ -70,7 +68,10 @@ app.set("env", __dirname + "/.env"); app.set("data", __dirname + "/data"); app.set("views", __dirname + "/views"); app.set("prisma", __dirname + "/prisma"); -app.set("node_modules/@prisma/client", __dirname + "/node_modules/@prisma/client"); +app.set( + "node_modules/@prisma/client", + __dirname + "/node_modules/@prisma/client" +); app.set("view engine", "ejs"); @@ -91,6 +92,8 @@ let zcjwttoken; zcjwttoken = await configManager.getConfig("security.jwttoken"); })(); app.all("*", async function (req, res, next) { + Error("test"); + //console.log(req.method +' '+ req.url + " IP:" + req.ip); const token = (req.headers["authorization"] || "").replace("Bearer ", "") || @@ -98,7 +101,7 @@ app.all("*", async function (req, res, next) { (req.body && req.body.token) || (req.headers && req.headers["token"]) || (req.query && req.query.token); - logger.info(token); + logger.debug(token); // Continue with the token verification if (token) { jwt.verify(token, zcjwttoken, (err, decodedToken) => { @@ -128,8 +131,8 @@ app.all("*", async function (req, res, next) { is_admin: 0, usertoken: token, }; - logger.info("JWT验证成功: " + userInfo.email); - logger.info("调试用户信息(session): " + JSON.stringify(res.locals)); + logger.debug("JWT验证成功: " + userInfo.email); + logger.debug("调试用户信息(session): " + JSON.stringify(res.locals)); } next(); @@ -146,7 +149,7 @@ app.all("*", async function (req, res, next) { is_admin: 0, usertoken: "", }; - logger.info("未找到JWT Token"); + logger.debug("未找到JWT Token"); next(); } }); @@ -196,7 +199,7 @@ app.get("/check", function (req, res, next) { message: "success", code: 200, }); -}); +logger.debug("check");}); process.on("uncaughtException", function (err) { logger.error("Caught exception: " + err); @@ -220,7 +223,6 @@ app.all("*", function (req, res, next) { code: "404", message: "找不到页面", }); - }); module.exports = app; diff --git a/package.json b/package.json index 180ef4e..e6b1351 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "express": "^4.21.1", "express-jwt": "^8.3.0", "express-session": "^1.18.1", + "express-winston": "^4.2.0", "html-entities": "^2.5.2", "jsonwebtoken": "^9.0.0", "morgan": "^1.10.0", @@ -30,7 +31,9 @@ "nodemailer": "^6.9.16", "otpauth": "^9.3.5", "phpass": "^0.1.1", - "request": "^2.88.0" + "request": "^2.88.0", + "winston": "^3.17.0", + "winston-daily-rotate-file": "^5.0.0" }, "devDependencies": { "prisma": "^5.22.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d8709e6..c14a7a5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,6 +50,9 @@ importers: express-session: specifier: ^1.18.1 version: 1.18.1 + express-winston: + specifier: ^4.2.0 + version: 4.2.0(winston@3.17.0) html-entities: specifier: ^2.5.2 version: 2.5.2 @@ -74,6 +77,12 @@ importers: request: specifier: ^2.88.0 version: 2.88.2 + winston: + specifier: ^3.17.0 + version: 3.17.0 + winston-daily-rotate-file: + specifier: ^5.0.0 + version: 5.0.0(winston@3.17.0) devDependencies: prisma: specifier: ^5.22.0 @@ -244,6 +253,13 @@ packages: resolution: {integrity: sha512-C/rPwJcqnV8VDr2/VtcQnymSpcfEEgH1Jm6V0VmfXNZFv4Qzf1eCS8nsec0gipYgZB+cBBjfXw5dAk6pJ8ubpw==} engines: {node: '>=16.0.0'} + '@colors/colors@1.6.0': + resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} + engines: {node: '>=0.1.90'} + + '@dabh/diagnostics@2.0.3': + resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} + '@noble/hashes@1.5.0': resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} engines: {node: ^14.21.3 || >=16} @@ -481,6 +497,9 @@ packages: '@types/node@22.7.4': resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + '@types/triple-beam@1.3.5': + resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} + accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -488,6 +507,10 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -557,17 +580,36 @@ packages: caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@3.2.1: + resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + + colorspace@1.1.4: + resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -676,6 +718,9 @@ packages: engines: {node: '>=0.10.0'} hasBin: true + enabled@2.0.0: + resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} + encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} @@ -695,6 +740,10 @@ packages: escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + etag@1.8.1: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} @@ -710,6 +759,12 @@ packages: express-unless@2.1.3: resolution: {integrity: sha512-wj4tLMyCVYuIIKHGt0FhCtIViBcwzWejX0EjNxveAa6dG+0XBCQhMbx+PnkLkFCxLC69qoFrxds4pIyL88inaQ==} + express-winston@4.2.0: + resolution: {integrity: sha512-EMD74g63nVHi7pFleQw7KHCxiA1pjF5uCwbCfzGqmFxs9KvlDPIVS3cMGpULm6MshExMT9TjC3SqmRGB9kb7yw==} + engines: {node: '>= 6'} + peerDependencies: + winston: '>=3.x <4' + express@4.21.1: resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==} engines: {node: '>= 0.10.0'} @@ -731,6 +786,12 @@ packages: resolution: {integrity: sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==} hasBin: true + fecha@4.2.3: + resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} + + file-stream-rotator@0.6.1: + resolution: {integrity: sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==} + filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} @@ -738,6 +799,9 @@ packages: resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} + fn.name@1.1.0: + resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} + follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} @@ -793,6 +857,10 @@ packages: engines: {node: '>=6'} deprecated: this library is no longer supported + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -842,6 +910,13 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + is-typedarray@1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} @@ -882,6 +957,9 @@ packages: jws@3.2.2: resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + kuler@2.0.0: + resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} + lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} @@ -903,6 +981,13 @@ packages: lodash.once@4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + logform@2.7.0: + resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} + engines: {node: '>= 12.0.0'} + media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -938,6 +1023,9 @@ packages: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + morgan@1.10.0: resolution: {integrity: sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==} engines: {node: '>= 0.8.0'} @@ -975,6 +1063,10 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + object-inspect@1.13.2: resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} engines: {node: '>= 0.4'} @@ -991,6 +1083,9 @@ packages: resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} engines: {node: '>= 0.8'} + one-time@1.0.0: + resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} + otpauth@9.3.5: resolution: {integrity: sha512-jQyqOuQExeIl4YIiOUz4TdEcamgAgPX6UYeeS9Iit4lkvs7bwHb0JNDqchGRccbRfvWHV6oRwH36tOsVmc+7hQ==} @@ -1052,6 +1147,10 @@ packages: readable-stream@2.3.7: resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + request@2.88.2: resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} engines: {node: '>= 6'} @@ -1063,6 +1162,10 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -1093,6 +1196,9 @@ packages: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + sqlstring@2.3.1: resolution: {integrity: sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==} engines: {node: '>= 0.6'} @@ -1102,6 +1208,9 @@ packages: engines: {node: '>=0.10.0'} hasBin: true + stack-trace@0.0.10: + resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -1116,10 +1225,17 @@ packages: strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + text-hex@1.0.0: + resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} + toidentifier@1.0.0: resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} engines: {node: '>=0.6'} @@ -1132,6 +1248,10 @@ packages: resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} engines: {node: '>=0.8'} + triple-beam@1.4.1: + resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} + engines: {node: '>= 14.0.0'} + tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} @@ -1183,6 +1303,20 @@ packages: resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} engines: {'0': node >=0.6.0} + winston-daily-rotate-file@5.0.0: + resolution: {integrity: sha512-JDjiXXkM5qvwY06733vf09I2wnMXpZEhxEVOSPenZMii+g7pcDcTBt2MRugnoi8BwVSuCT2jfRXBUy+n1Zz/Yw==} + engines: {node: '>=8'} + peerDependencies: + winston: ^3 + + winston-transport@4.9.0: + resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} + engines: {node: '>= 12.0.0'} + + winston@3.17.0: + resolution: {integrity: sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==} + engines: {node: '>= 12.0.0'} + snapshots: '@aws-crypto/crc32@5.2.0': @@ -1692,6 +1826,14 @@ snapshots: '@smithy/types': 3.7.1 tslib: 2.7.0 + '@colors/colors@1.6.0': {} + + '@dabh/diagnostics@2.0.3': + dependencies: + colorspace: 1.1.4 + enabled: 2.0.0 + kuler: 2.0.0 + '@noble/hashes@1.5.0': {} '@prisma/client@5.22.0(prisma@5.22.0)': @@ -2058,6 +2200,8 @@ snapshots: dependencies: undici-types: 6.19.8 + '@types/triple-beam@1.3.5': {} + accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -2070,6 +2214,10 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 @@ -2152,17 +2300,44 @@ snapshots: caseless@0.12.0: {} + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + color-convert@2.0.1: dependencies: color-name: 1.1.4 + color-name@1.1.3: {} + color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color@3.2.1: + dependencies: + color-convert: 1.9.3 + color-string: 1.9.1 + + colorspace@1.1.4: + dependencies: + color: 3.2.1 + text-hex: 1.0.0 + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -2262,6 +2437,8 @@ snapshots: dependencies: jake: 10.9.2 + enabled@2.0.0: {} + encodeurl@1.0.2: {} encodeurl@2.0.0: {} @@ -2274,6 +2451,8 @@ snapshots: escape-html@1.0.3: {} + escape-string-regexp@1.0.5: {} + etag@1.8.1: {} express-jwt@8.4.1: @@ -2297,6 +2476,12 @@ snapshots: express-unless@2.1.3: {} + express-winston@4.2.0(winston@3.17.0): + dependencies: + chalk: 2.4.2 + lodash: 4.17.21 + winston: 3.17.0 + express@4.21.1: dependencies: accepts: 1.3.8 @@ -2345,6 +2530,12 @@ snapshots: dependencies: strnum: 1.0.5 + fecha@4.2.3: {} + + file-stream-rotator@0.6.1: + dependencies: + moment: 2.30.1 + filelist@1.0.4: dependencies: minimatch: 5.1.6 @@ -2361,6 +2552,8 @@ snapshots: transitivePeerDependencies: - supports-color + fn.name@1.1.0: {} + follow-redirects@1.15.9: {} forever-agent@0.6.1: {} @@ -2409,6 +2602,8 @@ snapshots: ajv: 6.12.6 har-schema: 2.0.0 + has-flag@3.0.0: {} + has-flag@4.0.0: {} has-property-descriptors@1.0.2: @@ -2463,6 +2658,10 @@ snapshots: ipaddr.js@1.9.1: {} + is-arrayish@0.3.2: {} + + is-stream@2.0.1: {} + is-typedarray@1.0.0: {} isarray@1.0.0: {} @@ -2515,6 +2714,8 @@ snapshots: jwa: 1.4.1 safe-buffer: 5.2.1 + kuler@2.0.0: {} + lodash.includes@4.3.0: {} lodash.isboolean@3.0.3: {} @@ -2529,6 +2730,17 @@ snapshots: lodash.once@4.1.1: {} + lodash@4.17.21: {} + + logform@2.7.0: + dependencies: + '@colors/colors': 1.6.0 + '@types/triple-beam': 1.3.5 + fecha: 4.2.3 + ms: 2.1.3 + safe-stable-stringify: 2.5.0 + triple-beam: 1.4.1 + media-typer@0.3.0: {} merge-descriptors@1.0.3: {} @@ -2553,6 +2765,8 @@ snapshots: dependencies: brace-expansion: 2.0.1 + moment@2.30.1: {} + morgan@1.10.0: dependencies: basic-auth: 2.0.1 @@ -2590,6 +2804,8 @@ snapshots: object-assign@4.1.1: {} + object-hash@3.0.0: {} + object-inspect@1.13.2: {} on-finished@2.3.0: @@ -2602,6 +2818,10 @@ snapshots: on-headers@1.0.2: {} + one-time@1.0.0: + dependencies: + fn.name: 1.1.0 + otpauth@9.3.5: dependencies: '@noble/hashes': 1.5.0 @@ -2660,6 +2880,12 @@ snapshots: string_decoder: 1.1.1 util-deprecate: 1.0.2 + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + request@2.88.2: dependencies: aws-sign2: 0.7.0 @@ -2687,6 +2913,8 @@ snapshots: safe-buffer@5.2.1: {} + safe-stable-stringify@2.5.0: {} + safer-buffer@2.1.2: {} semver@7.6.3: {} @@ -2738,6 +2966,10 @@ snapshots: get-intrinsic: 1.2.4 object-inspect: 1.13.2 + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + sqlstring@2.3.1: {} sshpk@1.18.0: @@ -2752,6 +2984,8 @@ snapshots: safer-buffer: 2.1.2 tweetnacl: 0.14.5 + stack-trace@0.0.10: {} + statuses@1.5.0: {} statuses@2.0.1: {} @@ -2762,10 +2996,16 @@ snapshots: strnum@1.0.5: {} + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 + text-hex@1.0.0: {} + toidentifier@1.0.0: {} toidentifier@1.0.1: {} @@ -2775,6 +3015,8 @@ snapshots: psl: 1.9.0 punycode: 2.3.1 + triple-beam@1.4.1: {} + tslib@2.7.0: {} tunnel-agent@0.6.0: @@ -2815,3 +3057,31 @@ snapshots: assert-plus: 1.0.0 core-util-is: 1.0.2 extsprintf: 1.3.0 + + winston-daily-rotate-file@5.0.0(winston@3.17.0): + dependencies: + file-stream-rotator: 0.6.1 + object-hash: 3.0.0 + triple-beam: 1.4.1 + winston: 3.17.0 + winston-transport: 4.9.0 + + winston-transport@4.9.0: + dependencies: + logform: 2.7.0 + readable-stream: 3.6.2 + triple-beam: 1.4.1 + + winston@3.17.0: + dependencies: + '@colors/colors': 1.6.0 + '@dabh/diagnostics': 2.0.3 + async: 3.2.6 + is-stream: 2.0.1 + logform: 2.7.0 + one-time: 1.0.0 + readable-stream: 3.6.2 + safe-stable-stringify: 2.5.0 + stack-trace: 0.0.10 + triple-beam: 1.4.1 + winston-transport: 4.9.0 diff --git a/server/lib/global.js b/server/lib/global.js index b13f869..aec834b 100644 --- a/server/lib/global.js +++ b/server/lib/global.js @@ -57,8 +57,8 @@ exports.S3update = async function (name, file) { }); const data = await s3.send(command); - logger.info(data); - logger.info( + logger.debug(data); + logger.debug( `成功上传了文件 ${await configManager.getConfig("s3.bucket")}/${name}` ); } catch (err) { @@ -99,7 +99,7 @@ exports.randomPassword = (len = 12) => { // JWT 生成与校验 exports.jwt = (data) => { const token = jwt.sign(data, "test"); - logger.info(token); + logger.debug(token); return token; }; @@ -108,7 +108,7 @@ exports.GenerateJwt = async (json) => { try { // Retrieve the JWT secret from config const secret = await configManager.getConfig("security.jwttoken"); -logger.info(secret) +logger.debug(secret) // Check if the secret is defined if (!secret) { throw new Error('JWT secret is not defined in the configuration'); diff --git a/server/logger.js b/server/logger.js index b7a443e..aee45b0 100644 --- a/server/logger.js +++ b/server/logger.js @@ -1,22 +1,74 @@ -const { createLogger, format, transports } = require('winston'); -const { combine, timestamp, printf, errors } = format; +const { createLogger, format, transports } = require("winston"); +const { combine, timestamp, printf, errors, colorize } = format; +const DailyRotateFile = require("winston-daily-rotate-file"); +const path = require("path"); +// 获取环境变量中的日志级别和日志目录 +const logLevel = process.env.LOG_LEVEL || "info"; +const logDirectory = process.env.LOG_DIR || "logs"; + +// 自定义日志格式化方式 const logFormat = printf(({ level, message, timestamp, stack }) => { - return `${timestamp} ${level}: ${stack || message}`; + let logMessage = `${timestamp} ${level.padEnd(7)}: ${message}`; + if (stack) { + logMessage += `\n${stack}`; + } + return logMessage; }); +// 创建logger const logger = createLogger({ - level: 'info', + level: logLevel, format: combine( - timestamp(), - errors({ stack: true }), - logFormat + timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), // 自定义时间格式 + errors({ stack: true }), // 捕获错误堆栈信息 + logFormat // 自定义日志格式 ), transports: [ - new transports.Console(), - new transports.File({ filename: 'logs/error.log', level: 'error' }), - new transports.File({ filename: 'logs/combined.log' }) - ] + new transports.Console({ + format: combine( + colorize(), // 控制台输出颜色 + logFormat // 输出格式 + ), + }), + + // 错误日志文件:每天生成一个错误日志文件 + new DailyRotateFile({ + level: "error", + filename: path.join(logDirectory, "error-%DATE%.log"), + datePattern: "YYYY-MM-DD", + zippedArchive: true, + maxSize: "20m", + maxFiles: "14d", + }), + + // 综合日志文件:记录所有日志 + new DailyRotateFile({ + level: logLevel, + filename: path.join(logDirectory, "combined-%DATE%.log"), + datePattern: "YYYY-MM-DD", + zippedArchive: true, + maxSize: "20m", + maxFiles: "14d", + }), + ], }); +// 在开发环境中输出详细调试信息 +if (process.env.NODE_ENV === "development") { + logger.add( + new transports.Console({ + level: "debug", + format: combine( + colorize(), + timestamp(), + printf( + ({ level, message, timestamp }) => `${timestamp} ${level}: ${message}` + ) + ), + }) + ); +} + +// 导出logger module.exports = logger; diff --git a/server/router_project.js b/server/router_project.js index 86bbfb1..481e957 100644 --- a/server/router_project.js +++ b/server/router_project.js @@ -75,7 +75,7 @@ router.put("/:id/source", async (req, res, next) => { } try { - logger.info(req.body); + logger.debug(req.body); const sha256 = setProjectFile(req.body); const projectId = Number(req.params.id); const userId = Number(res.locals.userid); @@ -263,7 +263,7 @@ function isJson(str) { // 工具函数:设置项目文件 function setProjectFile(source) { - logger.info(source); + logger.debug(source); let sourcedata if (isJson(source)) { sourcedata =String(JSON.stringify(JSON.parse(source))) @@ -271,8 +271,8 @@ function setProjectFile(source) { sourcedata = String(source) } const sha256 = crypto.createHash("sha256").update(sourcedata).digest("hex"); - logger.info("sha256:", sha256); - logger.info(sourcedata); + logger.debug("sha256:", sha256); + logger.debug(sourcedata); I.prisma.ow_projects_file .create({ data: { sha256, source:sourcedata } }) .catch(logger.error); From 183ad00ec2fd40b5c3ea168c9d5b7bf0da87243f Mon Sep 17 00:00:00 2001 From: SunWuyuan <1847261658@qq.com> Date: Sun, 24 Nov 2024 11:19:21 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BD=BF=E7=94=A8winston=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.js | 9 ++++----- server/configManager.js | 2 +- server/lib/captcha/captcha.js | 5 +++-- server/lib/captcha/geetest.js | 15 ++++++++------- server/lib/database.js | 9 +++++---- server/lib/global.js | 2 +- server/{ => lib}/logger.js | 0 server/lib/method/projectlist.js | 3 ++- server/lib/method/projects.js | 9 +++++---- server/lib/method/users.js | 3 ++- server/lib/totpUtils.js | 5 +++-- server/middleware/auth.js | 1 + server/router_account.js | 25 +++++++++++++------------ server/router_api.js | 3 ++- server/router_comment.js | 5 +++-- server/router_my.js | 1 + server/router_project.js | 2 +- server/router_projectlist.js | 11 ++++++----- server/router_scratch.js | 31 ++++++++++++++++--------------- server/router_search.js | 3 ++- server/router_user.js | 1 + server/router_webhost.js | 13 +++++++------ server/services/emailService.js | 5 +++-- server/services/emailTemplates.js | 1 + 24 files changed, 91 insertions(+), 73 deletions(-) rename server/{ => lib}/logger.js (100%) diff --git a/app.js b/app.js index 5255598..061e944 100644 --- a/app.js +++ b/app.js @@ -3,12 +3,10 @@ var app = express(); const jwt = require("jsonwebtoken"); const configManager = require("./server/configManager.js"); -const logger = require("./server/logger.js"); +const logger = require("./server/lib/logger.js"); require("dotenv").config({ override: true }); - - expressWinston = require("express-winston"); app.use( @@ -199,7 +197,8 @@ app.get("/check", function (req, res, next) { message: "success", code: 200, }); -logger.debug("check");}); + logger.debug("check"); +}); process.on("uncaughtException", function (err) { logger.error("Caught exception: " + err); @@ -207,7 +206,7 @@ process.on("uncaughtException", function (err) { // Centralized error-handling middleware function app.use((err, req, res, next) => { - logger.error(err.stack); + logger.error(err); res.status(500).send({ status: "error", message: "Something went wrong!", diff --git a/server/configManager.js b/server/configManager.js index 69d3c07..3d0464c 100644 --- a/server/configManager.js +++ b/server/configManager.js @@ -1,5 +1,5 @@ +const logger = require("./lib/logger.js"); const { PrismaClient } = require("@prisma/client"); -const logger = require("./logger"); class ConfigManager { constructor() { diff --git a/server/lib/captcha/captcha.js b/server/lib/captcha/captcha.js index 882ea8a..64aac43 100644 --- a/server/lib/captcha/captcha.js +++ b/server/lib/captcha/captcha.js @@ -1,3 +1,4 @@ +const logger = require("../logger.js"); const configManager = require("../configManager"); const express = require("express"); @@ -20,12 +21,12 @@ app.use(async (req, res, next) => { }, function (error, httpResponse, body) { if (error) { - console.error("Error verifying recaptcha:", error); + logger.error("Error verifying recaptcha:", error); res.status(200).send({ message: "验证码验证失败", error: error }); } const response = JSON.parse(body); - console.log(response); + logger.debug(response); if (response.success) { next(); } else { diff --git a/server/lib/captcha/geetest.js b/server/lib/captcha/geetest.js index 6d40a92..4a9086e 100644 --- a/server/lib/captcha/geetest.js +++ b/server/lib/captcha/geetest.js @@ -1,3 +1,4 @@ +const logger = require("../logger.js"); const configManager = require("../../configManager"); const express = require("express"); @@ -23,7 +24,7 @@ app.use(async (req, res, next) => { // 处理验证码信息 try { - console.log(req.body.captcha); + logger.debug(req.body.captcha); if (req.body.captcha) { // 如果是字符串则转为json if (typeof req.body.captcha === "string") { @@ -38,12 +39,12 @@ app.use(async (req, res, next) => { : querystring.parse(req.url.split("?")[1]) || req.body; } } catch (error) { - console.error("Captcha Parsing Error:", error); + logger.error("Captcha Parsing Error:", error); res.status(400).send({ code: 400, msg: "Invalid captcha data" }); return; } - console.log(geetest); + logger.debug(geetest); // 生成签名 const sign_token = hmac_sha256_encode(geetest.lot_number, GEE_CAPTCHA_KEY); @@ -64,7 +65,7 @@ app.use(async (req, res, next) => { if (result.result === "success") { next(); // 验证成功,继续处理请求 } else { - console.log(`Validate fail: ${result.reason}`); + logger.debug(`Validate fail: ${result.reason}`); res.status(500).send({ code: 500, msg: `请完成验证码/${result.reason}`, @@ -72,7 +73,7 @@ app.use(async (req, res, next) => { }); } } catch (error) { - console.error("Geetest server error:", error); + logger.error("Geetest server error:", error); next(); // 极验服务器出错时放行,避免阻塞业务逻辑 } }); @@ -91,12 +92,12 @@ async function post_form(datas, url) { }); if (response.status !== 200) { - console.error(`Geetest Response Error, StatusCode: ${response.status}`); + logger.error(`Geetest Response Error, StatusCode: ${response.status}`); throw new Error("Geetest Response Error"); } return response.data; } catch (error) { - console.error("Request to Geetest failed:", error); + logger.error("Request to Geetest failed:", error); throw error; } } diff --git a/server/lib/database.js b/server/lib/database.js index a0636d1..8200d6d 100644 --- a/server/lib/database.js +++ b/server/lib/database.js @@ -1,3 +1,4 @@ +const logger = require("./logger.js"); // 连接MySQL var mysql = require("mysql"); var pool = mysql.createPool(process.env.DATABASE_URL); @@ -5,14 +6,14 @@ var pool = mysql.createPool(process.env.DATABASE_URL); //防止注入:'SELECT * FROM ow_users WHERE ?', WHERE exports.qww = function query_with_w(SQL, W, callback) { pool.getConnection(function (err, connection) { - //console.log(err) + //logger.debug(err) if (err) return callback(err, ""); // Use the connection connection.query(SQL, W, function (err, rows) { callback(err, rows); connection.release(); //释放链接 - console.log(SQL); + logger.debug(SQL); }); }); }; @@ -20,14 +21,14 @@ exports.qww = function query_with_w(SQL, W, callback) { //正常操作 exports.query = function query(SQL, callback) { pool.getConnection(function (err, connection) { - //console.log(err) + //logger.debug(err) if (err) return callback(err, ""); // Use the connection connection.query(SQL, function (err, rows) { callback(err, rows); connection.release(); //释放链接 - console.log(SQL); + logger.debug(SQL); }); }); }; diff --git a/server/lib/global.js b/server/lib/global.js index aec834b..60d051a 100644 --- a/server/lib/global.js +++ b/server/lib/global.js @@ -1,5 +1,5 @@ const configManager = require("../configManager"); -const logger = require("../logger"); +const logger = require("./logger"); const crypto = require("crypto"); const jwt = require("jsonwebtoken"); // 确保安装了 jsonwebtoken 库 diff --git a/server/logger.js b/server/lib/logger.js similarity index 100% rename from server/logger.js rename to server/lib/logger.js diff --git a/server/lib/method/projectlist.js b/server/lib/method/projectlist.js index a3073cb..3b87f21 100644 --- a/server/lib/method/projectlist.js +++ b/server/lib/method/projectlist.js @@ -1,3 +1,4 @@ +const logger = require("../logger.js"); const { PrismaClient } = require("@prisma/client"); const prisma = new PrismaClient(); const { getProjectsAndUsersByProjectsList } = require("./projects.js"); @@ -14,7 +15,7 @@ function cleanAndDeduplicateList(list) { // 统一的错误处理函数 function handleError(error) { - console.error(error); + logger.error(error); throw new Error(error.message || "发生了错误"); } diff --git a/server/lib/method/projects.js b/server/lib/method/projects.js index bde4f26..f5eb538 100644 --- a/server/lib/method/projects.js +++ b/server/lib/method/projects.js @@ -1,3 +1,4 @@ +const logger = require("../logger.js"); //prisma client const { PrismaClient } = require("@prisma/client"); const prisma = new PrismaClient(); @@ -26,11 +27,11 @@ async function getProjectsByList(list, userid) { select: select, }); - //console.log(projects); + //logger.debug(projects); projects = projects.filter((project) => { return !(project.state == "private" && project.authorid != userid); }); - //console.log(projects); + //logger.debug(projects); return projects; } @@ -40,9 +41,9 @@ async function getProjectsAndUsersByProjectsList(list, userid) { var users = await getUsersByList(userslist); return { projects: projects, users: users }; } -//(async () => {console.log(await getProjectsAndUsersByProjectsList([3, 126, 130, 131, 129], 2));})(); +//(async () => {logger.debug(await getProjectsAndUsersByProjectsList([3, 126, 130, 131, 129], 2));})(); -//console.log(await getProjectsAndUsersByProjectsList([3, 126, 130, 131, 129], 2)) +//logger.debug(await getProjectsAndUsersByProjectsList([3, 126, 130, 131, 129], 2)) module.exports = { getProjectsByList, getUsersByList, diff --git a/server/lib/method/users.js b/server/lib/method/users.js index 5314664..7a949cd 100644 --- a/server/lib/method/users.js +++ b/server/lib/method/users.js @@ -1,4 +1,5 @@ //prisma client +const logger = require("../logger.js"); const { PrismaClient } = require("@prisma/client"); const prisma = new PrismaClient(); @@ -21,7 +22,7 @@ async function getUsersByList(list) { select: select, }); - //console.log(users); + //logger.debug(users); return users; } diff --git a/server/lib/totpUtils.js b/server/lib/totpUtils.js index 0d77e2c..4044840 100644 --- a/server/lib/totpUtils.js +++ b/server/lib/totpUtils.js @@ -1,3 +1,4 @@ +const logger = require("./logger.js"); const OTPAuth = require("otpauth"); const I = require("./global.js"); @@ -203,7 +204,7 @@ async function validateTotpToken(req, res, next) { req.query.totp_token || req.body.totp_token || req.headers["x-totp-token"]; - console.log(token); + logger.debug(token); if (!res.locals.login) { // 未登录,返回401 Unauthorized状态码 return res.status(401).send({ status: "0", msg: "请先登录以继续操作" }); @@ -231,7 +232,7 @@ async function validateTotpToken(req, res, next) { // If valid, move to the next middleware or route handler next(); } catch (error) { - console.error("Error in TOTP validation middleware:", error); + logger.error("Error in TOTP validation middleware:", error); return res.status(500).json({ status: "error", message: "Internal server error during TOTP validation.", diff --git a/server/middleware/auth.js b/server/middleware/auth.js index 0fe8fdd..e9d533b 100644 --- a/server/middleware/auth.js +++ b/server/middleware/auth.js @@ -1,3 +1,4 @@ +const logger = require("../lib/logger.js"); const configManager = require("../configManager"); async function needlogin(req, res, next) { diff --git a/server/router_account.js b/server/router_account.js index d9c5fe8..a76955d 100644 --- a/server/router_account.js +++ b/server/router_account.js @@ -1,3 +1,4 @@ +const logger = require("./lib/logger.js"); const configManager = require("./configManager"); var express = require("express"); @@ -25,11 +26,11 @@ router.all("*", function (req, res, next) { /* (async () => { try { - console.log("site.name:", await configManager.getConfig("site.name")); + logger.debug("site.name:", await configManager.getConfig("site.name")); // 其他逻辑... } catch (error) { - console.error("Error:", error); + logger.error("Error:", error); } })(); */ @@ -101,7 +102,7 @@ router.post("/login", async function (req, res, next) { display_name: User["display_name"], avatar: User["images"], }); - //console.log(token); + //logger.debug(token); // res.cookie("token", token, { maxAge: 604800000 }); res.status(200).send({ status: "OK", @@ -155,7 +156,7 @@ router.post("/register", geetest, async function (req, res, next) { var INSERT = `INSERT INTO ow_users (username,email,password,display_name) VALUES ('${Date.now()}','${email}','${pw}','${display_name}')`; DB.query(INSERT, async function (err, newUser) { if (err) { - console.error(err); + logger.error(err); res.status(200).send({ message: "再试一次17" }); return; } @@ -265,7 +266,7 @@ router.get("/totp/list", needlogin, async (req, res) => { }, }); } catch (error) { - console.error("获取验证器列表时出错:", error); + logger.error("获取验证器列表时出错:", error); return res.status(500).json({ status: "error", message: "获取验证器列表失败", @@ -299,7 +300,7 @@ router.post("/totp/rename", needlogin, async (req, res) => { data: renamedTotp, }); } catch (error) { - console.error("重命名验证器时出错:", error); + logger.error("重命名验证器时出错:", error); return res.status(500).json({ status: "error", message: "重命名验证器失败", @@ -324,7 +325,7 @@ router.post("/totp/check", async (req, res) => { data: { validated: isValid }, }); } catch (error) { - console.error("验证令牌时出错:", error); + logger.error("验证令牌时出错:", error); return res.status(500).json({ status: "error", message: "验证令牌失败", @@ -348,7 +349,7 @@ router.post("/totp/delete", needlogin, async (req, res) => { data: deletedTotp, }); } catch (error) { - console.error("删除验证器时出错:", error); + logger.error("删除验证器时出错:", error); return res.status(500).json({ status: "error", message: "删除验证器失败", @@ -365,7 +366,7 @@ router.post("/totp/generate", needlogin, async (req, res) => { data: info, }); } catch (error) { - console.error("创建验证器时出错:", error); + logger.error("创建验证器时出错:", error); return res.status(500).json({ status: "error", message: "创建验证器失败", @@ -396,7 +397,7 @@ router.post("/totp/activate", needlogin, async (req, res) => { data: activatedTotp, }); } catch (error) { - console.error("激活验证器时出错:", error); + logger.error("激活验证器时出错:", error); return res.status(500).json({ status: "error", message: "激活验证器失败", @@ -448,7 +449,7 @@ router.post("/magiclink/generate", geetest, async (req, res) => { res.status(200).json({status: "success", message: "Magic Link 已发送到您的邮箱" }); } catch (error) { - console.error("生成 Magic Link 时出错:", error); + logger.error("生成 Magic Link 时出错:", error); res.status(200).json({ status: "error", message: "生成 Magic Link 失败" }); } }); @@ -496,7 +497,7 @@ router.get("/magiclink/validate", async (req, res) => { token: jwtToken, }); } catch (error) { - //console.error("验证 Magic Link 时出错:", error); + //logger.error("验证 Magic Link 时出错:", error); res.status(200).json({ status: "error",message: "验证 Magic Link 失败" }); } }); diff --git a/server/router_api.js b/server/router_api.js index 7a821fc..52a8b3a 100644 --- a/server/router_api.js +++ b/server/router_api.js @@ -1,3 +1,4 @@ +const logger = require("./lib/logger.js"); const configManager = require("./configManager"); var express = require("express"); @@ -62,7 +63,7 @@ router.get("/getuserinfo", async function (req, res, next) { }, }); if (!user[0]) { - console.log("用户不存在"); + logger.debug("用户不存在"); res.locals.tip = { opt: "flash", msg: "用户不存在" }; res.status(404).json({ status: "error", diff --git a/server/router_comment.js b/server/router_comment.js index 98166cd..b19eb4e 100644 --- a/server/router_comment.js +++ b/server/router_comment.js @@ -1,3 +1,4 @@ +const logger = require("./lib/logger.js"); const configManager = require("./configManager"); const express = require("express"); @@ -9,7 +10,7 @@ router.all("*", (req, res, next) => next()); // 统一的错误处理函数 const handleError = (res, err, message) => { - console.error(err); + logger.error(err); res.status(500).send({ errno: 1, errmsg: message, data: err }); }; @@ -96,7 +97,7 @@ router.get("/api/comment", async (req, res, next) => { //去重 user_ids = Array.from(new Set(user_ids)); - console.log(user_ids); + logger.debug(user_ids); const users = await getUsersByList(user_ids); const result = transformedComments.map((comment) => { const children = transformedChildrenComments.filter( diff --git a/server/router_my.js b/server/router_my.js index cfbb3a0..7a1e1b9 100644 --- a/server/router_my.js +++ b/server/router_my.js @@ -1,3 +1,4 @@ +const logger = require("./lib/logger.js"); const configManager = require("./configManager"); //个人中心 diff --git a/server/router_project.js b/server/router_project.js index 481e957..bd50657 100644 --- a/server/router_project.js +++ b/server/router_project.js @@ -1,3 +1,4 @@ +const logger = require("./lib/logger.js"); const configManager = require("./configManager"); const express = require("express"); const router = express.Router(); @@ -5,7 +6,6 @@ const crypto = require("crypto"); const DB = require("./lib/database.js"); const I = require("./lib/global.js"); const default_project = require("./lib/default_project.js"); -const logger = require("./logger.js"); // 中间件,确保所有请求均经过该处理 router.all("*", (req, res, next) => next()); diff --git a/server/router_projectlist.js b/server/router_projectlist.js index 5364073..86dc4d1 100644 --- a/server/router_projectlist.js +++ b/server/router_projectlist.js @@ -1,3 +1,4 @@ +const logger = require("./lib/logger.js"); const configManager = require("./configManager"); const express = require("express"); @@ -21,7 +22,7 @@ router.all("*", (req, res, next) => next()); // 统一的错误处理函数 const handleError = (res, message, err) => { - console.error(err); + logger.error(err); res.status(500).send({ status: "0", message, error: err }); }; @@ -80,19 +81,19 @@ router.get("/user/:id/:state?", async (req, res, next) => { let info; if (state === "private" && res.locals.userid == id) { - console.log("1"); + logger.debug("1"); info = await getUserProjectlist(id, ["private"]); } else if (state === "public") { - console.log("2"); + logger.debug("2"); info = await getUserProjectlist(id, ["public"]); } else if (!state || ["all", "undefined", "null", ""].includes(state)) { - console.log("3"); + logger.debug("3"); info = res.locals.userid == id ? await getUserProjectlist(id, ["private", "public"]) : await getUserProjectlist(id, ["public"]); } else { - console.log("4"); + logger.debug("4"); info = await getUserProjectlist(id, "public"); } diff --git a/server/router_scratch.js b/server/router_scratch.js index 9177198..94c257d 100644 --- a/server/router_scratch.js +++ b/server/router_scratch.js @@ -1,3 +1,4 @@ +const logger = require("./lib/logger.js"); const configManager = require("./configManager"); var express = require("express"); @@ -21,7 +22,7 @@ router.get("/scratchcount", function (req, res, next) { ` (SELECT count(id) FROM ow_projects WHERE state='public' AND type='scratch' ) AS scratch_count `; DB.query(SQL, function (err, data) { if (err) { - // console.error('数据库操作出错:'); + // logger.error('数据库操作出错:'); res.locals.scratch_count = 0; } else { res.locals.scratch_count = data[0].scratch_count; @@ -112,7 +113,7 @@ router.get("/projectinfo", function (req, res, next) { res.locals["is_author"] = SCRATCH[0].authorid == res.locals.userid ? true : false; - ////console.log(SCRATCH[0]); + ////logger.debug(SCRATCH[0]); res.json(SCRATCH[0]); }); } catch (err) { @@ -133,7 +134,7 @@ router.get("/projectinfo2", function (req, res, next) { ` WHERE ow_projects.id=${req.query.id} AND (ow_projects.state='public' or ow_projects.authorid=${res.locals.userid}) AND ow_projects.type='scratch' LIMIT 1`; DB.query(SQL, function (err, SCRATCH) { if (err || SCRATCH.length == 0) { - console.log(err); + logger.debug(err); res.locals.tip = { opt: "flash", msg: "项目不存在或未发布" }; res.send({ code: 404, status: "404", msg: "项目不存在或未发布" }); return; @@ -231,7 +232,7 @@ router.get("/projectinfo2", function (req, res, next) { }, project_token: res.locals.usertoken || "", }; - ////console.log(SCRATCH[0]); + ////logger.debug(SCRATCH[0]); res.json(jsontw); }); } catch (err) { @@ -313,7 +314,7 @@ router.post("/play/openSrc", function (req, res, next) { //2、从数据库加载 router.post("/project/:projectid", function (req, res, next) { try { - ////console.log('服务器:获取作品JSON源代码'); + ////logger.debug('服务器:获取作品JSON源代码'); var projectid = 0; if (req.params.projectid) { projectid = req.params.projectid; @@ -433,7 +434,7 @@ router.post("/saveProjcetTitle", function (req, res, next) { //保存作品源代码:此时作品已存在。req.body为项目JSON源代码 router.put("/projects/:projectid", function (req, res, next) { try { - // //console.log('服务器:保存作品JSON源代码'); + // //logger.debug('服务器:保存作品JSON源代码'); if (!res.locals.login) { res.status(404).send({}); return; @@ -469,7 +470,7 @@ router.put("/projects/:projectid", function (req, res, next) { //保存作品:缩略图 router.post("/thumbnail/:projectid", function (req, res, next) { try { - ////console.log('开始保存缩略图:'+req.params.projectid); + ////logger.debug('开始保存缩略图:'+req.params.projectid); // 请求的头部为 'Content-Type': 'image/png'时,用req.on接收文件 var _data = []; @@ -485,12 +486,12 @@ router.post("/thumbnail/:projectid", function (req, res, next) { fs.writeFile(strFileName, content, function (err) { if (err) { res.status(404).send({ status: "err" }); - //console.log(err); - //console.log("保存缩略图失败:" + strFileName); + //logger.debug(err); + //logger.debug("保存缩略图失败:" + strFileName); } else { I.S3update("scratch_slt/" + req.params.projectid, strFileName); - ////console.log('保存缩略图成功:'+strFileName); + ////logger.debug('保存缩略图成功:'+strFileName); res.status(200).send({ status: "ok" }); //fs.unlink(`./data/scratch_slt/${req.params.projectid}`,function (err) { if (err) { res.status(200).send( {'status':'文件上传失败'}); return; }}) } @@ -531,7 +532,7 @@ router.post("/shareProject/:projectid", function (req, res, next) { //保存新作品:保存源代码及作品名称。req.body为项目JSON源代码,?title=作品名称 router.post("/projects", function (req, res, next) { try { - //console.log("服务器:新建作品JSON源代码"); + //logger.debug("服务器:新建作品JSON源代码"); //if (!req.body) { res.send(404); return; } var title = "新作品"; @@ -564,7 +565,7 @@ router.post("/assets/:filename", function (req, res, next) { strFileName, function (bExists) { //if (bExists) { - // console.log("素材已存在:" + strFileName); + // logger.debug("素材已存在:" + strFileName); // res.status(200).send({ status: "ok" }); //} else { var _data = []; @@ -578,11 +579,11 @@ router.post("/assets/:filename", function (req, res, next) { fs.writeFile(strFileName, content, function (err) { if (err) { res.send(404); - //console.log("素材保存失败:" + strFileName); + //logger.debug("素材保存失败:" + strFileName); } else { I.S3update("material/asset/" + req.params.filename, strFileName); - console.log("素材保存成功:" + strFileName); + logger.debug("素材保存成功:" + strFileName); res.status(200).send({ status: "ok" }); //fs.unlink('./data/material/asset/' + req.params.filename,function (err) { if (err) { res.status(200).send( {'status':'文件上传失败'}); return; }}) } @@ -819,7 +820,7 @@ router.post("/getRandomBackdrop", function (req, res, next) { // 组件获取条件 tag:是否获取分类; f: 搜索字符串; t: 分类; l: 已经获取的背景数; n: 每次获取的背景数,默认为32个 router.post("/getCostumeLibrary", function (req, res, next) { try { - // //console.log(req.body); + // //logger.debug(req.body); var WHERE = ""; if (req.body.t != 0) { diff --git a/server/router_search.js b/server/router_search.js index 7981cc5..e13de3e 100644 --- a/server/router_search.js +++ b/server/router_search.js @@ -1,3 +1,4 @@ +const logger = require("./lib/logger.js"); const configManager = require("./configManager"); const express = require("express"); @@ -70,7 +71,7 @@ router.get("/", async (req, res, next) => { skip: (Number(curr) - 1) * Number(limit), take: Number(limit), }); - console.log(searchinfo); + logger.debug(searchinfo); // 统计项目总数 const projectcount = await I.prisma.ow_projects.count({ where: searchinfo, diff --git a/server/router_user.js b/server/router_user.js index 042e470..7393cb1 100644 --- a/server/router_user.js +++ b/server/router_user.js @@ -1,3 +1,4 @@ +const logger = require("./lib/logger.js"); const configManager = require("./configManager.js"); var express = require("express"); var router = express["Router"](); diff --git a/server/router_webhost.js b/server/router_webhost.js index 7b1b341..8164156 100644 --- a/server/router_webhost.js +++ b/server/router_webhost.js @@ -1,3 +1,4 @@ +const logger = require("./lib/logger.js"); const configManager = require("../configManager"); var express = require("express"); @@ -52,13 +53,13 @@ router.get("/:id/*", function (req, res) { var filestr = ""; var filename = req.path.split("/"); filename.splice(0, 2); - //console.log(filename) - //console.log(req.params.filename) - //console.log(JSON.parse(PROJECT[0].source)); + //logger.debug(filename) + //logger.debug(req.params.filename) + //logger.debug(JSON.parse(PROJECT[0].source)); if (getValue(filename, JSON.parse(PROJECT[0].source)) != false) { filestr = decode(getValue(filename, JSON.parse(PROJECT[0].source))); - console.log(filestr); + logger.debug(filestr); res.type("html").send(decode(filestr)); } else { @@ -107,8 +108,8 @@ router.post("/update/:id", function (req, res) { // 新作品 //if (req.body.id == '0'){ var INSERT =`INSERT INTO ow_projects (authorid, title,source) VALUES (${res.locals.userid}, ?, ?)`; var SET = [req.body.title,req.body.data] DB.qww(INSERT, SET, function (err, newPython) { if (err || newPython.affectedRows==0) { res.status(200).send({status: "0", msg: "保存失败" }); return; } res.status(200).send({status: "ok", msg: "保存成功", 'newid': newPython['insertId']}) }); return; } - console.log(req.body); - console.log(encodeHtmlInJson(req.body)); + logger.debug(req.body); + logger.debug(encodeHtmlInJson(req.body)); // 旧作品 var UPDATE = `UPDATE ow_projects SET ? WHERE id=${req.params.id} AND authorid=${res.locals.userid} LIMIT 1`; diff --git a/server/services/emailService.js b/server/services/emailService.js index f364cd2..78d18b3 100644 --- a/server/services/emailService.js +++ b/server/services/emailService.js @@ -1,3 +1,4 @@ +const logger = require("../lib/logger.js"); const configManager = require("../configManager"); const nodemailer = require("nodemailer"); @@ -10,7 +11,7 @@ configManager.getConfig("mail.service").then((res) => { configManager.getConfig("mail.pass").then((res) => { pass = res; - //console.log(service, user, pass); + //logger.debug(service, user, pass); transporter = nodemailer.createTransport({ service: service, secure: true, @@ -34,7 +35,7 @@ const sendEmail = async (to, subject, html) => { html, }); } catch (error) { - console.error("Error sending email:", error); + logger.error("Error sending email:", error); } }; diff --git a/server/services/emailTemplates.js b/server/services/emailTemplates.js index 2051b39..5c9d76b 100644 --- a/server/services/emailTemplates.js +++ b/server/services/emailTemplates.js @@ -1,3 +1,4 @@ +const logger = require("../lib/logger.js"); const registrationTemplate = async (email, password) => `