
OpenObserve 数据库验证测试指南从 ingest 到 meta 表的端到端数据一致性校验【免费下载链接】openobserveOpen source observability platform for logs, metrics, traces, RUM, Session replay, pipelines, SLO and LLM observability. A sophisticated, simple and highly performant alternative to Datadog, Splunk, and Elasticsearch with 140x lower storage costs and single binary deployment.项目地址: https://gitcode.com/GitHub_Trending/op/openobserve导读OpenObserve 的元数据stream schema、stream 配置、file_list、组织与用户信息等统一持久化在后端元数据库中。tests/db-testing/目录提供了一套独立的 Pythonpytest测试套件先通过 OpenObserve 的 HTTP API 写入ingest数据再绕过 API 直接连接 PostgreSQL 元数据库查询meta、file_list等表用API 写入 数据库直查的双通道方式验证落库状态。本文基于仓库内 tests/db-testing/README.md 及配套源码完整讲解该套件的设计定位、本地搭建步骤、fixture 体系、测试编写范式、CI 集成方式并结合 meta 表真实建表语句 和 配置解析源码 展开底层原理帮助你快速上手并扩展这类数据库级校验测试。这套测试的定位为什么需要独立的 DB 校验层OpenObserve 仓库中已存在多种测试形态db-testing刻意与它们区分开测试形态位置关注点Rust 集成测试tests/integration_test.rs进程内组装各 crate 并驱动 HTTP/GRPC 路由验证功能链路不引入额外 CI 时长API 测试tests/api-testing/通过 HTTP API 验证端点行为、入参出参、业务语义DB 验证测试tests/db-testing/通过 API ingest 数据后直接查询元数据库验证底层状态是否符合预期三者的核心差异在于断言发生在哪一层API 测试断言响应体DB 测试断言数据库中的最终状态。DB 验证能捕捉到 API 层看起来成功但底层落库异常的问题——例如 schema 未创建、file_list 未登记、Tantivy 索引未生成等这些状态只有直查数据库才能确认。目录结构与依赖仓库中该测试套件的完整布局如下对应 README 中的结构说明tests/db-testing/ ├── README.md # 本套件的说明文档 ├── pyproject.toml # Python 项目配置rye 管理 ├── requirements.lock # 锁定依赖由 rye 生成/维护 └── tests/ ├── conftest.py # pytest fixtures 与配置 └── test_*.py # 测试文件依赖项在 pyproject.toml 中声明pytest7.4.0—— 测试框架requests2.31.0—— 用于调用 OpenObserve 的 ingest / search APIpsycopg2-binary2.9.9—— PostgreSQL 驱动用于直连元数据库python-dotenv1.0.0—— 环境变量管理便于从.env读取连接信息。项目要求 Python 3.11构建后端为 hatchlingpytest 配置中testpaths [tests]、python_files [test_*.py]即自动发现tests/下所有test_*.py文件中的test_*函数。本地运行三步启动一套可复现的 DB 测试环境1. 安装 rye 并构建 OpenObserverye 负责 Python 依赖的同步与管理对应 README 的安装方式curl -sSf https://rye.astral.sh/get | bash随后构建 OpenObserve 二进制对应 README 第 2 步cargo build --features mimalloc产物位于target/debug/openobserve。2. 启动 PostgreSQL 实例用 Docker 一键拉起测试库对应 README 第 3 步docker run -d \ --name postgres-test \ -e POSTGRES_PASSWORDpassword \ -p 5432:5432 \ postgres:17.5-alpine3.223. 启动 OpenObservePostgres 元数据后端并跑测试OpenObserve 通过环境变量选择元数据后端关键变量在 src/config/src/config.rs 中定义ZO_META_STORE—— 元数据存储后端设为postgresZO_META_POSTGRES_DSN—— PostgreSQL 连接串如postgres://postgres:passwordlocalhost:5432/postgresZO_ROOT_USER_EMAIL/ZO_ROOT_USER_PASSWORD—— 根用户凭据测试用它做 API 认证另有ZO_META_POSTGRES_HOST/ZO_META_POSTGRES_PORT/ZO_META_POSTGRES_USER/ZO_META_POSTGRES_PASSWORD/ZO_META_POSTGRES_DBNAME等拆分变量用于主机与密码需分别注入的环境如 ECS/K8s 密钥管理当ZO_META_POSTGRES_DSN已设置时这些拆分变量会被忽略源码注释明确说明。终端一启动服务export ZO_META_STOREpostgres export ZO_META_POSTGRES_DSNpostgres://postgres:passwordlocalhost:5432/postgres export ZO_ROOT_USER_EMAILrootexample.com export ZO_ROOT_USER_PASSWORDComplexpass#123 target/debug/openobserve终端二同步依赖并执行测试cd tests/db-testing rye sync # 按 requirements.lock 安装依赖 rye run pytest -v需要说明config.rs 中对 PostgreSQL 后端有强制校验——当ZO_META_STORE为 postgres 时必须提供ZO_META_POSTGRES_DSN或完整的拆分变量否则启动会失败并给出提示对应 config.rs 校验逻辑。这正是 README Troubleshooting 中connection refused / 表不存在问题的最常见根因。Fixture 体系conftest.py 提供的测试基础设施所有 fixture 定义在 tests/db-testing/tests/conftest.py 中README 列出的可用 fixture 与其一一对应Fixture作用域默认值 / 说明openobserve_base_urlsession默认http://localhost:5080可用ZO_BASE_URL覆盖auth_credentialssession从ZO_ROOT_USER_EMAIL/ZO_ROOT_USER_PASSWORD读取默认rootexample.com/Complexpass#123db_connectionsession从ZO_META_POSTGRES_DSN建立 psycopg2 连接autocommitTrue会话结束自动关闭db_cursorfunction基于db_connection的游标用完即关test_orgsession默认defaulttest_streamsession默认db_test_streamingest_test_datafunction返回内层函数_ingest(data, stream_nameNone)向POST {base}/api/{org}/{stream}/_json发送 JSON 数组断言 HTTP 200并在写入后调用wait_for_ingestion()等待落盘query_apifunction返回内层函数_query(sql, stream_name)向POST {base}/api/{org}/_search提交 SQL 查询自动附加过去 24 小时到未来 1 小时的微秒级时间窗口保证数据可被检索wait_for_ingestion当前实现是简单的time.sleep(5)conftest.py 第 64-66 行因为 ingest 是异步的——数据先进入 WAL/内存再被写入 Parquet 文件、更新 file_list 与索引。README Tips 中也强调等待 ingest 完成必要时可按需调大等待秒数。测试编写范式写入 → 直查 → 断言README 规定每个测试遵循三步结构对应示例通过 API ingest 数据直查元数据库验证状态断言数据库状态符合预期。仓库中的真实测试完整演示了这一范式下面拆解两个代表性用例。用例一验证 schema 落库test_stream_schema_created_in_db来自 tests/db-testing/tests/test_db_validation.pytest_data [{ timestamp: datetime.now(timezone.utc).isoformat(), message: Test log message, level: info, user_id: user123, }] ingest_test_data(test_data) stream_key flogs/{test_stream} db_cursor.execute( SELECT key1, key2, value FROM meta WHERE module schema AND key1 %s AND key2 %s , (test_org, stream_key)) results db_cursor.fetchall() assert len(results) 0, fSchema not found in database for stream {test_stream}要点meta表中module schema表示流 schema 记录key1存 org 标识key2存logs/{stream_name}形式的流路径value存放 JSON 序列化的 schema。测试断言 schema 行存在并将 schema JSON 打印出来便于排障——这正是写入后 schema 是否真正落库的直证。用例二校验 file_list 与 Tantivy 索引test_tantivy_indexes_updated这是套件中信息量最大的用例test_db_validation.py 第 87-177 行它验证的是数据链路下游的持久化状态向独立流ttv_testingest 50 条含log字段的记录log字段默认开启全文索引等待 20 秒让文件持久化与 Tantivy 索引完成直查file_list表流路径格式为{org}/logs/{stream_name}过滤deleted false断言每个文件index_size非零证明 Tantivy 索引真正生成且file_list 中 records 总数等于 ingest 条数证明数据量与落盘记录完全对账。该用例输出每个文件的records / index_size / original_size / compressed_size并打印 ✓ 形式的结果摘要是数据完整性对账的模板级参考。meta 表真实结构README 参考与源码的对应README 给出了meta表参考结构标注以实际 schema 为准而仓库源码 src/infra/src/db/postgres.rs 中的真实建表语句如下CREATE TABLE IF NOT EXISTS meta ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, module VARCHAR(100) not null, key1 VARCHAR(256) not null, key2 VARCHAR(256) not null, start_dt BIGINT not null, value TEXT not null );与 README 的参考结构相比真实表没有org_id列——org 标识承载在key1中测试代码中key1 test_org即为证据并额外包含start_dt记录生效起始时间。建表逻辑还会对旧版本 0.9.2自动补充start_dt列并创建module、modulekey1、modulekey1key2三组索引以加速按模块/组织的查询postgres.rs 索引创建段。SQLite 后端有结构等价但方言不同的建表语句src/infra/src/db/sqlite.rs。README 列出的常用module取值与仓库模块划分一致schema—— 流 schema用例一直接验证stream_settings—— 流配置file_list—— 文件元数据用例二直接验证organization—— 组织设置user—— 用户数据。CI 集成README 说明测试在 GitHub Actions 的db-testing.ymlworkflow 中自动运行触发条件为 push 到main分支以及针对任意分支的 pull request。流程为启动 PostgreSQL 服务容器构建 OpenObserve以 Postgres 元数据后端配置并启动 OpenObserve运行 pytest失败时上传日志供排查。这与本地运行步骤一一对应即本地可复现 → CI 自动化的设计闭环。最佳实践与排障速查README Tips 部分归纳的实践要点结合源码可进一步理解其缘由需要清理时使用事务fixture 已处理大部分清理工作但meta是共享表事务可保证测试间互不污染等待 ingest 完成ingest 是异步链路内存 → WAL → 文件 → file_list/索引wait_for_ingestion()是必要等待勿直接断言善用print()调试测试中大量打印 schema JSON 与文件统计便于在 CI 日志中定位问题测试隔离每个测试应独立运行、不依赖其他测试的执行顺序共享库注意唯一性所有测试查询同一个共享数据库必要时使用唯一的 stream 名如ttv_test避免数据交叉。常见故障对照表对应 README Troubleshooting症状排查方向connection refusedPostgreSQL 是否在运行、端口是否映射核对ZO_META_POSTGRES_DSNtable not foundOpenObserve 可能尚未初始化 schema检查启动日志中的迁移错误迁移适配器见 src/migration/adapter/测试超时调大wait_for_ingestion()的等待秒数确认 OpenObserve 进程健康从源码看扩展方向README 的 Future Enhancements 列出了后续计划SQLite 后端测试、数据压缩compaction测试、schema 演进测试、多租户测试、性能/压测、备份恢复测试。从仓库现状看这些方向都已具备落地基础SQLite 后端已存在于 src/infra/src/db/sqlite.rs迁移适配器也同时支持 postgres 与 sqlitesrc/migration/adapter/mod.rs新增 backend 测试时只需按同样范式替换连接 fixture压缩、保留策略等后台任务在 src/compaction/ 中实现file_list 对账模式用例二可直接复用到压缩产物的校验多租户只需让ingest_test_data支持动态 orgtest_orgfixture 已按 org 维度组织断言。小结tests/db-testing/是 OpenObserve 质量体系中的状态层校验器它不与 Rust 集成测试、API 测试重复而是专门验证API 成功背后元数据库状态是否真实正确。掌握这套套件意味着你拥有了一个可复用的写入 → 直查 → 断言测试模板可以低成本扩展出 schema 演进、索引完整性、数据对账、多租户隔离等深度校验用例为 OpenObserve 的数据链路提供数据库级的可观测性与回归保障。【免费下载链接】openobserveOpen source observability platform for logs, metrics, traces, RUM, Session replay, pipelines, SLO and LLM observability. A sophisticated, simple and highly performant alternative to Datadog, Splunk, and Elasticsearch with 140x lower storage costs and single binary deployment.项目地址: https://gitcode.com/GitHub_Trending/op/openobserve创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考