feat: save and query request client ip for relay router; fix air theme bugs at log page;

This commit is contained in:
林水溶
2024-03-17 21:42:56 +09:00
parent 0eb2272bb7
commit cab01a8ebb
14 changed files with 120 additions and 46 deletions

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { API, copy, isAdmin, showError, showSuccess, timestamp2string } from '../helpers';
import { API, copy, isAdmin, showError, showSuccess, timestamp2string, safeGetLocalTimestamp } from '../helpers';
import { Avatar, Button, Form, Layout, Modal, Select, Space, Spin, Table, Tag } from '@douyinfe/semi-ui';
import { ITEMS_PER_PAGE } from '../constants';
@@ -128,6 +128,10 @@ const LogsTable = () => {
{renderQuota(text, 6)}
</div> : <></>);
}
}, {
title: '请求端IP', dataIndex: 'client_ip', render: (text, record, index) => {
return text;
}
}, {
title: '详情', dataIndex: 'content', render: (text, record, index) => {
return <Paragraph ellipsis={{ rows: 2, showTooltip: { type: 'popover', opts: { style: { width: 240 } } } }}
@@ -156,9 +160,10 @@ const LogsTable = () => {
model_name: '',
start_timestamp: timestamp2string(now.getTime() / 1000 - 86400),
end_timestamp: timestamp2string(now.getTime() / 1000 + 3600),
channel: ''
channel: '',
client_ip: ''
});
const { username, token_name, model_name, start_timestamp, end_timestamp, channel } = inputs;
const { username, token_name, model_name, start_timestamp, end_timestamp, channel, client_ip } = inputs;
const [stat, setStat] = useState({
quota: 0, token: 0
@@ -169,9 +174,9 @@ const LogsTable = () => {
};
const getLogSelfStat = async () => {
let localStartTimestamp = Date.parse(start_timestamp) / 1000;
let localEndTimestamp = Date.parse(end_timestamp) / 1000;
let res = await API.get(`/api/log/self/stat?type=${logType}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`);
let localStartTimestamp = safeGetLocalTimestamp(start_timestamp);
let localEndTimestamp = safeGetLocalTimestamp(end_timestamp);
let res = await API.get(`/api/log/self/stat?type=${logType}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&client_ip=${client_ip}`);
const { success, message, data } = res.data;
if (success) {
setStat(data);
@@ -181,9 +186,9 @@ const LogsTable = () => {
};
const getLogStat = async () => {
let localStartTimestamp = Date.parse(start_timestamp) / 1000;
let localEndTimestamp = Date.parse(end_timestamp) / 1000;
let res = await API.get(`/api/log/stat?type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}`);
let localStartTimestamp = safeGetLocalTimestamp(start_timestamp);
let localEndTimestamp = safeGetLocalTimestamp(end_timestamp);
let res = await API.get(`/api/log/stat?type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}&client_ip=${client_ip}`);
const { success, message, data } = res.data;
if (success) {
setStat(data);
@@ -238,12 +243,12 @@ const LogsTable = () => {
setLoading(true);
let url = '';
let localStartTimestamp = Date.parse(start_timestamp) / 1000;
let localEndTimestamp = Date.parse(end_timestamp) / 1000;
let localStartTimestamp = safeGetLocalTimestamp(start_timestamp);
let localEndTimestamp = safeGetLocalTimestamp(end_timestamp);
if (isAdminUser) {
url = `/api/log/?p=${startIdx}&page_size=${pageSize}&type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}`;
url = `/api/log/?p=${startIdx}&page_size=${pageSize}&type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}&client_ip=${client_ip}`;
} else {
url = `/api/log/self/?p=${startIdx}&page_size=${pageSize}&type=${logType}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
url = `/api/log/self/?p=${startIdx}&page_size=${pageSize}&type=${logType}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&client_ip=${client_ip}`;
}
const res = await API.get(url);
const { success, message, data } = res.data;
@@ -349,6 +354,10 @@ const LogsTable = () => {
placeholder="可选值"
name="model_name"
onChange={value => handleInputChange(value, 'model_name')} />
<Form.Input field="model_name" label="请求端IP" style={{ width: 176 }} value={client_ip}
placeholder="可选值"
name="client_ip"
onChange={value => handleInputChange(value, 'client_ip')} />
<Form.DatePicker field="start_timestamp" label="起始时间" style={{ width: 272 }}
initValue={start_timestamp}
value={start_timestamp} type="dateTime"
@@ -369,7 +378,7 @@ const LogsTable = () => {
</>}
<Form.Section>
<Button label="查询" type="primary" htmlType="submit" className="btn-margin-right"
onClick={refresh} loading={loading}>查询</Button>
onClick={()=>refresh(logType)} loading={loading}>查询</Button>
</Form.Section>
</>
</Form>

View File

@@ -230,4 +230,8 @@ export function shouldShowPrompt(id) {
export function setPromptShown(id) {
localStorage.setItem(`prompt-${id}`, 'true');
}
export function safeGetLocalTimestamp(timeString) {
return timeString ? Date.parse(timeString) / 1000 : ''
}

View File

@@ -14,6 +14,7 @@ const LogTableHead = ({ userIsAdmin }) => {
<TableCell>提示</TableCell>
<TableCell>补全</TableCell>
<TableCell>额度</TableCell>
<TableCell>请求端IP</TableCell>
<TableCell>详情</TableCell>
</TableRow>
</TableHead>

View File

@@ -57,6 +57,7 @@ export default function LogTableRow({ item, userIsAdmin }) {
<TableCell>{item.prompt_tokens || ''}</TableCell>
<TableCell>{item.completion_tokens || ''}</TableCell>
<TableCell>{item.quota ? renderQuota(item.quota, 6) : ''}</TableCell>
<TableCell>{item.client_ip || ''}</TableCell>
<TableCell>{item.content}</TableCell>
</TableRow>
</>

View File

@@ -5,6 +5,7 @@ import {
IconKey,
IconBrandGithubCopilot,
IconSitemap,
IconMapPin
} from "@tabler/icons-react";
import {
InputAdornment,
@@ -81,6 +82,30 @@ export default function TableToolBar({
/>
</FormControl>
<FormControl>
<InputLabel htmlFor="channel-client_ip-label">请求端IP</InputLabel>
<OutlinedInput
id="client_ip"
name="client_ip"
sx={{
minWidth: "100%",
}}
label="请求端IP"
value={filterName.client_ip}
onChange={handleFilterName}
placeholder="请求端IP"
startAdornment={
<InputAdornment position="start">
<IconMapPin
stroke={1.5}
size="20px"
color={grey500}
/>
</InputAdornment>
}
/>
</FormControl>
<FormControl>
<LocalizationProvider
dateAdapter={AdapterDayjs}

View File

@@ -28,7 +28,8 @@ export default function Log() {
start_timestamp: 0,
end_timestamp: new Date().getTime() / 1000 + 3600,
type: 0,
channel: ''
channel: '',
client_ip: ''
};
const [logs, setLogs] = useState([]);
const [activePage, setActivePage] = useState(0);

View File

@@ -57,9 +57,10 @@ const LogsTable = () => {
model_name: '',
start_timestamp: timestamp2string(0),
end_timestamp: timestamp2string(now.getTime() / 1000 + 3600),
channel: ''
channel: '',
client_ip: ''
});
const { username, token_name, model_name, start_timestamp, end_timestamp, channel } = inputs;
const { username, token_name, model_name, start_timestamp, end_timestamp, channel, client_ip } = inputs;
const [stat, setStat] = useState({
quota: 0,
@@ -73,7 +74,9 @@ const LogsTable = () => {
const getLogSelfStat = async () => {
let localStartTimestamp = Date.parse(start_timestamp) / 1000;
let localEndTimestamp = Date.parse(end_timestamp) / 1000;
let res = await API.get(`/api/log/self/stat?type=${logType}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`);
let res = await API.get(
`/api/log/self/stat?type=${logType}&token_name=${token_name}&model_name=${model_name}&client_ip=${client_ip}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`
);
const { success, message, data } = res.data;
if (success) {
setStat(data);
@@ -85,7 +88,9 @@ const LogsTable = () => {
const getLogStat = async () => {
let localStartTimestamp = Date.parse(start_timestamp) / 1000;
let localEndTimestamp = Date.parse(end_timestamp) / 1000;
let res = await API.get(`/api/log/stat?type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}`);
let res = await API.get(
`/api/log/stat?type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&client_ip=${client_ip}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}`
);
const { success, message, data } = res.data;
if (success) {
setStat(data);
@@ -110,9 +115,9 @@ const LogsTable = () => {
let localStartTimestamp = Date.parse(start_timestamp) / 1000;
let localEndTimestamp = Date.parse(end_timestamp) / 1000;
if (isAdminUser) {
url = `/api/log/?p=${startIdx}&type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}`;
url = `/api/log/?p=${startIdx}&type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&client_ip=${client_ip}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}`;
} else {
url = `/api/log/self/?p=${startIdx}&type=${logType}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
url = `/api/log/self/?p=${startIdx}&type=${logType}&token_name=${token_name}&model_name=${model_name}&client_ip=${client_ip}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
}
const res = await API.get(url);
const { success, message, data } = res.data;
@@ -211,6 +216,9 @@ const LogsTable = () => {
<Form.Input fluid label='模型名称' width={3} value={model_name} placeholder='可选值'
name='model_name'
onChange={handleInputChange} />
<Form.Input fluid label='请求端IP' width={3} value={client_ip} placeholder='可选值'
name='client_ip'
onChange={handleInputChange} />
<Form.Input fluid label='起始时间' width={4} value={start_timestamp} type='datetime-local'
name='start_timestamp'
onChange={handleInputChange} />
@@ -321,6 +329,15 @@ const LogsTable = () => {
>
额度
</Table.HeaderCell>
<Table.HeaderCell
style={{ cursor: 'pointer' }}
onClick={() => {
sortLog('client_ip');
}}
width={1}
>
请求端IP
</Table.HeaderCell>
<Table.HeaderCell
style={{ cursor: 'pointer' }}
onClick={() => {