spring-projects / spring-projects/spring-graphql

Improve metrics for _entities and fields

Open
#1,297 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: core type: enhancement
Dominant language
Java
Stars
1.6k
Forks
336
PR merge metrics
No merged PRs in 30d

Description

There's 2 improvements i see:

  1. Currently metrics like: graphql_datafetcher_seconds_count group all _entities interactions under _entities. For applications which have several entityMappings defined you cant differentiate between which entity is being resolved.
  2. In applications which have multiple schema mappings for the same field but different objects, it currently all gets combined under the field name, which makes it impossible to separate which type this field was being called on.

I have done some testing and the following seems to solve both issues

@Configuration
class GraphQLObservationConfig {

    @Bean
    fun dataFetcherObservationConvention(): DataFetcherObservationConvention = object : DefaultDataFetcherObservationConvention() {

        override fun fieldName(context: DataFetcherObservationContext): KeyValue {
            val env = context.environment
            val parent = (env.parentType as? GraphQLNamedType)?.name
            val field = env.field.name

            val enrichedField = if (field == "_entities") {
                // Normally all _entities queries are processed as _entities but since we have so many different entities we want
                // to know exactly which entities is being called
                (env.getArgument<Any?>("representations") as? List<*>)
                    ?.firstNotNullOfOrNull { rep -> (rep as? Map<*, *>)?.get("__typename") as? String }
                    ?.let { "$field($it)" } ?: field
            } else {
                // Converts a field to a <parent>.<field> metric for cases where we want to differentiate between fields
                // with the same name defined on different types, which would otherwise all be aggregated under the field name
                parent?.let { "$it.$field" } ?: field
            }

            return KeyValue.of(DataFetcherLowCardinalityKeyNames.FIELD_NAME, enrichedField)
        }
    }
}

it changes

  • e.g. the graphql_field_name for _entities queries to _entities(<entityName>)
  • the graphql_field_name for fields to <parent>.<fieldName>

If this could be made part of Spring Graphql it'd be greatly appreciated!

Let me know if any clarifications are needed!

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating DataFetcherObservationConvention and the code that produces the graphql_field_name metric. Use the proposed GraphQLObservationConfig behavior as the reference, then verify _entities metrics include the entity typename and same-named fields include their parent type. Done means both cases produce distinct graphql_field_name values with tests covering them.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, java, spring
Domain
api, backend, observability
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.