云计算百科
云计算领域专业知识百科平台

Litmus ChaosCenter GraphQL 服务器 Prometheus 指标全解析与 Grafana 可视化实战

  • 云原生
  • 运维
  • 可观测性

【免费下载链接】litmus

Litmus helps SREs and developers practice chaos engineering in a Cloud-native way. Chaos experiments are published at the ChaosHub (https://hub.litmuschaos.io). Community notes is at https://hackmd.io/a4Zu_sH4TZGeih-xCimi3Q

项目地址:
https://gitcode.com/gh_mirrors/li/litmus

点击查看 免费下载

Litmus 是一个以云原生方式帮助 SRE 与开发者实践混沌工程的开源项目,其控制平面(ChaosCenter)中的 GraphQL 服务器在 chaoscenter/graphql/server/pkg/metrics 包中内置了一套完整的 Prometheus 指标体系。本文将以该包文档为骨架,结合仓库源码深入剖析 litmus_api_*、litmus_experiment_*、litmus_*_agents 三类共 11 个指标的定义、标签与采集链路,并给出从端点验证、Prometheus 抓取配置到 Grafana 仪表盘导入的完整实战步骤。读完本文,你将能独立为 Litmus ChaosCenter 控制平面搭建一套可观测、可告警的指标监控方案。


一、指标体系的落点:控制平面可观测性

Litmus 的混沌实验编排分为控制平面与执行平面:控制平面由 ChaosCenter 的 GraphQL 服务器、认证服务、事件追踪器与订阅器等组件构成,负责实验编排、基础设施(Infra/Agent)管理和用户交互;执行平面则在目标集群上运行混沌实验。而 pkg/metrics 包正是控制平面中负责暴露 Prometheus 指标的核心模块,它回答了三个问题:

  • API 是否健康——请求量、响应延迟、错误率、认证失败;
  • 实验是否按预期运行——实验总量、运行次数、运行时长、当前状态;
  • 混沌 Agent(Infrastructure)是否在线——已连接、已断开、注册总数。
  • 这些指标统一通过一个独立的 HTTP 服务暴露,默认端口 8889,路径 /metrics,由 metrics.go 中定义的 11 个 Prometheus 指标向量承载。


    二、指标端点与端口配置

    2.1 独立指标服务器

    与业务 API 不同,指标并不挂在主 GraphQL 路由上,而是由 startMetricsServer() 启动一个独立、轻量的 Gin HTTP 服务,其实现位于 server.go:

    // startMetricsServer starts a separate HTTP server for Prometheus metrics
    func startMetricsServer() {
    metricsRouter := gin.New()
    metricsRouter.Use(gin.Recovery())
    metricsRouter.GET("/metrics", gin.WrapH(promhttp.Handler()))

    metricsPort := utils.Config.MetricsPort
    log.Infof("Metrics server running at http://localhost:%s/metrics", metricsPort)

    if err := http.ListenAndServe(":"+metricsPort, metricsRouter); err != nil {
    log.Fatalf("Failed to start metrics server: %v", err)
    }
    }

    关键点:

    • 端点使用 promhttp.Handler() 输出标准 Prometheus 文本格式,可直接被 Prometheus 抓取;
    • 该服务器在 main() 中以 go startMetricsServer() 协程方式启动(见 server.go),与 GraphQL 主服务互不阻塞;
    • 日志会打印实际监听地址,形如 Metrics server running at http://localhost:8889/metrics。

    2.2 端口:METRICS_PORT 环境变量

    端口由环境变量 METRICS_PORT 控制,默认值为 8889,其配置定义位于 utils/variables.go:

    MetricsPort string `envconfig:"METRICS_PORT" default:"8889"`

    因此你既可以通过环境变量覆盖端口(例如部署多套控制平面避免冲突时),也可以在部署清单中按需注入:

    env:
    – name: METRICS_PORT
    value: "8889"

    验证方式:启动 ChaosCenter 后,直接访问 http://localhost:8889/metrics 即可看到所有以 litmus_ 开头的指标。


    三、API 指标(litmus_api_*)

    这组指标描述 GraphQL 服务器的请求处理情况,均在 metrics.go 中定义:

    指标名类型含义标签
    litmus_api_requests_total Counter(CounterVec) 到达 GraphQL 服务器的 API 请求总数,携带 GraphQL 操作信息 endpoint、status、operation_name、operation_type
    litmus_api_response_time_milliseconds Histogram(HistogramVec) API 请求响应耗时(毫秒),分桶从 10ms 到 5s endpoint、operation_name、operation_type
    litmus_api_error_requests_total Counter(CounterVec) 出错请求总数 endpoint、error_type
    litmus_api_authentication_failures_total Counter(CounterVec) 认证失败次数 auth_method

    3.1 标签与取值

    • endpoint:Gin 路由的完整路径,如 /query;未匹配到任何路由时记为 unmatched(见 middleware.go);
    • status:HTTP 状态码字符串,如 200、500、404;
    • operation_name:GraphQL 操作名,如 listExperiment、runChaosExperiment、getExperiment;匿名操作记为 anonymous,非 GraphQL 请求记为 N/A;
    • operation_type:GraphQL 操作类型,取值为 query 或 mutation;
    • error_type:client_error(HTTP 状态码 ≥ 400 且 < 500)或 server_error(状态码 ≥ 500);
    • auth_method:认证方式,目前源码中为 bearer(见 authorization/middleware.go)。

    3.2 直方图分桶

    litmus_api_response_time_milliseconds 的分桶定义如下(单位毫秒):

    Buckets: []float64{10, 50, 100, 200, 500, 1000, 2000, 5000},

    即覆盖 10ms~5s 的响应耗时区间,配合 histogram_quantile 可计算 p50/p95/p99 等分位延迟,例如:

    histogram_quantile(0.99, sum by (le) (rate(litmus_api_response_time_milliseconds_bucket[5m])))

    3.3 采集链路

    API 指标的写入发生在 middleware.go 的 MetricsMiddleware() 中,它是一个 Gin 中间件,通过 router.Use(metrics.MetricsMiddleware()) 挂载在全局路由上(见 server.go)。其执行流程为:

  • 记录请求开始时间,取得路由 FullPath();
  • c.Next() 放行请求;
  • 请求结束后计算耗时(time.Since(start).Milliseconds());
  • 从 context 中读取 GraphQL 操作名与类型(键为 graphql_operation_name、graphql_operation_type,定义于 metrics.go);
  • 递增请求计数、写入耗时观测值;若状态码 ≥ 400 则按 client_error/server_error 归类递增错误计数。
  • 而 GraphQL 操作信息由 server.go 中的 AroundOperations 拦截器注入 context:

    srv.AroundOperations(func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler {
    oc := graphql.GetOperationContext(ctx)
    operationType := "query"
    if oc.Operation != nil && oc.Operation.Operation == "mutation" {
    operationType = "mutation"
    }
    operationName := oc.OperationName
    if operationName == "" {
    operationName = "anonymous"
    }
    // Store operation details in context for HTTP middleware to use
    ctx = context.WithValue(ctx, metrics.GraphqlOperationNameKey, operationName)
    ctx = context.WithValue(ctx, metrics.GraphqlOperationTypeKey, operationType)
    return next(ctx)
    })

    认证失败指标则由认证中间件在 JWT 令牌被吊销时递增(见 authorization/middleware.go),从而让运维者可以区分"业务出错"与"认证被拒"两类异常。


    四、实验指标(litmus_experiment_*)

    这组指标描述混沌实验及其运行情况,定义于 metrics.go:

    指标名类型含义标签
    litmus_experiments_total Gauge(GaugeVec) 系统中的实验总数 project_id、status、infra_id
    litmus_experiment_runs_total Counter(CounterVec) 实验累计运行次数 project_id、experiment_id、experiment_name、infra_id
    litmus_experiment_run_duration_seconds Histogram(HistogramVec) 实验运行耗时(秒),分桶从 1s 到 30 分钟 project_id、experiment_id、experiment_name、infra_id
    litmus_experiment_status Gauge(GaugeVec) 实验当前运行状态:1 = 运行中,0 = 未运行 project_id、experiment_id、experiment_name、status、infra_id

    4.1 直方图分桶

    litmus_experiment_run_duration_seconds 的分桶覆盖 1 秒到 30 分钟:

    Buckets: []float64{1, 5, 10, 30, 60, 120, 300, 600, 1200, 1800},

    适合统计大多数混沌实验(从 pod 删除到负载注入)的时长分布。

    4.2 写入时机与源码依据

    • 实验创建:在 chaos_experiment/handler/handler.go 中,创建实验成功后以 ExperimentsTotal.WithLabelValues(projectID, "Active", request.InfraID).Inc() 递增实验总量(注意:该指标声明为 Gauge,但实际以 Inc() 方式使用,反映的是实验累积总量,status 标签当前取值为 Active)。

    • 实验运行启动:在 chaos_experiment_run/handler/handler.go 中,实验运行记录创建成功并提交事务后:

    metrics.ExperimentRunsTotal.WithLabelValues(projectID, workflow.ExperimentID, workflow.Name, workflow.InfraID).Inc()
    metrics.ExperimentStatus.WithLabelValues(projectID, workflow.ExperimentID, workflow.Name, string(model.ExperimentRunStatusQueued), workflow.InfraID).Set(0)

    即排队(Queued)阶段状态值为 0;随后在 cron 实验启动时(见 handler.go)将状态置为 1(Running):

    metrics.ExperimentStatus.WithLabelValues(projectID, workflow.ExperimentID, workflow.Name, string(model.ExperimentRunStatusRunning), workflow.InfraID).Set(1)
    metrics.ExperimentRunsTotal.WithLabelValues(projectID, workflow.ExperimentID, workflow.Name, workflow.InfraID).Inc()

    • 实验完成:在 handler.go 中,当订阅者上报实验完成事件后,以 (当前时间 – 创建时间) 换算秒数观测运行时长,并将状态置 0:

    duration := float64(time.Now().UnixMilli()-experimentRun.CreatedAt) / 1000.0 // Convert to seconds
    metrics.ExperimentRunDuration.WithLabelValues(experiment.ProjectID, event.ExperimentID, experimentRun.ExperimentName, experiment.InfraID).Observe(duration)
    metrics.ExperimentStatus.WithLabelValues(experiment.ProjectID, event.ExperimentID, experimentRun.ExperimentName, executionData.Phase, experiment.InfraID).Set(0)

    因此 litmus_experiment_status 的值语义为:1 表示实验正在运行(Running),0 表示实验未在运行(Queued、Completed、Stopped、Error 等阶段);而 status 标签始终携带具体阶段字符串(如 Running、Completed、Stopped、Error),可以据此区分"正在运行"与"已完成"并分别筛选。


    五、Agent(基础设施)指标(litmus_*_agents)

    这组指标描述 ChaosCenter 管理的混沌 Agent(即连接各目标集群的混沌基础设施),定义于 metrics.go:

    指标名类型含义标签
    litmus_connected_agents Gauge(GaugeVec) 当前已连接的混沌 Agent 数量 project_id
    litmus_disconnected_agents Gauge(GaugeVec) 当前处于断开状态的 Agent 数量 project_id
    litmus_total_agents Gauge(GaugeVec) 已注册的 Agent 总数 project_id

    5.1 周期性刷新逻辑

    这组 Gauge 不是逐事件更新的,而是由 chaos_infrastructure/service.go 中的 RecordInfraMetrics(ctx) 以 30 秒为周期从数据库查询并刷新:

    ticker := time.NewTicker(30 * time.Second)
    …
    infras, err := in.infraOperator.GetInfras(ctx, bson.D{{"is_removed", false}})
    projectCounts := make(map[string][2]int) // [connected, total]
    for _, infra := range infras {
    counts := projectCounts[infra.ProjectID]
    counts[1]++ // total
    if infra.IsActive {
    counts[0]++ // connected
    }
    projectCounts[infra.ProjectID] = counts
    }
    for projectID, counts := range projectCounts {
    metrics.ConnectedAgents.WithLabelValues(projectID).Set(float64(counts[0]))
    metrics.DisconnectedAgents.WithLabelValues(projectID).Set(float64(counts[1] – counts[0]))
    metrics.TotalAgents.WithLabelValues(projectID).Set(float64(counts[1]))
    }

    由此可推导出以下监控口径:

    • 已连接 Agent = is_removed=false 且 IsActive=true 的基础设施数量;
    • 断开 Agent = 注册总数减去已连接数(即 disconnected = total – connected);
    • 该指标以 project_id 维度区分,可分别监控每个项目的 Agent 在线率,例如告警 litmus_disconnected_agents > 0。

    六、快速验证与 Prometheus 采集配置

    6.1 直接访问端点

    在本地开发环境,可以直接验证指标输出:

    curl http://localhost:8889/metrics

    在 Kubernetes 部署场景中,先通过端口转发暴露指标端口:

    kubectl port-forward -n litmus deployment/litmusportal-server 8889:8889
    curl http://localhost:8889/metrics | grep litmus_

    预期能看到类似 litmus_api_requests_total、litmus_experiment_runs_total、litmus_experiment_status 等指标及完整标签序列。

    6.2 创建 Metrics Service

    为了让 Prometheus(或 ServiceMonitor)能够稳定抓取指标,建议为指标端口单独创建一个 ClusterIP Service(参考 getting-started.md):

    apiVersion: v1
    kind: Service
    metadata:
    name: litmus-server-metrics
    namespace: litmus
    labels:
    app: litmus-server-metrics
    spec:
    selector:
    component: litmusportal-server
    ports:
    – name: metrics
    port: 8889
    targetPort: 8889
    type: ClusterIP

    应用:

    kubectl apply -f litmus-server-metrics-service.yaml

    6.3 创建 ServiceMonitor(Prometheus Operator 场景)

    若使用 Prometheus Operator / kube-prometheus-stack,可创建如下 ServiceMonitor 让 Prometheus 自动发现并每 30 秒抓取一次:

    apiVersion: monitoring.coreos.com/v1
    kind: ServiceMonitor
    metadata:
    name: litmus-server-metrics
    namespace: litmus
    labels:
    release: prometheus
    spec:
    selector:
    matchLabels:
    app: litmus-server-metrics
    endpoints:
    – port: metrics
    path: /metrics
    interval: 30s

    应用:

    kubectl apply -f litmus-server-metrics-monitor.yaml

    注意:release: prometheus 标签必须与你的 Prometheus Operator 配置的标签选择器一致;如果 Helm release 名称不同,请相应修改该标签。

    6.4 原生 Prometheus scrape 配置

    未使用 Operator 时,也可以在 scrape_configs 中直接配置:

    scrape_configs:
    – job_name: 'litmus-graphql-server'
    metrics_path: '/metrics'
    static_configs:
    – targets: ['litmus-server-metrics.litmus.svc.cluster.local:8889']

    6.5 验证抓取是否成功

    端口转发到 Prometheus UI 并检查目标状态:

    kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090

    打开 http://localhost:9090/targets,找到 litmus-server-metrics,其状态应显示为 UP。随后可在 Prometheus 查询页面执行:

    litmus_api_requests_total

    确认能返回带标签的指标序列。


    七、Grafana 仪表盘导入与面板清单

    仓库内置了一份预构建的 Grafana 仪表盘:chaoscenter/graphql/server/grafana/litmuschaos-metrics-dashboard.json(仪表盘标题为 LitmusChaos Control Plane Observability),导入后即可开箱可视化全部指标。

    7.1 导入步骤

  • 端口转发 Grafana:
  • kubectl port-forward -n monitoring deployment/prometheus-grafana 3000:3000

  • 浏览器打开 http://localhost:3000 并登录;
  • 依次进入 Dashboards → New → Import;
  • 上传 litmuschaos-metrics-dashboard.json;
  • 数据源选择 Prometheus,点击 Import 完成导入。
  • 7.2 内置面板清单

    从仪表盘 JSON 可以确认,它按三类指标组织了 19 个面板:

    • API 维度:API Overview、API Request Rate、API Error Rate、API p99 Latency、Auth Failures(5m rate)、API Request Rate by Endpoint、API Response Time(p50 / p95 / p99);
    • 实验维度:Experiment Runs、Total Experiment Runs、Total Experiments、Experiment Run Duration(p50)、Experiments Currently Running、Experiment Run Rate by Name & Infra、Experiment Run Duration by Name、Experiment Status Table;
    • Agent 维度:Infra Agents、Total Agents、Connected Agents、Disconnected Agents。

    7.3 常用 PromQL 示例

    基于上述指标,可以组合出以下常用查询:

    关注点PromQL
    API 请求速率 sum(rate(litmus_api_requests_total[5m]))
    5 分钟错误率 sum(rate(litmus_api_error_requests_total[5m]))
    认证失败速率 sum(rate(litmus_api_authentication_failures_total[5m]))
    正在运行的实验 litmus_experiment_status == 1
    实验平均运行时长 rate(litmus_experiment_run_duration_seconds_sum[1h]) / rate(litmus_experiment_run_duration_seconds_count[1h])
    每个项目的 Agent 在线数 sum by (project_id) (litmus_connected_agents)

    八、测试与质量保障

    该包附带完整的单元测试 metrics_test.go,覆盖了指标体系的正确性,可作为理解指标语义的最佳参考:

    • TestMetricsRegistration:验证 11 个指标向量均可被 Prometheus Registry 注册,不会引发重复注册 panic;
    • TestAPIRequestsTotal / TestExperimentRunsTotal:验证 Counter 在多次 Inc() 后计数正确,且不同标签组合互不干扰;
    • TestExperimentStatus / TestExperimentsTotal / TestAgentMetrics:验证 Gauge 的 Set/Inc 语义,其中 Agent 测试还校验了 connected + disconnected = total 的守恒关系;
    • TestMetricsMiddleware_SuccessRequest / TestMetricsMiddleware_ErrorRequest / TestMetricsMiddleware_UnmatchedRoute:通过 httptest 构造真实 Gin 路由,验证中间件对 200、500、404(未匹配路由记 unmatched)三种场景的指标写入;
    • TestContextKeys:锁定 context 键常量的取值。

    如需在本地运行测试:

    cd chaoscenter/graphql/server && go test ./pkg/metrics/…


    九、小结与最佳实践

    Litmus ChaosCenter GraphQL 服务器的指标体系以 pkg/metrics 包为单一事实来源,通过独立端口 8889 暴露,具有以下特点:

  • 三层观测视角:API 层(请求量/延迟/错误/认证)、实验层(总量/运行次数/时长/状态)、Agent 层(连接数/断开数/总数),覆盖控制平面健康度、混沌实验执行效果与基础设施在线率;
  • 标准 Prometheus 形态:Counter / Gauge / Histogram 三类指标全部使用 client_golang 定义并在 init() 中注册(见 metrics.go),可直接被任意 Prometheus 兼容系统抓取;
  • 开箱即用:仓库自带 Grafana 仪表盘 与 完整上手指引,从零搭建监控的成本很低。
  • 建议实践路径:先按第六章完成端点验证与采集配置,确认 Prometheus target 为 UP;再导入第七章的 Grafana 仪表盘建立可视化基线;随后针对 litmus_api_error_requests_total、litmus_api_authentication_failures_total、litmus_disconnected_agents 与 litmus_experiment_status == 1(长时间无变化)配置告警规则,即可形成一套完整的 ChaosCenter 控制平面可观测闭环。

    赞

    分享

    • 云原生
    • 运维
    • 可观测性

    【免费下载链接】litmus

    Litmus helps SREs and developers practice chaos engineering in a Cloud-native way. Chaos experiments are published at the ChaosHub (https://hub.litmuschaos.io). Community notes is at https://hackmd.io/a4Zu_sH4TZGeih-xCimi3Q

    项目地址:
    https://gitcode.com/gh_mirrors/li/litmus

    点击查看 免费下载

    上一篇:
    ATProto Feed Generator API 完全参考:方法、参数与响应详解

    下一篇:
    EasySwoole 路由系统详解:高性能 RESTful API 设计终极指南

    创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Litmus ChaosCenter GraphQL 服务器 Prometheus 指标全解析与 Grafana 可视化实战
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!