Skip to content

Commit

Permalink
update metric names and attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
aajtodd committed Jun 29, 2023
1 parent ccb3234 commit b979988
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,48 @@ public class HttpClientMetrics(
/**
* The amount of time it takes to acquire a connection from the pool
*/
public val connectionAcquireDuration: LongHistogram = meter.createLongHistogram("aws.smithy.http.connections.acquire_duration", "ms", "The amount of time requests take to acquire a connection from the pool")
public val connectionAcquireDuration: LongHistogram = meter.createLongHistogram(
"smithy.client.http.connections.acquire_duration",
"ms",
"The amount of time requests take to acquire a connection from the pool",
)

/**
* The amount of time a request spent queued waiting to be executed by the HTTP client
*/
public val concurrencyQueuedDuration: LongHistogram = meter.createLongHistogram(
"smithy.client.http.concurrency.queued_duration",
"ms",
"The amount of time a requests spent queued waiting to be executed by the HTTP client",
)

private val connectionLimitHandle = meter.createAsyncUpDownCounter(
"aws.smithy.http.connections.limit",
"smithy.client.http.connections.limit",
{ it.record(_connectionsLimit.value) },
"{connection}",
"Max connections configured for the HTTP client",
)

private val connectionUsageHandle = meter.createAsyncUpDownCounter(
"aws.smithy.http.connections.usage",
"smithy.client.http.connections.usage",
::recordConnectionState,
"{connection}",
"Current state of connections (idle, acquired)",
)

private val requestsHandle = meter.createAsyncUpDownCounter(
"aws.smithy.http.requests",
// TODO - enable?
// private val concurrencyLimitHandle = meter.createAsyncUpDownCounter(
// "smithy.client.http.concurrency.limit",
// { it.record(_connectionsLimit.value) },
// "{connection}",
// "Max connections configured for the HTTP client",
// )

private val concurrencyHandle = meter.createAsyncUpDownCounter(
"smithy.client.http.concurrency.usage",
::recordRequestsState,
"{request}",
"The current state of requests (queued, in-flight)",
"The current state of HTTP client request concurrency (queued, in-flight, available)",
)

/**
Expand Down Expand Up @@ -161,6 +182,6 @@ public class HttpClientMetrics(
override fun close() {
connectionLimitHandle.stop()
connectionUsageHandle.stop()
requestsHandle.stop()
concurrencyHandle.stop()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,6 @@ internal class OperationTelemetryInterceptor(
metrics.serializationDuration.record(serializeDuration, perRpcAttributes, metrics.provider.contextManager.current())
}

override fun readBeforeSigning(context: ProtocolRequestInterceptorContext<Any, HttpRequest>) {
signingStart = timeSource.markNow()
}

override fun readAfterSigning(context: ProtocolRequestInterceptorContext<Any, HttpRequest>) {
val signingDuration = signingStart?.elapsedNow()?.inWholeMilliseconds ?: return
metrics.serializationDuration.record(signingDuration, perRpcAttributes, metrics.provider.contextManager.current())
}

override fun readBeforeDeserialization(context: ProtocolResponseInterceptorContext<Any, HttpRequest, HttpResponse>) {
deserializeStart = timeSource.markNow()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ public class OperationMetrics(
val None: OperationMetrics = OperationMetrics("NoOp", TelemetryProvider.None)
}

public val rpcCallDuration: LongHistogram = meter.createLongHistogram("rpc.client.duration", "ms", "Overall call duration including retries")
public val rpcRequestSize: LongHistogram = meter.createLongHistogram("rpc.client.request.size", "By", "Size of RPC request message")
public val rpcResponseSize: LongHistogram = meter.createLongHistogram("rpc.client.response.size", "By", "Size of RPC response message")
public val serviceCallDuration: LongHistogram = meter.createLongHistogram("aws.smithy.service_call_duration", "ms", "The time it takes to connect to the service, send the request, and receive the HTTP status code and headers from the response")
public val serializationDuration: LongHistogram = meter.createLongHistogram("aws.smithy.serialization.duration", "ms", "The time it takes to serialize a request message body")
public val deserializationDuration: LongHistogram = meter.createLongHistogram("aws.smithy.deserialization.duration", "ms", "The time it takes to deserialize a response message body")
public val resolveEndpointDuration: LongHistogram = meter.createLongHistogram("aws.smithy.resolve_endpoint_duration", "ms", "The time it takes to resolve an endpoint for a request")
public val resolveIdentityDuration: LongHistogram = meter.createLongHistogram("aws.smithy.auth.resolve_identity_duration", "ms", "The time it takes to resolve an identity for signing a request")
public val signingRequestDuration: LongHistogram = meter.createLongHistogram("aws.smithy.auth.sign_request_duration", "ms", "The time it takes to sign a request")
public val rpcCallDuration: LongHistogram = meter.createLongHistogram("smithy.client.duration", "ms", "Overall call duration including retries")
public val rpcRequestSize: LongHistogram = meter.createLongHistogram("smithy.client.request.size", "By", "Size of the serialized request message")
public val rpcResponseSize: LongHistogram = meter.createLongHistogram("smithy.client.response.size", "By", "Size of the serialized response message")
public val serviceCallDuration: LongHistogram = meter.createLongHistogram("smithy.client.service_call_duration", "ms", "The time it takes to connect to the service, send the request, and receive the HTTP status code and headers from the response")
public val serializationDuration: LongHistogram = meter.createLongHistogram("smithy.client.serialization_duration", "ms", "The time it takes to serialize a request message body")
public val deserializationDuration: LongHistogram = meter.createLongHistogram("smithy.client.deserialization_duration", "ms", "The time it takes to deserialize a response message body")
public val resolveEndpointDuration: LongHistogram = meter.createLongHistogram("smithy.client.resolve_endpoint_duration", "ms", "The time it takes to resolve an endpoint for a request")
public val resolveIdentityDuration: LongHistogram = meter.createLongHistogram("smithy.client.auth.resolve_identity_duration", "ms", "The time it takes to resolve an identity for signing a request")
public val signingDuration: LongHistogram = meter.createLongHistogram("smithy.client.auth.signing_duration", "ms", "The time it takes to sign a request")
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,14 @@ internal fun<I, O> SdkHttpOperation<I, O>.instrument(): Pair<TraceSpan, Coroutin
val tracer = telemetry.provider.tracerProvider.getOrCreateTracer(scope)
val parentCtx = telemetry.provider.contextManager.current()

val initialAttributes = mutableAttributesOf {
val opAttributes = attributesOf {
"rpc.service" to serviceName
"rpc.method" to opName
}

initialAttributes.merge(telemetry.attributes)
val initialAttributes = telemetry.attributes.toMutableAttributes().apply {
merge(opAttributes)
}

val rpcName = "$serviceName.$opName"
val spanName = telemetry.spanName ?: rpcName
Expand All @@ -85,7 +87,7 @@ internal fun<I, O> SdkHttpOperation<I, O>.instrument(): Pair<TraceSpan, Coroutin
)

context[HttpOperationContext.OperationMetrics] = telemetry.metrics
context[HttpOperationContext.OperationAttributes] = initialAttributes
context[HttpOperationContext.OperationAttributes] = opAttributes

// wire up operation level telemetry (other metrics e.g. from http are instrumented elsewhere)
interceptors.add(OperationTelemetryInterceptor(telemetry.metrics, serviceName, opName))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ import aws.smithy.kotlin.runtime.retries.policy.StandardRetryPolicy
import aws.smithy.kotlin.runtime.telemetry.logging.debug
import aws.smithy.kotlin.runtime.telemetry.logging.logger
import aws.smithy.kotlin.runtime.telemetry.logging.trace
import aws.smithy.kotlin.runtime.util.attributesOf
import aws.smithy.kotlin.runtime.util.merge
import kotlin.coroutines.coroutineContext
import kotlin.time.ExperimentalTime
import kotlin.time.measureTime
import kotlin.time.measureTimedValue
import aws.smithy.kotlin.runtime.io.middleware.decorate as decorateHandler

Expand Down Expand Up @@ -269,12 +271,16 @@ internal class AuthHandler<Input, Output>(
val authOption = candidateAuthSchemes.firstOrNull { it.schemeId in authConfig.configuredAuthSchemes } ?: error("no auth scheme found for operation; candidates: $candidateAuthSchemes")
val authScheme = authConfig.configuredAuthSchemes[authOption.schemeId] ?: error("auth scheme ${authOption.schemeId} not configured")

val schemeAttr = attributesOf {
"auth.scheme_id" to authScheme.schemeId.id
}

// resolve identity from the selected auth scheme
val identityProvider = authScheme.identityProvider(authConfig.identityProviderConfig)
val identity = measureTimedValue {
identityProvider.resolve(authOption.attributes)
}.let {
request.context.operationMetrics.resolveIdentityDuration.record(it.duration.inWholeMilliseconds, request.context.operationAttributes)
request.context.operationMetrics.resolveIdentityDuration.record(it.duration.inWholeMilliseconds, schemeAttr)
it.value
}

Expand All @@ -299,7 +305,12 @@ internal class AuthHandler<Input, Output>(
// signing properties need to propagate from AuthOption to signer
modified.context.merge(authOption.attributes)
val signingRequest = SignHttpRequest(modified.subject, identity, modified.context)
authScheme.signer.sign(signingRequest)

measureTime {
authScheme.signer.sign(signingRequest)
}.let {
request.context.operationMetrics.signingDuration.record(it.inWholeMilliseconds, schemeAttr)
}

interceptors.readAfterSigning(modified.subject.immutableView())
return inner.call(modified)
Expand Down

0 comments on commit b979988

Please sign in to comment.