You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring GraphQL DataFetcher可观测性缺失错误相关键值问题咨询

Spring GraphQL DataFetcher可观测性缺失错误相关键值问题咨询

我完全理解你现在的困扰——用Spring Boot 3的可观测性功能监控GraphQL应用时,成功请求能正常拿到官方文档里提到的那些低基数键,可一旦出现ValidationError这类错误,本该生成的错误相关键就凭空消失了,哪怕调试时明明看到ObservationContext里已经捕获到了错误,最后却没出现在监控数据里,确实让人摸不着头脑。

结合你描述的环境(没有自定义处理器/过滤器、保留默认GraphQL错误处理),我来分析几个可能的原因,再给你对应的解决方案和最佳实践:

可能的原因

  1. 默认观测规则的触发条件限制
    Spring GraphQL的DefaultGraphQlObservationConvention默认实现里,可能只在请求完全无错误时才会生成完整的键值对,或者错误信息的处理时机晚于观测标签的生成阶段——简单说就是,当观测器准备生成低基数键的时候,错误还没被写入上下文,或者写入后没被触发读取。

  2. 观测上下文的属性传递遗漏
    虽然你调试时看到错误已经被存入ObservationContext,但在观测生命周期的后续环节(比如结束观测时),这些错误属性可能没有被正确提取并转化为监控标签,导致最终输出时缺失。

解决方案

1. 自定义GraphQlObservationConvention覆盖默认逻辑

这是最直接的方法,我们可以自己实现观测规则,确保错误场景下也能生成对应的键值对:

@Component
public class CustomGraphQlObservationConvention extends DefaultGraphQlObservationConvention {

    @Override
    public KeyValues getLowCardinalityKeyValues(GraphQlObservationContext context) {
        // 先继承默认的成功场景键值对
        KeyValues keyValues = super.getLowCardinalityKeyValues(context);
        
        // 检查上下文是否存在错误
        if (context.hasErrors()) {
            List<GraphQLError> errors = context.getErrors();
            GraphQLError firstError = errors.get(0);
            
            // 添加错误类型标签(低基数,适合监控)
            keyValues = keyValues.and(KeyValue.of("graphql.error.type", firstError.getClass().getSimpleName()));
            
            // 如果是ValidationError,还可以添加更细分的验证错误类型
            if (firstError instanceof ValidationError validationError) {
                keyValues = keyValues.and(KeyValue.of("graphql.validation.code", validationError.getValidationErrorType().name()));
            }
            
            // 标记请求存在错误
            keyValues = keyValues.and(KeyValue.of("graphql.has_errors", "true"));
        }
        
        return keyValues;
    }
}

2. 用ObservationFilter拦截观测生命周期

如果不想完全覆盖默认规则,可以添加一个观测过滤器,在观测结束前手动注入错误相关的标签:

@Component
public class GraphQlErrorObservationFilter implements ObservationFilter {

    @Override
    public Observation.Context filter(Observation.Context context) {
        // 只处理GraphQL相关的观测上下文
        if (context instanceof GraphQlObservationContext graphQlCtx && graphQlCtx.hasErrors()) {
            graphQlCtx.addLowCardinalityKeyValue(KeyValue.of("graphql.has_errors", "true"));
            // 这里可以根据需求添加更多错误标签
        }
        return context;
    }
}

3. 验证Metrics配置是否正确

检查你的配置文件,确保没有禁用GraphQL相关的metrics采集:

management:
  metrics:
    enable:
      graphql: true
    tags:
      # 确保全局标签不冲突
      application: ${spring.application.name}

监控GraphQL错误的最佳实践

  • 优先使用低基数标签:避免把错误消息这类高基数内容作为标签(会导致metrics膨胀),优先用错误类型、错误码这类固定值的标签。
  • 结合分布式追踪:如果用了Zipkin/Jaeger,可以在观测上下文里把错误信息添加到Span的Tags中,方便追踪错误请求的完整链路。
  • 利用Actuator GraphQL端点:开启/actuator/graphql端点(需要在配置里暴露),可以直接查看GraphQL的请求、错误统计,辅助排查问题。
  • 设置错误告警:在监控工具(比如Prometheus+Grafana)里,基于graphql.has_errors=true这类标签设置告警规则,及时发现异常请求。

备注:内容来源于stack exchange,提问作者Mars

火山引擎 最新活动