写了一个自己的appender,日志既按要求录入我指定的表格,又按照log4j.xml中配置的执行:
1.定义自己的Appender继承JDBCAppender(因为我是要按我的要求入指定表)
重写execute(sql)方法:利用JDBC入库操作。
/** * 重写log4j的日志保存类 * @author xxx * @date 2014-12-1 * @time 上午10:03:00 * @version 1.0 */ public class MyJDBCAppender extends JDBCAppender { private LoggingEvent e; /** * 打开数据库 * @throws SQLException */ public void openConn() { try { connection = getConnection(); } catch (SQLException e) { e.printStackTrace(); close(); } } /** * 重写入库方法,实现PreparedStatement */ @Override protected void execute(String sql) throws SQLException { PreparedStatement stmt = null; try { stmt = connection.prepareStatement(this.getSql()); Long time = e.getTimeStamp(); Log log = (Log) e.getMessage(); stmt.setString(1, String.valueOf(time));// ID为当前时间 stmt.setString(2, "xxx");// 操作类型 stmt.setString(3, log.getCode());// CODE stmt.setTimestamp(4, new Timestamp(time));// TIME stmt.setBoolean(5, log.isSucceed());// RESULT stmt.setString(6, log.getLogType().name());// TYPE stmt.setString(7, log.getMemo());// MEMO stmt.setString(8, log.getName());// NAME stmt.setTimestamp(9, new Timestamp(time));// UPDATEDATE stmt.setString(10, null==log.getCreator()?null:log.getCreator().getId()); stmt.execute(); } catch (SQLException e) { if (stmt != null) { stmt.close(); } e.printStackTrace(); } finally { if (stmt != null) { stmt.close(); } } } /** * 初始化event */ protected String getLogStatement(LoggingEvent event) { e = event; // return getLayout().format(event); return null; } }
2.再写一个自定义的日志工厂类:把刚刚自定义的Appender和Logger作为属性。
这样我logger.info(Log)的时候会先执行我自定义Appender中的execute方法
import org.apache.log4j.Logger; /** * 日志入库类 * @author xxx * @date 2014-12-1 * @time 上午10:03:00 * @version 1.0 */ public class MyLog { private static MyJDBCAppender jdbcAppender; private static Logger logger = Logger.getLogger(MyLog .class); static{ jdbcAppender = new MyJDBCAppender (); jdbcAppender.setDriver("数据库driver"); jdbcAppender.setURL("数据库url"); jdbcAppender.setUser("用户名"); jdbcAppender.setPassword("密码"); jdbcAppender.setSql("入库sql语句"); jdbcAppender.openConn();//数据库连接一直开着 logger.addAppender(jdbcAppender); } /** * 关闭数据库连接 */ public static void close() { jdbcAppender.close(); jdbcAppender = null; } /**自定义各种日志模板 start*/ /** * 操作日志入库:一般操作成功的时候调用 * @param clazz:打印日志的类 * @param actionType:日志动作类型 * @param memo:操作描述 */ public static void info(Class<?> clazz,ActionType actionType,String memo) { Log log = Log.Builder.newBuilder().actionType(actionType).isSucceed(true).build(); log.setLogType(LogType.OPERATE); log.setCreator(SessionUser.getOperator()); log.setMemo(memo); log.setCode(clazz.getSimpleName()); logger.info(log); } /** * 错误操作日志入库:严重的错误操作 * @param clazz:打印日志的类 * @param actionType:日志动作类型 * @param result:是否成功 * @param memo:操作描述 */ public static void error(Class<?> clazz,ActionType actionType,String memo) { Log log = Log.Builder.newBuilder().actionType(actionType).build(); log.setLogType(LogType.OPERATE); log.setSucceed(false); log.setCreator(SessionUser.getOperator()); log.setMemo("严重错误操作_"+memo); log.setCode(clazz.getSimpleName()); logger.error(log); } /** * 系统日志入库 * @param clazz:打印日志的类 * @param actionType:日志动作类型 * @param result:是否成功 * @param user:操作用户 * @param ip:IP地址 * @param memo:操作描述 */ public static void infoSys(Class<?> clazz,ActionType actionType,boolean result,Operator user,String ip,String memo) { Log log = Log.Builder.newBuilder().actionType(actionType).isSucceed(result).build(); log.setLogType(LogType.SYS); log.setCreator(null==user?SessionUser.getOperator():user); log.setName(null==ip?SessionUser.getUserIp():ip);//添加IP log.setMemo(memo); log.setCode(clazz.getSimpleName()); logger.info(log); } /** * 错误系统日志入库 * @param clazz:打印日志的类 * @param actionType:日志动作类型 * @param user:操作用户 * @param ip:当前用户ip * @param memo:操作描述 */ public static void errorSys(Class<?> clazz,ActionType actionType,Operator user,String ip,String memo) { Log log = Log.Builder.newBuilder().actionType(actionType).build(); log.setLogType(LogType.SYS); log.setSucceed(false); log.setCreator(null==user?SessionUser.getOperator():user); log.setName(null==ip?SessionUser.getUserIp():ip); log.setMemo(memo); log.setCode(clazz.getSimpleName()); logger.error(log); } /** * 安全日志入库 * @param clazz:打印日志的类 * @param actionType:日志动作类型 * @param result:是否成功 * @param memo:操作描述 */ public static void infoSecurity(Class<?> clazz,ActionType actionType,boolean result,String memo) { Log log = Log.Builder.newBuilder().actionType(actionType).isSucceed(result).build(); log.setLogType(LogType.SECURITY); log.setCreator(SessionUser.getOperator()); log.setMemo(memo); log.setCode(clazz.getSimpleName()); logger.info(log); } /** * 警告安全日志入库 * @param clazz:打印日志的类 * @param actionType:日志动作类型 * @param result:是否成功 * @param memo:操作描述 */ public static void warnSecurity(Class<?> clazz,ActionType actionType,boolean result,String memo) { Log log = Log.Builder.newBuilder().actionType(actionType).isSucceed(result).build(); log.setLogType(LogType.SECURITY); log.setCreator(SessionUser.getOperator()); log.setMemo(memo); log.setCode(clazz.getSimpleName()); logger.warn(log); } /** * 错误安全日志入库 * @param clazz:打印日志的类 * @param actionType:日志动作类型 * @param result:是否成功 * @param memo:操作描述 */ public static void errorSecurity(Class<?> clazz,ActionType actionType,String memo) { Log log = Log.Builder.newBuilder().actionType(actionType).build(); log.setLogType(LogType.SECURITY); log.setSucceed(false); log.setCreator(SessionUser.getOperator()); log.setMemo(memo); log.setCode(clazz.getSimpleName()); logger.error(log); } /**自定义各种日志模板 end*/ }