Spring AOP for background management system log Management

Source: Internet
Author: User
Tags aop log log static class system log trim
Spring AOP for background Management system log Management

Design principles and ideas: meta-annotation approach combined with AOP, flexible logging of operational logs enables logging of detailed error logs to provide support logging for operations to Minimize performance impact

1. Defining Log record meta annotations

Package com.myron.ims.annotation;

Import java.lang.annotation.*;

/**
 * Custom Note interception Controller
 * 
 * @author lin.r.x
 * *
/@Target ({elementtype.parameter, Elementtype.method})
@Retention (retentionpolicy.runtime) public
@interface Systemcontrollerlog {
    / * *
     Description Business Operation example: XXX management-Perform XXX operation
     * @return
     *
    /String description () default "";
}

2. Defining the entity classes used to log logs

Package Com.myron.ims.bean;
Import java.io.Serializable;
Import Com.myron.common.util.StringUtils;
Import Com.myron.common.util.UuidUtils;
Import Com.fasterxml.jackson.annotation.JsonFormat;
Import Java.util.Date;

Import Java.util.Map; /** * Log class-Record user action behavior * @author lin.r.x * */public class log implements serializable{private static final long Seri

    Alversionuid = 1L;           Private String Logid;            Log primary key private String type;           Log type private String title;          Log header private String remoteaddr;          Request address private String RequestUri;          URI private String method;          Request way private String params;           Submit parameter Private String exception;           Exception @JsonFormat (pattern= "Yyyy-mm-dd HH:mm:ss", timezone = "gmt+8") private Date operatedate;         Start time private String timeout;          End time private String userId; User ID public String getlogid () {RETurn Stringutils.isblank (logid)?
    LogId:logId.trim ();
    } public void Setlogid (String logid) {this.logid = Logid;
    } public String GetType () {return Stringutils.isblank (type)? Type:type.trim ();
    The public void SetType (String type) {this.type = type;
    } public String GetTitle () {return Stringutils.isblank (title)? Title:title.trim ();
    public void Settitle (String title) {this.title = title;
    } public String getremoteaddr () {return Stringutils.isblank (remoteaddr)? RemoteAddr:remoteAddr.trim ();
    } public void Setremoteaddr (String remoteaddr) {this.remoteaddr = remoteaddr;
    } public String Getrequesturi () {return Stringutils.isblank (requesturi)? RequestUri:requestUri.trim ();
    } public void Setrequesturi (String requesturi) {This.requesturi = RequestUri; } public String GetMethod () {return Stringutils.isblank (MeThod)?
    Method:method.trim ();
    } public void Setmethod (String method) {This.method = method;
    } public String Getparams () {return Stringutils.isblank (params)? Params:params.trim ();
    } public void SetParams (String params) {this.params = params; }/** * Set request parameters * @param parammap */public void Setmaptoparams (map<string, string[]> Paramma
        P) {if (Parammap = = null) {return;
        } StringBuilder params = new StringBuilder (); For (map.entry<string, string[]> param: ((map<string, string[]>) parammap). EntrySet ()) {Params.app
            End (("". Equals (Params.tostring ())? "": "&") + Param.getkey () + "=");
            String paramvalue = (param.getvalue () = null && param.getvalue (). length > 0? param.getvalue () [0]: ""); Params.append (Stringutils.abbr (Stringutils.endswithignorecase) (Param.getkey (), "password")? "": Paramvalue, 100));
    } this.params = Params.tostring ();
    } public String GetException () {return Stringutils.isblank (Exception)? Exception:exception.trim ();
    } public void SetException (String exception) {this.exception = exception;
    Public Date Getoperatedate () {return operatedate;
    } public void Setoperatedate (Date operatedate) {this.operatedate = operatedate;
    } public String GetTimeout () {return Stringutils.isblank (timeout)? Timeout:timeout.trim ();
    } public void SetTimeout (String timeout) {this.timeout = timeout;
    } public String GetUserId () {return Stringutils.isblank (userId)? UserId:userId.trim ();
    } public void Setuserid (String userId) {this.userid = UserId; }

}

3. Defining the log AOP facets class

Package COM.MYRON.IMS.AOP;
Import Java.lang.reflect.Method;
Import Java.text.SimpleDateFormat;
Import Java.util.Date;

Import Java.util.Map;
Import Javax.servlet.http.HttpServletRequest;

Import javax.servlet.http.HttpSession;
Import Org.aspectj.lang.JoinPoint;
Import Org.aspectj.lang.annotation.After;
Import org.aspectj.lang.annotation.AfterThrowing;
Import Org.aspectj.lang.annotation.Aspect;
Import Org.aspectj.lang.annotation.Before;
Import Org.aspectj.lang.annotation.Pointcut;
Import Org.aspectj.lang.reflect.MethodSignature;
Import Org.slf4j.Logger;
Import Org.slf4j.LoggerFactory;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.core.NamedThreadLocal;
Import Org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

Import org.springframework.stereotype.Component;
Import Com.myron.common.util.DateUtils;
Import Com.myron.common.util.UuidUtils;
Import Com.myron.ims.annotation.SystemControllerLog; Import Com.myron.ims.annotation.SystemSErvicelog;
Import Com.myron.ims.bean.Log;
Import Com.myron.ims.bean.User;

Import Com.myron.ims.service.LogService; /** * System Log Slice class * @author lin.r.x * */@Aspect @Component public class Systemlogaspect {private static final Logg

    ER logger = Loggerfactory.getlogger (Systemlogaspect. Class); private static final threadlocal<date> begintimethreadlocal = new Namedthreadlocal<date> ("Threadlo
    Cal BeginTime "); private static final threadlocal<log> logthreadlocal = new Namedthreadlocal<log> ("ThreadLocal Log

    ");

    private static final threadlocal<user> currentuser=new namedthreadlocal<> ("ThreadLocal User");

    @Autowired (required=false) private httpservletrequest request;

    @Autowired private Threadpooltaskexecutor Threadpooltaskexecutor;

    @Autowired private Logservice Logservice; /** * Controller layer pointcut Annotation intercept */@Pointcut ("@annotation (Com.myron.ims.annotation.SystemControllerLog)")
    public void Controlleraspect () {}/** * pre-notification is used to intercept the controller layer to record the start time of the user's operation * @param joinpoint pointcut * @ Throws Interruptedexception */@Before ("Controlleraspect ()") public void Dobefore (Joinpoint joinpoint) throw
        s interruptedexception{date begintime=new date ();
            Begintimethreadlocal.set (beginTime);//thread-bound variable (the data is visible only to the currently requested thread) if (logger.isdebugenabled ()) {//Here the log level is debug Logger.debug ("Start timer: {} URI: {}", New SimpleDateFormat ("Yyyy-mm-dd HH:mm:ss.
        SSS "). Format (beginTime), Request.getrequesturi ());       
        }//Read the user HttpSession session in session = Request.getsession ();    
        User user = (user) Session.getattribute ("Ims_user");

    Currentuser.set (user); /** * Post notification is used to intercept the controller layer record user's actions * @param joinpoint pointcut */@SuppressWarnings ("unchecked") @A Fter ("Controlleraspect ()") public void Doafter (Joinpoint joinpoint) {User user = CurrenTuser.get ();
            if (user!=null) {String title= "";                       String type= "Info"; Log type (info: Inbound, Error: Errors) string remoteaddr=request.getremoteaddr ();//requested IP string Requesturi=reque        St.getrequesturi ();//URI of the request String Method=request.getmethod (); Requested method type (Post/get) map<string,string[]> params=request.getparametermap ();
            The parameter of the request submission try {title=getcontrollermethoddescription2 (joinpoint);
            } catch (Exception e) {e.printstacktrace ();
            }//print JVM information. Long beginTime = Begintimethreadlocal.get (). GetTime ();//Get thread bound local variable (start time) long endTime = System.currenttimem  Illis (); 2, End time if (logger.isdebugenabled ()) {Logger.debug ("timed end: {} URI: {} time-consuming: {} Max Memory: {}m Allocate memory: {}m has allocated the remaining space in memory: {}m maximum available memory: {}m ", New SimpleDateFormat (" Yyyy-mm-dd hh:mm:Ss. SSS "). Format (endTime), Request.getrequesturi (), Dateutils.formatdatetime (Endtime-begintime), Runtime.getruntime (). MaxMemory ()/1024/1024, Runtim 
                        E.getruntime (). TotalMemory ()/1024/1024, Runtime.getruntime (). Freememory ()/1024/1024, (Runtime.getruntime (). MaxMemory ()-runtime.getruntime (). TotalMemory () +runtime.getruntime (). FreeMemory ())/1024/ 
            1024);
            } Log log=new log ();
            Log.setlogid (Uuidutils.creatuuid ());
            Log.settitle (title);
            Log.settype (type);
            LOG.SETREMOTEADDR (REMOTEADDR);
            Log.setrequesturi (RequestUri);
            Log.setmethod (method);
            Log.setmaptoparams (params);
            Log.setuserid (User.getid ());
            Date Operatedate=begintimethreadlocal.get ();
            Log.setoperatedate (operatedate); Log.settimeout (dateutils.fOrmatdatetime (Endtime-begintime));

            1. Directly perform the save Operation//this.logservice.createsystemlog (log);

            2. Optimize: Asynchronously Save log//new savelogthread (log, Logservice). Start ();
            3. Re-optimization: Perform log save Threadpooltaskexecutor.execute (new Savelogthread (log, Logservice)) via thread pool;
        Logthreadlocal.set (log); }}/** * Exception notification logging operation error log * @param joinpoint * @param e * * * @AfterThrowing (pointcut = "con  Trolleraspect () ", throwing =" E ") public void doafterthrowing (Joinpoint joinpoint, throwable e) {log log =
        Logthreadlocal.get ();
        Log.settype ("error");
        Log.setexception (E.tostring ());
    New Updatelogthread (log, Logservice). Start (); }/** * Gets the description of the method in the annotation for service layer annotations * @param joinpoint pointcut * @return discription */Public Stati C String GetServiceMthodDescription2 (Joinpoint joinpoint) {methodsignature signature = (methodsignature) joinpoin T.Getsignature ();
        Method method = Signature.getmethod ();
        Systemservicelog Servicelog = method. Getannotation (Systemservicelog.class);
        String discription = Servicelog.description ();
    return discription;
    }/** * Gets the description of the method in the note for the controller layer annotation * * @param joinpoint pointcut * @return discription * * public static String GetControllerMethodDescription2 (Joinpoint joinpoint) {methodsignature signature = (Methodsig
        Nature) joinpoint.getsignature ();
        Method method = Signature.getmethod ();
        Systemcontrollerlog Controllerlog = method. Getannotation (Systemcontrollerlog.class);
        String discription = Controllerlog.description ();
    return discription;
        }/** * Save log thread */private static class Savelogthread implements Runnable {private log log;

        Private Logservice Logservice;
  Public Savelogthread (log log, Logservice Logservice) {          This.log = log;
        This.logservice = Logservice;
        } @Override public void Run () {logservice.createlog (log);
        }}/** * log update thread */private static class Updatelogthread extends thread {private log log;

        Private Logservice Logservice;
            Public Updatelogthread (log log, Logservice Logservice) {super (UpdateLogThread.class.getSimpleName ());
            This.log = log;
        This.logservice = Logservice;
        } @Override public void Run () {this.logService.updateLog (log);
 }
    }
}

4.spring Configure scanning facets to enable support for @aspectj annotations

    <!--start support for @aspectj annotations--  
    <aop:aspectj-autoproxy/> 
    <!--scan Pointcut class components--
    <context: Component-scan base-package= "Com.myron.ims.aop"/>
    <context:component-scan base-package= " Com.myron.ims.service "/>

    <bean id=" Taskexecutor "   class=" Org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor ">  
        <property name=" Corepoolsize "value = "5"/>  
        <property name= "maxpoolsize" value= "ten"/>  
        <property name= " Waitfortaskstocompleteonshutdown "value=" true "/>  
    </bean>  

5. Add log annotations Using the example Logincontroller method

    /**
    * System login *
    /
    @RequestMapping ("/login.do")
    @SystemControllerLog (description= "Log in System")
    @ Responsebody public
    map<string, object> Login (string username, string password, Boolean rememberme, HttpServletRequest req) {
    //business code omitted ...
}   

    /**
     * Safe Exit Login
     * @return *
     /
    @SystemControllerLog (description= "Safe exit system")
    @RequestMapping (" Logout.do ") Public
    String logout () {
        Subject subject=securityutils.getsubject ();
        if (subject.isauthenticated ()) {
            subject.logout ();//session will be destroyed, in Sessionlistener listener session destroyed, Cleanup permission cache
        }
        return "/login.jsp";
    }

6. Operation Effect

7. Supplemental Source Address: Https://github.com/MusicXi/demo-aop-log

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.