Compare commits
2 Commits
ceee156e65
...
5f138ec9df
| Author | SHA1 | Date |
|---|---|---|
|
|
5f138ec9df | |
|
|
9584f370ad |
|
|
@ -11,7 +11,7 @@ import nodes as F
|
||||||
from tool import format_content_uuid
|
from tool import format_content_uuid
|
||||||
from tortoise.transactions import in_transaction
|
from tortoise.transactions import in_transaction
|
||||||
from tortoise.functions import Max
|
from tortoise.functions import Max
|
||||||
from fastapi import FastAPI, Depends, HTTPException
|
from fastapi import FastAPI, Depends, HTTPException, Query
|
||||||
from models.schemas.system import InitStatusResponse, InitConfigRequest, BaseResponse, TableResponse
|
from models.schemas.system import InitStatusResponse, InitConfigRequest, BaseResponse, TableResponse
|
||||||
from models.schemas.user import LoginRequest, LoginResponse
|
from models.schemas.user import LoginRequest, LoginResponse
|
||||||
from models.schemas.client import ClientRequest
|
from models.schemas.client import ClientRequest
|
||||||
|
|
@ -74,6 +74,10 @@ def get_current_user(token: str = Depends(oauth2_scheme)) -> DB.User | None:
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
def pagination_query(page:int = Query(1), page_size:int = Query(20)):
|
||||||
|
return {"page": page, "page_size": page_size}
|
||||||
|
|
||||||
|
|
||||||
async def is_init():
|
async def is_init():
|
||||||
init_config = await load_init_config()
|
init_config = await load_init_config()
|
||||||
init_status = init_config.get("is_init")
|
init_status = init_config.get("is_init")
|
||||||
|
|
@ -207,6 +211,7 @@ def create_app():
|
||||||
)
|
)
|
||||||
await work_log.save()
|
await work_log.save()
|
||||||
try:
|
try:
|
||||||
|
start_time = int(datetime.datetime.now().timestamp())
|
||||||
work_content = await DB.WorkContent.filter(work_id=work.id).first()
|
work_content = await DB.WorkContent.filter(work_id=work.id).first()
|
||||||
if not work_content:
|
if not work_content:
|
||||||
logger.warning(f"没有找到对应的内容: {work.uuid}")
|
logger.warning(f"没有找到对应的内容: {work.uuid}")
|
||||||
|
|
@ -251,7 +256,7 @@ def create_app():
|
||||||
await flow.run_async(shared)
|
await flow.run_async(shared)
|
||||||
app.state.tasks.pop(task_id, None)
|
app.state.tasks.pop(task_id, None)
|
||||||
app.state.task_nodes.pop(task_id, None)
|
app.state.task_nodes.pop(task_id, None)
|
||||||
|
end_time = int(datetime.datetime.now().timestamp())
|
||||||
# 更新日志
|
# 更新日志
|
||||||
work_log_result = []
|
work_log_result = []
|
||||||
for x in nodes:
|
for x in nodes:
|
||||||
|
|
@ -269,7 +274,7 @@ def create_app():
|
||||||
"result": shared.get(id, {}),
|
"result": shared.get(id, {}),
|
||||||
"status": status
|
"status": status
|
||||||
})
|
})
|
||||||
work_log.result = work_log_result
|
work_log.result = {"time": end_time - start_time, "logs": work_log_result}
|
||||||
if next((x for x in shared.values() if x.get("err")), None):
|
if next((x for x in shared.values() if x.get("err")), None):
|
||||||
work_log.status = DB.WorkLogsStatus.FAILED
|
work_log.status = DB.WorkLogsStatus.FAILED
|
||||||
else:
|
else:
|
||||||
|
|
@ -322,6 +327,7 @@ def create_app():
|
||||||
log: DB.WorkLogs = next((x for x in work_logs_list if x.work_id == work.id), DB.WorkLogs(user_id=-1))
|
log: DB.WorkLogs = next((x for x in work_logs_list if x.work_id == work.id), DB.WorkLogs(user_id=-1))
|
||||||
log_user: DB.User = next((u for u in user_list if u.id == log.user_id), DB.User())
|
log_user: DB.User = next((u for u in user_list if u.id == log.user_id), DB.User())
|
||||||
obj["last_user"] = log_user.username or ""
|
obj["last_user"] = log_user.username or ""
|
||||||
|
obj["last_use_time"] = log.result.get("time", 0)
|
||||||
obj["last_run_time"] = log.create_time.timestamp() if log.create_time else 0
|
obj["last_run_time"] = log.create_time.timestamp() if log.create_time else 0
|
||||||
obj["last_status"] = log.status or ""
|
obj["last_status"] = log.status or ""
|
||||||
obj["is_running"] = work.uuid in global_tasks
|
obj["is_running"] = work.uuid in global_tasks
|
||||||
|
|
@ -451,6 +457,12 @@ def create_app():
|
||||||
await DB.Client.filter(id=id).delete()
|
await DB.Client.filter(id=id).delete()
|
||||||
return BaseResponse()
|
return BaseResponse()
|
||||||
|
|
||||||
|
@app.get("/api/logs", tags=["Log"], description="日志列表", response_model=TableResponse)
|
||||||
|
async def log_list(p:dict = Depends(pagination_query), user: DB.User = Depends(get_current_user)):
|
||||||
|
page, page_size = p["page"], p["page_size"]
|
||||||
|
res = await DB.WorkLogs.all().order_by('-id').limit(page_size).offset((page - 1) * page_size)
|
||||||
|
return TableResponse(data=[x.json() for x in res], total=len(res))
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ async def async_run_cmd(
|
||||||
password: str = None,
|
password: str = None,
|
||||||
port: int = None,
|
port: int = None,
|
||||||
sudo: bool = False,
|
sudo: bool = False,
|
||||||
|
wait: int = 0,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
异步执行命令
|
异步执行命令
|
||||||
|
|
@ -15,6 +16,9 @@ async def async_run_cmd(
|
||||||
- 如果 host 不为空,则通过 SSH 执行远程命令
|
- 如果 host 不为空,则通过 SSH 执行远程命令
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if wait > 0:
|
||||||
|
await asyncio.sleep(wait)
|
||||||
|
|
||||||
async def read_stream(stream, stream_type):
|
async def read_stream(stream, stream_type):
|
||||||
async for line in stream:
|
async for line in stream:
|
||||||
text = line
|
text = line
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import asyncio
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from core.pocket_flow import AsyncNode
|
from core.pocket_flow import AsyncNode
|
||||||
from core.logger import logger
|
from core.logger import logger
|
||||||
|
|
@ -36,6 +37,7 @@ class StatusNode(AsyncNode):
|
||||||
"password": self.params[self.id].get("password"),
|
"password": self.params[self.id].get("password"),
|
||||||
"port": self.params[self.id].get("port"),
|
"port": self.params[self.id].get("port"),
|
||||||
"sudo": self.params[self.id].get("sudo", False),
|
"sudo": self.params[self.id].get("sudo", False),
|
||||||
|
"wait": self.params[self.id].get("wait", 3),
|
||||||
"cmd": cmd_str,
|
"cmd": cmd_str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { request } from "./base";
|
||||||
|
|
||||||
|
export const tableList = async (data = {}) => {
|
||||||
|
return request("/api/logs?" + new URLSearchParams(data).toString(), "GET")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -83,7 +83,12 @@ export default () => {
|
||||||
{
|
{
|
||||||
dataIndex: 'last_run_time',
|
dataIndex: 'last_run_time',
|
||||||
title: '最后执行时间',
|
title: '最后执行时间',
|
||||||
render: (_, record) => record?.last_run_time ? new Date(record?.last_run_time * 1000).toLocaleString() : ''
|
render: (_, record) => record?.last_run_time ? new Date(record?.last_run_time * 1000).toLocaleString() : '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'last_use_time',
|
||||||
|
title: '最后执行耗时',
|
||||||
|
render: (_, record) => record?.last_use_time ? formatSeconds(record?.last_use_time) : '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'last_status',
|
dataIndex: 'last_status',
|
||||||
|
|
@ -190,4 +195,11 @@ export default () => {
|
||||||
|
|
||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const formatSeconds = (seconds = 0) => {
|
||||||
|
const h = String(Math.floor(seconds / 3600)).padStart(2, "0");
|
||||||
|
const m = String(Math.floor((seconds % 3600) / 60)).padStart(2, "0");
|
||||||
|
const s = String(seconds % 60).padStart(2, "0");
|
||||||
|
return h === "00" ? `${m}:${s}` : `${h}:${m}:${s}`;
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import { ProTable } from "@ant-design/pro-components";
|
import { ProTable } from "@ant-design/pro-components";
|
||||||
import { Card } from "antd";
|
import { Card } from "antd";
|
||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
|
import { formatSeconds } from "../Flow";
|
||||||
|
import { tableList } from "../../api/log";
|
||||||
|
|
||||||
const LogPage = () => {
|
const LogPage = () => {
|
||||||
const actionRef = useRef(null);
|
const actionRef = useRef(null);
|
||||||
|
|
@ -26,7 +28,12 @@ const LogPage = () => {
|
||||||
{
|
{
|
||||||
dataIndex: 'last_run_time',
|
dataIndex: 'last_run_time',
|
||||||
title: '执行时间',
|
title: '执行时间',
|
||||||
render: (_, record) => record?.last_run_time ? new Date(record?.last_run_time * 1000).toLocaleString() : ''
|
render: (_, record) => record?.last_run_time ? new Date(record?.last_run_time * 1000).toLocaleString() : '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'time',
|
||||||
|
title: '执行耗时',
|
||||||
|
render: (_, record) => record?.time ? formatSeconds(record?.time) : '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'last_status',
|
dataIndex: 'last_status',
|
||||||
|
|
@ -51,6 +58,8 @@ const LogPage = () => {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
const onRequest = async (params) => {
|
const onRequest = async (params) => {
|
||||||
|
const res = await tableList(params)
|
||||||
|
console.log(res);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return <Card title="操作日志">
|
return <Card title="操作日志">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue