日誌內容複雜多樣,如何去收集有價值的日誌是咱們重點關注的。日誌的價值實際上是取決於業務操做的,不一樣的業務場景下相同類型的日誌的價值會大相徑庭。 根據以往的業務實踐,結合企業級的一些業務需求,咱們選定關注如下幾類日誌。java
這裏咱們專門針對系統日誌收集討論幾種收集方案sql
這裏是指經過logback、log4j等日誌組件來輸出文件,而後再經過文件輸出到logstash、kibana等日誌組件中,經過這些日誌組件來進行可視化統計與分析,這裏須要統一關鍵日誌輸出格式方便往後統計搜索。json
優勢mybatis
缺點app
攔截controller層,經過controller中的方法名是否包含insert、update、delete等關鍵字來記錄業務日誌。異步
優勢性能
缺點ui
這個方案粒度可大可小,代碼侵入性也比較小,可操做性比較強,若是須要獲取參數信息或者返回值信息,能夠經過註解配置獲取到,能夠集合fastjson中的jpath來獲取參數值下面有幾個僞代碼供參考代理
@Slf4j @Aspect public class SysLogAspect { @Around("@annotation(sysLog)") @SneakyThrows public Object around(ProceedingJoinPoint point, SysLog sysLog) { // 根據系統上下文獲取相關數據 Operation logVo = SysLogUtils.getOperationModel(); Object obj=null; try{ // 操做方式 logVo.setOperationName(sysLog.value()); // 操做時間 logVo.setOperationTime(new Date()); logVo.setObjectType(sysLog.objectType().name()); logVo.setAppName(StringUtils.defaultString(sysLog.appName(),"TSP")); // 發送異步日誌事件 obj = point.proceed(); if(StringUtils.isNotBlank(sysLog.objectIdKey())&&StringUtils.isNotBlank(sysLog.objectNameKey())){ Map<String,Object> params=Maps.newHashMap(); params.put("args",point.getArgs()); params.put("response",obj); logVo.setObjectId(getKeyValue(sysLog.objectIdKey(),params)); logVo.setObjectName(getKeyValue(sysLog.objectNameKey(),params)); } }catch (BusinessException e){ logVo.setException(e.getMessage()); throw new Exception(e); }catch (RuntimeException e){ logVo.setException(e.getMessage()); throw new Exception(e); }catch (Exception e){ logVo.setException(e.getMessage()); throw new Exception(e); }finally { ApplicationContextUtils.publishEvent(new OperationEvent(logVo)); } return obj; } private String getKeyValue(String key,Map<String,Object> params){ try{ Object mm= JSONPath.eval(params,key); if(mm!=null){ return mm.toString(); } }catch (Exception e){ log.error("JSONPath.eval:",e); } return null; } }
``調試
@SysLog(value = "xxxxxx",objectType = LogObjectType.OFFLINE_THRONG, objectIdKey = "$['args'][0][0]['id']",objectNameKey = "$['response'][0][0]['throngName']")
優勢
缺點
若是有些業務共用了方法,須要更小的粒度,或者須要記錄業務數據變動記錄,這時就只能選擇侵入式較強的方式來記錄日誌了,直接在業務代碼中記錄日誌
logClient.logObject(LogObjectType.XXX,id,UserContext.getUserName(),"編輯xxx","xxx變動爲xxxxx");
則可使用mybatis攔截器來進行,若是沒有使用mybatis,則能夠作一個通用的preparestatement以及statement代理。
固然如今已經有很對監控組件能夠知足這個需求,好比說jeager、javamelody、druid等
通常狀況下咱們會採用多種方式來記錄業務日誌,這個都是根據具體需求來進行評估用哪幾種方式能夠更好的達到產品需求。