add preview api

pull/17608/head
fuwx 1 year ago
parent a6767d746d
commit ab453fa9d6
No known key found for this signature in database
GPG Key ID: C8FA8C18DFB4702B

@ -1,4 +1,5 @@
import io
import requests
from flask import send_file
from flask_login import current_user # type: ignore
@ -587,6 +588,148 @@ class APOToolBuiltinListApi(Resource):
)
def get_step(start_time, end_time):
time_diff = end_time - start_time
SECOND = 1000000 # microseconds
MINUTE = 60 * SECOND
HOUR = 60 * MINUTE
step = SECOND # default step is 1 second
if time_diff <= 15 * MINUTE:
step = 30 * SECOND
elif time_diff <= 30 * MINUTE:
step = 1 * MINUTE
elif time_diff <= 1 * HOUR:
step = 2 * MINUTE
elif time_diff <= 1.5 * HOUR:
step = 3 * MINUTE
elif time_diff <= 3 * HOUR:
step = 6 * MINUTE
elif time_diff <= 6 * HOUR:
step = 12 * MINUTE
elif time_diff <= 12 * HOUR:
step = 24 * MINUTE
elif time_diff <= 15 * HOUR:
step = 30 * MINUTE
elif time_diff <= 30 * HOUR:
step = 1 * HOUR
else:
step = ((time_diff + 30 * SECOND - 1) // (30 * SECOND)) * SECOND
return step
def get_url(type):
match type:
case "metric":
return dify_config.APO_BACKEND_URL + "/api/metric/query"
case "alert":
return dify_config.APO_BACKEND_URL + "/api/alerts/descendant/anormal/delta"
case "topology":
return dify_config.APO_BACKEND_URL + "/api/service/relation"
class APOToolPreviewApi(Resource):
def post(self):
user = current_user
user_id = user.id
tenant_id = user.current_tenant_id
parser = reqparse.RequestParser()
parser.add_argument("type", type=str, required=True, nullable=False, location="json")
parser.add_argument("title", type=str, required=True, nullable=False, location="json")
parser.add_argument("startTime", type=int, required=True, nullable=True, location="json")
parser.add_argument("endTime", type=int, required=True, nullable=True, location="json")
parser.add_argument("params", type=dict, required=True, nullable=False, location="json")
args = parser.parse_args()
res = {}
match args["type"]:
case "metric":
url = get_url(args["type"])
json = {
"metricName": args["title"],
"params": args["params"],
"startTime": args["startTime"],
"endTime": args["endTime"],
"step": get_step(args["startTime"], args["endTime"]),
}
resp = requests.post(url, json=json)
raw = resp.json()['result']
res = {
'type': 'metric',
'display': True,
'unit': raw['unit'],
'data': {
"timeseries": raw['timeseries']
}
}
case "topology":
url = get_url(args["type"])
params = args["params"]
json = {
"service": params['service'],
"endpoint": params['endpoint'],
"entryService": params['service'],
"entryEndpoint": params['endpoint'],
"startTime": args["startTime"],
"endTime": args["endTime"],
"withTopology": True,
"removeClientCall": True,
}
resp = requests.get(url, params=json)
raw = resp.json()
res = {
'type': 'topology',
'display': True,
'data': raw
}
case "alert":
url = get_url(args["type"])
params = args["params"]
json = {
"service": params['service'],
"endpoint": params['endpoint'],
"startTime": args["startTime"],
"endTime": args["endTime"],
'anormalTypes': "app,container,infra,network,error,appInstance",
'deltaStartTime': args["startTime"],
'deltaEndTime': args["endTime"],
'step': get_step(args["startTime"], args["endTime"]),
}
resp = requests.post(url, json=json)
raw = resp.json()
res = {
'type': 'topology',
'display': True,
'data': raw
}
case "log":
url = dify_config.APO_BACKEND_URL + "/api/log/fault/pagelist"
params = args["params"]
json = {
'service': [params['service']],
'startTime': args["startTime"],
'endTime': args["endTime"],
'pageNum': 1,
'pageSize': 10
}
resp = requests.post(url, json=json)
raw = resp.json()['list'][0]
content_url = dify_config.APO_BACKEND_URL + "/api/log/fault/content"
content = requests.post(content_url, json=raw).json()
res = {
'type': 'log',
'display': True,
'data': content,
}
return jsonable_encoder(res)
class ToolApiListApi(Resource):
@setup_required
@login_required
@ -674,6 +817,7 @@ api.add_resource(ToolWorkflowProviderListToolApi, "/workspaces/current/tool-prov
api.add_resource(ToolBuiltinListApi, "/workspaces/current/tools/builtin")
api.add_resource(APOToolBuiltinListApi, "/workspaces/current/tools/apo")
api.add_resource(APOToolPreviewApi, "/workspaces/current/tools/apo/preview")
api.add_resource(ToolApiListApi, "/workspaces/current/tools/api")
api.add_resource(ToolWorkflowListApi, "/workspaces/current/tools/workflow")

@ -8,7 +8,7 @@ identity:
description:
human:
en_US: threshold judgement
zh_Hans: 阈值判定
zh_Hans: 基于固定阈值检测数据,超过阈值认为异常
pt_BR: threshold judgement
llm: threshold judgement
parameters:

@ -13,7 +13,7 @@ description:
llm: Query the entry service alert events
display:
type: alert
unit: alert
title: alert
parameters:
- name: service
type: string

@ -35,7 +35,7 @@ class SelectContainerCPUTool(BuiltinTool):
resp = requests.post(dify_config.APO_BACKEND_URL + '/api/metric/query', json=params)
list = resp.json()['result']
list = json.dumps({
'type': 'cpu',
'type': 'metric',
'display': True,
'unit': list['unit'],
'data': {

@ -6,8 +6,8 @@ identity:
zh_Hans: 查询容器CPU利用率
pt_BR: Query the CPU utilization of the container
display:
type: cpu
unit: precent
type: metric
title: 基础设施情况 - 容器CPU - 容器CPU使用率 - Containerd
description:
human:
en_US: Query the CPU utilization of the container

@ -35,7 +35,7 @@ class SelectContainerRSSTool(BuiltinTool):
resp = requests.post(dify_config.APO_BACKEND_URL + '/api/metric/query', json=params)
list = resp.json()['result']
list = json.dumps({
'type': 'memory',
'type': 'metirc',
'display': True,
'unit': list['unit'],
'data': {

@ -12,8 +12,8 @@ description:
pt_BR: Query container resident memory usage
llm: Query container resident memory usage
display:
type: memory
unit: bytes
type: metric
title: 基础设施情况 - 容器内存 - 容器内存使用率 - Containerd
parameters:
- name: pod
type: string

@ -35,7 +35,7 @@ class ContainerRTTTool(BuiltinTool):
resp = requests.post(dify_config.APO_BACKEND_URL + '/api/metric/query', json=params)
list = resp.json()['result']
list = json.dumps({
'type': 'memory',
'type': 'metric',
'display': True,
'unit': list['unit'],
'data': {

@ -12,8 +12,8 @@ description:
pt_BR: Query container rtt
llm: Query container rtt
display:
type: network
unit: seconds
type: metric
title: 基础设施情况 - 容器网络 - 与下游服务RTT
parameters:
- name: pod
type: string

@ -13,7 +13,7 @@ description:
llm: Query service log data
display:
type: log
unit: log
title: log
parameters:
- name: service
type: string

@ -1,88 +0,0 @@
import json
from collections.abc import Generator
from typing import Any, Optional
import requests
from configs import dify_config
from core.tools.builtin_tool.tool import BuiltinTool
from core.tools.entities.tool_entities import ToolInvokeMessage
class FaultLogTool(BuiltinTool):
def _invoke(
self,
user_id: str,
tool_parameters: dict[str, Any],
conversation_id: Optional[str] = None,
app_id: Optional[str] = None,
message_id: Optional[str] = None,
) -> Generator[ToolInvokeMessage, None, None]:
service = tool_parameters.get("service")
endpoint = tool_parameters.get("endpoint")
entryService = tool_parameters.get("entryService")
entryEndpoint = tool_parameters.get("entryEndpoint")
start_time = tool_parameters.get("startTime")
end_time = tool_parameters.get("endTime")
type = tool_parameters.get("type")
params = {
"anormalTypes": "app,container,infra,network,error,appInstance",
"endTime": end_time,
"endpoint": endpoint,
"entryEndpoint": entryEndpoint,
"entryService": entryService,
"service": service,
"startTime": start_time,
"step": self.get_step(start_time, end_time),
"type": [type],
"withTopology": True,
}
url = "http://192.168.1.6:13680/api/nodeinfo"
res = {}
with requests.post(url, json=params, stream=True) as response:
# 逐行读取流式响应
for line in response.iter_lines():
if line: # 过滤空行
# 解码字节为字符串
decoded_line = line.decode('utf-8')
res = json.loads(decoded_line[5:].strip())
list = json.dumps({
'type': 'nodeinfo',
'display': True,
'data': res,
})
yield self.create_text_message(list)
def get_step(self, start_time, end_time):
time_diff = end_time - start_time
SECOND = 1000000 # microseconds
MINUTE = 60 * SECOND
HOUR = 60 * MINUTE
step = SECOND # default step is 1 second
if time_diff <= 15 * MINUTE:
step = 30 * SECOND
elif time_diff <= 30 * MINUTE:
step = 1 * MINUTE
elif time_diff <= 1 * HOUR:
step = 2 * MINUTE
elif time_diff <= 1.5 * HOUR:
step = 3 * MINUTE
elif time_diff <= 3 * HOUR:
step = 6 * MINUTE
elif time_diff <= 6 * HOUR:
step = 12 * MINUTE
elif time_diff <= 12 * HOUR:
step = 24 * MINUTE
elif time_diff <= 15 * HOUR:
step = 30 * MINUTE
elif time_diff <= 30 * HOUR:
step = 1 * HOUR
else:
step = ((time_diff + 30 * SECOND - 1) // (30 * SECOND)) * SECOND
return step

@ -1,108 +0,0 @@
identity:
name: node_info
author: APO
label:
en_US: node_info
zh_Hans: 获取节点信息
pt_BR: node_info
description:
human:
en_US: A tool for getting fault log.
zh_Hans: 获取节点信息
pt_BR: A tool for getting fault log.
llm: A tool for getting fault log.
display:
type: info
unit: info
parameters:
- name: entryService
type: string
required: true
label:
en_US: entryService
zh_Hans: 入口服务名
pt_BR: entryService
human_description:
en_US: Time format in strftime standard.
zh_Hans: 拓扑入口服务名
pt_BR: Time format in strftime standard.
llm_description: toplogy service name
form: llm
- name: entryEndpoint
type: string
required: true
label:
en_US: entryEndpoint
zh_Hans: 入口服务端点
pt_BR: entryEndpoint
human_description:
en_US: Time format in strftime standard.
zh_Hans: 拓扑入口服务端点
pt_BR: Time format in strftime standard.
llm_description: toplogy endpoint
form: llm
- name: service
type: string
required: true
label:
en_US: service
zh_Hans: 服务名
pt_BR: service
human_description:
en_US: Time format in strftime standard.
zh_Hans: 查询指定服务的名称
pt_BR: Time format in strftime standard.
llm_description: Time format in strftime standard.
form: llm
- name: endpoint
type: string
required: true
label:
en_US: endpoint
zh_Hans: 服务端点
pt_BR: endpoint
human_description:
en_US: Time format in strftime standard.
zh_Hans: 指定服务的端点
pt_BR: Time format in strftime standard.
llm_description: toplogy endpoint
form: llm
- name: startTime
type: number
required: true
label:
en_US: startTime
zh_Hans: startTime
pt_BR: startTime
human_description:
en_US: Data query start time
zh_Hans: 开始时间 (微秒)
pt_BR: Data query start time
llm_description: Data query start time
form: llm
- name: endTime
type: number
required: true
label:
en_US: endTime
zh_Hans: endTime
pt_BR: endTime
human_description:
en_US: Data query end time
zh_Hans: 结束时间 (微秒)
pt_BR: Data query end time
llm_description: Data query start time
form: llm
- name: type
type: string
required: false
label:
en_US: type
zh_Hans: 查询数据类型(log, slow, error)
pt_BR: type
human_description:
en_US: Time format in strftime standard.
zh_Hans: 指定查询数据类型(log, slow, error)。
pt_BR: Time format in strftime standard.
llm_description: Time format in strftime standard.
form: llm

@ -18,13 +18,13 @@ class SelectCPUTool(BuiltinTool):
app_id: Optional[str] = None,
message_id: Optional[str] = None,
) -> Generator[ToolInvokeMessage, None, None]:
node_name = tool_parameters.get("nodeName")
node = tool_parameters.get("node")
start_time = tool_parameters.get("startTime")
end_time = tool_parameters.get("endTime")
params = {
'metricName': '宿主机监控指标 - Quick CPU / Mem / Disk - CPU Busy',
'params': {
"node": node_name,
"node": node,
},
'startTime': start_time,
'endTime': end_time,
@ -33,7 +33,7 @@ class SelectCPUTool(BuiltinTool):
resp = requests.post(dify_config.APO_BACKEND_URL + '/api/metric/query', json=params)
list = resp.json()['result']
list = json.dumps({
'type': 'cpu',
'type': 'metric',
'display': True,
'unit': list['unit'],
'data': {

@ -12,16 +12,16 @@ description:
pt_BR: Query the CPU utilization of the host
llm: Query the CPU utilization of the host
display:
type: cpu
unit: precent
type: metric
title: 宿主机监控指标 - Quick CPU / Mem / Disk - CPU Busy
parameters:
- name: nodeName
- name: node
type: string
required: true
label:
en_US: nodeName
zh_Hans: nodeName
pt_BR: nodeName
en_US: node
zh_Hans: node
pt_BR: node
human_description:
en_US: Specified host name
zh_Hans: 指定的主机名

@ -13,7 +13,7 @@ description:
llm: Query the entry service topology
display:
type: topology
unit: topology
title: topology
parameters:
- name: service
type: string

@ -320,7 +320,7 @@ class ToolDescription(BaseModel):
class APODisPlay(BaseModel):
type: str = Field(..., description="The type of the apo data display")
unit: str = Field(..., description="The unit of the apo data display")
title: str = Field(..., description="The title of the apo data display")
class ToolEntity(BaseModel):
identity: ToolIdentity

Loading…
Cancel
Save