使⽤SpringAOP、ThreadLocal、⾃定义注解完成操作⽇志的
记录
之前搞过操作⽇志的东西,这⾥简单的使⽤Spring AOP、ThreadLocal、⾃定义注解来实现对于操作⽇志的记录,在学习技术的同时,熟悉对于⽇志的记录。
⼀般情况下系统打印的⽇志分成了三种:
1:系统⽇志(便于研发⼈员调试排查问题的)。
2:追踪⽇志(多个组件相互调⽤时单纯只依赖系统⽇志效率低下,该⽇志便于追踪复杂业务的调⽤链)。
3:操作⽇志(也叫业务⽇志,记录⼀笔业务)。
这⾥仅介绍操作⽇志,操作⽇志(即业务⽇志)是在软件运⾏时记录⼀笔业务的描述,执⾏结果,产⽣的影响。
以下场景需要记录操作⽇志:
1. 系统⽤户对系统的业务操作。如⽤户添加,修改,删除信息。
2. 服务⾃⾝对(数据库的)数据产⽣影响的操作。如服务⾃⾝的定时任务运⾏,对数据进⾏了新增、修改、删除操作。
记录规范操作⽇志的原因
1. 系统⽇志⼀般只是是给研发⼈员排查问题看的,不⼀定⾮要打印⽇志。⽽操作⽇志是记录所有平台⽤户和系统对平台的操作,是给
平台的管理员⽤户看的,因此需要记录每⼀笔业务操作,并且要有⼀定可交互的、美观的UI界⾯。
操作⽇志中⼀般需要这些字段:
操作者、操作环境、操作动作、被操作对象、结果、附属信息和其他
基于以上介绍,我们可以简单的来实现⾃定义注解记录操作⽇志的代码:
1.⾃定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
/**
* 操作业务模块标⽰。模块标识的多语⾔词条在服务封装时提供
* @return
*/
String moduleId() default "";
/**
* 操作动作标识,
* 表⽰登录、查询、新增、修改、删除、上传、部署、下载等操作。
* 操作动作标识的多语⾔词条在组件封装时提供。
* @return
*/
String action();
/**
* 操作内容详情,
* 在其他所有字段⽆法满⾜⽤户操作内容描述的情况下能通过本项尽可能准确、详细的描述⽤户的操作内容。 * ⽀持多语⾔,写操作参数,采⽤“,”号分隔;不⽀持多语⾔,写操作内容
* @return
*/
String actionDetail() default "";
/**
* actionDetail⽀持多语⾔时,写操作内容详情标识,标识的多语⾔词条在组件封装时提供。
* 标识的多语⾔值⽀持占位符,采⽤%1,%2,%n形式,n表⽰第n个参数;不⽀持多语⾔,留空
* @return
*/
String actionMessageId() default "";
/**
* 终端类型
* @return
*/
String terminalType() default BusLogConstants.TERMINAL_TYPE_WEB;
/**
* 对象类型
* @return
*/
String objectType() default "";
}
2.业务⽇志服务类
public interface ILogHelper {
/**
* 获取当前远程ID信息
* @return
*/
String getRemoteIp();
/**
* 获取当前操作⼈员
* @return
*/
String getUserId();
/**
* 当前操作⼈员
* @return
*/
default String getUserName(){
return "";
}
/**
* 获取当前操作的mac地址
* @return
*/
String getMac();
/**
* 获取serviceId
* @return
*/
String getServiceId();
/**
* 获取组件ID
* @return
*/
String getComponentId();
}
该接⼝主要⽤于获取操作者的ip、⽤户名、组件id等信息。
3. 业务⽇志接⼝实现
@Service("logHelper")
public class LogHelperServiceImpl implements ILogHelper {
@Autowired
private IAgentService agentService;
@Override
public String getRemoteIp() {
HttpServletRequest request = Request();
if (request == null) {
return "localhost";
}
RemoteIp(request);
}
/**
* 操作者为⽤户时,填写⽤户名;
* 操作者为系统内部任务时,填写执⾏任务的服务实例名,格式为“组件标识.段标识.实例序号”
*
* @return
*/
@Override
public String getUserId() {
String userIndexCode = UserId();
if (StringUtils.isEmpty(userIndexCode)) {
TaskUserId();
}
return userIndexCode;
}
/**
* 操作者为⽤户时,填写⽤户对于⼈员姓名;
* 操作者为系统内部任务时,为空
*
* @return userName
*/
@Override
public String getUserName() {
//单点登录后的session中⽆该字段,这⾥默认为空,如有需要,组件⾃⼰查询⽤户信息
return null;
}
@Override
public String getMac() {
return null;
}
@Override
public String getComponentId() {
thread技术ComponentId();
}
}
可以看到在获取操作信息时,是从RequestContextUtil和RequestSourceUtils中去获取的。
4. 请求上下⽂⼯具类
/**
* 请求上下⽂⼯具类,需要配置filter使⽤
* @author gonghao
*/
public class RequestContextUtil {
private static Logger log = Logger(RequestContextUtil.class);
private static Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;
private static ThreadLocal<HttpServletRequest> request = new ThreadLocal<>();
private static ThreadLocal<HttpServletResponse> response = new ThreadLocal<>();
private static ThreadLocal<UserSession> userSession = new ThreadLocal<>();
/**
* 平台启动的时候调⽤,当获取不到语⾔信息的时候,返回的默认语⾔
* @param locale
*/
public static void setDefaultLocale(Locale locale){
DEFAULT_LOCALE = locale;
}
private static List<String> SUPPORT_LOCALE = new ArrayList<>(10);
/**
* 平台启动的时候调⽤,设置⽀持的语⾔列表
* @param supportLocales
*/
public static void setSupportLocales(List<Locale> supportLocales){
if(supportLocales!=null){
SUPPORT_LOCALE = supportLocales.stream().map(e-&String()).List()); }
}
public static void setUserSession(UserSession info) {
RequestContextUtil.userSession.set(info);
}
public static UserSession getUserSession() {
return ();
}
public static void setRequest(HttpServletRequest request) {
}
public static void setResponse(HttpServletResponse response) {
}
public static HttpServletRequest getRequest() {
();
}
public static HttpServletResponse getResponse() {
();
}
/**
* 获取默认的语⾔信息
* @return
*/
private static Locale getDefaultLocale() {
if (Request() != null) {
Locale locale = Request().getLocale();
if (locale != null && !StringUtils.String())) {
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论