查询和导出审计记录

分页读取工作区审计记录,将结果逐行保存为本地 JSON 文件,并查询审计概览。

准备

  1. 配置 SDK 和个人访问令牌。

  2. 选择工作区并获取工作区 ID。

  3. 输出位置:选择一个不存在的本地文件路径;默认保存为当前目录的 audit-logs.jsonl,已有文件不会被覆盖。

如需更换保存位置,在终端设置输出路径:

export AUDIT_OUTPUT='./audit-logs.jsonl'

分页读取并保存记录

运行前确认当前身份有权读取目标工作区审计记录。示例将全部查询到的页面写入本地文件,每行一条 JSON 记录。

import os

import moi_product_sdk as sdk

client = sdk.new_with_personal_access_token(
    os.environ["PRODUCT_API_BASE_URL"], os.environ["PRODUCT_API_KEY"]
)
workspace_id = os.environ["WORKSPACE_ID"]
workspace = client.workspace(workspace_id)
from google.protobuf.json_format import MessageToDict
import json

output = os.environ.get("AUDIT_OUTPUT", "audit-logs.jsonl")
page_number = 1
saved = 0
with open(output, "x", encoding="utf-8") as stream:
    while True:
        page = workspace.members().audit_logs(
            sdk.with_page(page_number), sdk.with_page_size(100)
        )
        for item in page.items:
            stream.write(json.dumps(MessageToDict(item, preserving_proto_field_name=True), ensure_ascii=False) + "\n")
            saved += 1
        if not page.items or page.page * page.page_size >= page.total:
            break
        page_number += 1
overview = workspace.members().audit_log_overview()
print("保存路径:", output, "记录数:", saved)
print("概览总数:", overview.total, "成功:", overview.success, "失败:", overview.failed)
package main

import (
	"context"
	"fmt"
	sdk "github.com/matrixorigin/matrixflow/sdk/go-sdk"
	"google.golang.org/protobuf/encoding/protojson"
	"os"
)

func main() {
	ctx := context.Background()
	client, err := sdk.NewWithPersonalAccessToken(os.Getenv("PRODUCT_API_BASE_URL"), os.Getenv("PRODUCT_API_KEY"))
	if err != nil {
		panic(err)
	}
	workspaceID := os.Getenv("WORKSPACE_ID")
	workspace, err := client.Workspace(workspaceID)
	if err != nil {
		panic(err)
	}
	_ = workspace
	output := os.Getenv("AUDIT_OUTPUT")
	if output == "" {
		output = "audit-logs.jsonl"
	}
	stream, err := os.OpenFile(output, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
	if err != nil {
		panic(err)
	}
	defer stream.Close()
	saved := 0
	for pageNumber := 1; ; pageNumber++ {
		page, err := workspace.Members().AuditLogs(ctx, sdk.WithPage(pageNumber), sdk.WithPageSize(100))
		if err != nil {
			panic(err)
		}
		for _, item := range page.GetItems() {
			data, err := (protojson.MarshalOptions{UseProtoNames: true}).Marshal(item)
			if err != nil {
				panic(err)
			}
			if _, err = stream.Write(append(data, '\n')); err != nil {
				panic(err)
			}
			saved++
		}
		if len(page.GetItems()) == 0 || int64(page.GetPage())*int64(page.GetPageSize()) >= page.GetTotal() {
			break
		}
	}
	overview, err := workspace.Members().AuditLogOverview(ctx)
	if err != nil {
		panic(err)
	}
	fmt.Println("保存路径:", output, "记录数:", saved)
	fmt.Println("概览总数:", overview.GetTotal(), "成功:", overview.GetSuccess(), "失败:", overview.GetFailed())
}

程序输出保存路径和记录数。查询期间新增的日志可能使概览总数与保存条数不同。中途出错时,文件只包含已读取的记录;换一个文件路径重试。

最后更新于