feat: 添加 G5 独立写入功能

- 新增 G5 数据库连接配置与可关闭的写入开关
- 在现有 legacy/G4 写入成功路径后,追加独立的 G5 写入流程
- G5 使用与 G4 相同的数据结构映射,但不写入 guid,由数据库自生成 int4 guid
- room_status 新增 G5 独立 upsert 写入路径,并保留旧表与 G5 表的独立开关
- 新增 G5 写入统计与启动摘要输出
- 更新 StatsCounters 和 StatsReporter 以支持 G5 统计
- 增加测试覆盖,确保 G5 写入逻辑与 room_status 的独立执行
- 新增 G5 相关数据库表结构 SQL 文件
This commit is contained in:
2026-03-10 16:29:24 +08:00
parent fe76884b27
commit 2f8857f98e
14 changed files with 924 additions and 130 deletions

View File

@@ -9,28 +9,36 @@ describe('StatsCounters', () => {
stats.incFiltered(2);
stats.incKafkaPulled(5);
stats.incDbWriteFailed(4);
stats.incG5Written(6);
stats.incG5WriteFailed(1);
const first = stats.snapshotAndResetMinute();
assert.equal(first.dbWritten, 3n);
assert.equal(first.filtered, 2n);
assert.equal(first.kafkaPulled, 5n);
assert.equal(first.dbWriteFailed, 4n);
assert.equal(first.g5Written, 6n);
assert.equal(first.g5WriteFailed, 1n);
const second = stats.snapshotAndResetMinute();
assert.equal(second.dbWritten, 0n);
assert.equal(second.filtered, 0n);
assert.equal(second.kafkaPulled, 0n);
assert.equal(second.dbWriteFailed, 0n);
assert.equal(second.g5Written, 0n);
assert.equal(second.g5WriteFailed, 0n);
});
});
describe('StatsReporter', () => {
it('writes three [STATS] info logs to redis console', () => {
it('writes all [STATS] info logs to redis console', () => {
const stats = new StatsCounters();
stats.incDbWritten(7);
stats.incFiltered(8);
stats.incKafkaPulled(9);
stats.incDbWriteFailed(2);
stats.incG5Written(5);
stats.incG5WriteFailed(1);
const calls = { push: [] };
const redis = {
@@ -43,17 +51,19 @@ describe('StatsReporter', () => {
const reporter = new StatsReporter({ redis, stats });
reporter.flushOnce();
assert.equal(calls.push.length, 9);
assert.equal(calls.push.length, 11);
for (const c of calls.push) assert.equal(c.level, 'info');
assert.match(calls.push[0].message, /Legacy写入量: 7条$/);
assert.match(calls.push[1].message, /Legacy写入失败量: 2条$/);
assert.match(calls.push[2].message, /G4Hot写入量: 0条$/);
assert.match(calls.push[3].message, /G4Hot写入失败量: 0条$/);
assert.match(calls.push[4].message, /RoomStatus写入量: 0条$/);
assert.match(calls.push[5].message, /RoomStatus失败量: 0条$/);
assert.match(calls.push[6].message, /G4Hot错误表插入量: 0条$/);
assert.match(calls.push[7].message, /数据过滤量: 8条$/);
assert.match(calls.push[8].message, /Kafka拉取量: 9条$/);
assert.match(calls.push[4].message, /G5写入量: 5条$/);
assert.match(calls.push[5].message, /G5写入失败量: 1条$/);
assert.match(calls.push[6].message, /RoomStatus写入量: 0条$/);
assert.match(calls.push[7].message, /RoomStatus失败量: 0条$/);
assert.match(calls.push[8].message, /G4Hot错误表插入量: 0条$/);
assert.match(calls.push[9].message, /数据过滤量: 8条$/);
assert.match(calls.push[10].message, /Kafka拉取量: 9条$/);
});
});