Sfoglia il codice sorgente

feat: 增加日志定位文件

lanjianrong 1 giorno fa
parent
commit
3c67e15ec4

+ 2 - 1
app/controller/weapp_tender_controller.js

@@ -708,7 +708,8 @@ module.exports = app => {
                 const { rid } = ctx.query;
                 const revise = rid
                     ? await ctx.service.ledgerRevise.getRevise(ctx.tender.id, rid)
-                    : ctx.service.ledgerRevise.getLastestRevise(ctx.tender.id);
+                    : await ctx.service.ledgerRevise.getLastestRevise(ctx.tender.id);
+                if (!revise) throw '修订数据不存在或已失效';
                 revise.preHis = revise.pre_his_id ? await ctx.service.ledgerHistory.getDataById(revise.pre_his_id) : null;
                 revise.curHis = revise.his_id ? await ctx.service.ledgerHistory.getDataById(revise.his_id) : null;
                 await ctx.service.reviseAudit.loadReviseUser(revise);

+ 0 - 129
app/middleware/weapp_auth2.js

@@ -1,129 +0,0 @@
-module.exports = (options, app) => {
-return async function wechatAuth2(ctx, next) {
-    const traceId = ctx.logId ||
-        `${Date.now()}-${Math.random().toString(16).slice(2)}`;
-    const startTime = Date.now();
-
-    ctx.logger.warn(
-        '[WEAPP_TRACE] id=%s start method=%s url=%s',
-        traceId,
-        ctx.method,
-        ctx.originalUrl
-    );
-
-    const token =
-        ctx.headers.authorization &&
-        ctx.headers.authorization.replace('Bearer ', '');
-
-    const code = ctx.headers['platform-code'];
-
-    if (!token || !code) {
-        ctx.logger.warn(
-            '[WEAPP_TRACE] id=%s auth_failed reason=missing_token_or_code cost=%dms',
-            traceId,
-            Date.now() - startTime
-        );
-
-        ctx.body = {
-            code: 2,
-            msg: '请登录',
-            data: null,
-        };
-        return;
-    }
-
-    try {
-        const decoded = jwt.verify(
-            token,
-            weappConfig.jwtSecret
-        );
-
-        ctx.logger.warn(
-            '[WEAPP_TRACE] id=%s jwt_done cost=%dms',
-            traceId,
-            Date.now() - startTime
-        );
-
-        const projectData =
-            await ctx.service.project.getProjectByCode(
-                code.trim()
-            );
-
-        ctx.logger.warn(
-            '[WEAPP_TRACE] id=%s project_done cost=%dms',
-            traceId,
-            Date.now() - startTime
-        );
-
-        if (projectData === null) {
-            throw '不存在项目数据';
-        }
-
-        const projectAccount =
-            await ctx.service.projectAccount.getDataByCondition({
-                weapp_openid: decoded.openid,
-                project_id: projectData.id,
-                enable: 1,
-            });
-
-        ctx.logger.warn(
-            '[WEAPP_TRACE] id=%s account_done cost=%dms',
-            traceId,
-            Date.now() - startTime
-        );
-
-        if (!projectAccount) {
-            throw '账号不存在或未启用';
-        }
-
-        ctx.session.sessionUser = {
-            ...projectAccount,
-            accountId: projectAccount.id,
-        };
-
-        ctx.session.sessionProject = projectData;
-    } catch (error) {
-        ctx.logger.error(
-            '[WEAPP_TRACE] id=%s auth_error url=%s cost=%dms',
-            traceId,
-            ctx.originalUrl,
-            Date.now() - startTime,
-            error
-        );
-
-        if (error.name === 'TokenExpiredError') {
-            ctx.body = {
-                code: 2,
-                msg: '登陆凭证过期,请重新登陆',
-                data: null,
-            };
-            return;
-        }
-
-        ctx.body = {
-            code: -1,
-            msg: error.toString() || '请登录',
-            data: null,
-        };
-        return;
-    }
-
-    ctx.logger.warn(
-        '[WEAPP_TRACE] id=%s auth_done controller_start cost=%dms',
-        traceId,
-        Date.now() - startTime
-    );
-
-    try {
-        await next();
-    } finally {
-        ctx.logger.warn(
-            '[WEAPP_TRACE] id=%s request_end status=%s cost=%dms url=%s',
-            traceId,
-            ctx.status,
-            Date.now() - startTime,
-            ctx.originalUrl
-        );
-    }
-};
-}

+ 67 - 0
app/middleware/weapp_request_logger.js

@@ -0,0 +1,67 @@
+'use strict';
+
+/**
+ * 微信小程序接口请求日志。
+ *
+ * 仅记录定位请求所需的元数据,不记录 authorization、platform-code、
+ * cookie、请求体或完整响应,避免敏感信息进入日志。
+ */
+module.exports = options => {
+    const slowThreshold = Number(options.slowThreshold) || 3000;
+
+    return async function weappRequestLogger(ctx, next) {
+        const startTime = Date.now();
+        const requestId = ctx.logId || ctx.app.uuid.v1();
+        let requestError = null;
+
+        ctx.logId = requestId;
+        ctx.set('X-Request-Id', requestId);
+
+        try {
+            await next();
+        } catch (error) {
+            requestError = error;
+            throw error;
+        } finally {
+            const duration = Date.now() - startTime;
+            const user = ctx.session && ctx.session.sessionUser;
+            const project = ctx.session && ctx.session.sessionProject;
+            const tender = ctx.tender;
+            const responseBody = ctx.body;
+            const businessCode = responseBody && typeof responseBody === 'object'
+                ? responseBody.code
+                : undefined;
+            const logData = {
+                requestId,
+                requestTime: new Date(startTime).toISOString(),
+                method: ctx.method,
+                path: ctx.path,
+                status: ctx.status,
+                code: businessCode,
+                duration,
+                slow: duration >= slowThreshold,
+                uid: user && (user.accountId || user.id),
+                projectId: project && project.id,
+                projectCode: project && project.code,
+                tenderId: tender && tender.id,
+                ip: ctx.ip,
+            };
+            const accessLogger = ctx.getLogger('weappAccess');
+
+            if (duration >= slowThreshold) {
+                accessLogger.warn(JSON.stringify(logData));
+            } else {
+                accessLogger.info(JSON.stringify(logData));
+            }
+
+            if (requestError || ctx.status >= 500 || (typeof businessCode === 'number' && businessCode < 0)) {
+                const errorData = Object.assign({}, logData, {
+                    error: requestError
+                        ? (requestError.stack || requestError.message || requestError.toString())
+                        : responseBody && responseBody.msg,
+                });
+                ctx.getLogger('weappError').error(JSON.stringify(errorData));
+            }
+        }
+    };
+};

+ 1 - 1
app/router.js

@@ -65,7 +65,7 @@ module.exports = app => {
     const safeInspectionCheck = app.middlewares.safeInspectionCheck();
     const safeStageCheck = app.middlewares.safeStageCheck();
     // weapp中间件
-    const weappAuth = app.middlewares.weappAuth2();
+    const weappAuth = app.middlewares.weappAuth();
     const weappTenderCheck = app.middlewares.weappTenderCheck();
     // 登入登出相关
     app.get('/login', 'loginController.index');

+ 3 - 3
app/service/revise_audit.js

@@ -480,7 +480,7 @@ module.exports = app => {
                 const shenpiUrl = await this.ctx.helper.urlToShort(
                     this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + revise.tid + '/revise/' + revise.id + '/info'
                 );
-                const weappPagePath = `/pages/message-entry/index?tenderId=${this.ctx.tender.id}&tenderName=${this.ctx.tender.data.name}&type=revise&targetCode=${this.ctx.session.sessionProject.code}`
+                const weappPagePath = `/pages/message-entry/index?tenderId=${this.ctx.tender.id}&tenderName=${this.ctx.tender.data.name}&type=revise&dataId=${revise.id}&targetCode=${this.ctx.session.sessionProject.code}`
                 const wechatData = {
                     wap_url: shenpiUrl,
                     weapp_page: weappPagePath,
@@ -607,7 +607,7 @@ module.exports = app => {
                             await transaction.updateRows(this.tableName, updateOther);
                         }
                     }
-                    const weappPagePath = `/pages/message-entry/index?tenderId=${this.ctx.tender.id}&tenderName=${this.ctx.tender.data.name}&type=revise&targetCode=${this.ctx.session.sessionProject.code}`
+                    const weappPagePath = `/pages/message-entry/index?tenderId=${this.ctx.tender.id}&tenderName=${this.ctx.tender.data.name}&type=revise&dataId=${revise.id}&targetCode=${this.ctx.session.sessionProject.code}`
                     // 无下一审核人表示,审核结束
                     if (nextAuditors.length > 0) {
                         const nextAuditUpdateData = nextAuditors.map(x => { return { id: x.id, status: auditConst.status.checking, begin_time: time }});
@@ -773,7 +773,7 @@ module.exports = app => {
                 const shenpiUrl = await this.ctx.helper.urlToShort(
                     this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + revise.tid + '/revise/' + revise.id + '/info'
                 );
-                const weappPagePath = `/pages/message-entry/index?tenderId=${this.ctx.tender.id}&tenderName=${this.ctx.tender.data.name}&type=revise&targetCode=${this.ctx.session.sessionProject.code}`
+                const weappPagePath = `/pages/message-entry/index?tenderId=${this.ctx.tender.id}&tenderName=${this.ctx.tender.data.name}&type=revise&dataId=${revise.id}&targetCode=${this.ctx.session.sessionProject.code}`
 
                 const wechatData = {
                     wap_url: shenpiUrl,

+ 13 - 1
config/config.default.js

@@ -65,7 +65,13 @@ module.exports = appInfo => {
     config.pageSize = 15;
 
     // 中间件
-    config.middleware = ['gzip', 'urlParse', 'sortFilter', 'autoLogger', 'autoFinishLogger'];
+    config.middleware = ['gzip', 'urlParse', 'sortFilter', 'autoLogger', 'weappRequestLogger', 'autoFinishLogger'];
+
+    // 微信小程序接口请求日志
+    config.weappRequestLogger = {
+        match: /^\/wx\/weapp(?:\/|$)/,
+        slowThreshold: 3000,
+    };
 
     // session配置
     config.session = {
@@ -179,6 +185,12 @@ module.exports = appInfo => {
         out: {
             file: path.join(appInfo.root, 'logs', appInfo.name, config.version, 'out.log'),
         },
+        weappAccess: {
+            file: path.join(appInfo.root, 'logs', appInfo.name, config.version, 'weapp-access.log'),
+        },
+        weappError: {
+            file: path.join(appInfo.root, 'logs', appInfo.name, config.version, 'weapp-error.log'),
+        },
     };
 
     config.bodyParser = {