基於Log4j NDC 多執行緒條件下記錄日誌,排查生產問題
阿新 • • 發佈:2018-12-09
在大吞吐,高併發的場景, 一個請求到達後端,通常是轉換成多執行緒並行處理請求, 如何通過一個標誌找到這個請求對應的多個執行緒,瞭解這個請求的完整的處理情況,從而幫助我們定位這次呼叫到底哪一步出現了問題,對我們快速定位排查生產問題是非常有用的。我們在每個子任務程式碼開始處(每個子任務都會啟動一個新的執行緒)將當前執行緒的執行緒號設定為父執行緒的執行緒號,在日誌中通過這個執行緒號將整個處理過程關聯起來了, 下面程式碼是一個子任務, MiscUtil.setNDC(param) 方法在子執行緒開始時設定了ndc 和父執行緒相同,原始碼如下:
@Override public OnwayAndArrived call() throws Exception { MiscUtils.setNDC(param); Transaction tx = Cat.newTransaction("Callable", "FundOnwayAndArrivedCallable.call"); try { String clientNo = param.getBecifNo(); String bankAcc = param.getAccountList(); String businCode = param.getExtensionMap().get("businCode"); String startDate = param.getStartDate(); String endDate = param.getEndDate(); OnwayAndArrived on = OnwayAndArrivedService.this.queryFundOnWayAndArrived(clientNo, bankAcc, businCode, null, startDate, endDate); tx.setSuccessStatus(); return on; }catch (Exception e) { LOGGER.error(e.getMessage()); tx.setStatus(e); return null; }finally { tx.complete(); } } public static void setNDC(AbstractBaseParam baseParamParam) { Map<String, String> extensionMap = baseParamParam.getExtensionMap(); if (null != extensionMap && extensionMap.containsKey(Constant.LOG_NDC)) { NDC.clear(); NDC.push(extensionMap.get(Constant.LOG_NDC)); } }