From c07caeb45ba9de3faf8aa27260c24af834446910 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Wed, 23 Jul 2025 21:37:46 +0800 Subject: [PATCH] refactor: make log level to use int32 --- internal/domain/workflow_log.go | 9 +- internal/repository/workflow_log.go | 2 +- internal/workflow/dispatcher/invoker.go | 2 +- migrations/1753272000_v0.4.0_migrate.go | 91 +++++++++++++++ pkg/logging/handler.go | 15 +-- pkg/logging/level.go | 31 ------ pkg/logging/record.go | 3 +- ui/src/App.tsx | 1 + .../components/workflow/WorkflowRunDetail.tsx | 104 ++---------------- ui/src/domain/workflowLog.ts | 9 +- ui/src/pages/ConsoleLayout.tsx | 31 +----- ui/src/pages/settings/SettingsAppearance.tsx | 2 +- 12 files changed, 126 insertions(+), 174 deletions(-) create mode 100644 migrations/1753272000_v0.4.0_migrate.go delete mode 100644 pkg/logging/level.go diff --git a/internal/domain/workflow_log.go b/internal/domain/workflow_log.go index 05eef5a7c..a386bb03e 100644 --- a/internal/domain/workflow_log.go +++ b/internal/domain/workflow_log.go @@ -1,6 +1,9 @@ package domain -import "strings" +import ( + "log/slog" + "strings" +) const CollectionNameWorkflowLog = "workflow_logs" @@ -11,7 +14,7 @@ type WorkflowLog struct { NodeId string `json:"nodeId" db:"nodeId"` NodeName string `json:"nodeName" db:"nodeName"` Timestamp int64 `json:"timestamp" db:"timestamp"` // 毫秒级时间戳 - Level string `json:"level" db:"level"` + Level int32 `json:"level" db:"level"` Message string `json:"message" db:"message"` Data map[string]any `json:"data" db:"data"` } @@ -21,7 +24,7 @@ type WorkflowLogs []WorkflowLog func (r WorkflowLogs) ErrorString() string { var builder strings.Builder for _, log := range r { - if log.Level == "ERROR" { + if log.Level >= int32(slog.LevelError) { builder.WriteString(log.Message) builder.WriteString("\n") } diff --git a/internal/repository/workflow_log.go b/internal/repository/workflow_log.go index 11bad3275..295c8a98c 100644 --- a/internal/repository/workflow_log.go +++ b/internal/repository/workflow_log.go @@ -104,7 +104,7 @@ func (r *WorkflowLogRepository) castRecordToModel(record *core.Record) (*domain. NodeId: record.GetString("nodeId"), NodeName: record.GetString("nodeName"), Timestamp: int64(record.GetInt("timestamp")), - Level: record.GetString("level"), + Level: int32(record.GetInt("level")), Message: record.GetString("message"), Data: logdata, } diff --git a/internal/workflow/dispatcher/invoker.go b/internal/workflow/dispatcher/invoker.go index 8fbf3134a..27bc439b5 100644 --- a/internal/workflow/dispatcher/invoker.go +++ b/internal/workflow/dispatcher/invoker.go @@ -83,7 +83,7 @@ func (w *workflowInvoker) processNode(ctx context.Context, node *domain.Workflow log.NodeId = current.Id log.NodeName = current.Name log.Timestamp = record.Time.UnixMilli() - log.Level = record.Level.String() + log.Level = int32(record.Level) log.Message = record.Message log.Data = record.Data log.CreatedAt = record.Time diff --git a/migrations/1753272000_v0.4.0_migrate.go b/migrations/1753272000_v0.4.0_migrate.go new file mode 100644 index 000000000..98219ce3d --- /dev/null +++ b/migrations/1753272000_v0.4.0_migrate.go @@ -0,0 +1,91 @@ +package migrations + +import ( + "github.com/pocketbase/pocketbase/core" + m "github.com/pocketbase/pocketbase/migrations" +) + +func init() { + m.Register(func(app core.App) error { + tracer := NewTracer("v0.4.0") + tracer.Printf("go ...") + + // update collection `workflow_logs` + { + collection, err := app.FindCollectionByNameOrId("pbc_1682296116") + if err != nil { + return err + } + + field := collection.Fields.GetByName("level") + if field != nil && field.Type() == "text" { + // add temp field `levelTmp` + if err := collection.Fields.AddMarshaledJSONAt(7, []byte(`{ + "hidden": false, + "id": "number760395071", + "max": null, + "min": null, + "name": "levelTmp", + "onlyInt": false, + "presentable": false, + "required": false, + "system": false, + "type": "number" + }`)); err != nil { + return err + } + if err := app.Save(collection); err != nil { + return err + } + + // copy `level` to `levelTmp` + if _, err := app.DB().NewQuery("UPDATE workflow_logs SET levelTmp = -4 WHERE level = 'DEBUG'").Execute(); err != nil { + return err + } + if _, err := app.DB().NewQuery("UPDATE workflow_logs SET levelTmp = 4 WHERE level = 'WARN'").Execute(); err != nil { + return err + } + if _, err := app.DB().NewQuery("UPDATE workflow_logs SET levelTmp = 8 WHERE level = 'ERROR'").Execute(); err != nil { + return err + } + if _, err := app.DB().NewQuery("UPDATE workflow_logs SET levelTmp = 0 WHERE levelTmp IS NULL").Execute(); err != nil { + return err + } + + // remove old field `level` + collection.Fields.RemoveById(field.GetId()) + if err := app.Save(collection); err != nil { + println(err) + return err + } + + // rename field `levelTmp` to `level` + if err := collection.Fields.AddMarshaledJSONAt(6, []byte(`{ + "hidden": false, + "id": "number760395071", + "max": null, + "min": null, + "name": "level", + "onlyInt": false, + "presentable": false, + "required": false, + "system": false, + "type": "number" + }`)); err != nil { + return err + } + if err := app.Save(collection); err != nil { + println(err) + return err + } + + tracer.Printf("collection '%s' updated", collection.Name) + } + } + + tracer.Printf("done") + return nil + }, func(app core.App) error { + return nil + }) +} diff --git a/pkg/logging/handler.go b/pkg/logging/handler.go index 7cdacdd7b..519cf18bf 100644 --- a/pkg/logging/handler.go +++ b/pkg/logging/handler.go @@ -2,7 +2,6 @@ package logging import ( "context" - "fmt" "log/slog" "sync" @@ -114,22 +113,10 @@ func (h *HookHandler) Handle(ctx context.Context, r slog.Record) error { log := &Record{ Time: r.Time, + Level: r.Level, Message: r.Message, Data: types.JSONMap[any](data), } - switch r.Level { - case slog.LevelDebug: - log.Level = LevelDebug - case slog.LevelInfo: - log.Level = LevelInfo - case slog.LevelWarn: - log.Level = LevelWarn - case slog.LevelError: - log.Level = LevelError - default: - log.Level = Level(fmt.Sprintf("LV(%d)", r.Level)) - } - if err := h.writeRecord(ctx, log); err != nil { return err } diff --git a/pkg/logging/level.go b/pkg/logging/level.go deleted file mode 100644 index 1aefe84d6..000000000 --- a/pkg/logging/level.go +++ /dev/null @@ -1,31 +0,0 @@ -package logging - -import "log/slog" - -type Level string - -const ( - LevelDebug Level = "DEBUG" - LevelInfo Level = "INFO" - LevelWarn Level = "WARN" - LevelError Level = "ERROR" -) - -func (l Level) String() string { - return string(l) -} - -func (l Level) Level() slog.Level { - switch l { - case LevelDebug: - return slog.LevelDebug - case LevelInfo: - return slog.LevelInfo - case LevelWarn: - return slog.LevelWarn - case LevelError: - return slog.LevelError - default: - return slog.Level(-1) - } -} diff --git a/pkg/logging/record.go b/pkg/logging/record.go index 38208535d..951e613dc 100644 --- a/pkg/logging/record.go +++ b/pkg/logging/record.go @@ -1,6 +1,7 @@ package logging import ( + "log/slog" "time" types "github.com/pocketbase/pocketbase/tools/types" @@ -8,7 +9,7 @@ import ( type Record struct { Time time.Time - Level Level + Level slog.Level Message string Data types.JSONMap[any] } diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 47e50c056..dc75fbbea 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -93,6 +93,7 @@ const RootApp = () => { Layout: { ...antdTheme?.components?.Layout, bodyBg: "transparent", + headerBg: "transparent", siderBg: "transparent", }, Dropdown: { diff --git a/ui/src/components/workflow/WorkflowRunDetail.tsx b/ui/src/components/workflow/WorkflowRunDetail.tsx index f59e390e3..35759eca8 100644 --- a/ui/src/components/workflow/WorkflowRunDetail.tsx +++ b/ui/src/components/workflow/WorkflowRunDetail.tsx @@ -9,7 +9,7 @@ import { ClientResponseError } from "pocketbase"; import CertificateDetailDrawer from "@/components/certificate/CertificateDetailDrawer"; import Show from "@/components/Show"; import { type CertificateModel } from "@/domain/certificate"; -import { type WorkflowLogModel } from "@/domain/workflowLog"; +import { WorkflowLogLevel, type WorkflowLogModel } from "@/domain/workflowLog"; import { WORKFLOW_RUN_STATUSES, type WorkflowRunModel } from "@/domain/workflowRun"; import { useBrowserTheme } from "@/hooks"; import { listByWorkflowRunId as listCertificatesByWorkflowRunId } from "@/repository/certificate"; @@ -138,10 +138,14 @@ const WorkflowRunLogs = ({ runId, runStatus }: { runId: string; runStatus: strin
{message} @@ -259,94 +263,6 @@ const WorkflowRunLogs = ({ runId, runStatus }: { runId: string; runStatus: strin ); }; -const WorkflowRunArtifacts = ({ runId }: { runId: string }) => { - const { t } = useTranslation(); - - const { notification } = App.useApp(); - - const tableColumns: TableProps["columns"] = [ - { - key: "$index", - align: "center", - fixed: "left", - width: 50, - render: (_, __, index) => index + 1, - }, - { - key: "type", - title: t("workflow_run_artifact.props.type"), - render: () => t("workflow_run_artifact.props.type.certificate"), - }, - { - key: "name", - title: t("workflow_run_artifact.props.name"), - render: (_, record) => { - return ( -
- - {record.subjectAltNames} - -
- ); - }, - }, - { - key: "$action", - align: "end", - width: 120, - render: (_, record) => ( -
- -
- ), - }, - ]; - const [tableData, setTableData] = useState([]); - const { loading: tableLoading } = useRequest( - () => { - return listCertificatesByWorkflowRunId(runId); - }, - { - refreshDeps: [runId], - onSuccess: (res) => { - setTableData(res.items); - }, - onError: (err) => { - if (err instanceof ClientResponseError && err.isAbort) { - return; - } - - console.error(err); - notification.error({ message: t("common.text.request_error"), description: getErrMsg(err) }); - - throw err; - }, - } - ); - - return ( - <> - {t("workflow_run.artifacts")} - - columns={tableColumns} - dataSource={tableData} - loading={tableLoading} - locale={{ - emptyText: , - }} - pagination={false} - rowKey={(record) => record.id} - size="small" - /> - - ); -}; +const WorkflowRunArtifacts = ({ runId }: { runId: string }) => {}; export default WorkflowRunDetail; diff --git a/ui/src/domain/workflowLog.ts b/ui/src/domain/workflowLog.ts index fa125360f..bd2ae63e0 100644 --- a/ui/src/domain/workflowLog.ts +++ b/ui/src/domain/workflowLog.ts @@ -2,7 +2,14 @@ export interface WorkflowLogModel extends Omit { nodeId: string; nodeName: string; timestamp: ReturnType; - level: "DEBUG" | "INFO" | "WARN" | "ERROR"; + level: number; message: string; data: Record; } + +export enum WorkflowLogLevel { + Debug = -4, + Info = 0, + Warn = 4, + Error = 8, +} diff --git a/ui/src/pages/ConsoleLayout.tsx b/ui/src/pages/ConsoleLayout.tsx index 091c48cda..8a0f5d629 100644 --- a/ui/src/pages/ConsoleLayout.tsx +++ b/ui/src/pages/ConsoleLayout.tsx @@ -12,10 +12,10 @@ import { IconMenu2, IconSettings, } from "@tabler/icons-react"; -import { Alert, Button, Drawer, Layout, Menu, type MenuProps, theme } from "antd"; +import { Alert, Button, Divider, Drawer, Layout, Menu, type MenuProps, theme } from "antd"; -import AppLocale, { useAppLocaleMenuItems } from "@/components/AppLocale"; -import AppTheme, { useAppThemeMenuItems } from "@/components/AppTheme"; +import AppLocale from "@/components/AppLocale"; +import AppTheme from "@/components/AppTheme"; import AppVersion from "@/components/AppVersion"; import Show from "@/components/Show"; import { APP_DOCUMENT_URL, APP_REPO_URL } from "@/domain/app"; @@ -30,9 +30,6 @@ const ConsoleLayout = () => { const { token: themeToken } = theme.useToken(); - const localeMenuItems = useAppLocaleMenuItems(); - const themeMenuItems = useAppThemeMenuItems(); - const handleLogoutClick = () => { auth.clear(); navigate("/login"); @@ -76,26 +73,6 @@ const ConsoleLayout = () => { - - - ), - label: t("common.menu.theme"), - children: themeMenuItems, - }, - { - key: "locale", - icon: ( - - - - ), - label: t("common.menu.locale"), - children: localeMenuItems, - }, { key: "document", icon: ( @@ -126,7 +103,7 @@ const ConsoleLayout = () => { - +
} />} /> diff --git a/ui/src/pages/settings/SettingsAppearance.tsx b/ui/src/pages/settings/SettingsAppearance.tsx index 52c46b87c..6db58c741 100644 --- a/ui/src/pages/settings/SettingsAppearance.tsx +++ b/ui/src/pages/settings/SettingsAppearance.tsx @@ -52,7 +52,7 @@ const SettingsAppearanceTheme = ({ className, style }: { className?: string; sty
{themeItems.map((item) => (
-
+
{item.label}