1

I am using spring aop to do logging for my application : I have before after and afterthrowing advice configured but the line numbers that I see is not of the target class but that of the class used for logging How can I solve this Below is my configuration

Spring xml :

<aop:aspectj-autoproxy proxy-target-class="false" />

Class used for logging :

package com.digilegal.services.ahc.logging;

import java.lang.reflect.Modifier;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

@Aspect
public class AHCLogging {

    @Before("execution(* com.digilegal.services..*.*(..))")
    public void logBefore(JoinPoint joinPoint) {

        Logger log = Logger.getLogger(joinPoint.getTarget().getClass());
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        if (!Modifier.isPrivate(signature.getModifiers())
                && !signature.getName().startsWith("get")
                && !signature.getName().startsWith("set")
                && !signature.getName().startsWith("is")) {
            log.trace("ENTER METHOD ::"
                    + signature.getReturnType().getSimpleName() + " "
                    + signature.getName() + "("
                    + paramterType(signature.getParameterTypes()) + ")");
        }

    }

    @After("execution(* com.digilegal.services..*.*(..))")
    public void logAfter(JoinPoint joinPoint) {
        Logger log = Logger.getLogger(joinPoint.getTarget().getClass());
        MethodSignature signature = (MethodSignature)     joinPoint.getSignature();

        if (!Modifier.isPrivate(signature.getModifiers())
                && !signature.getName().startsWith("get")
                && !signature.getName().startsWith("set")
                && !signature.getName().startsWith("is")) {
            log.trace("EXIT METHOD ::"
                    + signature.getReturnType().getSimpleName() + " "
                    + signature.getName() + "("
                    + paramterType(signature.getParameterTypes()) + ")");
        }
    }

    @AfterThrowing(pointcut = "execution(* com.digilegal.services..*.*        (..))",throwing= "error")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {
        Logger log = Logger.getLogger(joinPoint.getTarget().getClass());
        MethodSignature signature = (MethodSignature)     joinPoint.getSignature();

        if (!Modifier.isPrivate(signature.getModifiers())
                && !signature.getName().startsWith("get")
                && !signature.getName().startsWith("set")
                && !signature.getName().startsWith("is")) {
            log.error("EXCEPTION IN METHOD ::"
                    + signature.getReturnType().getSimpleName() + " "
                    + signature.getName() + "("
                    + paramterType(signature.getParameterTypes()) + ")");
            log.error("Exception",error);
        }
    }

    private String paramterType(Class<?>[] classes) {
        StringBuffer buffer = new StringBuffer();
        String returnValue = "";

        for (Class<?> string : classes) {
            buffer.append(Modifier.toString(string.getModifiers()));
            buffer.append(" ");
            buffer.append(string.getSimpleName());
            buffer.append(",");
        }

        returnValue = buffer.toString();

        if (returnValue.trim().length() > 0) {
            returnValue = returnValue.substring(0, returnValue.length() -         1);
        }

        return returnValue;
    }
}

Am I missing something or is it suppose to be like this

Thanks

Nirav

kriegaex
  • 63,017
  • 15
  • 111
  • 202
nirav
  • 77
  • 1
  • 10
  • There is nothing in there mentioning line numbers so I'm not sure what you are asking about. Also you are aware of the fact that spring already has a class that can log these things for you (instead of adding your own?). Check the [`CustomizableTraceInterceptor`](http://docs.spring.io/autorepo/docs/spring/current/javadoc-api/org/springframework/aop/interceptor/CustomizableTraceInterceptor.html) – M. Deinum Apr 04 '15 at 08:45
  • Cool thanks for pointing out about the Spring class it would help a lot but the thing i am talking about is this :Apr 04, 2015 15:25:08:775 TRACE LoginBean:30 - ENTER METHOD ::void doLogin(public ActionEvent) where 30 is the line number of the logging class and not LoginBean – nirav Apr 04 '15 at 09:55

1 Answers1

6

I think this is not specifically a Spring AOP problem but just the way Log4j works, see Javadoc for PatternLayout:

L

Used to output the line number from where the logging request was issued.

WARNING Generating caller location information is extremely slow and should be avoided unless execution speed is not an issue.

So my recommendation is to use a pattern layout without line number and use Spring AOP's capability of determining line numbers, roughly like this:

joinPoint.getSourceLocation().getLine()
kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • 1
    Well, if it does, please accept and upvote my answer. – kriegaex Apr 06 '15 at 09:28
  • 4
    This method `joinPoint.getSourceLocation().getLine()` is not supported by Spring-AOP up to 4.2.2. `Exception in thread "main" java.lang.UnsupportedOperationException` – Timofey Oct 22 '15 at 19:52
  • I am really not a Spring user, but have you seen [this](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.html)? I do not know if it helps. Be it as it might, the problem in this question was wrong Log4J usage anyway. – kriegaex Oct 23 '15 at 09:48
  • Shame, does does not work on Spring 4.2.4 either... Darn it! – rray Dec 17 '15 at 22:20
  • How about using full AspectJ in Spring via LTW, then? – kriegaex Dec 18 '15 at 08:14