hi, regarding the otel ktor server plugin, i notic...
# ktor
r
hi, regarding the otel ktor server plugin, i noticed the default span names / http.route attribute generated include route nodes with transparent selectors, so things like
(authentication: jwt)
show up within the generated span name which gets really noisy. Here's an example span name / http.route value:
Copy code
GET /(authenticate auth-x-forwarded-client-certs)/MTLSRouteVisibilitySelector(visibility=Private)/MTLSRouteVisibilitySelector(visibility=Public)/api/v1/users
ideally, this would be just
/api/v1/users
. the ktor otel server plugin just simply transforms the route into a string which includes all route nodes regardless if that node doesn't actually change the route path itself.
Copy code
application.monitor.subscribe(RoutingRoot.RoutingCallStarted) { call ->
    HttpServerRoute.update(Context.current(), HttpServerRouteSource.SERVER, { _, arg -> arg!!.route.parent.toString() }, call)
  }
After digging in a bit, I think some logic that filtered out routes where the selector wasn't apart of
RoutePathComponent
would do the trick. Would a PR be accepted that would: 1. change the default implementation of the http.route lambda to filter out routing nodes with non RoutePathComponent selectors 2. and support a new configuration item in the plugin that accepts a lambda of
(Call) -> String
to get the http.route from the call to allow overriding in case people want different behavior?
claude came up with something like this which seems to work in my limited testing:
Copy code
private fun Route.filteredPath(): String {
    val parentPath = parent?.filteredPath()

    if (selector !is RoutePathComponent) {
        return parentPath ?: ""
    }

    return when (parentPath) {
        null -> when (selector) {
            is TrailingSlashRouteSelector -> "/"
            else -> "/$selector"
        }

        else -> when (selector) {
            is TrailingSlashRouteSelector -> if (parentPath.endsWith('/')) parentPath else "$parentPath/"
            else -> if (parentPath.endsWith('/')) "$parentPath$selector" else "$parentPath/$selector"
        }
    }
}
I don't love the duplication of the existing Route.toString(), this feels like this could be an extension function just shipped within ktor itself which could be used in the otel instrumentation
b
We already have a utility function for this:
Copy code
/**
 * String representation of the path matched by this route.
 *
 * [Report a problem](<https://ktor.io/feedback/?fqname=io.ktor.server.routing.path>)
 */
public val Route.path: String
    get() = path()

/**
 * Constructs the full path of the routing node by combining the path of the parent node
 * and the formatted path of this node's selector, using the provided format.
 *
 * [Report a problem](<https://ktor.io/feedback/?fqname=io.ktor.server.routing.path>)
 *
 * @param format formats each selector in the node's lineage. Defaults to [RoutePathFormat.Default].
 * @return the full path of the routing node as a string.
 */
public fun Route.path(format: RoutePathFormat = RoutePathFormat.Default): String {
    val parentPath = parent?.path(format)
    val pathComponent = selector as? RoutePathComponent ?: return parentPath.orEmpty()
    val formattedPath = format.format(pathComponent)
    return when {
        parentPath == null -> formattedPath
        formattedPath.isEmpty() -> parentPath
        parentPath.endsWith('/') || formattedPath.startsWith('/') -> "$parentPath$formattedPath"
        else -> "$parentPath/$formattedPath"
    }
}
It would make sense to use this instead of
toString()
in the otel plugin
r
Lmao, amazing. Ya I think just using that would be simplest fix for sure
b
it was only introduced in 3.3.0 I think... so maybe if they're supporting back to 3.0 it won't be possible
r
Got it, so maybe we'll have to do some duplication for now. This also would be a potential breaking change because it would shift the http route name. So we'd need to feature flag/opt into it if we release for ktor2/3
👍 1
just deployed an internal fix on our side which to use route.path and works like a charm. @Bruce Hamilton is this something ktor would be willing to accept a pr for?
b
nice. yeah, fire away 👍