ktor net attribute extraction (#5027)
* ktor net attribute extraction * spotless
This commit is contained in:
parent
12c15b226f
commit
55e44d790c
|
@ -5,7 +5,6 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.ktor.v1_0
|
||||
|
||||
import io.ktor.application.*
|
||||
import io.ktor.request.*
|
||||
import io.opentelemetry.context.propagation.TextMapGetter
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.ktor.v1_0
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
// Source: Regular Expressions Cookbook 2nd edition - 8.17.
|
||||
// Matching IPv6 Addresses
|
||||
private val ipv6 = Pattern.compile( // Non Compressed
|
||||
"^(?:(?:(?:[A-F0-9]{1,4}:){6}" + // Compressed with at most 6 colons
|
||||
"|(?=(?:[A-F0-9]{0,4}:){0,6}" + // and 4 bytes and anchored
|
||||
"(?:[0-9]{1,3}\\.){3}[0-9]{1,3}(?![:.\\w]))" + // and at most 1 double colon
|
||||
"(([0-9A-F]{1,4}:){0,5}|:)((:[0-9A-F]{1,4}){1,5}:|:)" + // Compressed with 7 colons and 5 numbers
|
||||
"|::(?:[A-F0-9]{1,4}:){5})" + // 255.255.255.
|
||||
"(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}" + // 255
|
||||
"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" + // Standard
|
||||
"|(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}" + // Compressed with at most 7 colons and anchored
|
||||
"|(?=(?:[A-F0-9]{0,4}:){0,7}[A-F0-9]{0,4}(?![:.\\w]))" + // and at most 1 double colon
|
||||
"(([0-9A-F]{1,4}:){1,7}|:)((:[0-9A-F]{1,4}){1,7}|:)" + // Compressed with 8 colons
|
||||
"|(?:[A-F0-9]{1,4}:){7}:|:(:[A-F0-9]{1,4}){7})(?![:.\\w])\$",
|
||||
Pattern.CASE_INSENSITIVE
|
||||
)
|
||||
|
||||
// Source: Regular Expressions Cookbook 2nd edition - 8.16.
|
||||
// Matching IPv4 Addresses
|
||||
private val ipv4 = Pattern.compile(
|
||||
"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}" +
|
||||
"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\$"
|
||||
)
|
||||
|
||||
fun isIpAddress(address: String): Boolean {
|
||||
return ipv4.matcher(address).matches() || ipv6.matcher(address).matches()
|
||||
}
|
|
@ -5,11 +5,9 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.ktor.v1_0
|
||||
|
||||
import io.ktor.application.*
|
||||
import io.ktor.features.*
|
||||
import io.ktor.request.*
|
||||
import io.ktor.response.*
|
||||
import io.ktor.routing.*
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.ktor.v1_0
|
||||
|
||||
import io.ktor.features.*
|
||||
import io.ktor.request.*
|
||||
import io.ktor.response.*
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.net.NetServerAttributesExtractor
|
||||
|
@ -16,15 +15,23 @@ internal class KtorNetServerAttributesExtractor : NetServerAttributesExtractor<A
|
|||
return SemanticAttributes.NetTransportValues.IP_TCP
|
||||
}
|
||||
|
||||
override fun peerName(request: ApplicationRequest): String {
|
||||
return request.origin.host
|
||||
override fun peerName(request: ApplicationRequest): String? {
|
||||
var remote = request.local.remoteHost
|
||||
if (remote != null && "unknown" != remote && !isIpAddress(remote)) {
|
||||
return remote
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun peerPort(request: ApplicationRequest): Int {
|
||||
return request.origin.port
|
||||
override fun peerPort(request: ApplicationRequest): Int? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun peerIp(request: ApplicationRequest): String {
|
||||
return request.origin.remoteHost
|
||||
override fun peerIp(request: ApplicationRequest): String? {
|
||||
var remote = request.local.remoteHost
|
||||
if (remote != null && "unknown" != remote && isIpAddress(remote)) {
|
||||
return remote
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.ktor.v1_0
|
||||
|
||||
import spock.lang.Specification
|
||||
|
||||
class IpAddressUtilTest extends Specification {
|
||||
|
||||
def "test ip address"() {
|
||||
expect:
|
||||
assert IpAddressUtilKt.isIpAddress("2001:0660:7401:0200:0000:0000:0edf:bdd7")
|
||||
assert !IpAddressUtilKt.isIpAddress("2001:0660:7401:0200:0000:0000:0edf:bdd7:33")
|
||||
assert IpAddressUtilKt.isIpAddress("127.0.0.1")
|
||||
assert !IpAddressUtilKt.isIpAddress("127.0.0.1.1")
|
||||
assert !IpAddressUtilKt.isIpAddress("localhost")
|
||||
}
|
||||
}
|
|
@ -679,7 +679,7 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
|||
}
|
||||
// net.peer.name resolves to "127.0.0.1" on windows which is same as net.peer.ip so then not captured
|
||||
"$SemanticAttributes.NET_PEER_NAME" { it == null || it == address.host }
|
||||
"$SemanticAttributes.NET_PEER_PORT" { it == null || it instanceof Long }
|
||||
"$SemanticAttributes.NET_PEER_PORT" { it == null || (it instanceof Long && it != port) }
|
||||
"$SemanticAttributes.NET_PEER_IP" { it == null || it == peerIp(endpoint) } // Optional
|
||||
|
||||
"$SemanticAttributes.HTTP_CLIENT_IP" { it == null || it == TEST_CLIENT_IP }
|
||||
|
|
Loading…
Reference in New Issue