From 8e8ceb74396c4333e63d4a5ef209eb7af928e9b7 Mon Sep 17 00:00:00 2001 From: Archer <545436317@qq.com> Date: Mon, 20 May 2024 10:31:44 +0800 Subject: [PATCH] Add request log and uncatch error tip. (#1531) --- Dockerfile | 2 +- .../global/core/workflow/runtime/utils.ts | 19 ++++++++++++++++++- packages/service/common/middle/entry.ts | 6 ++++++ packages/service/common/system/tools.ts | 12 ++++++++++++ packages/service/core/chat/controller.ts | 2 +- .../core/workflow/Flow/ChatTest.tsx | 16 +++------------- .../app/src/pages/api/v1/chat/completions.ts | 4 +++- .../detail/components/SimpleEdit/ChatTest.tsx | 18 ++++-------------- projects/app/src/service/mongo.ts | 2 ++ 9 files changed, 50 insertions(+), 31 deletions(-) diff --git a/Dockerfile b/Dockerfile index 63dc481508..75e745c081 100644 --- a/Dockerfile +++ b/Dockerfile @@ -86,4 +86,4 @@ USER nextjs ENV serverPath=./projects/$name/server.js -ENTRYPOINT ["sh","-c","node ${serverPath}"] \ No newline at end of file +ENTRYPOINT ["sh","-c","node --max-old-space-size=4096 ${serverPath}"] \ No newline at end of file diff --git a/packages/global/core/workflow/runtime/utils.ts b/packages/global/core/workflow/runtime/utils.ts index e4e238ee19..956435a373 100644 --- a/packages/global/core/workflow/runtime/utils.ts +++ b/packages/global/core/workflow/runtime/utils.ts @@ -1,5 +1,5 @@ import { ChatCompletionRequestMessageRoleEnum } from '../../ai/constants'; -import { NodeOutputKeyEnum } from '../constants'; +import { NodeInputKeyEnum, NodeOutputKeyEnum } from '../constants'; import { FlowNodeTypeEnum } from '../node/constant'; import { StoreNodeItemType } from '../type'; import { StoreEdgeItemType } from '../type/edge'; @@ -8,6 +8,23 @@ import { VARIABLE_NODE_ID } from '../constants'; import { isReferenceValue } from '../utils'; import { ReferenceValueProps } from '../type/io'; +export const getMaxHistoryLimitFromNodes = (nodes: StoreNodeItemType[]): number => { + let limit = 10; + nodes.forEach((node) => { + node.inputs.forEach((input) => { + if ( + (input.key === NodeInputKeyEnum.history || + input.key === NodeInputKeyEnum.historyMaxAmount) && + typeof input.value === 'number' + ) { + limit = Math.max(limit, input.value); + } + }); + }); + + return limit * 2; +}; + export const initWorkflowEdgeStatus = (edges: StoreEdgeItemType[]): RuntimeEdgeItemType[] => { return ( edges?.map((edge) => ({ diff --git a/packages/service/common/middle/entry.ts b/packages/service/common/middle/entry.ts index 7f81b478a8..8bdd09f2f8 100644 --- a/packages/service/common/middle/entry.ts +++ b/packages/service/common/middle/entry.ts @@ -2,6 +2,7 @@ import { jsonRes } from '../response'; import type { NextApiResponse } from 'next'; import { withNextCors } from './cors'; import { ApiRequestProps } from '../../type/next'; +import { addLog } from '../system/log'; export type NextApiHandler = ( req: ApiRequestProps, @@ -11,6 +12,8 @@ export type NextApiHandler = ( export const NextEntry = ({ beforeCallback = [] }: { beforeCallback?: Promise[] }) => { return (...args: NextApiHandler[]): NextApiHandler => { return async function api(req: ApiRequestProps, res: NextApiResponse) { + const start = Date.now(); + addLog.info(`Request start ${req.url}`); try { await Promise.all([withNextCors(req, res), ...beforeCallback]); @@ -20,6 +23,9 @@ export const NextEntry = ({ beforeCallback = [] }: { beforeCallback?: Promise { global.whisperModel = config.whisperModel; global.reRankModels = config.reRankModels; }; + +export const systemStartCb = () => { + process.on('uncaughtException', (err) => { + console.error('Uncaught Exception:', err); + // process.exit(1); // 退出进程 + }); + + process.on('unhandledRejection', (reason, promise) => { + console.error('Unhandled Rejection at:', promise, 'reason:', reason); + // process.exit(1); // 退出进程 + }); +}; diff --git a/packages/service/core/chat/controller.ts b/packages/service/core/chat/controller.ts index c382964d69..b5de13f772 100644 --- a/packages/service/core/chat/controller.ts +++ b/packages/service/core/chat/controller.ts @@ -32,7 +32,7 @@ export async function getChatItems({ return { history }; } -/* 临时适配旧的对话记录,清洗完数据后可删除(4.30刪除) */ +/* 临时适配旧的对话记录 */ export const adaptStringValue = (value: any): ChatItemValueItemType[] => { if (typeof value === 'string') { return [ diff --git a/projects/app/src/components/core/workflow/Flow/ChatTest.tsx b/projects/app/src/components/core/workflow/Flow/ChatTest.tsx index 7304385852..f9e04fb029 100644 --- a/projects/app/src/components/core/workflow/Flow/ChatTest.tsx +++ b/projects/app/src/components/core/workflow/Flow/ChatTest.tsx @@ -25,6 +25,7 @@ import { useTranslation } from 'next-i18next'; import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge'; import { getDefaultEntryNodeIds, + getMaxHistoryLimitFromNodes, initWorkflowEdgeStatus, storeNodes2RuntimeNodes } from '@fastgpt/global/core/workflow/runtime/utils'; @@ -57,19 +58,8 @@ const ChatTest = ( const startChat = useCallback( async ({ chatList, controller, generatingMessage, variables }: StartChatFnProps) => { /* get histories */ - let historyMaxLen = 6; - nodes.forEach((node) => { - node.inputs.forEach((input) => { - if ( - (input.key === NodeInputKeyEnum.history || - input.key === NodeInputKeyEnum.historyMaxAmount) && - typeof input.value === 'number' - ) { - historyMaxLen = Math.max(historyMaxLen, input.value); - } - }); - }); - const history = chatList.slice(-(historyMaxLen * 2) - 2, -2); + let historyMaxLen = getMaxHistoryLimitFromNodes(nodes); + const history = chatList.slice(-historyMaxLen - 2, -2); // 流请求,获取数据 const { responseText, responseData, newVariables } = await streamFetch({ diff --git a/projects/app/src/pages/api/v1/chat/completions.ts b/projects/app/src/pages/api/v1/chat/completions.ts index 96e3b8ca41..5237f151ff 100644 --- a/projects/app/src/pages/api/v1/chat/completions.ts +++ b/projects/app/src/pages/api/v1/chat/completions.ts @@ -10,6 +10,7 @@ import type { ChatCompletionCreateParams } from '@fastgpt/global/core/ai/type.d' import type { ChatCompletionMessageParam } from '@fastgpt/global/core/ai/type.d'; import { getDefaultEntryNodeIds, + getMaxHistoryLimitFromNodes, initWorkflowEdgeStatus, storeNodes2RuntimeNodes, textAdaptGptResponse @@ -168,11 +169,12 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { })(); // 1. get and concat history; 2. get app workflow + const limit = getMaxHistoryLimitFromNodes(app.modules); const [{ history }, { nodes, edges }] = await Promise.all([ getChatItems({ appId: app._id, chatId, - limit: 30, + limit, field: `dataId obj value` }), getAppLatestVersion(app._id, app) diff --git a/projects/app/src/pages/app/detail/components/SimpleEdit/ChatTest.tsx b/projects/app/src/pages/app/detail/components/SimpleEdit/ChatTest.tsx index eeab756e4c..3835b30024 100644 --- a/projects/app/src/pages/app/detail/components/SimpleEdit/ChatTest.tsx +++ b/projects/app/src/pages/app/detail/components/SimpleEdit/ChatTest.tsx @@ -4,7 +4,6 @@ import { useTranslation } from 'next-i18next'; import React, { useCallback, useEffect, useRef } from 'react'; import ChatBox from '@/components/ChatBox'; import type { ComponentRef, StartChatFnProps } from '@/components/ChatBox/type.d'; -import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { streamFetch } from '@/web/common/api/fetch'; import MyTooltip from '@/components/MyTooltip'; import MyIcon from '@fastgpt/web/components/common/Icon'; @@ -13,6 +12,7 @@ import { checkChatSupportSelectFileByModules } from '@/web/core/chat/utils'; import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; import { getDefaultEntryNodeIds, + getMaxHistoryLimitFromNodes, initWorkflowEdgeStatus, storeNodes2RuntimeNodes } from '@fastgpt/global/core/workflow/runtime/utils'; @@ -53,19 +53,9 @@ const ChatTest = ({ if (!workflowData) return Promise.reject('workflowData is empty'); /* get histories */ - let historyMaxLen = 6; - workflowData?.nodes.forEach((node) => { - node.inputs.forEach((input) => { - if ( - (input.key === NodeInputKeyEnum.history || - input.key === NodeInputKeyEnum.historyMaxAmount) && - typeof input.value === 'number' - ) { - historyMaxLen = Math.max(historyMaxLen, input.value); - } - }); - }); - const history = chatList.slice(-(historyMaxLen * 2) - 2, -2); + let historyMaxLen = getMaxHistoryLimitFromNodes(workflowData.nodes); + + const history = chatList.slice(-historyMaxLen - 2, -2); // 流请求,获取数据 const { responseText, responseData } = await streamFetch({ diff --git a/projects/app/src/service/mongo.ts b/projects/app/src/service/mongo.ts index e91d1dce6d..3de425e0e0 100644 --- a/projects/app/src/service/mongo.ts +++ b/projects/app/src/service/mongo.ts @@ -11,6 +11,7 @@ import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun'; import { initGlobal } from './common/system'; import { startMongoWatch } from './common/system/volumnMongoWatch'; import { startTrainingQueue } from './core/dataset/training/utils'; +import { systemStartCb } from '@fastgpt/service/common/system/tools'; /** * connect MongoDB and init data @@ -21,6 +22,7 @@ export function connectToDatabase(): Promise { initGlobal(); }, afterHook: async () => { + systemStartCb(); // init system config getInitConfig(); //init vector database, init root user