OpenObserve HTTP API 组合根openobserve-api-http架构解析领域拆分、路由装配与中间件链【免费下载链接】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 仓库中的openobserve-api-httpcrate——它是服务端二进制中唯一的 HTTP 传输层组合根composition root负责把相互独立的 API 领域 crate、路由器、OpenAPI 文档与限流路径映射组装成可运行的 HTTP 服务。读完本文你将掌握 OpenObserve API 层的四大业务域划分原则、新增接口时的归属决策规则以及 HTTP 服务从启动、路由装配到认证/审计/限流中间件链的完整源码实现路径。一、什么是 openobserve-api-http唯一允许聚合 API crate 的层次依据 src/api/http/README.mdopenobserve-api-http被明确定义为HTTP 传输组合根它组合服务端二进制所依赖的独立 API crate、路由器、OpenAPI schema 以及限流rate-limit路径映射。整个 API 层被划分为四个业务域 crate各司其职Crate职责范围openobserve-api-ingest日志、指标、trace/OTLP、RUM 与集群cluster数据摄取openobserve-api-search搜索、日志 pattern 提取、PromQL、trace 查询、saved-view 与 search-job APIopenobserve-api-pipelinespipelines、functions、enrichment tables 与可复用的正则转换 patternopenobserve-api-managementalerts、dashboards、organizations、users、streams、actions、AI、节点与平台管理以及其他控制面control-planeAPI另有两个支撑 crate 不拥有业务域openobserve-api-common承载共享 HTTP 类型、extractor 与认证逻辑openobserve-core承载应用服务与业务逻辑。这一分组在 src/api/README.md 中有同样完整的概述其中明确写着一句话The http crate is the composition rootHTTP crate 是组合根。二、核心约束API crate 之间禁止互相依赖文档给出的最重要设计纪律是API crates must not depend on one another. Cross-domain behavior belongs in a non-API shared crate such asopenobserve-core,common,audit, oropenobserve-api-common. This crate is the only layer that aggregates API crates.即四个业务域 crate 相互之间不得依赖。跨域行为必须下沉到非 API 的共享 crateopenobserve-core、common、audit、openobserve-api-common等中实现openobserve-api-http是唯一将各 API crate 聚合起来的层次。这从依赖关系上杜绝了业务域之间的循环耦合让 ingest / search / pipelines / management 可以独立演进与编译。从 Cargo.toml 可以验证这一设计openobserve-api-http的依赖列表同时引入了openobserve-api-ingest、openobserve-api-management、openobserve-api-pipelines、openobserve-api-search、openobserve-api-common与openobserve-core这正是组合根汇聚一切的体现。三、新增 API 时如何选择归属 crate四条决策规则文档给出了一套非常实用的放置准则当你要在 OpenObserve 上新增一个接口时按资源主要归属来选择 crate进入 OpenObserve 的数据→src/api/ingest读取或查询已存储的可观测数据→src/api/search数据转换与处理配置→src/api/pipelinesCRUD、管理、自动化、alerts、dashboards、stream 与节点管理、健康检查、认证与配置→src/api/management。关于共享代码的边界文档进一步规定被两个及以上 API crate 使用的代码只有当它是传输层专属transport-specific时才放入openobserve-api-common共享的业务行为放入openobserve-core共享的元数据与通用工具放入common业务端点永远不允许放进 common crate。这意味着 common crate 只应是HTTP 传输层的口袋任何承载真实业务语义的 handler 都必须落在对应域 crate 或openobserve-core中。该 crate 本身是内部 workspace cratepublish false不会独立发布新的业务逻辑通常应在openobserve-core实现让openobserve-api-http专注于 HTTP 传输装配。四、源码纵深从 main.rs 到 HTTP 服务的启动链路组合根并非只在文档层面存在。在 src/main.rs 中服务端二进制正是通过如下调用把 HTTP 服务拉起来的// init http server if let Err(e) openobserve_api_http::server::run(web::ui_routes).await { log::error!(HTTP server runs failed: {e}); }这里web::ui_routes是一个函数指针fn(str) - axum::Router对应 src/web/src/ui.rs 中定义的 UI 路由工厂。设计上刻意让 API crate 不依赖 web crate也不依赖configcrateUI 路由工厂由二进制注入base href值由调用方解析后传入。4.1 监听地址解析server_addrserver.rs 中的server_addr()依据配置决定监听地址若cfg.http.ipv6_enabled为 true监听[::]:{port}否则取cfg.http.addr为空时默认0.0.0.0拼上cfg.http.port。4.2 通用中间件apply_common_middlewaresserver.rs 中apply_common_middlewares依次挂载AccessLogLayer访问日志格式由get_http_access_log_format()决定SlowLogLayer慢请求日志阈值为cfg.limit.http_slow_log_thresholdextract_real_ip真实客户端 IP 提取来源由cfg.http.real_ip_source解析隐式回退到 ConnectInfo在路由外层再叠加CompressionLayer响应压缩与可选的TraceLayertower-http 追踪层受 tracing 相关配置控制。4.3 TLS 与优雅关闭serve shutdown_signalserve() 使用axum-server提供服务当cfg.http.tls_enabled时从tls_cert_path/tls_key_path加载 PEM 证书走bind_rustls否则走普通bind。同时监听SIGQUIT/SIGTERM/SIGINTWindows 下对应 ctrl-break / ctrl-c / ctrl-close / ctrl-shutdown触发handle.graceful_shutdown(Some(Duration::from_secs(max(1, shutdown_timeout))))的有界优雅关闭随后调用common::infra::cluster::set_offline()将节点标记为 offline——保证流量摘除与数据一致性。五、路由装配create_app_router 与四大路由集合组合根的核心路由逻辑位于 handler/http/router/mod.rs 的create_app_router。它依据节点角色分派Router 节点LOCAL_NODE.is_router()合并crate::router::http::create_router_routes()生成的代理路由将请求转发到后端节点、/config路由与proxy_routes(true)并企业版叠加RateLimitLayer非 Router 节点挂载basic_routes()、/config、/api即service_routes()、other_service_routes()与proxy_routes(true)。最后统一处理base_uri非空时整体 nest并补充尾斜杠重定向与 UI 挂载ui_enabled时把/web挂到base_uri/web/根路径/永久重定向到该路径。请求体大小上限由DefaultBodyLimit::max(cfg.limit.req_payload_limit)控制。5.1 basic_routes健康检查与免认证平面basic_routes() 提供不需要走统一认证的端点健康检查/healthz、/schedulez、/metricsPrometheus 格式OAuth/OIDC 元数据/.well-known/oauth-authorization-server、/.well-known/oauth-protected-resourceRFC 9728 路径后缀形式/auth下的登录、预签名 URL、邀请相关路由/node下的节点管理路由带认证Swagger UIswagger_enabled时挂载见下节与/docs永久重定向无状态告警图表渲染/api/v2/{org_id}/alerts/charts/renderURL 内 HMAC 签名自校验外部告警源 webhook/api/v2/{org_id}/incidents/eventshandler 内部做 token 校验公开状态页/api/status_pages_public/{slug}*与/status/{slug}synthetics.enabled时注册。5.2 service_routes主 API 面service_routes() 是体量最大的路由集合源码中约 700 行以/{org_id}为前缀组织涵盖组织与用户/{org_id}/users、/{org_id}/settings、/{org_id}/settings/v2、/{org_id}/ingestion-tokens等ES 兼容层/{org_id}/、/{org_id}/_license、/{org_id}/_xpack、/{org_id}/_ilm/policy/{name}、/{org_id}/_index_template/{name}等Streams 管理/{org_id}/streams全套 CRUD 与字段/schema/缓存清理摄取端点/{org_id}/_bulk、/{org_id}/{stream_name}/_multi、/_json、/_hec、Loki push、OTLP logs/metrics/profiles/traces 写入查询端点/{org_id}/_search、/_search_multi、/{org_id}/{stream_name}/_around、/_values、saved views、search historyPromQL/{org_id}/prometheus/api/v1/*全家族query、query_range、exemplars、metadata、series、labels 等Pipelines 与 backfill、functions、enrichment tables、re_patterns企业版Alerts / incidents / templates / destinations / deduplication、dashboards / reports / annotations、SLOs、synthetics 与状态页管理KV store、folders、roles/groupsFGA 授权、cipher keys、MCP 端点/{org_id}/mcp、sourcemaps、LLM model pricing 等。源码注释中还体现了路由注册顺序的硬性经验命名路由必须先于{id}通配路由注册例如/{org_id}/slos/move必须先于/{org_id}/slos/{slo_id}否则move会被解析成 SLO id以及静态与嵌套路由必须排在/{entity_id}之前。5.3 other_service_routesAWS / GCP / RUM 兼容通道other_service_routes() 分别挂载/aws/{org_id}/{stream_name}/_kinesis_firehoseAWS Kinesis Firehose 兼容/gcp/{org_id}/{stream_name}/_subGCP Pub/Sub 兼容/rum/v1/{org_id}/logs|replay|rumRUM 摄取。三者均使用各自的认证中间件aws_auth_middleware/gcp_auth_middleware/rum_auth_middleware并统一经过RequestDecompressionLayergzip/deflate/brotli与 snappy 预处理。六、中间件链认证、审计与请求预处理service_routes()底部按注释顺序给主 API 面叠加了完整的中间件链router/mod.rsblocked_orgs_middleware → audit_middleware → auth_middleware → RequestDecompressionLayer → preprocess_encoding_middleware → Server 响应头 → CORS要点如下认证中间件auth_middleware先同步提取RequestDataURI/method/headers再用AuthExtractor::from_request_parts解析认证信息最后经oo_validator校验通过后把user_id头注入下游 handler同时还处理 Prometheus POST 缺 Content-Type 的兼容 hack。对 MCP 端点/{org_id}/mcp的 401 响应会附加 RFC 9728 的WWW-Authenticate: Bearer resource_metadata...头企业版且 Dex 开启时引导 MCP 客户端走 OAuth 流程。审计中间件企业版audit_middleware在audit_enabled且非摄取写入路径如_stream结尾、ai/chat_stream、is_ingestion_write时记录请求体、查询参数、响应码与user_id并通过audit(AuditMessage { ... })落审计事件。特别地remote task 的 secret 写入路径auth/headers/signing会被脱敏为[REDACTED: remote task secret write]避免审计日志成为秘密的第二份明文副本。代理 SSRF 防护proxyhandler 在发起请求前先经common::utils::ssrf_guard::SsrfGuard::validate_url_with_config_async校验目标 URL含 DNS 解析并使用build_safe_client构建 reqwest 客户端重定向链与连接期 DNS 也会被再次校验。CORS 白名单cors_layer()默认只放行web_url对应的 schemehostport忽略 path按 RFC 6454 的 Origin 语义做字节级精确比较防止https://app.example.com.evil.com前缀匹配绕过额外来源可通过ZO_CORS_ALLOWED_ORIGINS逗号分隔追加web_url未配置时开发环境降级为全放行并输出警告日志。七、OpenAPI 文档生成与 Swagger UIopenobserve-api-http同时承担 OpenAPI schema 生成职责lib.rs 的 crate 级注释即写明 HTTP transport composition root, including OpenAPI schema generation。handler/http/router/openapi.rs 通过 utoipa 的#[derive(OpenApi)]声明式汇总上百条pathshealthz、users、organizations、streams、ingest、PromQL、traces、dashboards、alerts、incidents、folders、functions、pipeline、reports、SLOs、synthetics、MCP 等大量components.schemas来自config::meta::*与各域 crate 的 models20 个tags分组Meta、Auth、Logs、Search、Alerts、Incidents、AI、Metrics、Traces、Patterns、Synthetics 等SecurityAddon修改器动态注入AuthorizationAPI Key Header与BasicAuth两种安全方案并按base_uri覆盖servers。企业版还通过EnterpriseExperimentApiDoc把 experiments/playground/remote_tasks 等端点合并进同一份文档。OpenAPI 文档在swagger_enabled时挂载于/swaggerJSON 位于/api-doc/openapi.json/docs会 302 到 Swagger UI。仓库内还带有对应的单元测试如folder_scoped_writes_document_forbidden见 openapi.rs断言文件夹级写操作必须声明 403 响应否则客户端无法与接口 bug区分。此外企业版限流初始化o2_ratelimit::init正是复用openapi_info()生成的接口信息来做默认限流规则映射见 main.rs。八、特性开关与编译边界Cargo.toml 展示了该 crate 的 feature 矩阵它们会级联透传到各 API crate 与openobserve-coreenterprise引入o2_dex、o2_enterprise、o2_ratelimit并给 ingest/management/pipelines/search/common/core/stream 全部打上 enterprise 标记cloud隐含 enterprise追加云计费、AWS/Azure marketplace、邀请与账单等路由vectorscan透传到搜索相关 crateprofiling开启 memory/cpu profile 与 jemalloc stats 调试端点。publish false进一步确认了它内部装配层、不对外发布的定位。路由源码中大量#[cfg(feature enterprise)]/#[cfg(feature cloud)]区块如 AI、workflows、search_jobs、domain_management、synthetics job lease 等与上述 feature 一一对应OS 构建下这些端点直接不注册404而非 403——这是无此端点与无许可两种语义的刻意区分。九、总结组合根的分层哲学纵观 src/api/http/README.md 与上述源码openobserve-api-http体现的分层哲学可以概括为三条域内聚合ingest / search / pipelines / management 四个域 crate 各自内聚互不依赖跨域行为下沉到openobserve-core、common、audit等非 API crate传输与业务分离openobserve-api-common只放传输专属的共享代码业务端点绝不进入 common新的业务逻辑一律进openobserve-core单一组合点只有openobserve-api-http有权聚合所有 API crate统一完成路由注册、中间件装配、OpenAPI 生成与限流映射使服务端二进制main.rs只需一行调用即可拉起完整的 HTTP 前端。对于希望为 OpenObserve 贡献新接口的开发者本文给出的决策路径是先按资源归属选定域 crate再在 handler/http/router/mod.rs 的service_routes()或basic_routes()中注册路由注意命名路由先于通配路由的顺序并在 openapi.rs 中补充 OpenAPI 声明即可让新端点同时获得认证、审计、限流与文档化能力。【免费下载链接】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),仅供参考