Files
seqlog/seqlog.go
bourdon 90cc9e21c9 重构:重命名核心组件并增强查询功能
主要更改:

1. 核心重命名
   - Seqlog -> LogHub (更准确地反映其作为日志中枢的角色)
   - NewSeqlog() -> NewLogHub()
   - LogCursor -> ProcessCursor (更准确地反映其用于处理场景)
   - seqlog_manager.go -> loghub.go (文件名与结构体名对应)

2. TopicProcessor.Reset 增强
   - 如果正在运行且没有待处理的日志,会自动停止后重置
   - 如果有待处理的日志,返回详细错误(显示已处理/总记录数)
   - 简化了 LogHub.ResetTopic,移除显式 Stop 调用

3. 新增查询方法
   - TopicProcessor.QueryFromFirst(count) - 从第一条记录向索引递增方向查询
   - TopicProcessor.QueryFromLast(count) - 从最后一条记录向索引递减方向查询
   - LogHub.QueryFromFirst(topic, count)
   - LogHub.QueryFromLast(topic, count)

4. 测试覆盖
   - 添加 query_test.go - QueryFromProcessing 测试
   - 添加 TestQueryFromFirstAndLast - TopicProcessor 查询测试
   - 添加 TestLogHubQueryFromFirstAndLast - LogHub 查询测试
   - 添加 TestTopicResetWithPendingRecords - Reset 增强功能测试

5. 示例代码
   - 添加 example/get_record/ - 演示 QueryFromProcessing 用法
   - 更新所有示例以使用 LogHub 和新 API

所有测试通过 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-04 13:26:21 +08:00

83 lines
2.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package seqlog
import "github.com/google/uuid"
// seqlog 是一个 Go 语言日志收集和处理库
//
// 核心特性:
// - 单文件日志处理:专注于单个日志文件的读取和处理
// - 游标尺机制:通过游标跟踪日志文件的读取位置,支持断点续读
// - 自动恢复:程序重启时自动发现已存在的日志文件并从上次位置继续处理
// - 日志收集:提供高效的日志收集和解析能力
// - tail -f 模式:支持持续监控日志文件的新增内容
// - UUID 去重:每条日志自动生成唯一 UUID便于外部去重
// - slog 集成:内置 slog.Logger 支持,提供结构化日志记录
// - 统计功能:提供可恢复的统计信息,包括写入/处理次数、字节数、错误计数等
// - 双向查询:支持基于当前处理位置的向前/向后查询,自动标注记录状态
// - 事件通知:支持订阅各种事件(写入、处理、启动、停止等),实时状态变化通知
//
// 使用示例:
//
// // 写入日志
// writer, _ := seqlog.NewLogWriter("app.log")
// offset, _ := writer.Append([]byte("log message"))
//
// // 读取日志
// cursor, _ := seqlog.NewCursor("app.log")
// defer cursor.Close()
// for {
// rec, err := cursor.Next()
// if err != nil {
// break
// }
// // rec.UUID 是自动生成的唯一标识符,可用于去重
// fmt.Printf("UUID: %s, Data: %s\n", rec.UUID, string(rec.Data))
// }
//
// // tail -f 模式
// handler := func(rec *Record) error {
// fmt.Println(string(rec.Data))
// return nil
// }
// tailer, _ := seqlog.NewTailer("app.log", handler, nil)
// tailer.Start()
//
// // 使用 LogHub 管理器(带 slog 支持和自动恢复)
// logger := slog.Default()
// handler := func(topic string, rec *seqlog.Record) error {
// fmt.Printf("[%s] %s\n", topic, string(rec.Data))
// return nil
// }
// seq := seqlog.NewLogHub("/tmp/logs", logger, handler)
// seq.Start() // 自动发现并恢复已存在的日志文件
// seq.Write("app", []byte("application log"))
//
// // 获取统计信息
// stats, _ := seq.GetTopicStats("app")
// fmt.Printf("写入: %d 条, %d 字节\n", stats.WriteCount, stats.WriteBytes)
//
// // 查询记录
// query, _ := seq.NewTopicQuery("app")
// defer query.Close()
// current, _ := query.GetCurrent() // 获取当前处理位置
// backward, _ := query.QueryBackward(5) // 向后查询 5 条
// forward, _ := query.QueryForward(5) // 向前查询 5 条
//
// // 订阅事件
// seq.Subscribe("app", seqlog.EventWriteSuccess, func(event *seqlog.Event) {
// fmt.Printf("写入成功: offset=%d\n", event.Position)
// })
//
// seq.Stop()
// Record 日志记录
//
// 存储格式:[4B len][4B CRC][16B UUID][data]
// 注意Offset 不存储在数据文件中,而是由索引文件管理
type Record struct {
Len uint32 // 数据长度
CRC uint32 // CRC 校验和
UUID uuid.UUID // UUID用于去重
Data []byte // 实际数据
}