diff --git a/README.md b/README.md index ca63776..1880e08 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ Gateway提供了基本的管理服务,提供简单的登录授权,和实时 - [x] dashboard监控 - [x] 静态文件服务代理 - [x] 穿透隧道功能 -- [x] 请求日志记录监控 - [ ] 动态插件管理 ## 技术栈 diff --git a/src/Gateway/Tunnel/TunnelExensions.cs b/src/Gateway/Tunnel/TunnelExensions.cs index ae0e595..740c35f 100644 --- a/src/Gateway/Tunnel/TunnelExensions.cs +++ b/src/Gateway/Tunnel/TunnelExensions.cs @@ -44,7 +44,7 @@ public static class TunnelExensions var stream = new DuplexHttpStream(context); - using var reg = lifetime.ApplicationStopping.Register(() => stream.Abort()); + await using var reg = lifetime.ApplicationStopping.Register(() => stream.Abort()); // Keep reusing this connection while, it's still open on the backend while (!context.RequestAborted.IsCancellationRequested) diff --git a/web/src/App.tsx b/web/src/App.tsx index 481b2e5..bb75016 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -4,7 +4,6 @@ import MainLayout from './layout/main-layout'; import Home from './pages/home'; import 'reset-css'; import Gateway from './pages/gateway'; -import Logger from './pages/logger'; import Setting from './pages/settings'; import Login from './pages/login'; @@ -20,10 +19,6 @@ const router = createBrowserRouter([{ path: "Gateway", element: }, - { - path: "Logger", - element: - }, { path: "Setting", element: diff --git a/web/src/layout/main-layout.tsx b/web/src/layout/main-layout.tsx index dbc11d5..3be4b5f 100644 --- a/web/src/layout/main-layout.tsx +++ b/web/src/layout/main-layout.tsx @@ -17,8 +17,6 @@ export default function MainLayout() { setSelectedKeys(['Home']); } else if (path === '/Gateway') { setSelectedKeys(['Gateway']); - } else if (path === '/Logger') { - setSelectedKeys(['Logger']); } else if (path === '/Setting') { setSelectedKeys(['Setting']); } @@ -35,8 +33,6 @@ export default function MainLayout() { navigate('/'); } else if (key.itemKey === 'Gateway') { navigate('/Gateway'); - } else if (key.itemKey === 'Logger') { - navigate('/Logger'); } else if (key.itemKey === 'Setting') { navigate('/Setting'); } @@ -45,7 +41,6 @@ export default function MainLayout() { items={[ { itemKey: 'Home', text: '首页', icon: }, { itemKey: 'Gateway', text: '代理设置', icon: }, - { itemKey: 'Logger', text: '日志', icon: }, { itemKey: 'Setting', text: '设置', icon: }, ]} header={{ diff --git a/web/src/pages/home/index.tsx b/web/src/pages/home/index.tsx index 3f5e934..a13488a 100644 --- a/web/src/pages/home/index.tsx +++ b/web/src/pages/home/index.tsx @@ -1,166 +1,9 @@ -import { Panel } from '../../service/RequestLogService'; import { useEffect, useState } from "react"; -import { VChart } from "@visactor/react-vchart"; import { Col, Row } from '@douyinfe/semi-ui'; import { stream } from '../../service/NetWorkService'; -import { debounce } from '../../utils/utils' import * as echarts from 'echarts'; export default function Home() { - const [hours, setHours] = useState(24); - const [requestSize, setRequestSize] = useState({ - spec: { - - type: 'area', - data: { - values: [ - ] - }, - title: { - visible: true, - text: '最近24小时记录' - }, - xField: 'time', - yField: 'value' - } - }); - - const [requestStatusCode, setRequestStatusCode] = useState({ - spec: { - type: 'bar', - data: { - values: [ - ] - } - } - }) - const [requestPath, setRequestPath] = useState({ - spec: { - type: 'pie', - data: [ - { - id: 'id0', - values: [ - ] - } - ], - outerRadius: 0.8, - valueField: 'value', - categoryField: 'type', - title: { - visible: true, - text: '路由热度排名' - }, - legends: { - visible: true, - orient: 'left' - }, - label: { - visible: true - }, - tooltip: { - mark: { - content: [ - { - key: (datum: { [x: string]: any; }) => datum['type'], - value: (datum: { [x: string]: string; }) => datum['value'] + '%' - } - ] - } - } - } - }) - - async function loadingPanel() { - const response = await Panel(hours) as any; - setRequestSize({ - spec: { - type: 'area', - data: { - values: response.data.requestSize - }, - title: { - visible: true, - text: '最近24小时记录' - }, - xField: 'time', - yField: 'value' - } - }); - setRequestPath({ - spec: { - type: 'pie', - data: [ - { - id: 'id0', - values: response.data.requestPath - } - ], - outerRadius: 0.8, - valueField: 'value', - categoryField: 'type', - title: { - visible: true, - text: '路由热度排名' - }, - legends: { - visible: true, - orient: 'left' - }, - label: { - visible: true - }, - tooltip: { - mark: { - content: [ - { - key: (datum: { [x: string]: any; }) => datum['type'], - value: (datum: { [x: string]: string; }) => datum['value'] + '%' - } - ] - } - } - } - }); - - - setRequestStatusCode({ - spec: { - type: 'bar', - data: { - values: response.data.requestStatusCode - }, - xField: ['type', 'country'], - yField: 'value', - seriesField: 'country', - animationAppear: { - duration: 1500, - easing: 'linear' - }, - legends: [{ visible: true, position: 'middle', orient: 'bottom' }], - // @ts-ignore - animationAppear: { - duration: 500, - oneByOne: true - }, - axes: [ - { - orient: 'left', - } - ] - } - }); - } - - - useEffect(() => { - const loadingPanelFunction = debounce(loadingPanel, 500, true); - loadingPanelFunction() - }, [hours]); - - useEffect(() => { - }, []); - useEffect(() => { var chartDom = document.getElementById('network')!; var myChart = echarts.init(chartDom); @@ -168,7 +11,7 @@ export default function Home() { option = { title: { - text: '实时流量监控' + text: '实时流量' }, tooltip: { trigger: 'axis' @@ -291,7 +134,7 @@ export default function Home() { fetchData(); // 设置定时器,每隔一段时间调用获取数据的函数 - const intervalId = setInterval(fetchData, 6000); // 每5秒获取一次数据 + const intervalId = setInterval(fetchData, 5900); // 每5秒获取一次数据 // 组件卸载时清除定时器 return () => { @@ -302,7 +145,14 @@ export default function Home() { return (
- +

