日志内容复杂多样,如何去收集有价值的日志是咱们重点关注的。日志的价值实际上是取决于业务操做的,不一样的业务场景下相同类型的日志的价值会大相径庭。 根据以往的业务实践,结合企业级的一些业务需求,咱们选定关注如下几类日志。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等
通常状况下咱们会采用多种方式来记录业务日志,这个都是根据具体需求来进行评估用哪几种方式能够更好的达到产品需求。