iRule help for server response time
Hi folks, new to iRules and programming in general.
I'm logging server response times with this simple iRule:
when HTTP_REQUEST {
set http_request_time [clock clicks -milliseconds]
}
when HTTP_RESPONSE {
set http_response_time [clock clicks -milliseconds]
log local0. "Time to response = [expr $http_response_time - $http_request_time]"
}
How would I expand the iRule so that only responses taking longer than 1000ms are logged?
And for those responses over 1000ms I would like to log requested URI, client IP address & port, and server IP address & port.
I have tried variations on the following but can't get it right, and would appreciate some help!
when HTTP_REQUEST {
set http_request_time [clock clicks -milliseconds]
}
when HTTP_RESPONSE {
set http_response_time [clock clicks -milliseconds]
}
if {[expr $http_response_time - $http_request_time] > 1000
} then {
log local0. "Server response took longer than 1000ms. TCP connection from [IP::client_addr]:[TCP::client_port] to [IP::local_addr]:[TCP::local_port]. Requested URI is [HTTP::uri]"
}
Thanks in advance
You are very close! A few things:
- conditionals in Tcl are implicitly wrapped in an expr, so there is no need to rewrap the expression;
- there is no then sub-command/keyword;
- all code must be in an event block;
- IP::local_addr and TCP::local_port have two contexts: the clientside (which means the Virtual Server VIP:port) and the serverside (which means the source address and port for the proxy connection toward the Pool Member). If you are not explicit about which context you mean, the context appropriate for the event will be used. Thus, for HTTP_RESPONSE, the implicit context is serverside, so to mean "VIP:port", you must explicitly disambiguate using the clientside command;
- HTTP::uri is not available in HTTP_RESPONSE so you must retrieve and store the value in HTTP_REQUEST.
A few references regarding this:
- https://devcentral.f5.com/wiki/iRules.clientside.ashx
- See Valid Events section of https://devcentral.f5.com/wiki/iRules.HTTP__uri.ashx
when HTTP_REQUEST { set http_request_time [clock clicks -milliseconds] set request_uri [HTTP::uri] } when HTTP_RESPONSE { if { [clock clicks -milliseconds] - $http_request_time > 1000 } { log local0. "Server response took longer than 1000ms. TCP connection from [IP::client_addr]:[TCP::client_port] to [clientside [IP::local_addr]]:[clientside [TCP::local_port]]. Requested URI is $request_uri" } }
For production usage, you should consider either using High-Speed Logging or, better yet, the built-in HTTP Request Logging Profile employing CLIENT_IP, CLIENT_PORT, VIRTUAL_IP, VIRTUAL_PORT, HTTP_URI and RESPONSE_MSECS in the template. This would log every request, but you could process the (remotely deposited) logs for those that take longer than a threshold (like 1000 ms).