定义了一个切面 Spring Aop的添加了注解的设置userId等
自定义注解:
package com.pinyu.system.global.ann;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 日志切面注解
*/
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MethodLog {
/**
* 该注解作用于方法上时需要备注信息
*/
String remark() default "";
String operType() default "";
}
切面:
package com.pinyu.system.global.aspect;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.pinyu.system.dao.OperationLogDao;
import com.pinyu.system.entity.UserEntity;
import com.pinyu.system.global.ann.MethodLog;
import com.pinyu.system.utils.SessionUtils;
/**
* @author ypp 创建时间:2018年10月9日 上午10:37:34
* @Description: TODO(日志切面)
*/
@Component
@Aspect
public class OperationLogAspect {
protected Logger logger = LogManager.getLogger(OperationLogAspect.class);
@Autowired
private OperationLogDao logDao;
public OperationLogAspect() {
logger.info("用户操作日志");
}
/**
* 切点
*/
@Pointcut("@annotation(com.pinyu.system.global.ann.MethodLog)")
public void methodCachePointcut() {
}
/**
* 切面
*
* @param point
* @return
* @throws Throwable
*/
@Around("methodCachePointcut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
String ip = getIp(request);
UserEntity loginUser = SessionUtils.getLoginUser(request);
ThreadContext.put("userId",String.valueOf(loginUser.getId()));
ThreadContext.put("creater", loginUser.getRealName());
ThreadContext.put("createUserName", loginUser.getUserName());
ThreadContext.put("ip", ip);
String methodRemark = getMthodRemark(point);
Object[] method_param;
Object object;
// OperationLogEntity optLog = new OperationLogEntity();
// optLog.setExFlag(OperationLogEntity.EX_FALSE);
// try {
// method_param = point.getArgs(); // 获取方法参数
// // String param=(String) point.proceed(point.getArgs());
object = point.proceed();
// } catch (Exception e) {
// // 异常处理记录日志..log.error(e);
// StringWriter stringWriter = new StringWriter();
// PrintWriter writer = new PrintWriter(stringWriter);
// e.printStackTrace(writer);
// StringBuffer buffer = stringWriter.getBuffer();
// optLog.setExFlag(OperationLogEntity.EX_TRUE);
// optLog.setExceptionMsg(buffer.toString());
// throw e;
// }
// optLog.setCreaterId(loginUser.getId());
// optLog.setIp(ip);
// optLog.setCreater(loginUser.getRealName());
// optLog.setCreateUserName(loginUser.getUserName());
// optLog.setOperation(methodRemark);
// optLog.setCreateDate(new Date());
// logDao.add(optLog);
return object;
}
/**
* 获取请求ip
*
* @param request
* @return
*/
public static String getIp(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
// String ip = request.getHeader("X-Forwarded-For");
// if (StringUtils.isBlank(ip) || ip.length() == 0 || ip.equals("unKnown")) {
//
// }
//
// if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
// int index = ip.indexOf(",");
// if (index != -1) {
// return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip.substring(0, index);
// } else {
// return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
// }
// }
// ip = request.getHeader("X-Real-IP");
// if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
// return ip;
// }
// return request.getRemoteAddr().equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
}
/**
* 获取方法中的中文备注
*
* @param joinPoint
* @return
* @throws Exception
*/
public static String getMthodRemark(ProceedingJoinPoint joinPoint) throws Exception {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] method = targetClass.getMethods();
String methode = "";
for (Method m : method) {
if (m.getName().equals(methodName)) {
Class[] tmpCs = m.getParameterTypes();
if (tmpCs.length == arguments.length) {
MethodLog methodCache = m.getAnnotation(MethodLog.class);
if (methodCache != null) {
methode = methodCache.remark();
}
break;
}
}
}
return methode;
}
}
SQL:
/*
Navicat MySQL Data Transfer
Source Server : 211.149.199.68
Source Server Version : 50723
Source Host : 211.149.199.68:3306
Source Database : mypinyu
Target Server Type : MYSQL
Target Server Version : 50723
File Encoding : 65001
Date: 2018-11-01 17:20:59
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for sys_logs
-- ----------------------------
DROP TABLE IF EXISTS `sys_logs`;
CREATE TABLE `sys_logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`class` varchar(100) DEFAULT NULL COMMENT '日志类',
`function` varchar(100) DEFAULT NULL COMMENT '执行的方法名',
`level` varchar(100) DEFAULT NULL COMMENT '日志级别',
`logger` varchar(100) DEFAULT NULL,
`message` text COMMENT '日志内容',
`create_date` timestamp NULL DEFAULT NULL COMMENT '时间',
`ip` varchar(255) DEFAULT NULL COMMENT 'IP地址',
`user_id` varchar(255) DEFAULT NULL,
`create_user_name` varchar(255) DEFAULT NULL,
`creater` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3519 DEFAULT CHARSET=utf8 COMMENT='系统日志';
代码 :
package com.pinyu.system.global.config.log4j2;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnection;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.springframework.stereotype.Component;
import com.pinyu.system.utils.SystemPropertiesUtils;
/**
* @author ypp
* 创建时间:2018年11月1日 下午2:33:44
* @Description: TODO(log4j2日志存储到数据库)
*/
@Component
public class ConnectionFactory {
private static interface Singleton {
final ConnectionFactory INSTANCE = new ConnectionFactory();
}
private final DataSource dataSource;
private ConnectionFactory() {
try {
Class.forName(SystemPropertiesUtils.getDataSourceDriverClassName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.exit(0);
}
Properties properties = new Properties();
properties.setProperty("user", SystemPropertiesUtils.getDataSourceUserName());
properties.setProperty("password", SystemPropertiesUtils.getDataSourcePassword());
GenericObjectPoolpool = new GenericObjectPool();
DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
SystemPropertiesUtils.getDataSourceUrl(),properties
);
new PoolableConnectionFactory(connectionFactory, pool, null, null, false, true);
this.dataSource = new PoolingDataSource(pool);
}
public static Connection getDatabaseConnection() throws SQLException {
return Singleton.INSTANCE.dataSource.getConnection();
}
}
用的dbcp连接池
log4j2配置文件
D:/apache-tomcat-8.5.33/logs
%d{yyyy-MM-dd HH:mm:ss} %-5level %class{36} %L
%M - %msg%xEx%n
${PATTERN_FORMAT}
${PATTERN_FORMAT}
${PATTERN_FORMAT}
注意Root要配置上面数据库DatabaseAppender的信息,其他东西都比较简单。但是有个问题,所有的日志都记录到数据库了,并不能满足实际需求。数据库是可以保存日志信息了