tomcat-dev mailing list archives

All,
I'm in the process of constructing a filter that logs context access to
a database, but I'm running into a bit of trouble.
First off, if anyone knows of any free filters that do this, then I'm
barking up the wrong tree. I don't want to reinvent the wheel! (And I
can't believe this isn't a common thing.)
Most of the information that you'd need for an access log is readily
available in the request and response objects, however two common
metrics are (seemingly) difficult to get to, namely the response size
(in bytes) and the response HTTP status code. I won't wail on how the
response object should have a "getStatus()" and "getResponseSize()"
magic methods; they probably aren't in the spec (I haven't bothered to
check).
I figured my optimal solution was a filter, since I'd like this thing to
be somewhat portable. (Tomcat valves aren't portable, correct?) Now, I
have read "The Essentials of Filters"
(http://java.sun.com/products/servlet/Filters.html), and believe that I
understand it well enough, and I have also looked at the source for the
Compression filter.
For the status code, my wrapper has overridden the setStatus(int sc) and
sendError(int sc)/sendError(int sc, String message) methods. I trap the
status code as appropriate and then pass the values right on through to
the original response. Then it's a simple matter of adding a
getStatus() method on my wrapper to obtain the status.
For the response size, I had to also write a wrapper class extending
ServletOutputStream. This class takes a ServletOutputStream as an
argument to the constructor, which is then stored as a protected member
(named "output"). The write() method was implemented to increment a
long by 1 every time the method is called, then immediately pass the
argument right along to the "output" member. write(int b) was the only
method that I overrode. I also added a method to retrieve the long that
was incremented each time write() was called, thus telling me how many
bytes were sent to the client. I have also tried simply overriding the
setContentLength() method in my response wrapper, but this wasn't
entirely successful, as you'll see in my problems below.
My problems are this:
1. Somehow HTTP status codes of 200 (SC_OK) are set without being
properly trapped by the response wrapper. I have to set a default value
of 200 in the wrapper, which I'd rather not do. Redirects,
page-not-found, etc., are properly trapped.
2. The response size measurement is completely off. Trapping
setContentLength() in the response wrapper seems to not catch every case
(404's and 500's don't seem to call setContentLength(), or they call it
before I create the wrapper). The stream wrapper is similarly
inaccurate, in that error pages don't seem to call the write() method.
Probably both issues are related.
Is my approach too simple-minded? Am I trying to do too much with
what's available to a filter? Is this something that's more properly
suited to a valve?
Thanks for your help, and sorry for the length.
Brantley Hobbs
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org