소스 검색

Feature/service api workflow logs (#8323)

fanlia 7 달 전
부모
커밋
5f03e66489

+ 27 - 0
api/controllers/service_api/app/workflow.py

@@ -1,6 +1,7 @@
 import logging
 
 from flask_restful import Resource, fields, marshal_with, reqparse
+from flask_restful.inputs import int_range
 from werkzeug.exceptions import InternalServerError
 
 from controllers.service_api import api
@@ -22,10 +23,12 @@ from core.errors.error import (
 )
 from core.model_runtime.errors.invoke import InvokeError
 from extensions.ext_database import db
+from fields.workflow_app_log_fields import workflow_app_log_pagination_fields
 from libs import helper
 from models.model import App, AppMode, EndUser
 from models.workflow import WorkflowRun
 from services.app_generate_service import AppGenerateService
+from services.workflow_app_service import WorkflowAppService
 
 logger = logging.getLogger(__name__)
 
@@ -113,6 +116,30 @@ class WorkflowTaskStopApi(Resource):
         return {"result": "success"}
 
 
+class WorkflowAppLogApi(Resource):
+    @validate_app_token
+    @marshal_with(workflow_app_log_pagination_fields)
+    def get(self, app_model: App):
+        """
+        Get workflow app logs
+        """
+        parser = reqparse.RequestParser()
+        parser.add_argument("keyword", type=str, location="args")
+        parser.add_argument("status", type=str, choices=["succeeded", "failed", "stopped"], location="args")
+        parser.add_argument("page", type=int_range(1, 99999), default=1, location="args")
+        parser.add_argument("limit", type=int_range(1, 100), default=20, location="args")
+        args = parser.parse_args()
+
+        # get paginate workflow app logs
+        workflow_app_service = WorkflowAppService()
+        workflow_app_log_pagination = workflow_app_service.get_paginate_workflow_app_logs(
+            app_model=app_model, args=args
+        )
+
+        return workflow_app_log_pagination
+
+
 api.add_resource(WorkflowRunApi, "/workflows/run")
 api.add_resource(WorkflowRunDetailApi, "/workflows/run/<string:workflow_id>")
 api.add_resource(WorkflowTaskStopApi, "/workflows/tasks/<string:task_id>/stop")
+api.add_resource(WorkflowAppLogApi, "/workflows/logs")

+ 106 - 0
web/app/components/develop/template/template_workflow.en.mdx

@@ -413,3 +413,109 @@ Workflow applications offers non-session support and is ideal for translation, a
     </CodeGroup>
   </Col>
 </Row>
+
+---
+
+<Heading
+  url='/workflows/logs'
+  method='GET'
+  title='Get workflow logs'
+  name='#Get-Workflow-Logs'
+/>
+<Row>
+  <Col>
+    Returns worklfow logs, with the first page returning the latest `{limit}` messages, i.e., in reverse order.
+
+    ### Query
+
+    <Properties>
+      <Property name='keyword' type='string' key='keyword'>
+        Keyword to search
+      </Property>
+      <Property name='status' type='string' key='status'>
+        succeeded/failed/stopped
+      </Property>
+      <Property name='page' type='int' key='page'>
+        current page, default is 1.
+      </Property>
+      <Property name='limit' type='int' key='limit'>
+          How many chat history messages to return in one request, default is 20.
+      </Property>
+    </Properties>
+
+    ### Response
+  - `page` (int) Current page
+  - `limit` (int) Number of returned items, if input exceeds system limit, returns system limit amount
+  - `total` (int) Number of total items
+  - `has_more` (bool) Whether there is a next page
+  - `data` (array[object]) Log list
+    - `id` (string) ID
+    - `workflow_run` (object) Workflow run
+      - `id` (string) ID
+      - `version` (string) Version
+      - `status` (string) status of execution, `running` / `succeeded` / `failed` / `stopped`
+      - `error` (string) Optional reason of error
+      - `elapsed_time` (float) total seconds to be used
+      - `total_tokens` (int) tokens to be used
+      - `total_steps` (int) default 0
+      - `created_at` (timestamp) start time
+      - `finished_at` (timestamp) end time
+    - `created_from` (string) Created from
+    - `created_by_role` (string) Created by role
+    - `created_by_account` (string) Optional Created by account
+    - `created_by_end_user` (object) Created by end user
+      - `id` (string) ID
+      - `type` (string) Type
+      - `is_anonymous` (bool) Is anonymous
+      - `session_id` (string) Session ID
+    - `created_at` (timestamp) create time
+  </Col>
+  <Col sticky>
+
+    <CodeGroup title="Request" tag="GET" label="/workflows/logs" targetCode={`curl -X GET '${props.appDetail.api_base_url}/workflows/logs'\\\n --header 'Authorization: Bearer {api_key}'`}>
+
+    ```bash {{ title: 'cURL' }}
+    curl -X GET '${props.appDetail.api_base_url}/workflows/logs?limit=1'
+    --header 'Authorization: Bearer {api_key}'
+    ```
+
+    </CodeGroup>
+    ### Response Example
+    <CodeGroup title="Response">
+    ```json {{ title: 'Response' }}
+    {
+        "page": 1,
+        "limit": 1,
+        "total": 7,
+        "has_more": true,
+        "data": [
+            {
+                "id": "e41b93f1-7ca2-40fd-b3a8-999aeb499cc0",
+                "workflow_run": {
+                    "id": "c0640fc8-03ef-4481-a96c-8a13b732a36e",
+                    "version": "2024-08-01 12:17:09.771832",
+                    "status": "succeeded",
+                    "error": null,
+                    "elapsed_time": 1.3588523610014818,
+                    "total_tokens": 0,
+                    "total_steps": 3,
+                    "created_at": 1726139643,
+                    "finished_at": 1726139644
+                },
+                "created_from": "service-api",
+                "created_by_role": "end_user",
+                "created_by_account": null,
+                "created_by_end_user": {
+                    "id": "7f7d9117-dd9d-441d-8970-87e5e7e687a3",
+                    "type": "service_api",
+                    "is_anonymous": false,
+                    "session_id": "abc-123"
+                },
+                "created_at": 1726139644
+            }
+        ]
+    }
+    ```
+    </CodeGroup>
+  </Col>
+</Row>

+ 106 - 0
web/app/components/develop/template/template_workflow.zh.mdx

@@ -409,3 +409,109 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等
     </CodeGroup>
   </Col>
 </Row>
+
+---
+
+<Heading
+  url='/workflows/logs'
+  method='GET'
+  title='获取 workflow 日志'
+  name='#Get-Workflow-Logs'
+/>
+<Row>
+  <Col>
+    倒序返回workflow日志
+
+    ### Query
+
+    <Properties>
+      <Property name='keyword' type='string' key='keyword'>
+        关键字
+      </Property>
+      <Property name='status' type='string' key='status'>
+        执行状态 succeeded/failed/stopped
+      </Property>
+      <Property name='page' type='int' key='page'>
+        当前页码, 默认1.
+      </Property>
+      <Property name='limit' type='int' key='limit'>
+        每页条数, 默认20.
+      </Property>
+    </Properties>
+
+    ### Response
+  - `page` (int) 当前页码
+  - `limit` (int) 每页条数
+  - `total` (int) 总条数
+  - `has_more` (bool) 是否还有更多数据
+  - `data` (array[object]) 当前页码的数据
+    - `id` (string) 标识
+    - `workflow_run` (object) Workflow 执行日志
+      - `id` (string) 标识
+      - `version` (string) 版本
+      - `status` (string) 执行状态, `running` / `succeeded` / `failed` / `stopped`
+      - `error` (string) (可选) 错误
+      - `elapsed_time` (float) 耗时,单位秒
+      - `total_tokens` (int) 消耗的token数量
+      - `total_steps` (int) 执行步骤长度
+      - `created_at` (timestamp) 开始时间
+      - `finished_at` (timestamp) 结束时间
+    - `created_from` (string) 来源
+    - `created_by_role` (string) 角色
+    - `created_by_account` (string) (可选) 帐号
+    - `created_by_end_user` (object) 用户
+      - `id` (string) 标识
+      - `type` (string) 类型
+      - `is_anonymous` (bool) 是否匿名
+      - `session_id` (string) 会话标识
+    - `created_at` (timestamp) 创建时间
+  </Col>
+  <Col sticky>
+
+    <CodeGroup title="Request" tag="GET" label="/workflows/logs" targetCode={`curl -X GET '${props.appDetail.api_base_url}/workflows/logs'\\\n --header 'Authorization: Bearer {api_key}'`}>
+
+    ```bash {{ title: 'cURL' }}
+    curl -X GET '${props.appDetail.api_base_url}/workflows/logs?limit=1'
+    --header 'Authorization: Bearer {api_key}'
+    ```
+
+    </CodeGroup>
+    ### Response Example
+    <CodeGroup title="Response">
+    ```json {{ title: 'Response' }}
+    {
+        "page": 1,
+        "limit": 1,
+        "total": 7,
+        "has_more": true,
+        "data": [
+            {
+                "id": "e41b93f1-7ca2-40fd-b3a8-999aeb499cc0",
+                "workflow_run": {
+                    "id": "c0640fc8-03ef-4481-a96c-8a13b732a36e",
+                    "version": "2024-08-01 12:17:09.771832",
+                    "status": "succeeded",
+                    "error": null,
+                    "elapsed_time": 1.3588523610014818,
+                    "total_tokens": 0,
+                    "total_steps": 3,
+                    "created_at": 1726139643,
+                    "finished_at": 1726139644
+                },
+                "created_from": "service-api",
+                "created_by_role": "end_user",
+                "created_by_account": null,
+                "created_by_end_user": {
+                    "id": "7f7d9117-dd9d-441d-8970-87e5e7e687a3",
+                    "type": "service_api",
+                    "is_anonymous": false,
+                    "session_id": "abc-123"
+                },
+                "created_at": 1726139644
+            }
+        ]
+    }
+    ```
+    </CodeGroup>
+  </Col>
+</Row>