2

我最近一直致力于在我们的 GraphQL 网关中添加监控指标。

我们正在为网关使用graphql-spring-boot 启动器。

阅读以下文档后,我设法将基本的 graphql.timer.query.* 指标发送到 Datadog

到目前为止,我所取得的成就是,当我发送 GraphQL 查询/突变时,我会相应地收集请求计数和时间。例如发送下面的查询

query HelloWorldQuery {
  greeting(
    name: "Bob"
  ) {
    message
  }
}

我会看到指标graphql.timer.query.count/graphql.timer.query.sum带有标签operationName=HelloWorldQuery

它工作得很好,直到我想测试一个有错误的查询。我意识到没有与失败查询相关的指标/标签。例如,如果我上面的查询返回空数据和一些 GraphQL 错误,我仍然会 collect graphql.timer.query.count (operationName=HelloWorldQuery),但没有其他标签可以告诉我该查询存在错误。

在网关中,我已经实现了一个 custom GraphQLErrorHandler,所以我想也许我应该在那个类中添加错误计数器(通过 MeterRegistry),但是我无法operationName从 GraphQLError 类型中简单地获取。我能得到的最好的是 error.getPath() ,它给出了方法名称(例如greeting)而不是自定义查询名称(HelloWorldQuery- 与graphql.timer.query.*提供的一致)。

我的问题是,如何解决上述问题?通常收集 GraphQL 查询指标(包括错误)的最佳方式是什么?

-------------------更新-------------------

2019-12-31我在这里 阅读了有关 GraphQL Instrumentation 的更多信息,并检查了graphql-spring-boot repo 中的MetricsInstrumentation实现,我想通过在其中添加错误度量来扩展 MetricsInstrumentation 类。

2020-01-02 我试图摄取我的 CustomMetricsInstrumentation 类,但没有运气。有内部自动配置接线,我不能在中间插入我的自动配置。

4

1 回答 1

3

TracingInstrumentation您可以使用自己的实现覆盖默认值。由于GraphQLInstrumentationAutoConfiguration类中的 @ConditionalOnMissingBean 注释,它将被自动拾取。这是一个添加两个自定义指标的简单示例:graphql.counter.query.successgraphql.counter.query.error

@Component
public class CustomMetricsInstrumentation extends TracingInstrumentation {

    private static final String QUERY_STATUS_COUNTER_METRIC_NAME = "graphql.counter.query";
    private static final String OPERATION_NAME_TAG = "operationName";
    private static final String UNKNOWN_OPERATION_NAME = "unknown";

    private MeterRegistry meterRegistry;

    public CustomMetricsInstrumentation(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }

    @Override
    public CompletableFuture<ExecutionResult> instrumentExecutionResult(ExecutionResult executionResult,
                                                                        InstrumentationExecutionParameters parameters) {

        String status = CollectionUtils.isEmpty(executionResult.getErrors()) ? "success" : "error";
        String operation = parameters.getOperation() != null ? parameters.getOperation() : UNKNOWN_OPERATION_NAME;
        Collection<Tag> tags = Arrays.asList(Tag.of(OPERATION_NAME_TAG, operation));

        meterRegistry.counter(QUERY_STATUS_COUNTER_METRIC_NAME + "." + status, tags).increment();

        return super.instrumentExecutionResult(executionResult, parameters);
    }
}

我的application.yaml,以防万一:

graphql:
  servlet:
    tracing-enabled: true
    actuator-metrics: true
management:
  endpoint:
  metrics:
    enabled: true
  endpoints:
    web:
      exposure:
        include: health,metrics

我正在使用 spring-boot-starter-parent:2.2.2.RELEASE,graphql-spring-boot-starter:6.0.0

我希望它有所帮助。

于 2020-01-05T23:37:29.313 回答