+ 数据面板 +

- -
-
-
-
-
- - -
- 7天请求状态码分布 -
- -
); } \ No newline at end of file diff --git a/web/src/pages/logger/index.tsx b/web/src/pages/logger/index.tsx deleted file mode 100644 index 6e3003d..0000000 --- a/web/src/pages/logger/index.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import { Button, Input, Pagination, Table, Toast, DatePicker } from "@douyinfe/semi-ui"; -import { useEffect, useState } from "react"; -import { RequestLog } from '../../service/RequestLogService' - - -export default function Logger() { - - const [total, setTotal] = useState(0); - const [data, setData] = useState([]); - const [input, setInput] = useState({ - page: 1, - pageSize: 20, - keyword: '', - startTime: null as any, - endTime: null as any, - }); - - const columns = [ - { - title: '请求地址', - dataIndex: 'path', - }, - { - title: '请求方式', - dataIndex: 'method', - }, - { - title: 'IP', - dataIndex: 'ip', - }, - { - title: '请求状态', - dataIndex: 'statusCode', - }, - { - title: '请求耗时(ms)', - dataIndex: 'executionDuration' - }, - { - title: '浏览器信息', - dataIndex: 'browserInfo', - // 超出隐藏 - ellipsis: true, - - }, - { - title: '扩展字段', - dataIndex: 'extraProperties', - }, - ]; - - useEffect(() => { - loadingData(); - }, [input]); - - async function loadingData() { - try { - const data = await RequestLog(input) as any; - setData(data.items); - setTotal(data.total); - } catch (error) { - Toast.error('加载失败' + error); - } - } - - return ( -
-
- { - setInput({ - ...input, - keyword: e - }) - }} - style={{ - width: '200px', - marginRight: '20px', - }} - /> - { - setInput({ - ...input, - startTime: value - }) - }} - /> - { - setInput({ - ...input, - endTime: value - }) - }} - /> - -
- - - { - setInput({ - ...input, - page: page - }) - }} onPageSizeChange={(pageSize) => { - setInput({ - ...input, - pageSize: pageSize - }) - }}> - - - - ) -} \ No newline at end of file diff --git a/web/src/pages/settings/index.tsx b/web/src/pages/settings/index.tsx index d74d910..8ca5187 100644 --- a/web/src/pages/settings/index.tsx +++ b/web/src/pages/settings/index.tsx @@ -7,7 +7,6 @@ import { getList ,update} from "../../service/SettingService"; export default function Setting() { const [maxBodySize, setMaxBodySize] = useState(100); - const [maxLogDay, setMaxLogDay] = useState(30); const LogRetentionTime = "Gateway:Setting:LogRetentionTime"; const maxRequestBodySize = "Gateway:Setting:MaxRequestBodySize"; @@ -18,16 +17,10 @@ export default function Setting() { // 获取values的数组中你的name为maxRequestBodySize const v1 = values.find((item: any) => item.name === maxRequestBodySize); - setMaxBodySize(v1.defaultValue); - const v2 = values.find((item: any) => item.name === LogRetentionTime); - setMaxLogDay(v2.defaultValue); + setMaxBodySize(v1?.defaultValue); } function save() { - update(LogRetentionTime, maxLogDay) - .then(() => { - Toast.success('保存成功') - }) update(maxRequestBodySize, maxBodySize) .then(() => { Toast.success('保存成功') @@ -53,16 +46,14 @@ export default function Setting() { fontWeight: 'bold', marginBottom: '20px', }}> + + 最大请求Body大小(MB) + { setMaxBodySize(e as any) }} size='large' style={{ marginTop: '20px', }} placeholder='最大请求Body大小(MB)'> - { - setMaxLogDay(e as any) - }} style={{ - marginTop: '20px', - }} type="number" placeholder='日志保留最大天数'> diff --git a/web/src/service/RequestLogService.ts b/web/src/service/RequestLogService.ts deleted file mode 100644 index 45ccf9c..0000000 --- a/web/src/service/RequestLogService.ts +++ /dev/null @@ -1,25 +0,0 @@ -import request from "../utils/request"; - -/*** -* 获取请求日志列表 -* @param hours {number} 时长(小时) -* @constructor -*/ -export function Panel(hours:number){ - return request.get("/api/gateway/panel",{ - params:{ - hours - } - }); -} - -/** - * 获取请求日志列表 - * @param params - * @returns - */ -export function RequestLog(params:any){ - return request.get("/api/gateway/request-log",{ - params - }); -} \ No newline at end of file