mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-30 22:26:38 +08:00
125 lines
3.6 KiB
Go
125 lines
3.6 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package risk_control
|
|
|
|
import (
|
|
"Wavelet/plugins/domain/risk_control/logstore"
|
|
"context"
|
|
)
|
|
|
|
// Repository 层:本插件根包内唯一的持久化访问入口。
|
|
//
|
|
// 真正的 SQL / 驱动实现位于 logstore 子包(受 logstore skill 约束的存储抽象),
|
|
// 本文件负责解析当前生效日志库并转发读写、迁移与查询,使 service.go 只做用例编排。
|
|
|
|
// accessLogMigrationBatchSize 是日志引擎迁移时单批搬运的行数。
|
|
const accessLogMigrationBatchSize = 1000
|
|
|
|
// writeAccessLogBatch 持久化批写缓冲队列中取出的一批访问日志。
|
|
func writeAccessLogBatch(ctx context.Context, items []*logstore.UserAccessLog) error {
|
|
rows := make([]logstore.UserAccessLog, 0, len(items))
|
|
for _, item := range items {
|
|
if item == nil {
|
|
continue
|
|
}
|
|
rows = append(rows, *item)
|
|
}
|
|
store, err := logstore.Active(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return store.UserAccessLogs.BatchInsert(ctx, rows)
|
|
}
|
|
|
|
// listAccessLogs 按过滤条件读取一页访问日志。
|
|
func listAccessLogs(ctx context.Context, filter logstore.AccessLogFilter, page, pageSize int) ([]logstore.UserAccessLog, uint64, error) {
|
|
store, err := logstore.Active(ctx)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
return store.UserAccessLogs.List(ctx, filter, page, pageSize)
|
|
}
|
|
|
|
// accessLogDailyTrend 读取最近 days 天的按天访问趋势。
|
|
func accessLogDailyTrend(ctx context.Context, days int) ([]logstore.DailyTrend, error) {
|
|
store, err := logstore.Active(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return store.UserAccessLogs.GetDailyTrend(ctx, days)
|
|
}
|
|
|
|
// activeLogDatabase 返回当前生效日志库的引擎标识。
|
|
func activeLogDatabase(ctx context.Context) (string, error) {
|
|
store, err := logstore.Active(ctx)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return store.Status.ActiveDatabase(ctx)
|
|
}
|
|
|
|
// logStoreMigrating 报告日志库是否处于迁移冻结期。
|
|
func logStoreMigrating(ctx context.Context) bool {
|
|
return logstore.Migrating(ctx)
|
|
}
|
|
|
|
// loadMigrationStores 解析迁移源(当前生效库)与目标引擎库。
|
|
func loadMigrationStores(ctx context.Context, targetEngine string) (src, dst *logstore.Store, err error) {
|
|
src, err = logstore.Active(ctx)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
dst, err = logstore.BuildForMigration(ctx, targetEngine)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return src, dst, nil
|
|
}
|
|
|
|
// copyAccessLogs 清空目标库、按源库时间范围预建分区后分批搬运全部源数据,
|
|
// 并在每批完成后通过 reportProgress 回调累计已搬运行数。
|
|
func copyAccessLogs(ctx context.Context, src, dst *logstore.Store, reportProgress func(copied int)) error {
|
|
if _, err := dst.UserAccessLogs.DeleteAll(ctx); err != nil {
|
|
return err
|
|
}
|
|
from, to, err := src.UserAccessLogs.MigrationRange(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !from.IsZero() && !to.IsZero() {
|
|
if err := dst.UserAccessLogs.EnsurePartitions(ctx, from, to); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
var afterID uint64
|
|
var copied int
|
|
for {
|
|
rows, err := src.UserAccessLogs.ListForMigration(ctx, afterID, accessLogMigrationBatchSize)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(rows) == 0 {
|
|
break
|
|
}
|
|
if err := dst.UserAccessLogs.BatchInsert(ctx, rows); err != nil {
|
|
return err
|
|
}
|
|
afterID = rows[len(rows)-1].ID
|
|
copied += len(rows)
|
|
if reportProgress != nil {
|
|
reportProgress(copied)
|
|
}
|
|
if len(rows) < accessLogMigrationBatchSize {
|
|
break
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// resetLogStoreCache 丢弃缓存的生效日志库,使下一次访问重新解析。
|
|
func resetLogStoreCache() {
|
|
logstore.InvalidateCache()
|
|
}
|