views:

45

answers:

2

I'm kind of new to the Java world, and I need to debug a restful Javax Web Service application.

Some pages raise exceptions, and they are logged correctly, but I would like to have the URL of the page that called the code, inside of my logs, as well as the stacktrace.

GET and POST information would be vital too.

Is it possible?

A: 

Yes... use AccessLogValve.

For example, in c:\Program Files\Apache Software Foundation\Tomcat 6.0\conf\server.xml, put something like the following into your <Host> element:

   <Valve className="org.apache.catalina.valves.AccessLogValve"
        directory="logs/access-logs/" prefix="localhost_access_log."
        suffix=".log"
        pattern="%h %l %t &quot;%r&quot; %s %b &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot; %T"
        resolveHosts="false"/> 

See the docs for information about the % fields. E.g. you asked for GET and POST information; the method is shown by the %r (or %m) field. If you want query parameters, they will be part of the query string (%q) for GETs.

The above information will go into an access log that you specify. If you are asking to have this information in the error logs whenever (and only when) an error occurs: some components do that already, but I don't know how to make it happen otherwise. When I get an error and there's no URL given, I use the timestamps from the error logs and access logs to correlate the two.

You can set the granularity of logging for various facilities: see Logging in Tomcat. That can get you more information, which may or may not be relevant to any errors that occur.

LarsH
This data would go into the access log - I think the OP wants it logged in error log along with stacktrace. so he can track the error with the originator.
JoseK
@JoseK thanks for the feedback. I updated my post to reflect that to the degree that I could. Glad to learn from your answer.
LarsH
@LarsH - you're welcome :)
JoseK
This does not show POST parameters
Mahoua
@Mahoua That's right. I don't think AccessLogValve can do that. It's designed for one-record-per-line logging. You might try RequestDumperValve, but it looks like JoseK's answer is more up your alley.
LarsH
The request body ("POST parameters") can be megabytes in size, and it could be a jpg or mp3. In general it's not something that fits well in a log file. See my comment on JoseK's answer...
LarsH
+2  A: 

Since you want this in your error logs along with (or close to) the stacktrace, you probably need a Filter.

Implement the doFilter() method to check and log the calling URL for each request. I've given some sample code below.

Once you get access to the HttpServletRequest object, you can call any of it's methods.See the getRequestURI() and getMethod() which are the ones you need.

public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException
  {

HttpServletRequest hsr = (HttpServletRequest) request;


String incomingUrl=hsr.getRequestURI(); // fetch URL
String method =hsr.getMethod(); // fetch GET/POST method
logger.debug ("The caller was " + incomingUrl + method); // Send the output to any logger which you have defined
chain.doFilter(request, response);
}

I'm assuming you have a logger in place and you can send the output to the log file you wish to.

Map this Filter on a url-pattern like /mywebservice in the web.xml so that it does not get called on other requests but only on your web service.

<filter>
        <filter-name>Logging_URL_Filter</filter-name>
        <filter-class>com.mysite.URLFilter</filter-class>
    </filter>
<filter-mapping>
          <filter-name>Logging_URL_Filter</filter-name>
          <url-pattern>/mywebservice</url-pattern>
    </filter-mapping>
JoseK
Thanks, it works, but it's called for every page access.Is there a way to trigger it only on errors?
Mahoua
If you want to get at the request body (the data for POST requests), use `hsr.getReader()` (http://download.oracle.com/docs/cd/E17802_01/products/products/servlet/2.5/docs/servlet-2_5-mr2/index.html) if it's character data.
LarsH
@Mahoua : Unfortunately in this case, the Filter is always triggered before the request is executed, so it wont know if it's going to be a success or error.
JoseK