Search code examples
springspring-aoppointcut

Writing a precise pointcut expression


I am using Spring AOP for logging wherein I want to log input/output of all methods present in package. I have written following pointcut for target package.

@Pointcut("within(com.mypackage.model.*)")
public void allmethods(){};

My logging method is as below.

@Before("allmethods()")
    public void LoggingAdviceBefore(JoinPoint joinPoint) 
    {
        StringBuffer logMessage = new StringBuffer();
        if(joinPoint != null && joinPoint.getTarget()!=null && joinPoint.getTarget().getClass()!=null)
        {
            logMessage.append(joinPoint.getTarget().getClass().getName());
            logMessage.append(".");
            logMessage.append(joinPoint.getSignature().getName());
            logMessage.append("(");
            // append args
            Object[] args = joinPoint.getArgs();
            for (int i = 0; i < args.length; i++) {
                logMessage.append(args[i]).append(",");
            }
            if (args.length > 0) {
                logMessage.deleteCharAt(logMessage.length() - 1);
            }

            logMessage.append(")");
            log.info(logMessage.toString());
        }

    }

The code is working fine.

My problem is, even if I do some simple operations like, populating an array list within my code, even that information is getting logged. I don't want such information to be logged.

I want to log inputs only for the methods that I had written in the classes present in target package & not for the code written inside those methods. How do I achieve this?


Solution

  • You can use the below code which I had written months back to understand SNMP framework implementation, it prints i/o of all the methods in package and subpackage, you can remove irrelevant classes and modify according to your needs, if required.

    @Aspect
    public class Snmp4JProfiler {
    
        private static final Logger LOG = LoggerFactory.getLogger(Snmp4JProfiler.class);
    
        @Pointcut("execution (* org.snmp4j.Snmp.*(..))")
        public void allSnmpServices() {
        }
    
        @Pointcut("execution (* org.snmp4j.security.U*.*(..))")
        public void allUSMServices() {
        }
    
        @Around("allUSMServices() || allSnmpServices()")
        public Object executionTimeOfService(ProceedingJoinPoint pjp) throws Throwable {
    
            MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
            String className = pjp.getSignature().getDeclaringTypeName();
            final String methodName = methodSignature.getName();
    
    
            String methodArgs = "";
            for (Object obj : pjp.getArgs()) {
    
                if (obj == null) {
                    methodArgs += "no args or null,";
                } else if (obj instanceof UsmTimeEntry) {
                    UsmTimeEntry timeEntry = (UsmTimeEntry) obj;
                    methodArgs += obj.toString() + "[" + timeEntry.getEngineBoots() + "," + timeEntry.getLatestReceivedTime() + ","
                            + timeEntry.getTimeDiff() + "," + timeEntry.getEngineID() + "]";
                } else if (obj instanceof Object[]) {
                    methodArgs += obj.toString() + " " + Arrays.toString((Object[]) obj);
                } else {
                    methodArgs += obj;
                }
    
            }
    
            LOG.info("Start of method#" + methodName + " #class#" + className + " #args#" + methodArgs);
    
            try {
                Object output = pjp.proceed();
    
                String rtValues = "";
                if (output == null) {
                    rtValues += "no args or null,";
                } else if (output instanceof UsmTimeEntry) {
                    UsmTimeEntry timeEntry = (UsmTimeEntry) output;
                    rtValues += output.toString() + "[" + timeEntry.getEngineBoots() + "," + timeEntry.getLatestReceivedTime() + ","
                            + timeEntry.getTimeDiff() + "," + timeEntry.getEngineID() + "]";
                } else if (output instanceof Object[]) {
                    rtValues += output.toString() + " " + Arrays.toString((Object[]) output);
                } else {
                    rtValues += output;
                }
    
                LOG.info("End of method#" + methodName + " #class#" + className + " #return#" + rtValues);
                return output;
            } catch (Exception ex) {
                LOG.info("End of method#" + methodName + " #class#" + className + " #error#" + ex.getMessage());
                throw ex;
            }
    
        }
    
    }