mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 01:06:59 +08:00
feat: Support recording system operation logs (#651)
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: 3d4bd2d673dc
|
||||
Revises: 24e961f6326b
|
||||
Create Date: 2025-12-19 13:30:54.743171
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import sqlmodel.sql.sqltypes
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '3d4bd2d673dc'
|
||||
down_revision = '24e961f6326b'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.create_table('sys_logs',
|
||||
sa.Column('id', sa.BIGINT(), autoincrement=True, nullable=False),
|
||||
sa.Column('operation_type', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||
sa.Column('operation_detail', sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column('user_id', sa.BIGINT(), autoincrement=False, nullable=True),
|
||||
sa.Column('operation_status', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||
sa.Column('oid', sa.BIGINT(), autoincrement=False, nullable=True),
|
||||
sa.Column('ip_address', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||
sa.Column('user_agent', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||
sa.Column('execution_time', sa.BIGINT(), autoincrement=False, nullable=True),
|
||||
sa.Column('error_message', sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.Column('create_time', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
||||
sa.Column('module', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||
sa.Column('remark', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||
sa.Column('resource_id',sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||
sa.Column('request_method', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||
sa.Column('request_path', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||
sa.PrimaryKeyConstraint('id', name=op.f('sys_logs_pkey'))
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_table('sys_logs')
|
||||
@@ -21,6 +21,8 @@ from apps.system.schemas.permission import SqlbotPermission, require_permissions
|
||||
from common.core.deps import CurrentAssistant, SessionDep, CurrentUser, Trans
|
||||
from common.utils.command_utils import parse_quick_command
|
||||
from common.utils.data_format import DataFormat
|
||||
from sqlbot_xpack.audit.models.log_model import OperationType, OperationDetails, OperationModules
|
||||
from sqlbot_xpack.audit.schemas.logger_decorator import system_log, LogConfig
|
||||
|
||||
router = APIRouter(tags=["Data Q&A"], prefix="/chat")
|
||||
|
||||
@@ -80,6 +82,12 @@ async def rename(session: SessionDep, chat: RenameChat):
|
||||
|
||||
|
||||
@router.delete("/{chart_id}", response_model=str, summary=f"{PLACEHOLDER_PREFIX}delete_chat")
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.DELETE_QA,
|
||||
operation_detail=OperationDetails.DELETE_QA_DETAILS,
|
||||
module=OperationModules.QA,
|
||||
resource_id_expr="chart_id"
|
||||
))
|
||||
async def delete(session: SessionDep, chart_id: int):
|
||||
try:
|
||||
return delete_chat(session=session, chart_id=chart_id)
|
||||
@@ -92,6 +100,12 @@ async def delete(session: SessionDep, chart_id: int):
|
||||
|
||||
@router.post("/start", response_model=ChatInfo, summary=f"{PLACEHOLDER_PREFIX}start_chat")
|
||||
@require_permissions(permission=SqlbotPermission(type='ds', keyExpression="create_chat_obj.datasource"))
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.CREATE_QA,
|
||||
operation_detail=OperationDetails.CREATE_QA_DETAILS,
|
||||
module=OperationModules.QA,
|
||||
result_id_expr="id"
|
||||
))
|
||||
async def start_chat(session: SessionDep, current_user: CurrentUser, create_chat_obj: CreateChat):
|
||||
try:
|
||||
return create_chat(session, current_user, create_chat_obj)
|
||||
|
||||
@@ -3,6 +3,8 @@ from fastapi import APIRouter, File, UploadFile, HTTPException
|
||||
from apps.dashboard.crud.dashboard_service import list_resource, load_resource, \
|
||||
create_resource, create_canvas, validate_name, delete_resource, update_resource, update_canvas
|
||||
from apps.dashboard.models.dashboard_model import CreateDashboard, BaseDashboard, QueryDashboard, DashboardResponse
|
||||
from sqlbot_xpack.audit.models.log_model import OperationType, OperationDetails, OperationModules
|
||||
from sqlbot_xpack.audit.schemas.logger_decorator import system_log, LogConfig
|
||||
from common.core.deps import SessionDep, CurrentUser
|
||||
|
||||
router = APIRouter(tags=["dashboard"], prefix="/dashboard")
|
||||
@@ -29,16 +31,34 @@ async def update_resource_api(session: SessionDep, user: CurrentUser, dashboard:
|
||||
|
||||
|
||||
@router.delete("/delete_resource/{resource_id}")
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.DELETE_DASHBOARD,
|
||||
operation_detail=OperationDetails.DELETE_DASHBOARD_DETAILS,
|
||||
module=OperationModules.DASHBOARD,
|
||||
resource_id_expr="resource_id"
|
||||
))
|
||||
async def delete_resource_api(session: SessionDep, resource_id: str):
|
||||
return delete_resource(session, resource_id)
|
||||
|
||||
|
||||
@router.post("/create_canvas", response_model=BaseDashboard)
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.CREATE_DASHBOARD,
|
||||
operation_detail=OperationDetails.CREATE_DASHBOARD_DETAILS,
|
||||
module=OperationModules.DASHBOARD,
|
||||
result_id_expr="id"
|
||||
))
|
||||
async def create_canvas_api(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
|
||||
return create_canvas(session, user, dashboard)
|
||||
|
||||
|
||||
@router.post("/update_canvas", response_model=BaseDashboard)
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.UPDATE_DASHBOARD,
|
||||
operation_detail=OperationDetails.UPDATE_DASHBOARD_DETAILS,
|
||||
module=OperationModules.DASHBOARD,
|
||||
resource_id_expr="dashboard.id"
|
||||
))
|
||||
async def update_canvas_api(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
|
||||
return update_canvas(session, user, dashboard)
|
||||
|
||||
|
||||
@@ -28,7 +28,8 @@ from ..crud.field import get_fields_by_table_id
|
||||
from ..crud.table import get_tables_by_ds_id
|
||||
from ..models.datasource import CoreDatasource, CreateDatasource, TableObj, CoreTable, CoreField, FieldObj, \
|
||||
TableSchemaResponse, ColumnSchemaResponse, PreviewResponse
|
||||
|
||||
from sqlbot_xpack.audit.models.log_model import OperationType, OperationDetails, OperationModules
|
||||
from sqlbot_xpack.audit.schemas.logger_decorator import system_log, LogConfig
|
||||
router = APIRouter(tags=["Datasource"], prefix="/datasource")
|
||||
path = settings.EXCEL_PATH
|
||||
|
||||
@@ -69,6 +70,12 @@ async def check_by_id(session: SessionDep, trans: Trans,
|
||||
|
||||
|
||||
@router.post("/add", response_model=CoreDatasource, summary=f"{PLACEHOLDER_PREFIX}ds_add")
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.CREATE_DATASOURCE,
|
||||
operation_detail=OperationDetails.CREATE_DATASOURCE_DETAILS,
|
||||
module=OperationModules.DATASOURCE,
|
||||
result_id_expr="id"
|
||||
))
|
||||
async def add(session: SessionDep, trans: Trans, user: CurrentUser, ds: CreateDatasource):
|
||||
def inner():
|
||||
return create_ds(session, trans, user, ds)
|
||||
@@ -87,6 +94,12 @@ async def choose_tables(session: SessionDep, trans: Trans, tables: List[CoreTabl
|
||||
|
||||
@router.post("/update", response_model=CoreDatasource, summary=f"{PLACEHOLDER_PREFIX}ds_update")
|
||||
@require_permissions(permission=SqlbotPermission(type='ds', keyExpression="ds.id"))
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.UPDATE_DATASOURCE,
|
||||
operation_detail=OperationDetails.UPDATE_DATASOURCE_DETAILS,
|
||||
module=OperationModules.DATASOURCE,
|
||||
resource_id_expr="ds.id"
|
||||
))
|
||||
async def update(session: SessionDep, trans: Trans, user: CurrentUser, ds: CoreDatasource):
|
||||
def inner():
|
||||
return update_ds(session, trans, user, ds)
|
||||
@@ -96,6 +109,12 @@ async def update(session: SessionDep, trans: Trans, user: CurrentUser, ds: CoreD
|
||||
|
||||
@router.post("/delete/{id}", response_model=None, summary=f"{PLACEHOLDER_PREFIX}ds_delete")
|
||||
@require_permissions(permission=SqlbotPermission(type='ds', keyExpression="id"))
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.DELETE_DATASOURCE,
|
||||
operation_detail=OperationDetails.DELETE_DATASOURCE_DETAILS,
|
||||
module=OperationModules.DATASOURCE,
|
||||
resource_id_expr="id"
|
||||
))
|
||||
async def delete(session: SessionDep, id: int = Path(..., description=f"{PLACEHOLDER_PREFIX}ds_id")):
|
||||
return delete_ds(session, id)
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ from apps.system.crud.aimodel_manage import async_model_info
|
||||
from apps.system.crud.assistant import init_dynamic_cors
|
||||
from apps.system.middleware.auth import TokenMiddleware
|
||||
from apps.system.schemas.permission import RequestContextMiddleware
|
||||
from sqlbot_xpack.audit.schemas.request_context import RequestContextMiddlewareCommon
|
||||
from common.core.config import settings
|
||||
from common.core.response_middleware import ResponseMiddleware, exception_handler
|
||||
from common.core.sqlbot_cache import init_sqlbot_cache
|
||||
@@ -201,6 +202,7 @@ if settings.all_cors_origins:
|
||||
app.add_middleware(TokenMiddleware)
|
||||
app.add_middleware(ResponseMiddleware)
|
||||
app.add_middleware(RequestContextMiddleware)
|
||||
app.add_middleware(RequestContextMiddlewareCommon)
|
||||
app.include_router(api_router, prefix=settings.API_V1_STR)
|
||||
|
||||
# Register exception handlers
|
||||
|
||||
Reference in New Issue
Block a user