mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-04 07:06:36 +08:00
76 lines
4.2 KiB
Markdown
76 lines
4.2 KiB
Markdown
---
|
||
name: "logstore"
|
||
description: "OpenFlare / Wavelet:当新增或修改日志/分析用途表(节点访问日志、用户访问日志、可观测时序)、接入 internal/repository/logstore、切换日志主库、实现 PG/SQLite 回落,或判断一张表该走业务主库还是日志库时必须使用。"
|
||
---
|
||
|
||
# 日志用途表开发
|
||
|
||
开始前阅读根目录 `AGENTS.md`。DDL 用 `database-migration`;高频写入队列用 `clickhouse-batchwriter`;切换任务用 `new-async-task`。本技能只回答:**这张表是不是日志表,以及如何接入可切换的日志主库。**
|
||
|
||
设计背景见 [日志存储解耦](../../../docs/design/logstore.md)。
|
||
|
||
## 先判定
|
||
|
||
日志表同时满足:
|
||
|
||
- 追加写入、几乎不更新单行
|
||
- 按时间查询/聚合,允许按保留天数删除
|
||
- 关闭 ClickHouse 后仍要能写、能查
|
||
- 不参与网站/节点/证书等事务一致性
|
||
|
||
**不要**做成日志表:Zone、节点、配置版本、任务执行、上传元数据。这些走主库 `repository`。
|
||
|
||
当前日志域:
|
||
|
||
| 域 | 接口 | 表 |
|
||
| :--- | :--- | :--- |
|
||
| 节点访问日志 | `AccessLogStore` | `of_node_access_logs` |
|
||
| 可观测 | `ObservabilityStore` | `of_node_metric_snapshots` / `of_node_edge_health` / `of_node_obs_frps` / `of_node_obs_frpc` |
|
||
| 用户访问审计 | `UserAccessLogStore` | `w_user_access_logs` |
|
||
|
||
## 分层
|
||
|
||
| 层级 | 路径 | 职责 |
|
||
| :--- | :--- | :--- |
|
||
| 抽象 | `internal/repository/logstore` | 接口 + `Active`/`BuildForMigration`;apps **只**面向这里或 `repository` 门面 |
|
||
| CH 实现 | `logstore/clickhouse_store.go` 委托 `analytics` | 原生批量 + 现有聚合 SQL |
|
||
| 主库实现 | `logstore/postgres_store.go` | PG(按月分区)与 SQLite(普通表)共用 GORM |
|
||
| Model | `internal/model/analytics` | 实体与批量 SQL,无 IO |
|
||
| 入队 | `chwriter` / `risk_control` + `batchwriter` | flush 调 logstore `BatchInsert*`;CH 入队经 hooks |
|
||
| 切换 | `of_log_db_switch` | 冻结 → `chwriter.Drain` → 逐表复制 → 翻转 |
|
||
| 约束 | `logstore/imports_test.go` | apps 禁止 import `repository/analytics` |
|
||
|
||
`log_database` 只能是「随主库」或 `clickhouse`。`log_database` / `log_db_migration` 受保护。
|
||
|
||
## 新增一张日志表
|
||
|
||
1. **Model**(`internal/model/analytics`):`TableName` + `InsertColumns` / `BatchInsertSQL`。
|
||
2. **三套 DDL**:CH `MergeTree` + `toYYYYMM`;PG `PARTITION BY RANGE(时间列)`(主键含分区键);SQLite 普通表。不要在主库建 CH 物化视图,聚合实时算。
|
||
3. **挂到已有域或新接口**:能进 `AccessLogStore` / `ObservabilityStore` / `UserAccessLogStore` 就不要再拆包。新域才新增接口并放进 `Store`。
|
||
4. **方法最少集**:`BatchInsert`(含 `ensureWritable`)、业务查询、`ListForMigration`、`MigrationRange`、`DeleteAll`、`DeleteBefore`、`EnsurePartitions`(仅 PG 预建)。
|
||
5. **双实现**:CH 委托 `analyticsrepo`;GORM 共用一套,方言 SQL 放 `dialect_*.go`。零值 id 用 `idgen.NextUint64ID()`。
|
||
6. **`buildStore`**:CH / GORM 两分支都挂上。
|
||
7. **写入**:独立 `batchwriter`;`FlushFunc` → `logstore.Active`。节点日志/可观测走 `SetAccessLogHooks` / `SetObservabilityHooks`,不要让 apps 碰 `ChConn`。
|
||
8. **切换任务**:`clearTarget` + `copy*` 增加该表;源数据不删,失败不翻转。
|
||
9. **清理**:访问类走 `log_retention_days_*`;性能指标走 `metric_retention_days`。不要擅自共用错误的 TTL。
|
||
10. **import-lint**:apps 新增对 `analytics` 或 `infra/persistence`(`batchwriter`/`idgen` 除外)的 import 必须失败。
|
||
|
||
## 禁止
|
||
|
||
- apps 直连 `analyticsrepo` / `db.ChConn` / `db.ChDB` 做日志读写
|
||
- 只建 CH、不建主库回落
|
||
- Handler 内逐条 `PrepareBatch`
|
||
- 业务表塞进 logstore
|
||
- 管理端改 `log_database` / `log_db_migration`
|
||
|
||
## 验证
|
||
|
||
```bash
|
||
go test ./internal/repository/logstore ./internal/repository/analytics
|
||
go test ./internal/apps/openflare/... ./internal/apps/admin/logs ./internal/apps/admin/status
|
||
make swagger
|
||
make code-check
|
||
```
|
||
|
||
对照:`of_node_access_logs` 或 `w_user_access_logs` 的 model、三库 goose、`logstore` 双实现、`chwriter`/`risk_control` flush、`LogDBSwitchHandler`。
|