Java/Tools
Aspect Logger, 소스코드에 일일이 Logger를 찍기 귀찮을 때...
허니몬
2014. 1. 10. 11:57
Aspect Logger Sample
package com.sil.docsflow.common.support.spring;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Created with IntelliJ IDEA.
*
* @author: ihoneymon
* Date: 14. 1. 10
*/
public class AspectLogger {
private static final Logger logger = LoggerFactory.getLogger(AspectLogger.class);
public void afterThrowingAdvice(JoinPoint joinPoint, Throwable exception) {
String signatureInfo = getSignatureInfo(joinPoint);
String exceptionMessage = exception.getMessage();
if (exceptionMessage == null || exceptionMessage.trim().length() < 1) {
exceptionMessage = "oops! occured exception";
}
logger.debug("=>> ### " + signatureInfo + " : " + exceptionMessage, exception);
logger.warn("<<= ### " + signatureInfo + " : " + exceptionMessage);
}
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
String signatureInfo = getSignatureInfo(joinPoint);
logger.debug("=>> " + signatureInfo);
Object retVal = joinPoint.proceed();
logger.debug("<<= " + signatureInfo + (retVal != null ? " : " + retVal : ""));
return retVal;
}
private String getSignatureInfo(JoinPoint joinPoint) {
String signatureName = joinPoint.getSignature().getName();
String className = joinPoint.getTarget().getClass().getSimpleName();
StringBuilder sb = new StringBuilder();
sb.append(className).append('.').append(signatureName).append('(');
Object[] args = joinPoint.getArgs();
if (args != null && args.length > 0) {
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof String) sb.append('\"');
sb.append(args[i]);
if (args[i] instanceof String) sb.append('\"');
if (i < args.length - 1) {
sb.append(',');
}
}
}
sb.append(')');
return sb.toString();
}
}
일반적으로 사용가능한 Aspect Logger.
이를 사용하기 위한 logging.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<aop:aspectj-autoproxy/>
<bean id="loggingAspect" class="{package}.AspectLogger"/>
<aop:config>
<aop:aspect ref="loggingAspect">
<aop:pointcut id="loggingPointCut" expression="execution(* {package}.{class}({method})) $amp;$amp; !execution(* {package}.AopLogger(..))"/>
<aop:around method="aroundAdvice" pointcut-ref="loggingPointCut"/>
<aop:after-throwing method="afterThrowingAdvice" pointcut-ref="loggingPointCut" throwing="exception"/>
</aop:aspect>
</aop:config>
</beans>
위의 설정에서 빼먹지 말 것은, <aop:pointcut id="loggingPointCut" expression="execution(* {package}.{class}({method})) $amp;$amp; !execution(* {package}.AopLogger(..))"/>
에서 !execution
이다. AspectLogger 자신을 포인트컷에서 제외시켜주어야 한다. 다른 곳에서는 별다른 문제가 없었는데… 지금 개발하고 있는 프로젝트에서 끊임없이 자신을 물고 들어가면서 로그를 찍다가 예외들을 뱉는다. 그래서 묻어두었다가 logger를 입력하는 것이 귀찮아서 다시 AspectLogger를 꺼내어 들었다.