开源可观测性平台SigNoz实战:基于OpenTelemetry与ClickHouse的一体化监控方案
1. 项目概述从“可观测性”的痛点说起如果你在运维一个稍微有点规模的线上服务或者正在开发一个微服务架构的应用那么下面这个场景你一定不陌生凌晨三点监控告警响了CPU使用率飙升。你打开监控面板看到某个节点的CPU曲线确实冲到了90%但问题是哪个服务、哪个接口、哪段代码导致的你只能凭经验去猜是数据库查询慢了还是某个外部API调用超时了接着你需要在日志系统里大海捞针在链路追踪工具里翻找可疑的调用链在指标系统里核对各种关联数据。几个工具来回切换信息支离破碎定位问题的黄金时间就在这种“拼图游戏”中白白流逝了。这就是传统监控体系下“可观测性”的典型困境指标Metrics、日志Logs、追踪Traces三大支柱数据相互割裂。我们缺的不是工具而是一个能将这三者有机融合、提供统一分析视角的平台。这也是为什么当我第一次接触到SigNoz这个开源项目时会感到眼前一亮。SigNoz 将自己定位为Datadog、New Relic 的开源替代方案其核心目标就是构建一个统一的可观测性平台让你在一个界面里就能完成从宏观指标异常下钻到具体错误日志和慢追踪的全链路分析。简单来说SigNoz 是一个集成了指标监控、分布式链路追踪、日志聚合与分析的全栈可观测性解决方案。它采用OpenTelemetry作为数据采集和标准化的基石后端使用ClickHouse作为高性能的时序数据存储前端则提供了一个功能丰富、类似 Grafana 但更专注于可观测性场景的查询与分析界面。对于中小团队、创业公司或者任何希望以可控成本甚至是零成本获得强大可观测性能力的开发者而言SigNoz 提供了一个极具吸引力的选择。2. 核心架构与设计哲学拆解要理解 SigNoz 为什么能成为 Datadog 的有力挑战者我们必须深入其架构设计。它的设计哲学非常清晰拥抱标准、专注性能、一体化体验。2.1 基石OpenTelemetry 的全面拥抱这是 SigNoz 最明智也最具前瞻性的选择。OpenTelemetry简称 OTel是由 CNCF 孵化的项目旨在为可观测性数据指标、日志、追踪提供一套统一的标准 API、SDK 和采集器。在过去你要接入 Jaeger追踪、Prometheus指标、Fluentd日志可能需要三套不同的客户端库和代理配置复杂数据格式也不互通。SigNoz 从设计之初就将 OTel 作为一等公民。这意味着采集无痛你的应用只需要集成 OTel SDK通过配置就可以将追踪、指标、日志通过 OTel Logs Bridge统一发送到 SigNoz。这大大降低了接入成本和技术栈复杂度。数据关联OTel 规范定义了贯穿整个请求链路的trace_id和span_id。当 SigNoz 后端收到这些数据时它能天然地将同一个请求的追踪 spans、该请求过程中产生的日志、以及由此聚合出的服务指标如请求延迟、错误率关联在一起。这是实现“一键下钻”能力的根本。未来兼容随着 OTel 标准的不断成熟和普及任何遵循该标准的应用或中间件都能轻松地将数据接入 SigNoz保证了平台的长期生命力和扩展性。注意虽然 SigNoz 强烈推荐使用 OTel但它并非强制。其采集器OpenTelemetry Collector也支持接收 Jaeger、Zipkin 等格式的追踪数据以及 Prometheus 格式的指标。不过要获得最佳的一体化体验OTel 是最推荐的路径。2.2 引擎ClickHouse 作为存储核心可观测性数据是典型的时间序列数据且数据量巨大尤其是追踪和日志查询模式复杂既有实时聚合也有历史下钻。SigNoz 没有选择 Elasticsearch传统日志方案或 Prometheus Thanos传统指标方案而是选择了ClickHouse作为统一的存储后端。这个选择背后有深刻的考量极高的压缩比ClickHouse 的列式存储和高效的压缩算法能将对存储空间要求极高的追踪和日志数据压缩 10 倍甚至更多。这直接降低了硬件成本和长期存储的可行性。恐怖的查询性能对于可观测性场景中常见的聚合查询如“过去5分钟服务A的错误率”、“按接口分组统计P99延迟”ClickHouse 的向量化执行引擎和预聚合能力通过物化视图能提供亚秒级的响应速度。这对于交互式排查问题至关重要。SQL 的强大与灵活ClickHouse 支持标准的 SQL 方言。这意味着 SigNoz 的前端查询能力非常强大用户可以通过相对熟悉的 SQL 语法进行灵活的数据探索和自定义查询降低了学习成本也提高了平台的灵活性。当然这个选择也有代价。ClickHouse 的写入吞吐虽然很高但对高频、小批量的实时写入不如 Elasticsearch 优化得那么极致。SigNoz 通过使用 Kafka或 Redpanda作为缓冲队列来解耦数据接收和写入完美解决了这个问题。数据先进入队列再由 SigNoz 的流水线服务消费并批量写入 ClickHouse既保证了可靠性又发挥了 ClickHouse 的批量写入优势。2.3 界面一体化的前端设计SigNoz 的前端不是 Grafana 的简单套壳。它是为可观测性量身定做的。其界面逻辑紧密围绕Metrics、Traces、Logs 的关联分析来设计。服务仪表盘Service Dashboard这是你的首页。直观地展示所有服务的关键黄金指标请求速率RPS、错误率、平均响应时间Avg Duration和P99/P95延迟。点击任何一个服务即可进入该服务的专属视图。追踪Traces浏览器这里你可以查看所有的分布式追踪。强大的过滤功能让你可以按服务、操作、状态码、持续时间甚至自定义标签来筛选。最关键的是当你点击一个缓慢或错误的追踪Span时右侧会直接关联展示该 Span 时间段内在相同服务/实例上产生的所有日志。无需跳转上下文一目了然。日志Logs管理虽然 SigNoz 的日志功能相对 Traces 和 Metrics 晚一些但发展迅速。支持基于trace_id的日志查询是核心亮点。你可以在日志面板直接输入trace_idxxxx找到该次请求的全部日志。反之在查看日志时如果该日志包含trace_id也可以一键跳转到对应的完整追踪链路。指标Metrics查询器提供类似 PromQL 的查询界面但底层查询会转换为对 ClickHouse 的 SQL 查询。你可以在这里定义自定义的监控图表和告警规则。这种设计将“可观测性”从一个概念落地为一种流畅的操作体验。你不再是在三个独立的工具间传递trace_id而是在一个平台内完成自然的上下文切换。3. 从零开始部署与核心配置实战理论说得再多不如亲手部署一遍。SigNoz 提供了极其友好的入门方式特别是对于本地开发和测试。3.1 快速本地部署Docker Compose 方案对于大多数想尝鲜和评估的个人开发者或小团队Docker Compose 是最快的方式。SigNoz 官方维护了一个功能完整的docker-compose.yaml文件。# 1. 克隆仓库选择稳定版本如 v0.28.0 git clone -b v0.28.0 https://github.com/SigNoz/signoz.git cd signoz/deploy/docker/clickhouse-setup # 2. 启动所有服务 docker-compose -f docker-compose.yaml up -d这个命令会启动一整套服务包括otel-collector: OpenTelemetry 收集器接收应用数据。clickhouse: 存储所有可观测性数据。query-service: 后端查询服务处理前端请求。frontend: SigNoz 的 Web 界面。alertmanager和alerts-service: 告警相关服务。redis: 缓存。启动完成后访问http://localhost:3301就能看到 SigNoz 的登录界面。首次使用你需要用默认邮箱adminsignoz.io和密码admin注册一个管理员账户。实操心得在本地运行尤其是 Mac 或 Windows 上可能会因为 Docker 资源限制导致 ClickHouse 启动缓慢或失败。如果前端一直无法连接可以查看clickhouse容器的日志docker logs signoz-clickhouse -f确保它已完全启动并监听端口。建议为 Docker Desktop 分配至少 4GB 内存。3.2 生产环境部署考量Docker Compose 适合单机测试但对于生产环境你需要考虑高可用、可扩展性和数据持久化。官方推荐使用Kubernetes Helm Chart进行部署。# 添加 SigNoz Helm 仓库 helm repo add signoz https://charts.signoz.io helm repo update # 安装 SigNoz helm install my-signoz signoz/signoz -n platform --create-namespace生产部署的关键配置点存储必须为 ClickHouse 配置持久化存储卷PersistentVolume否则数据在 Pod 重启后会丢失。在 Helm values 中配置clickhouse.persistence.enabledtrue并指定 storageClass。资源限制根据数据量预估为clickhouse、query-service等核心组件设置合理的resources.requests/limits。ClickHouse 是内存和CPU消耗大户。高可用对于核心服务如otel-collector、query-service可以通过设置replicaCount: 2来实现简单的多副本。更复杂的高可用需要规划 ClickHouse 集群分片与复制目前 SigNoz 的 Helm Chart 对 ClickHouse 集群的支持还在完善中大型部署可能需要自行维护 ClickHouse 集群。数据保留策略可观测性数据量增长很快。需要在 SigNoz 前端界面Settings - General - Retention Period或直接配置 ClickHouse 的 TTLTime To Live来设置不同数据的保留时间。例如追踪数据保留7天指标聚合数据保留30天。3.3 应用接入以 Go 和 Python 应用为例部署好平台下一步就是让应用数据“流”进来。我们以最典型的 Go 和 Python 微服务为例。Go 应用接入package main import ( go.opentelemetry.io/otel go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc go.opentelemetry.io/otel/propagation go.opentelemetry.io/otel/sdk/resource sdktrace go.opentelemetry.io/otel/sdk/trace semconv go.opentelemetry.io/otel/semconv/v1.17.0 ) func initTracer() func() { // 1. 创建 OTLP gRPC 导出器指向 SigNoz 的 Collector exporter, err : otlptracegrpc.New(context.Background(), otlptracegrpc.WithEndpoint(localhost:4317), // SigNoz Collector 默认端口 otlptracegrpc.WithInsecure(), // 生产环境应使用 TLS ) if err ! nil { log.Fatal(err) } // 2. 创建资源标识描述你的服务 res, _ : resource.Merge( resource.Default(), resource.NewWithAttributes( semconv.SchemaURL, semconv.ServiceName(your-go-service), semconv.ServiceVersion(1.0.0), attribute.String(environment, demo), ), ) // 3. 创建 Tracer Provider tp : sdktrace.NewTracerProvider( sdktrace.WithBatcher(exporter), sdktrace.WithResource(res), ) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) // 返回一个关闭函数用于程序退出时刷新数据 return func() { if err : tp.Shutdown(context.Background()); err ! nil { log.Printf(Error shutting down tracer provider: %v, err) } } } func main() { shutdown : initTracer() defer shutdown() // 你的业务代码... tr : otel.Tracer(example-tracer) ctx, span : tr.Start(context.Background(), my-operation) defer span.End() // ... 执行操作 }Python (Django/Flask) 应用接入对于 Python通常使用自动插桩Auto-instrumentation来最小化代码侵入。# 1. 安装必要的包 pip install opentelemetry-distro opentelemetry-exporter-otlp pip install opentelemetry-instrumentation-flask opentelemetry-instrumentation-requests # 2. 通过环境变量配置并自动运行你的应用 export OTEL_SERVICE_NAMEyour-python-service export OTEL_EXPORTER_OTLP_ENDPOINThttp://localhost:4317 # HTTP 协议对应 4318 端口。gRPC 用 4317。 export OTEL_EXPORTER_OTLP_PROTOCOLhttp/protobuf # 使用 opentelemetry-bootstrap 自动安装所有检测库 opentelemetry-bootstrap -a install # 3. 用 opentelemetry-instrument 包装命令启动你的应用 opentelemetry-instrument --traces_exporter otlp --metrics_exporter otlp \ python your_app.py接入后访问你的应用接口然后去 SigNoz 的Traces页面应该就能看到相关的追踪数据了。指标数据如 HTTP 请求数、延迟也会被自动捕获。4. 核心功能场景化深度使用指南平台搭好了数据也进来了接下来就是如何用它真正提升效率。我们通过几个典型场景来拆解。4.1 场景一快速定位接口性能瓶颈假设监控告警显示user-service的 P99 延迟从 200ms 飙升到了 2s。第一步服务概览。打开 SigNoz首页的 Service Dashboard 就能看到user-service的延迟曲线异常。点击user-service进入服务详情页。第二步下钻到慢追踪。在服务详情页找到“Traces”标签页。使用过滤器Service user-service并且Duration 1s你可以设置一个阈值。列表会列出所有慢请求的追踪。第三步分析追踪火焰图。点击一个慢追踪右侧会展开火焰图Flamegraph和甘特图Gantt Chart。火焰图能直观地告诉你时间花在了哪里。你可能会发现大部分时间消耗在一个名为GET /api/internal/profile的数据库查询或外部调用上。第四步关联日志。在火焰图上点击那个耗时的 Span右侧的“Logs”标签页会自动加载在该 Span 执行期间、同一服务实例上产生的所有日志。你可能会看到类似“SQL query slow: SELECT * FROM users WHERE ...”、“Redis connection timeout”这样的错误或警告日志。至此你从宏观指标异常到具体的慢接口再到可能的原因慢SQL、网络超时全部在一个界面内完成耗时可能不到一分钟。4.2 场景二排查偶发性错误用户报告偶尔会收到 500 错误但并非每次重现。错误率监控在user-service的详情页关注“错误率”图表。确认错误是否在特定时间段频发。过滤错误追踪在 Traces 页面过滤Status Code 2OTel 中 2 代表 Error。查看这些错误追踪的共性。对比分析SigNoz 提供了一个强大的功能——“对比模式”。你可以选择一个成功的追踪和一个失败的追踪进行对比。系统会高亮显示两者在调用链路上的差异比如失败的追踪在某个下游服务调用时缺失了一个 Span或者返回了不同的状态码这能快速指引你找到错误分叉点。检查异常日志同样点击错误 Span 查看关联日志。结合日志中的错误堆栈信息基本就能定位到出错的代码行或依赖服务。4.3 场景三基于业务指标的告警除了系统指标我们更关心业务指标。例如我们希望当“下单失败率”超过 5% 时告警。发送自定义指标在你的下单服务中使用 OTel SDK 发送自定义指标。meter : otel.Meter(order-service) failureCounter, _ : meter.Int64Counter(order.failure.count) // 在下单失败时 failureCounter.Add(ctx, 1, attribute.String(payment_gateway, stripe))在 SigNoz 中定义告警进入Alerts页面创建新的告警规则。数据源选择clickhouse。查询语句使用 SigNoz 扩展的 SQL 语法。例如计算过去5分钟的失败率SELECT (sum(order.failure.count) / sum(order.total.count)) * 100 as failure_rate FROM signoz_metrics.distributed_samples WHERE timestamp now() - 300 AND metric_name IN (order.failure.count, order.total.count) GROUP BY metric_name设置阈值条件failure_rate 5并配置告警渠道如 Slack, Webhook。4.4 场景四日志的集中管理与追踪关联对于已经使用传统日志代理如 Filebeat/Fluentd的应用也可以将日志接入 SigNoz。配置日志转发在你的 Fluentd 配置中将日志输出到 SigNoz 的 OTLP 接收端。match your.log.tag type otlp endpoint http://your-signoz-collector:4318 service_name your-service # 关键从日志中解析或注入 trace_id 和 span_id headers trace_id ${record.dig(trace_id)} span_id ${record.dig(span_id)} /headers /match在 SigNoz 中查询之后你就可以在 SigNoz 的 Logs 页面通过服务名、日志级别、关键字进行搜索。更重要的是如果日志里带有trace_id你可以直接点击它跳转到完整的请求追踪实现上下文的无缝切换。5. 性能调优、问题排查与运维心得运行一段时间后你可能会遇到一些性能和运维上的挑战。这里分享一些实战经验。5.1 性能与资源优化ClickHouse 写入优化SigNoz 的流水线服务pipeline负责将队列中的数据写入 ClickHouse。如果数据量很大可以调整其批处理参数如flush_interval,flush_size来平衡延迟和吞吐。监控 ClickHouse 的system.metrics表关注InsertedRows和InsertedBytes速率是否正常。查询加速对于频繁查询的聚合指标如服务每分钟错误率可以在 ClickHouse 中创建**物化视图Materialized View**进行预聚合。SigNoz 的部分核心指标已经内置了物化视图。对于自定义的关键业务指标考虑依样画葫芦能极大提升仪表盘加载速度。存储成本控制这是重中之重。务必设置数据保留策略。SigNoz 前端可以设置全局保留时间。对于更精细的控制你需要直接操作 ClickHouse为不同的表设置 TTL。例如原始追踪数据 (signoz_traces.distributed_traces) 保留7天但可以创建一个物化视图将每天的慢追踪duration 10s聚合到另一张表保留30天。-- 示例为 traces 表设置 7 天 TTL ALTER TABLE signoz_traces.distributed_traces ON CLUSTER cluster MODIFY TTL timestamp INTERVAL 7 DAY;5.2 常见问题排查速查表问题现象可能原因排查步骤前端无法访问 (localhost:3301)服务未完全启动端口冲突1.docker-compose ps检查所有服务状态。2.docker logs signoz-frontend查看前端日志。3. 检查本地 3301 端口是否被占用。应用发送数据后SigNoz 无显示OTel Collector 配置错误网络不通数据格式不对1. 检查应用配置的 OTLP 端点 (localhost:4317) 是否正确。2.docker logs signoz-otel-collector查看 Collector 是否收到数据及有无错误。3. 用curl或grpcurl测试 Collector 端口是否可达。4. 检查应用 SDK 版本与 Collector 是否兼容。查询速度非常慢ClickHouse 内存不足查询过于复杂缺少索引1. 检查 ClickHouse 容器/节点的内存使用率 (docker stats或top)。2. 在 SigNoz 前端打开浏览器开发者工具查看哪个 API 请求慢。3. 登录 ClickHouse使用EXPLAIN分析慢查询语句。磁盘空间增长过快数据保留策略未设置日志级别过低产生过多数据1. 检查 SigNoz 设置中的 Retention Period。2. 检查应用日志级别是否为 DEBUG适当调整为 INFO 或 WARN。3. 计算每日数据摄入量规划合理的保留周期。告警不触发或重复触发告警规则条件设置错误评估间隔不合理1. 仔细检查告警规则中的查询语句在Metrics查询器先手动执行验证结果。2. 调整告警规则的“评估间隔”Evaluation Interval避免过于频繁。3. 配置告警的“冷却时间”Cool Down Period防止抖动。5.3 生产环境运维建议监控 SigNoz 自身用 SigNoz 监控 SigNoz 自身。为signoz命名空间下的服务collector, query-service, clickhouse配置基础资源告警CPU、内存、磁盘。这是确保可观测性平台自身高可用的前提。备份与恢复定期备份 ClickHouse 的数据。ClickHouse 提供了clickhouse-backup等工具。制定灾难恢复预案知道如何从备份中恢复数据。版本升级关注 SigNoz 的 Release Notes。升级前务必在测试环境验证。特别是大版本升级可能涉及数据表结构变更需要按照官方指南进行数据迁移。安全加固生产环境务必启用 TLS 加密 OTLP 数据传输。修改默认的管理员密码。通过网络策略限制对 SigNoz 管理端口3301和 Collector 端口4317, 4318的访问。考虑集成 OAuth/SSO 进行用户认证。SigNoz 作为一个快速发展的开源项目其社区非常活跃。遇到问题时除了查阅官方文档其 GitHub Issues 和 Slack 频道是寻求帮助的好地方。从我个人的使用体验来看它已经能够覆盖中小型企业 80% 以上的可观测性需求。它的优势在于“开箱即用”的一体化体验和基于开放标准的设计避免了供应商锁定。当然与成熟的商业方案相比它在极端规模下的性能调优、企业级功能如精细的权限控制、审计日志方面还有成长空间但这正是开源项目的魅力所在——你可以参与其中与社区一起将它塑造成你需要的模样。对于任何正在被多套监控工具折磨或者预算有限但渴望拥有强大可观测性能力的团队SigNoz 绝对值得你投入时间深入评估和尝试。