QPS Stats
This commit is contained in:
21
libs/stats.js
Normal file
21
libs/stats.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
const stats = {
|
||||||
|
apiqps: 0,
|
||||||
|
lastAccess: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const addAPIQPS = () => {
|
||||||
|
stats.apiqps++;
|
||||||
|
clearStats();
|
||||||
|
};
|
||||||
|
|
||||||
|
const clearStats = () => {
|
||||||
|
const now = Date.now();
|
||||||
|
if (stats.lastAccess + 1000 < now) {
|
||||||
|
const now_formated = new Date(now).toISOString();
|
||||||
|
console.log(`${now_formated} - APIQPS: ${stats.apiqps}`);
|
||||||
|
stats.apiqps = parseInt(stats.apiqps / 3);
|
||||||
|
stats.lastAccess = now;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { stats, addAPIQPS };
|
||||||
7
pages/api/stats.js
Normal file
7
pages/api/stats.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { stats, addAPIQPS } from "../../libs/stats";
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
addAPIQPS();
|
||||||
|
res.setHeader("Cache-Control", "no-cache no-store must-revalidate");
|
||||||
|
res.status(200).json(stats);
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import { authenticate, setLimit, getLimit } from "../../../libs/db";
|
import { authenticate, setLimit, getLimit } from "../../../libs/db";
|
||||||
|
import { addAPIQPS } from "../../../libs/stats";
|
||||||
|
|
||||||
export default function handler(req, res) {
|
export default function handler(req, res) {
|
||||||
|
addAPIQPS();
|
||||||
// put method
|
// put method
|
||||||
if (req.method === "PUT") {
|
if (req.method === "PUT") {
|
||||||
const { token, limit } = req.body;
|
const { token, limit } = req.body;
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import { authenticate, getTimeRanges, insertTimeRange } from "../../../libs/db";
|
import { authenticate, getTimeRanges, insertTimeRange } from "../../../libs/db";
|
||||||
|
|
||||||
|
import { addAPIQPS } from "../../../libs/stats";
|
||||||
|
|
||||||
export default function handler(req, res) {
|
export default function handler(req, res) {
|
||||||
|
addAPIQPS();
|
||||||
// get method
|
// get method
|
||||||
if (req.method === "GET") {
|
if (req.method === "GET") {
|
||||||
res.setHeader("Cache-Control", "no-cache no-store must-revalidate");
|
res.setHeader("Cache-Control", "no-cache no-store must-revalidate");
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import {
|
|||||||
updateUsernameWithLimit,
|
updateUsernameWithLimit,
|
||||||
} from "../../../../libs/db";
|
} from "../../../../libs/db";
|
||||||
|
|
||||||
|
import { addAPIQPS } from '../../../../libs/stats';
|
||||||
|
|
||||||
export default function handler(req, res) {
|
export default function handler(req, res) {
|
||||||
|
addAPIQPS();
|
||||||
// check if id is valid
|
// check if id is valid
|
||||||
const { id } = req.query;
|
const { id } = req.query;
|
||||||
if (id === undefined) {
|
if (id === undefined) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { authenticate, getStarted, setStarted } from "../../../libs/db";
|
import { authenticate, getStarted, setStarted } from "../../../libs/db";
|
||||||
|
import { addAPIQPS } from "../../../libs/stats";
|
||||||
|
|
||||||
export default function handler(req, res) {
|
export default function handler(req, res) {
|
||||||
|
addAPIQPS();
|
||||||
// get method
|
// get method
|
||||||
if (req.method === "GET") {
|
if (req.method === "GET") {
|
||||||
res.setHeader("Cache-Control", "no-cache no-store must-revalidate");
|
res.setHeader("Cache-Control", "no-cache no-store must-revalidate");
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ import {
|
|||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import config from '../next.config';
|
import config from "../next.config";
|
||||||
|
|
||||||
const prefix = config.basePath ? config.basePath : '';
|
const prefix = config.basePath ? config.basePath : "";
|
||||||
|
|
||||||
export default function Time(props) {
|
export default function Time(props) {
|
||||||
const [ranges, setRanges] = useState([]);
|
const [ranges, setRanges] = useState([]);
|
||||||
@@ -29,9 +29,20 @@ export default function Time(props) {
|
|||||||
const [snackbarSuccess, setSnackbarSuccess] = useState(false);
|
const [snackbarSuccess, setSnackbarSuccess] = useState(false);
|
||||||
const [limit, setLimit] = useState(1);
|
const [limit, setLimit] = useState(1);
|
||||||
const [token, setToken] = useState("");
|
const [token, setToken] = useState("");
|
||||||
|
const [stats, setStats] = useState({});
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const getStats = () => {
|
||||||
|
fetch(`${prefix}/api/stats`, {
|
||||||
|
method: "GET",
|
||||||
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((res) => {
|
||||||
|
setStats(res);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const setStarted = (started) => {
|
const setStarted = (started) => {
|
||||||
fetch(`${prefix}/api/time/started`, {
|
fetch(`${prefix}/api/time/started`, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
@@ -98,6 +109,7 @@ export default function Time(props) {
|
|||||||
|
|
||||||
const refreshRanges = () => {
|
const refreshRanges = () => {
|
||||||
getLimit();
|
getLimit();
|
||||||
|
getStats();
|
||||||
fetch(`${prefix}/api/time/ranges`)
|
fetch(`${prefix}/api/time/ranges`)
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
@@ -275,13 +287,20 @@ export default function Time(props) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
|
sx={{
|
||||||
|
userSelect: "none",
|
||||||
|
}}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={() => refreshRanges()}
|
onClick={() => refreshRanges()}
|
||||||
>
|
>
|
||||||
Refresh
|
Refresh
|
||||||
</Button>
|
</Button>
|
||||||
<Typography>当前每人排班数量上限:{limit}</Typography>
|
<Typography>
|
||||||
|
当前每人数量上限: {limit}
|
||||||
|
<br />
|
||||||
|
服务器负载 (QPS): {stats.apiqps}
|
||||||
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<TableContainer>
|
<TableContainer>
|
||||||
<Table>
|
<Table>
|
||||||
|
|||||||
Reference in New Issue
Block a user