Imagine a webapp which (sometimes) takes long time to respond to some HTTP (POST/GET/etc) request - how would You find such a request on server side?
So far I've used tomcat AccessLogValve to see the "completed" requests, but that doesn't let me to see the "in-progress" (stuck) ones :(
For example:
with
netstat
I'm able to identify long-lived sockets which could give me a count of currently-stuck requests (not URIs though), but HTTP keep-alives invalidate this approachI could stackdump the app-server (
kill -3 <server_pid>
) multiple times and guess which threads are running long and reverse-engineer the URIs - not a smart way eitherI could inject a router/proxy in front of web-app server (substitute hostnames, clone certs) which would show me the currently-running calls - not a simple approach
I could fall into just running
tcpdump
continously and parsing the traffic to keep list of currently-running URIs, but what to do with httpS then?the closest I found is tomcat7's StuckThreadDetectionValve which'd periodically reports long-running calls, but it outputs the stacktrace (not URI) and doesn't provide "live" data (e.g. only polls periodically, floods the logs and lets to see the state of 1-60 seconds ago, but not "now")
Maybe I'm just missing/overlooking one of vital/core/basic tomcat features? or maybe weblogic (or any other app-server) has something robust to offer for this?
I'm kind of lost without such simple and essential feature. Help? Please?
OK - creation of my own Valve was a proper and easy approach, sharing below. Apache did rework AccessLogValve multiple times, but all revisions follow same concept:
invoke(...)
method just usesgetNext().invoke(request,response)
to invoke a chain of remaining valves and the actual handler/executorlog(...)
method is invoked after above is completeSo we only need to:
log(...)
before thegetNext().invoke(request,response)
log(...)
to distinguish "before" and "after" invocationsEasiest way would've been:
But tomcat_6.0.16 code wasn't well-extendable, so I prefixed log-messages (in a hard-coded manner) with
Thread.getName()
and "before"/"after" indicator. Also I preferred to use reflection to accessprivate AccessLogValve.getDate()
:compiled above code with catalina.jar + servlet-api.jar and produced new catalina-my.jar, which was placed into tomcat/lib folder. After that - I've modified server.xml to have:
Here's the sample output:
This way all "in-progress" URIs can be easily retrieved at any moment: