0

I have built a logger class for all my repositories, services and controllers. I am making it log every method call with the following method :

@Before("execution(* com.mdenis.tno..controller..*(..)) || " + 
        "execution(* com.mdenis.tno..service..*(..)) || " + 
        "execution(* com.mdenis.tno..repository..*(..))")
private void logMethodCallWithParameters(JoinPoint joinPoint)
{
    String arguments = "";

    for (Object argument : Arrays.asList(joinPoint.getArgs()))
    {
        arguments = arguments + argument.toString() + ", ";
    }

    if (arguments.contains(", "))
    {
        arguments = arguments.substring(0, arguments.lastIndexOf(","));
    }

    if (arguments.compareTo("") == 0)
    {
        logger.debug("Method " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() 
            + " called with no argument");
    }
    else
    {
        logger.debug("Method " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() 
            + " called with argument(s) " + arguments);
    }
}

This works great but my services all extend a base service that has the common methods in it. A call to a method in PostServiceImpl therefore results in the following log statement :

Method com.mdenis.tno.service.impl.BaseServiceImpl.findAllPaginated returning with result Page 1 of 2 containing com.mdenis.tno.model.Post instances.

I would like to know if there is a way for the extending class name (PostServiceImpl) to be logged instead of the superclass name (BaseServiceImpl).

Thanks!

Martin
  • 1,977
  • 5
  • 30
  • 67

1 Answers1

0

You use

joinPoint.getTarget().getClass().getCanonicalName()

for the class name.

daniu
  • 14,137
  • 4
  • 32
  • 53
  • i think you mean getTarget().getClass().getCanonicalName() and yes that indeed works thanks! – Martin Jan 20 '19 at 16:31
  • There is however a side effect with JpaRepository methods, they return something like "com.sun.proxy.$Proxy198.save" for the method name. I totally get why this is happening given the whole Spring proxy-ing thing but is there a way around this? – Martin Jan 20 '19 at 16:40
  • @Martin not an elegant one I'm aware of. I wouldn't apply aspects to repositories (rather the calling services), but apart from that you probably need to get the class' declared interfaces and log the most specific one that extends the one on which the aspect is activated. – daniu Jan 20 '19 at 16:52
  • Maybe you want to check out my [answer here](https://stackoverflow.com/a/48980140/1082681) and look into my utility method `unProxy(..)`. Does it help if you integrate it in your aspect and call it like `unProxy(joinPoint.getTarget()).getClass().getCanonicalName()`? I did not try because you did not share an [MCVE](http://stackoverflow.com/help/mcve) I could use it upon. – kriegaex Feb 03 '19 at 05:45