https://kotlinlang.org logo
#http4k
Title
# http4k
m

michaelbannister

05/28/2021, 3:09 PM
Hello! I’ve been playing with the OpenTelemetry module for the Tracing filters and wanted to have an easy way to name the server spans for each different route. Rather than pass a spanNamer – which would have the effect of having my naming logic separated from the routing definition, I extended the routing DSL a little bit to get this:
Copy code
fun endpoints() = "/orders" bind POST to routes(
            "/create" bind ::createOrder named "Create Order",
            "/submit" bind ::submitOrder named "Submit Order",
    )

object SpanNameFilter {
    operator fun invoke(name: String) = Filter { next ->
        { req ->
            Span.current().updateName(name)
            next(req)
        }
    }
}

infix fun RoutingHttpHandler.named(name: String) = SpanNameFilter(name).then(this)
Wondered if this might be something you’d be interested in adding to the opentelemetry module in some form or other? Or is there a different way of doing this you’d recommend? Would a more general ability to name RoutingHttpHandlers be useful?
Related note: the OpenTelemetry spec says that HTTP spans shouldn’t use the full URI path as a span name, since often (with IDs in paths) this yields high-cardinality span names. So the default spanNamer is a bit risky in that respect. I wondered if ServerFilters.OpenTelemetryTracing could use the same logic it used to set the
http.route
attribute, for the span name?
r

Razvan

05/28/2021, 4:41 PM
Hi, I don’t use (sadly) OT, but I see in the Server et Client Filter the span name being a function. So I guess you can set your own fonction to set the spanNamer from the request… the full URI is not always the best as you say it can have ids. but it’s a simple default, up to you to come up with something custom to your endpoint:
Copy code
fun ServerFilters.OpenTelemetryTracing(
    openTelemetry: OpenTelemetry = GlobalOpenTelemetry.get(),
    spanNamer: (Request) -> String = { it.uri.toString() },
    error: (Request, Throwable) -> String = { _, t -> t.localizedMessage },
): Filter
Well after re-reading your post I guess that does not help as you wanted to keep the naming in the route… instead of another mapping function. Forget it!
2 Views