You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2026-06-03 18:35:08 +02:00
Update ServerRequest to accept server name (#3619)
* Update ServerRequest to accept server name * Update docs to include Apache and nginx examples * Test the server not containing a port
This commit is contained in:
@@ -136,14 +136,39 @@ func (c *HTTPConv) ClientRequest(req *http.Request) []attribute.KeyValue {
|
||||
}
|
||||
|
||||
// ServerRequest returns attributes for an HTTP request received by a server.
|
||||
//
|
||||
// The server must be the primary server name if it is known. For example this
|
||||
// would be the ServerName directive
|
||||
// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache
|
||||
// server, and the server_name directive
|
||||
// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an
|
||||
// nginx server. More generically, the primary server name would be the host
|
||||
// header value that matches the default virtual host of an HTTP server. It
|
||||
// should include the host identifier and if a port is used to route to the
|
||||
// server that port identifier should be included as an appropriate port
|
||||
// suffix.
|
||||
//
|
||||
// If the primary server name is not known, server should be an empty string.
|
||||
// The req Host will be used to determine the server instead.
|
||||
//
|
||||
// The following attributes are always returned: "http.method", "http.scheme",
|
||||
// "http.flavor", "http.target", "net.host.name". The following attributes are
|
||||
// returned if they related values are defined in req: "net.host.port",
|
||||
// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id",
|
||||
// "http.client_ip".
|
||||
func (c *HTTPConv) ServerRequest(req *http.Request) []attribute.KeyValue {
|
||||
func (c *HTTPConv) ServerRequest(server string, req *http.Request) []attribute.KeyValue {
|
||||
n := 5 // Method, scheme, target, proto, and host name.
|
||||
host, p := splitHostPort(req.Host)
|
||||
var host string
|
||||
var p int
|
||||
if server == "" {
|
||||
host, p = splitHostPort(req.Host)
|
||||
} else {
|
||||
// Prioritize the primary server name.
|
||||
host, p = splitHostPort(server)
|
||||
if p < 0 {
|
||||
_, p = splitHostPort(req.Host)
|
||||
}
|
||||
}
|
||||
hostPort := requiredHTTPPort(req.TLS != nil, p)
|
||||
if hostPort > 0 {
|
||||
n++
|
||||
|
||||
@@ -178,13 +178,34 @@ func TestHTTPServerRequest(t *testing.T) {
|
||||
attribute.String("enduser.id", user),
|
||||
attribute.String("http.client_ip", clientIP),
|
||||
},
|
||||
hc.ServerRequest(req))
|
||||
hc.ServerRequest("", req))
|
||||
}
|
||||
|
||||
func TestHTTPServerName(t *testing.T) {
|
||||
req := new(http.Request)
|
||||
var got []attribute.KeyValue
|
||||
const (
|
||||
host = "test.semconv.server"
|
||||
port = 8080
|
||||
)
|
||||
portStr := strconv.Itoa(port)
|
||||
server := host + ":" + portStr
|
||||
assert.NotPanics(t, func() { got = hc.ServerRequest(server, req) })
|
||||
assert.Contains(t, got, attribute.String("net.host.name", host))
|
||||
assert.Contains(t, got, attribute.Int("net.host.port", port))
|
||||
|
||||
req = &http.Request{Host: "alt.host.name:" + portStr}
|
||||
// The server parameter does not include a port, ServerRequest should use
|
||||
// the port in the request Host field.
|
||||
assert.NotPanics(t, func() { got = hc.ServerRequest(host, req) })
|
||||
assert.Contains(t, got, attribute.String("net.host.name", host))
|
||||
assert.Contains(t, got, attribute.Int("net.host.port", port))
|
||||
}
|
||||
|
||||
func TestHTTPServerRequestFailsGracefully(t *testing.T) {
|
||||
req := new(http.Request)
|
||||
var got []attribute.KeyValue
|
||||
assert.NotPanics(t, func() { got = hc.ServerRequest(req) })
|
||||
assert.NotPanics(t, func() { got = hc.ServerRequest("", req) })
|
||||
want := []attribute.KeyValue{
|
||||
attribute.String("http.method", "GET"),
|
||||
attribute.String("http.target", ""),
|
||||
|
||||
Reference in New Issue
Block a user