Friday, December 27, 2013

Logging Rest calls in JBoss

Trying to use HTTP request logging will be of no use since REST calls use different content type than regular HTTP cals.
A custom server-side REST interceptor can do our job.

  • Create a maven based project and include dependencies to resteasy-jaxrs (groupId org.jboss.resteasy),resteasy-jaxb-provider (groupId org.jboss.resteasy) and servlet-api (groupId javax.servlet)
  • Create a class that contains our interceptor:

@Provider
@ServerInterceptor
public class RestEasyLogger implements PreProcessInterceptor, MessageBodyWriterInterceptor {

    Logger logger = Logger.getLogger(RestEasyLogger.class);

    @Context
    HttpServletRequest servletRequest;

    public ServerResponse preProcess(HttpRequest request,
            ResourceMethod resourceMethod) throws Failure,
            WebApplicationException {

        logger.info("Receiving request : " + servletRequest.getRequestURL().toString());

        BufferedInputStream bis = new BufferedInputStream(request.getInputStream());
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        String content = "";
        int result;
        try {
            result = bis.read();
            while (result != -1) {
                byte b = (byte) result;
                buf.write(b);
                result = bis.read();
            }
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(RestEasyLogger.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            content = buf.toString("UTF-8");
            ByteArrayInputStream bi = new ByteArrayInputStream(buf.toByteArray());
            request.setInputStream(bi);
        } catch (UnsupportedEncodingException ex) {
            java.util.logging.Logger.getLogger(RestEasyLogger.class.getName()).log(Level.SEVERE, null, ex);
        }

        logger.info("\t\t" + content);

        return null;
    }

    public void write(MessageBodyWriterContext mbwc) throws IOException, WebApplicationException {

        OutputStream oStream = mbwc.getOutputStream();
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        mbwc.setOutputStream(buf);
        mbwc.proceed();
        String content = buf.toString("UTF-8");
        oStream.write(buf.toByteArray());
        mbwc.setOutputStream(oStream);
        logger.info("\t\t" + content);

    }


  • Configure logging for our class in standalone-full.xml (or whatever configuration file you use for JBoss start-up)

         <subsystem xmlns="urn:jboss:domain:logging:1.1">
            <console-handler name="CONSOLE">
                <level name="INFO"/>
                <formatter>
                    <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
                </formatter>
            </console-handler>
            <periodic-rotating-file-handler name="FILE">
                <formatter>
                    <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
                </formatter>
                <file relative-to="jboss.server.log.dir" path="server.log"/>
                <suffix value=".yyyy-MM-dd"/>
                <append value="true"/>
            </periodic-rotating-file-handler>
            <periodic-rotating-file-handler name="FILE-RESTEASY">
                <formatter>
                    <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
                </formatter>
                <file relative-to="jboss.server.log.dir" path="rs.log"/>
                <suffix value=".yyyy-MM-dd"/>
                <append value="true"/>
            </periodic-rotating-file-handler>
            <logger category="com.arjuna">
                <level name="WARN"/>
            </logger>
            <logger category="org.apache.tomcat.util.modeler">
                <level name="WARN"/>
            </logger>
            <logger category="sun.rmi">
                <level name="WARN"/>
            </logger>
            <logger category="jacorb">
                <level name="WARN"/>
            </logger>
            <logger category="jacorb.config">
                <level name="ERROR"/>
            </logger>
            <logger category="ro.mycompany.jbpm.resteasy.logging.RestEasyLogger" use-parent-handlers="false">
                <level name="DEBUG"/>
                <handlers>
                    <handler name="FILE-RESTEASY"/>
                </handlers>
            </logger>
            <root-logger>
                <level name="INFO"/>
                <handlers>
                    <handler name="CONSOLE"/>
                    <handler name="FILE"/>
                </handlers>
            </root-logger>
        </subsystem>



  • Deploy the resulted jar inside the targeted war (inside WEB_INF\lib)
  • Do some REST calls; you should be able to see detailed info in standalone\log\rs.log

1 comment :

  1. Can you provide the link for reading the response via MessageBodyReaderContext

    ReplyDelete