JAVA實現通用日誌記錄__JAVA

來源:互聯網
上載者:User

前言:
之前想在filter層直接過濾httpServerletRequest請求進行Tlog,但是之後再getWriter()的 時候報
already been call異常。查了下,才發現原來流形式的只能讀取一次。。就好像食物,吃了就沒了。。
所以在filter和inteceptor裡面是沒法通過擷取request的流來進行日誌記錄的。

於是還是準備用通用的方法:controller層aop進行切面記錄日誌。 使用Aop記錄動作記錄 第一步:添加Aop

/** * 統一TlogHandler * @author Mingchenchen * */public class LogAopHandler {    @Autowired    private AuditLogDao auditLogDao;    /**     * controller層面記錄動作記錄     * 注意此處是aop:around的 因為需要得到請求前的參數以及請求後介面返回的結果     * @throws Throwable      */    public Object doSaveLog(ProceedingJoinPoint joinPoint) throws Throwable {         MethodSignature method = (MethodSignature) joinPoint.getSignature();        String methodName = method.getName();        Object[] objects = joinPoint.getArgs();        String requestBody = null;        if (objects!=null && objects.length>0) {            for (Object object : objects) {                if (object == null) {                    requestBody = null;//POST介面參數為空白 比如刪除XXX                }else if (object instanceof String) {                    requestBody = (String) object;//有些介面直接把參數轉換成對象了                }else {                    requestBody = JSONObject.toJSONString(object);                }            }        }        //只記錄POST方法的日誌        boolean isNeedSaveLog = false;        //此處不能用getAnnotationByType 是JAVA8的特性,因為註解能夠重名,所以得到的是數組        RequestMapping annotation = method.getMethod().getAnnotation(RequestMapping.class);        for (RequestMethod requestMethod : annotation.method()) {            if (requestMethod==RequestMethod.POST) {                isNeedSaveLog = true;            }        }        JSONObject requestBodyJson = null;        try {            requestBodyJson = JSONObject.parseObject(requestBody);        } catch (Exception e) {            //do nothing 即POST請求沒傳body        }        HttpServletRequest request = RequestContextUtil.getRequestByCurrentContext();        String userName = RequestContextUtil.getUserNameByCurrentContext();        if (StringUtil.isEmpty(userName)) {            try {                userName = DmsCache.get(requestBodyJson.getString("userName")).getName();            } catch (Exception e) {                userName = RequestContextUtil.getAsynUserInfoByAutoDeploy().getName();            }        }        //得到request的參數後讓方法執行它         //注意around的情況下需要返回result 否則將不會傳回值給要求者        Object result = joinPoint.proceed(objects);        try {            JSONObject resultJson = JSONObject.parseObject(result.toString());            if (isNeedSaveLog) {//如果是POST請求 則記錄日誌                LogTypeEnum logTypeEnum = LogTypeEnum.getDesByMethodName(methodName);                if (logTypeEnum != null) {                    AuditLogEntity auditLogEntity = new AuditLogEntity();                    auditLogEntity.setUuid(StringUtil.createRandomUuid());                    auditLogEntity.setOperator(userName);                    auditLogEntity.setRequestIp(request.getRemoteAddr());                    auditLogEntity.setRequestUrl(request.getRequestURI().replace("/cloud-master", ""));                    auditLogEntity.setEventType(logTypeEnum.getKey());                    auditLogEntity.setEventDesc(logTypeEnum.getDescription());                    auditLogEntity.setRequest(requestBody);                    int isSuccess = "200".equals(resultJson.getString("code")) ? 1 : 0;                    auditLogEntity.setSuccessFlag(isSuccess);                    auditLogEntity.setResponse(result.toString());                    auditLogEntity.setCreateTime(new Date());                    auditLogDao.insert(auditLogEntity);                }            }        } catch (Exception e) {            e.printStackTrace();        }        return result;    }  }
第二步:在spring的xml中聲明
    <!-- 記錄動作記錄 -->    <bean id="operationLogAop" class="com.ming.learn.core.aop.LogAopHandler"/>     <aop:config>       <aop:aspect id="logAOP" ref="operationLogAop">         <aop:pointcut id="target" expression="execution(* com.ming.learn..*Controller.*(..))"/>         <aop:around method="doSaveLog" pointcut-ref="target"/>       </aop:aspect>     </aop:config>

如此一來,核心步驟就完成了,剩下的就是自己組裝需要記錄的東西了。 第三步:寫Dao、Entity、Mapper

import java.util.Date;import javax.persistence.Column;import javax.persistence.Id;import javax.persistence.Table;/** * 日誌審計 * @author Mingchenchen * */@Table(name="audit_log")public class AuditLogEntity {    @Id    private String uuid;    @Column(name="event_type")    private String eventType;//事件類型    @Column(name="event_desc")    private String eventDesc;//事件中文描述    @Column(name="operator")    private String operator;//操作者    @Column(name="request_ip")    private String requestIp;//用戶端地址    @Column(name="request_url")    private String requestUrl;//請求地址    @Column(name="request")    private String request;//請求body    @Column(name="response")    private String response;//請求傳回值    @Column(name="create_time")    private Date createTime;    public String getUuid() {        return uuid;    }    public void setUuid(String uuid) {        this.uuid = uuid;    }    public String getEventType() {        return eventType;    }    public void setEventType(String eventType) {        this.eventType = eventType;    }    public String getEventDesc() {        return eventDesc;    }    public void setEventDesc(String eventDesc) {        this.eventDesc = eventDesc;    }    public String getOperator() {        return operator;    }    public void setOperator(String operator) {        this.operator = operator;    }    public String getRequestIp() {        return requestIp;    }    public void setRequestIp(String requestIp) {        this.requestIp = requestIp;    }    public String getRequestUrl() {        return requestUrl;    }    public void setRequestUrl(String requestUrl) {        this.requestUrl = requestUrl;    }    public String getRequest() {        return request;    }    public void setRequest(String request) {        this.request = request;    }    public String getResponse() {        return response;    }    public void setResponse(String response) {        this.response = response;    }    public Date getCreateTime() {        return createTime;    }    public void setCreateTime(Date createTime) {        this.createTime = createTime;    }}
第四步:根據Controller的方法名稱定製響應的事件類型
import java.util.Map;import java.util.concurrent.ConcurrentHashMap;/** * 動作記錄類型 * @author Mingchenchen * */public enum LogTypeEnum {    //使用者    COMMON_LOGIN("login","login","登入");    //其他    private String methodName;//方法名稱與controller一致    private String key;//儲存到資料庫的事件類型    private String description;//儲存到資料庫的描述    private LogTypeEnum(String methodName,String key,String description){        this.methodName = methodName;        this.key = key;        this.description = description;    }    public String getMethodName() {        return methodName;    }    public void setMethodName(String methodName) {        this.methodName = methodName;    }    public String getKey() {        return key;    }    public void setKey(String key) {        this.key = key;    }    public String getDescription() {        return description;    }    public void setDescription(String description) {        this.description = description;    }    /**     * 根據方法名返回     * @param methodName     * @return     */    public static LogTypeEnum getDesByMethodName(String methodName){        return innerMap.map.get(methodName);    }    /**     * 內部類 使用者儲存所有的enum 無須通過Enum.values()每次遍曆     * @author Mingchenchen     *     */    private static class innerMap{        private static Map<String, LogTypeEnum> map = new ConcurrentHashMap<>(128);        static{            //初始化整個枚舉類到Map            for (LogTypeEnum logTypeEnum : LogTypeEnum.values()) {                map.put(logTypeEnum.getMethodName(), logTypeEnum);            }        }    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.