Skip to content

Commit

Permalink
Replace usages of Micrometer Tags with Iterable<Tag> (#1612)
Browse files Browse the repository at this point in the history
Co-authored-by: Kavitha Srinivasan <41588701+srinivasankavitha@users.noreply.github.com>
  • Loading branch information
DanielThomas and srinivasankavitha authored Aug 28, 2023
1 parent 85fc520 commit aaa04f8
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package com.netflix.graphql.dgs.metrics

import com.netflix.graphql.dgs.Internal
import io.micrometer.core.instrument.Tag
import io.micrometer.core.instrument.Tags

object DgsMetrics {

Expand Down Expand Up @@ -104,9 +103,8 @@ object DgsMetrics {
*/
SUCCESS(GqlTag.OUTCOME.key, "success") {
/** Returns the success [tag] along with the [JAVA_CLASS] of the value.*/
override fun <T : Any> tags(v: T): Tags {
return Tags.of(tag)
.and(JAVA_CLASS.tags(v))
override fun <T : Any> tags(v: T): Iterable<Tag> {
return listOf(tag).plus(JAVA_CLASS.tags(v))
}
},

Expand All @@ -115,16 +113,15 @@ object DgsMetrics {
*/
FAILURE(GqlTag.OUTCOME.key, "failure") {
/** Returns failure [tag] along with the [JAVA_CLASS] of the value.*/
override fun <T : Any> tags(v: T): Tags {
return Tags.of(tag)
.and(JAVA_CLASS.tags(v))
override fun <T : Any> tags(v: T): Iterable<Tag> {
return listOf(tag).plus(JAVA_CLASS.tags(v))
}
},

/** Tag that reflects the class associated with the metric. */
JAVA_CLASS("class", "unknown") {
override fun <T : Any> tags(v: T): Tags {
return Tags.of(key, v::class.java.name)
override fun <T : Any> tags(v: T): Iterable<Tag> {
return listOf(Tag.of(key, v::class.java.name))
}
},

Expand All @@ -133,13 +130,13 @@ object DgsMetrics {
*The metric with this tag will normally be accompanied by the [JAVA_CLASS] tag as well.
*/
JAVA_CLASS_METHOD("method", "unknown") {
override fun <T : Any> tags(v: T): Tags {
return Tags.of(key, "$v")
override fun <T : Any> tags(v: T): Iterable<Tag> {
return listOf(Tag.of(key, "$v"))
}
};

val tag: Tag = Tag.of(key, defaultValue)

abstract fun <T : Any> tags(v: T): Tags
abstract fun <T : Any> tags(v: T): Iterable<Tag>
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import graphql.ExecutionResult
import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters
import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters
import io.micrometer.core.instrument.Tag
import io.micrometer.core.instrument.Tags
import java.util.*

class DgsGraphQLCollatedMetricsTagsProvider(
Expand All @@ -34,7 +33,7 @@ class DgsGraphQLCollatedMetricsTagsProvider(
) : DgsGraphQLMetricsTagsProvider {

override fun getContextualTags(): Iterable<Tag> {
return Tags.of(contextualTagCustomizer.flatMap { it.getContextualTags() })
return contextualTagCustomizer.flatMap { it.getContextualTags() }
}

override fun getExecutionTags(
Expand All @@ -43,14 +42,14 @@ class DgsGraphQLCollatedMetricsTagsProvider(
result: ExecutionResult,
exception: Throwable?
): Iterable<Tag> {
return Tags.of(executionTagCustomizer.flatMap { it.getExecutionTags(state, parameters, result, exception) })
return executionTagCustomizer.flatMap { it.getExecutionTags(state, parameters, result, exception) }
}

override fun getFieldFetchTags(
state: DgsGraphQLMetricsInstrumentation.MetricsInstrumentationState,
parameters: InstrumentationFieldFetchParameters,
exception: Throwable?
): Iterable<Tag> {
return Tags.of(fieldFetchTagCustomizer.flatMap { it.getFieldFetchTags(state, parameters, exception) })
return fieldFetchTagCustomizer.flatMap { it.getFieldFetchTags(state, parameters, exception) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import graphql.schema.GraphQLObjectType
import graphql.validation.ValidationError
import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.Tag
import io.micrometer.core.instrument.Tags
import io.micrometer.core.instrument.Timer
import org.slf4j.Logger
import org.slf4j.LoggerFactory
Expand Down Expand Up @@ -68,12 +67,13 @@ class DgsGraphQLMetricsInstrumentation(
miState.isIntrospectionQuery = QueryUtils.isIntrospectionQuery(parameters.executionInput)

return SimpleInstrumentationContext.whenCompleted { result, exc ->
val tags = tagsProvider.getContextualTags() +
tagsProvider.getExecutionTags(miState, parameters, result, exc) +
miState.tags()
miState.stopTimer(
properties.autotime
.builder(GqlMetric.QUERY.key)
.tags(tagsProvider.getContextualTags())
.tags(tagsProvider.getExecutionTags(miState, parameters, result, exc))
.tags(miState.tags())
.tags(tags)
)
}
}
Expand All @@ -84,23 +84,26 @@ class DgsGraphQLMetricsInstrumentation(
state: InstrumentationState
): CompletableFuture<ExecutionResult> {
val miState: MetricsInstrumentationState = state as MetricsInstrumentationState
val tags =
Tags.empty()
.and(tagsProvider.getContextualTags())
.and(tagsProvider.getExecutionTags(miState, parameters, executionResult, null))
.and(miState.tags())
val baseTags = tagsProvider.getContextualTags() +
tagsProvider.getExecutionTags(miState, parameters, executionResult, null) +
miState.tags()

fun errorTags(values: ErrorUtils.ErrorTagValues): Iterable<Tag> {
val errorTags = listOf(
Tag.of(GqlTag.PATH.key, values.path),
Tag.of(GqlTag.ERROR_CODE.key, values.type),
Tag.of(GqlTag.ERROR_DETAIL.key, values.detail)
)
return baseTags + errorTags
}

ErrorUtils
.sanitizeErrorPaths(executionResult)
.forEach {
registrySupplier
.get()
.counter(
GqlMetric.ERROR.key,
tags.and(GqlTag.PATH.key, it.path)
.and(GqlTag.ERROR_CODE.key, it.type)
.and(GqlTag.ERROR_DETAIL.key, it.detail)
).increment()
.counter(GqlMetric.ERROR.key, errorTags(it))
.increment()
}

return CompletableFuture.completedFuture(executionResult)
Expand All @@ -124,10 +127,9 @@ class DgsGraphQLMetricsInstrumentation(

return DataFetcher { environment ->
val registry = registrySupplier.get()
val baseTags =
Tags.of(GqlTag.FIELD.key, gqlField)
.and(tagsProvider.getContextualTags())
.and(miState.tags())
val baseTags = mutableListOf(Tag.of(GqlTag.FIELD.key, gqlField)) +
tagsProvider.getContextualTags() +
miState.tags()

val sampler = Timer.start(registry)
try {
Expand Down Expand Up @@ -197,9 +199,7 @@ class DgsGraphQLMetricsInstrumentation(
error: Throwable?,
baseTags: Iterable<Tag>
) {
val recordedTags = Tags
.of(baseTags)
.and(tagsProvider.getFieldFetchTags(state, parameters, error))
val recordedTags = baseTags + tagsProvider.getFieldFetchTags(state, parameters, error)

timerSampler.stop(
properties
Expand Down Expand Up @@ -231,28 +231,28 @@ class DgsGraphQLMetricsInstrumentation(
}

@Internal
fun tags(): Tags {
return Tags
.of(
GqlTag.QUERY_COMPLEXITY.key,
queryComplexity.map { it.toString() }.orElse(TagUtils.TAG_VALUE_NONE)
)
.and(
GqlTag.OPERATION.key,
operation.map { it.uppercase() }.orElse(TagUtils.TAG_VALUE_NONE)
)
.and(
limitedTagMetricResolver.tags(
GqlTag.OPERATION_NAME.key,
operationName.orElse(TagUtils.TAG_VALUE_ANONYMOUS)
)
)
.and(
limitedTagMetricResolver.tags(
GqlTag.QUERY_SIG_HASH.key,
querySignature.map { it.hash }.orElse(TagUtils.TAG_VALUE_NONE)
)
)
fun tags(): Iterable<Tag> {
val tags = mutableListOf<Tag>()
tags += Tag.of(
GqlTag.QUERY_COMPLEXITY.key,
queryComplexity.map { it.toString() }.orElse(TagUtils.TAG_VALUE_NONE)
)
tags += Tag.of(
GqlTag.OPERATION.key,
operation.map { it.uppercase() }.orElse(TagUtils.TAG_VALUE_NONE)
)

tags += limitedTagMetricResolver.tags(
GqlTag.OPERATION_NAME.key,
operationName.orElse(TagUtils.TAG_VALUE_ANONYMOUS)
)

tags += limitedTagMetricResolver.tags(
GqlTag.QUERY_SIG_HASH.key,
querySignature.map { it.hash }.orElse(TagUtils.TAG_VALUE_NONE)
)

return tags
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@ package com.netflix.graphql.dgs.metrics.micrometer

import com.netflix.graphql.dgs.Internal
import io.micrometer.core.instrument.Tag
import io.micrometer.core.instrument.Tags
import java.util.*

@Internal
interface LimitedTagMetricResolver {

fun tags(key: String, value: String): Tags {
return tag(key, value).map { Tags.of(it) }.orElse(Tags.empty())
fun tags(key: String, value: String): Iterable<Tag> {
return tag(key, value).map { listOf(it) }.orElse(emptyList())
}

fun tag(key: String, value: String): Optional<Tag>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.netflix.graphql.dgs.metrics.DgsMetrics.GqlMetric
import com.netflix.graphql.dgs.metrics.DgsMetrics.GqlTag
import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.Tag
import io.micrometer.core.instrument.Tags
import io.micrometer.core.instrument.Timer
import net.bytebuddy.implementation.bind.annotation.Pipe
import org.dataloader.BatchLoader
Expand All @@ -26,7 +25,7 @@ internal class BatchLoaderInterceptor(
timerSampler.stop(
Timer.builder(ID)
.tags(
Tags.of(
listOf(
Tag.of(GqlTag.LOADER_NAME.key, name),
Tag.of(GqlTag.LOADER_BATCH_SIZE.key, result.size.toString())
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.netflix.graphql.dgs.metrics.DgsMetrics.GqlMetric
import com.netflix.graphql.dgs.metrics.DgsMetrics.GqlTag
import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.Tag
import io.micrometer.core.instrument.Tags
import io.micrometer.core.instrument.Timer
import net.bytebuddy.implementation.bind.annotation.Pipe
import org.dataloader.BatchLoaderWithContext
Expand All @@ -26,7 +25,7 @@ internal class BatchLoaderWithContextInterceptor(
timerSampler.stop(
Timer.builder(ID)
.tags(
Tags.of(
listOf(
Tag.of(GqlTag.LOADER_NAME.key, name),
Tag.of(GqlTag.LOADER_BATCH_SIZE.key, result.size.toString())
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.netflix.graphql.dgs.metrics.DgsMetrics.GqlMetric
import com.netflix.graphql.dgs.metrics.DgsMetrics.GqlTag
import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.Tag
import io.micrometer.core.instrument.Tags
import io.micrometer.core.instrument.Timer
import net.bytebuddy.implementation.bind.annotation.Pipe
import org.dataloader.MappedBatchLoader
Expand All @@ -25,7 +24,7 @@ internal class MappedBatchLoaderInterceptor(
timerSampler.stop(
Timer.builder(ID)
.tags(
Tags.of(
listOf(
Tag.of(GqlTag.LOADER_NAME.key, name),
Tag.of(GqlTag.LOADER_BATCH_SIZE.key, result.size.toString())
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.netflix.graphql.dgs.metrics.DgsMetrics.GqlMetric
import com.netflix.graphql.dgs.metrics.DgsMetrics.GqlTag
import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.Tag
import io.micrometer.core.instrument.Tags
import io.micrometer.core.instrument.Timer
import net.bytebuddy.implementation.bind.annotation.Pipe
import org.dataloader.MappedBatchLoaderWithContext
Expand All @@ -26,7 +25,7 @@ internal class MappedBatchLoaderWithContextInterceptor(
timerSampler.stop(
Timer.builder(ID)
.tags(
Tags.of(
listOf(
Tag.of(GqlTag.LOADER_NAME.key, name),
Tag.of(GqlTag.LOADER_BATCH_SIZE.key, result.size.toString())
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,21 @@ import graphql.ExecutionResult
import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters
import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters
import io.micrometer.core.instrument.Tag
import io.micrometer.core.instrument.Tags

interface DgsGraphQLMetricsTagsProvider {

fun getContextualTags(): Iterable<Tag> = Tags.empty()
fun getContextualTags(): Iterable<Tag> = emptyList()

fun getExecutionTags(
state: DgsGraphQLMetricsInstrumentation.MetricsInstrumentationState,
parameters: InstrumentationExecutionParameters,
result: ExecutionResult,
exception: Throwable?
): Iterable<Tag> = Tags.empty()
): Iterable<Tag> = emptyList()

fun getFieldFetchTags(
state: DgsGraphQLMetricsInstrumentation.MetricsInstrumentationState,
parameters: InstrumentationFieldFetchParameters,
exception: Throwable?
): Iterable<Tag> = Tags.empty()
): Iterable<Tag> = emptyList()
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import graphql.ExecutionResult
import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters
import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters
import io.micrometer.core.instrument.Tag
import io.micrometer.core.instrument.Tags

class SimpleGqlOutcomeTagCustomizer : DgsExecutionTagCustomizer, DgsFieldFetchTagCustomizer {

Expand All @@ -33,9 +32,9 @@ class SimpleGqlOutcomeTagCustomizer : DgsExecutionTagCustomizer, DgsFieldFetchTa
exception: Throwable?
): Iterable<Tag> {
return if (result.errors.isNotEmpty() || exception != null) {
Tags.of(FAILURE.tag)
listOf(FAILURE.tag)
} else {
Tags.of(SUCCESS.tag)
listOf(SUCCESS.tag)
}
}

Expand All @@ -45,9 +44,9 @@ class SimpleGqlOutcomeTagCustomizer : DgsExecutionTagCustomizer, DgsFieldFetchTa
error: Throwable?
): Iterable<Tag> {
return if (error == null) {
Tags.of(SUCCESS.tag)
listOf(SUCCESS.tag)
} else {
Tags.of(FAILURE.tag)
listOf(FAILURE.tag)
}
}
}
Loading

0 comments on commit aaa04f8

Please sign in to comment.