在我現在的基於Spring的web應用程序項目上,開發人員已經爲每個函數寫入了兩條日誌語句。一個日誌入口函數,另一個日誌退出。這個想法是追蹤執行路徑 - 至少是一個功能級別。如何跟蹤進入和退出基於Spring的Web應用程序的所有功能?
有沒有辦法做到這一點,而沒有亂拋垃圾的整個代碼庫與這些重複的陳述?
要清楚,我們想要記錄所有函數,而不僅僅是Spring bean的公共方法。
在我現在的基於Spring的web應用程序項目上,開發人員已經爲每個函數寫入了兩條日誌語句。一個日誌入口函數,另一個日誌退出。這個想法是追蹤執行路徑 - 至少是一個功能級別。如何跟蹤進入和退出基於Spring的Web應用程序的所有功能?
有沒有辦法做到這一點,而沒有亂拋垃圾的整個代碼庫與這些重複的陳述?
要清楚,我們想要記錄所有函數,而不僅僅是Spring bean的公共方法。
你可以用Spring AOP來做到這一點。
Spring AOP將允許您在方法調用之前和/或之後「攔截」方法調用並執行任意代碼。您還可以檢查參數並返回這些方法的值。
達到你所談論的記錄,你會做這樣的事情,有可能使用around advice:
所有有關如何做到這一點的Spring細節可以在提供的文檔中找到。
這是否意味着我想記錄的任何對象都必須是Spring bean? –
類別。我認爲如果你也使用Spring支持的'AspectJ',你可以做任何bean。在Spring AOP文檔中,查看第7.8節及其子節。 –
@ MikeM.Lin您可以分享一個示例或參考教程嗎? –
與尼古拉斯相同的想法。你可以使用Spring AOP來做到這一點。
我喜歡使用註釋,以便在源代碼中指定邏輯,而不是在方面的建議中指定。
定義的註釋
package aop;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Traceable {}
定義方面
package aop;
@Aspect
public class TraceableAspect {
private final static AtomicLong Count = new AtomicLong(0);
@Around("execution(* *(..)) && @annotation(aop.Traceable)")
public Object aroundTraceableMethod(ProceedingJoinPoint pjp) throws Throwable {
Logger logger = LoggerFactory.getLogger(pjp.getTarget().getClass());
if (logger.isTraceEnabled()) {
return executeWithTrace(pjp, logger, Count.incrementAndGet());
}
return pjp.proceed();
}
private Object executeWithTrace(ProceedingJoinPoint pjp, Logger logger, long id) throws Throwable {
long start = System.currentTimeMillis();
try {
logger.trace(String.format("#### - #%d - Starting execution of method '%s'", id, pjp.toShortString()));
return pjp.proceed();
} catch (Throwable throwable) {
logger.error(String.format("#### - #%d - Error while executing method '%s' : %s", id, pjp.toShortString(), throwable.toString()));
throw throwable;
} finally {
if (logger.isTraceEnabled()) {
logger.trace(String.format("#### - #%d - End of method '%s' (duration %s ms)", id, pjp.toShortString(), (System.currentTimeMillis() - start)));
}
}
}
}
使用在春季啓動項目方面
package project;
@Profile("with-trace-aop")
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class SecToolWebApplicationTraceableAspect extends aop.TraceableAspect {
@PostConstruct
public void init(){
Logger logger = LoggerFactory.getLogger(this.getClass());
logger.warn("###-AOP-### TraceableAspect initialized for this application");
}
}
**在控制器
package project;
@RestController
public class ModelController {
@Traceable
@RequestMapping(method = RequestMethod.GET, value = "/{date}")
@ResponseBody
public <Collection<TE> find(@PathVariable @DateTimeFormat(pattern = DateUtils.DATE_FORMAT) Date date) {
...
}
}
重要當一個類被鏈接到通知的一個跟蹤方法中,所有的「最終」的方法沒有更多的調用。不使用「最終」
因此,假設跟蹤模式記錄被激活是很重要的,該方法的每次調用「發現」將被追蹤
注意這不,如果
工作這可能有一些幫助 - http:// stackoverflow。com/questions/2071050/is-using-spring-aop-for-logging-a-good-idea – adarshr
通常,選擇代表決策點的重要方法以及記錄方法+參數的入口和方法+退出時返回值。缺點是這需要少量的實際思考。 – Kevin
實際思考,ey?這不會,Kevin;) –