Announcement Announcement Module
Collapse
No announcement yet.
CustomizableTraceInterceptor Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • CustomizableTraceInterceptor

    Hi,

    I'm using the CustomizableTraceInterceptor to trace my method calls, works fine.
    I have set useDynamicLogger and hideProxyClassNames to true, so I can use standard log4j config to decide which class shall be traced which not.

    The problem I'm facing is that I want exception ALWAYS logged, Enter and Exit only if enabled.

    It seems that this is not possible with a single CustomizableTraceInterceptor. Setting loglevel to ERROR means that nothing is logged anymore, because the CustomizableTraceInterceptor seems to need level TRACE or DEBUG.

    Do I really need another Interceptor for logging exception always?

    Thx

  • #2
    I would take a look at the code for this, it explains what you need to do.
    Code:
    	/**
    	 * Writes the supplied message and {@link Throwable} to the
    	 * supplied <code>Log</code> instance. By default messages are written
    	 * at <code>TRACE</code> level. Sub-classes can override this method
    	 * to control which level the message is written at.
    	 */
    	protected void writeToLog(Log logger, String message, Throwable ex) {
    		if (ex != null) {
    			logger.trace(message, ex);
    		}
    		else {
    			logger.trace(message);
    		}
    	}

    Comment


    • #3
      It seem that the logger must be on level DEBUG/TRACE. If I set the corresponding log4j-logger to ERROR my interceptor is never called

      Comment


      • #4
        OK, looking into the sources makes it clear:

        Code:
        	protected boolean isLogEnabled(Log logger) {
        		return logger.isTraceEnabled();
        	}
        Unfortunately one cannot really override CustomizableTraceInterceptor.invokeUnderTrace because the message patterns are private.

        So I wrote a second interceptor for exception-logging only:
        Code:
        public class ExceptionLogInterceptor extends AbstractTraceInterceptor {
        	private boolean logAlways = false;
        	
        	public void setLogAlways(boolean logAlways) {
        		this.logAlways = logAlways;
        	}
        
        	@Override
        	protected Object invokeUnderTrace(MethodInvocation invocation, Log logger) throws Throwable {
        		try {
        			return invocation.proceed();
        		}
        		catch (Throwable ex) {
        			String name = invocation.getMethod().getDeclaringClass().getName() + "." + invocation.getMethod().getName();
        			logger.error(name, ex);
        			throw ex;
        		}
        	}
        	
        	@Override
        	protected boolean isLogEnabled(Log logger) {
        		//log only if ERROR is on and 
        		//(TRACE off (exception already logged by a TraceInterceptor) or logAlways is set to true)
        		return logger.isErrorEnabled() && (logAlways || !logger.isTraceEnabled());
        	}
        }
        And ordered it after the TraceInterceptor.

        Comment


        • #5
          Why does it have to be that hard?
          Code:
          	protected void writeToLog(Log logger, String message, Throwable ex) {
          		if (ex != null) {
          			logger.error(message, ex);
          		}
          		else {
          			logger.trace(message);
          		}
          	}

          Comment


          • #6
            As I already said: if the logger is not on level TRACE writeToLog is never called. See above.
            Thanx for your help!

            Comment

            Working...
            X