AOP+LOG4J日志框架(自定义注解)

工作中用到日志功能,参考网上一些资料,写了个比较通用的日志框架,现在拿出来分享,内容没有做太多解释,如有不清楚的地方可以给我留言或是通过网上查资料来解决。
设计思路:通过AOP进入方法之前拦截做行为日志记录,方法抛异常拦截做错误日志记录。实现自定义注解,可以存入行为中文注释,也可以配置成完全根据注解来决定是否记录日志的策略,支持控制台、文件、数据库、邮件和异步处理等功能以及针对数据库可以添加行为统计、异常统计和钻取明细等等。
web.xml文件配置如下:
<!-- 日志 -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.xml</param-value>
</context-param>
<!-- 监听器 放在spring监听器之前-->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>


spring配置文件如下:

<!-- 日志 AOP-->
<bean id="logBeforeAdvice" class="com.berheley.bi.system.log.logManage.LogBeforeAdvice">
<property name="annotation" value="true"/>
</bean>
<bean id="logThrowingAdvice" class="com.berheley.bi.system.log.logManage.LogThrowingAdvice">
<property name="annotation" value="true"/>
</bean>
<!-- 日志 begin-->
<aop:config>
<aop:advisor pointcut="execution(* com.berheley.bi.meta..*.*(..))" advice-ref="logBeforeAdvice"/>
</aop:config>
<!-- 日志 end -->

import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.MethodBeforeAdvice;

/**
*
* 类功能描述:日志框架
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-4-9 下午05:23:41
*/
public class LogBeforeAdvice implements MethodBeforeAdvice {

protected Log log = LogFactory.getLog(this.getClass());

private boolean annotation = true;

public void setAnnotation(boolean annotation) {
this.annotation = annotation;
}

/**
* service方法前调用,记录行为或调试
*/
public void before(Method method, Object[] args, Object target) throws Throwable {
LogUtils.beforeLog(target.getClass(), method, args, log, annotation);
}
}


import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.ThrowsAdvice;

import com.berheley.bi.basic.exp.BusinessException;

/**
*
* 类功能描述:日志框架
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-4-9 下午05:23:41
*/
public class LogThrowingAdvice implements ThrowsAdvice {

protected Log log = LogFactory.getLog(this.getClass());

private boolean annotation = true;

public void setAnnotation(boolean annotation) {
this.annotation = annotation;
}

/**
*
* @function:抛出异常时调用,记录错误内容
* @param method
* @param args
* @param target
* @param ex
* @throws BusinessException
* @author: mengqingyu 2013-4-9 下午05:24:20
*/
public void afterThrowing(Method method, Object[] args, Object target,
Exception ex) throws BusinessException {
// DOMConfigurator.configure(LogThrowingAdvice.class.getResource("/log4j.xml"));//临时测试用
LogUtils.throwingLog(target.getClass(), method, args, ex, log, annotation);
}
}

log4j配置文件如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!-- log4j xml配置 控制台、文件、数据库和邮件 支持异步 mengqingyu -->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- 控制台 -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="conversionPattern" value="[%-5p] %d{yyyy-MM-dd HH:mm:ss} %m %n"/>
</layout>
</appender>

<!-- 文件 -->
<appender name="webframe" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${webframe.root}/WEB-INF/logs/webframe.log"/>
<!-- 8K为一个写单元
<param name="BufferedIO" value="true" />
<param name="BufferSize" value="8192" />
-->
<param name="append" value="true"/>
<param name="datePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="conversionPattern" value="[%-5p] %d{yyyy-MM-dd HH:mm:ss} %m %n"/>
</layout>
</appender>

<!-- 数据库 -->
<appender name="db" class="com.berheley.bi.system.log.log4j.JDBCCustomAppender">
<param name="bufferSize" value="1" />
<layout class="org.apache.log4j.PatternLayout">
<param name="conversionPattern"
value="insert into t_log (LOG_NAME_,USER_NAME_,CLASS_,METHOD_NAME_,CREATE_TIME_,LOG_LEVEL_,METHOD_PARAM_,MSG_BRIEF_,MSG_DETAIL_,CLASS_DISCRIPTION_,METHOD_DISCRIPTION_) values ('%X{LOG_NAME_}','%X{USER_NAME_}','%X{CLASS_}','%X{METHOD_NAME_}','%d{yyyy-MM-dd HH:mm:ss}','%p','%X{METHOD_PARAM_}','%m','%X{MSG_DETAIL_}','%X{CLASS_DISCRIPTION_}','%X{METHOD_DISCRIPTION_}')" />
</layout>
<!-- 级别过滤
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMax" value="error" />
<param name="LevelMin" value="error" />
</filter>
-->
</appender>

<!-- 邮件 可配置多个appender模块划分-->
<appender name="mail" class="com.berheley.bi.system.log.log4j.SMTPCustomAppender">
<param name="threshold" value="fatal"/>
<param name="bufferSize" value="1"/>
<param name="from" value="1@gmail.com"/>
<param name="smtpHost" value="smtp.gmail.com"/>
<param name="smtpAuth" value="true"/>
<param name="smtpUsername" value="1@gmail.com"/>
<param name="smtpPassword" value="1"/>
<param name="subject" value=" Log4J Message"/>
<param name="packages" value="com.berheley.bi.fillform,com.berheley.bi.system"/> <!-- 可以配置多个以,号间隔 -->
<param name="to" value="1@gmail.com"/> <!-- 可以配置多个以,号间隔 -->
<layout class="com.berheley.bi.system.log.log4j.HTMLCustomLayout"/>
</appender>

<!-- 多线程 -->
<appender name="async" class="org.apache.log4j.AsyncAppender">
<param name="bufferSize" value="100" />
<appender-ref ref="db" />
<appender-ref ref="mail" />
</appender>

<!-- 继承root log4j包下运行异步线程日志 -->
<logger name="com.berheley.bi.system.log">
<level value="info"/>
<appender-ref ref="async"/>
</logger>

<!-- 输出级别 -->
<root>
<priority value="error" />
<appender-ref ref="console" />
<appender-ref ref="webframe" />
</root>

<!-- 单个日志级别控制
<category name="monitorLogger" additivity="false">
<priority value="info" />
<appender-ref ref="console"/>
</category >
-->
</log4j:configuration>



import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.log4j.MDC;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.webframe.web.springmvc.exp.AjaxException;

import com.berheley.bi.basic.exp.BusinessException;
import com.berheley.bi.system.login.LoginUser;

/**
*
* 类功能描述: 日志工具类,设置属性
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-4-12 下午04:55:44
*/
public abstract class LogUtils {

public static final String WEB_CONTEXT_ = "WEB_CONTEXT_";

public static final String LOG_NAME_ = "LOG_NAME_";

public static final String USER_NAME_ = "USER_NAME_";

public static final String CLASS_ = "CLASS_";

public static final String PACKAGES_ = "PACKAGES_";

public static final String METHOD_NAME_ = "METHOD_NAME_";

public static final String METHOD_PARAM_ = "METHOD_PARAM_";

public static final String CLASS_DISCRIPTION_ = "CLASS_DISCRIPTION_";

public static final String METHOD_DISCRIPTION_ = "METHOD_DISCRIPTION_";

public static final String MSG_DETAIL_ = "MSG_DETAIL_";

/**
*
* @function:操作行为记录
* @param clazz 类对象
* @param method 方法对象
* @param args 方法参数
* @param log 日志对象
* @throws BusinessException
* @author: mengqingyu 2013-5-30 下午05:29:57
*/
public static void beforeLog(Class<?> clazz, Method method, Object[] args, Log log, boolean annotation) throws BusinessException{
LogDiscription methodDiscription = method.getAnnotation(LogDiscription.class);
if(annotation==false||methodDiscription!=null){
initLog(clazz, method, args, null, methodDiscription);
log.info(new StringBuilder("info:").append(LogUtils.getClassName()).append("->").append(LogUtils.getMethodName()));
}
}

/**
*
* @function:异常记录
* @param clazz 类对象
* @param method 方法对象
* @param args 方法参数
* @param ex 异常对象
* @param log 日志对象
* @throws BusinessException
* @author: mengqingyu 2013-5-30 下午05:30:00
*/
public static void throwingLog(Class<?> clazz, Method method, Object[] args, Exception ex, Log log, boolean annotation) throws BusinessException{
LogDiscription methodDiscription = method.getAnnotation(LogDiscription.class);
if(annotation==false||methodDiscription!=null){
initLog(clazz, method, args, ex, methodDiscription);
if(ex instanceof BusinessException || ex instanceof AjaxException){
log.error(ex.getMessage(),ex);
}
else{
log.fatal(ex.getMessage(),ex);
}
}
}

/**
*
* @function:初始化参数
* @param clazz 类对象
* @param method 方法对象
* @param args 方法参数
* @param ex 异常对象
* @throws BusinessException
* @author: mengqingyu 2013-4-12 下午04:56:09
*/
protected static void initLog(Class<?> clazz, Method method, Object[] args, Exception ex, LogDiscription methodDiscription) throws BusinessException{
if(clazz==null||method==null)
throw new BusinessException("日志初始化参数clazz或method为空");

setLogName();
setClass(clazz);
setMethodName(method);
setMethodParam(args,methodDiscription);
setClassDiscription(clazz.getAnnotation(LogDiscription.class));
setMethodDiscription(methodDiscription);
setMsgDetail(ex);
}

/**
*
* @function:初始化参数
* @param clazz 类对象
* @param method 方法名称
* @param classTypes 方法参数类型
* @param args 方法参数
* @param ex 异常对象
* @throws BusinessException
* @author: mengqingyu 2013-4-12 下午04:56:09
*/
@SuppressWarnings("rawtypes")
public static Method initLog(Class<?> clazz, String methodName, Class[] classTypes) throws BusinessException{
if(clazz==null||methodName==null)
throw new BusinessException("日志初始化参数:clazz或method为空");

Method method;
try {
method = clazz.getMethod(methodName, classTypes);
} catch (SecurityException e) {
throw new BusinessException("方法权限错误"+methodName,e);
} catch (NoSuchMethodException e) {
throw new BusinessException("方法名或参数类型错误:"+methodName,e);
}
return method;
}

private static void setLogName(){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String Username;
String RealName;
if(auth!=null){
LoginUser loginUser = (LoginUser)auth.getPrincipal();
Username = loginUser.getUsername();
RealName = loginUser.getRealName();
}
else{
Username = Thread.currentThread().getName();
RealName = "无";
}
MDC.put(LogUtils.LOG_NAME_, Username);
MDC.put(LogUtils.USER_NAME_, RealName);
}

private static void setClass(Class<?> clazz){
MDC.put(LogUtils.CLASS_, clazz.getName().substring(clazz.getName().lastIndexOf(".")+1));
MDC.put(LogUtils.PACKAGES_, clazz.getName());
}

private static void setMethodName(Method method){
MDC.put(LogUtils.METHOD_NAME_, method.getName());
}

private static void setMethodParam(Object[] args, LogDiscription logDiscription){
if(args!=null){
StringBuilder methodParam = new StringBuilder();
String param = logDiscription==null?"":logDiscription.param();
if("".equals(param)){
for(Object o:args){
methodParam.append(o).append("<br/>");
}
}
else{
String[] paramArray = param.split(",");
int paramLength = paramArray.length;
if(paramLength != args.length){
methodParam.append("参数注释错误");
}
else{
for(int i=0;i<args.length;i++){
methodParam.append(paramArray[i]).append(":").append(args[i]).append("<br/>");
}
}
}
MDC.put(LogUtils.METHOD_PARAM_, replaceParam(methodParam.toString()));
}
}

private static void setClassDiscription(LogDiscription logDiscription){
MDC.put(LogUtils.CLASS_DISCRIPTION_, replaceParam(logDiscription==null?"":logDiscription.clazz()));
}

private static void setMethodDiscription(LogDiscription logDiscription){
MDC.put(LogUtils.METHOD_DISCRIPTION_, replaceParam(logDiscription==null?"":logDiscription.method()));
}

/**
*
* @function:设置异常信息
* @param ex 异常对象
* @author: mengqingyu 2013-4-12 下午04:56:53
*/
public static void setMsgDetail(Exception ex){
if(ex!=null){
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
MDC.put(LogUtils.MSG_DETAIL_, sw);
}
}

/**
*
* @function:获取类名称
* @return
* @author: mengqingyu 2013-4-12 下午04:57:13
*/
public static String getClassName(){
return MDC.get(LogUtils.CLASS_)==null?"null":MDC.get(LogUtils.CLASS_).toString();
}

/**
*
* @function:获取方法名称
* @return
* @author: mengqingyu 2013-4-12 下午04:57:30
*/
public static String getMethodName(){
return MDC.get(LogUtils.METHOD_NAME_)==null?"null":MDC.get(LogUtils.METHOD_NAME_).toString();
}

private static String replaceParam(String value){
return value.replace(",", "\\,").replace("'", "\\'");
}
}

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
*
* 类功能描述:自定义日志注解
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-4-12 下午01:57:44
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface LogDiscription {
/**
* 用法:在类名上方加入注解代码 @LogDiscription(clazz="表单分配")
* @function:类注释
* @return
* @author: mengqingyu 2013-4-12 下午01:57:10
*/
String clazz() default "";

/**
* 用法:在方法名上方加入注解代码 @LogDiscription(method = "立即发布",param = "任务ID:{0} 主键:{1} 创建时间:{2}")
* @function:方法注释
* @return
* @author: mengqingyu 2013-4-12 下午01:57:22
*/
String method() default "";

/**
*
* @function:方法参数注释
* @return
* @author: mengqingyu 2013-4-12 下午01:57:30
*/
String param() default "";
}

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;

import javax.sql.DataSource;

import org.apache.log4j.jdbc.JDBCAppender;
import org.apache.log4j.spi.ErrorCode;
import org.apache.log4j.spi.LoggingEvent;
import org.webframe.web.util.WebFrameUtils;

/**
*
* 类功能描述:log4j 入库日志管理,重写此类解决数据源、批量插入和日志过滤等问题
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-4-9 下午02:20:08
*/
public class JDBCCustomAppender extends JDBCAppender {

/**
* 类功能描述:数据库连接池,单例,延迟实例化
*/
private static class DataSourceHolder {
private static final DataSource dataSource = (DataSource) WebFrameUtils.getApplicationContext().getBean("dataSource");
}

/**
* 在日志加入集合过程中进行处理
*/
@SuppressWarnings("unchecked")
@Override
public void append(LoggingEvent event) {
buffer.add(event);
if (buffer.size() >= bufferSize)
flushBuffer();
}

/**
* 从连接池中获取连接
*/
@Override
protected Connection getConnection() throws SQLException {
return DataSourceHolder.dataSource.getConnection();
}

/**
* 删去了源方法中的一些操作
*/
@Override
public void close() {
this.closed = true;
}

/**
* 释放连接
*/
@Override
protected void closeConnection(Connection con) {
try {
con.close();
} catch (SQLException e) {
errorHandler.error("Error closing connection", e, ErrorCode.GENERIC_FAILURE);
}
}

/**
* 重写批量插入操作
*/
@SuppressWarnings("unchecked")
@Override
public void flushBuffer() {
Connection con = null;
Statement stmt = null;
try {
con = getConnection();
stmt = con.createStatement();
removes.ensureCapacity(buffer.size());
for (Iterator<LoggingEvent> i = buffer.iterator(); i.hasNext();) {
LoggingEvent logEvent = i.next();
stmt.addBatch(getLogStatement(logEvent));
removes.add(logEvent);
}
stmt.executeBatch();
} catch (SQLException e) {
errorHandler.error("Failed to excute sql", e,ErrorCode.FLUSH_FAILURE);
} finally {
try {
stmt.close();
} catch (SQLException e) {
errorHandler.error("Failed to excute sql", e,ErrorCode.FLUSH_FAILURE);
} finally {
closeConnection(con);
}
}
buffer.removeAll(removes);
removes.clear();
}
}

import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.net.SMTPAppender;
import org.apache.log4j.spi.ErrorCode;
import org.apache.log4j.spi.LoggingEvent;

/**
*
* 类功能描述:log4j 邮件日志管理,重写此类解决不支持权限认证、缓存问题和gmail端口号问题,注:新版本log4j已经支持认证
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-4-11 下午01:44:19
*/
public class SMTPCustomAppender extends SMTPAppender {

protected String smtpUsername;

protected String smtpPassword;

protected String smtpAuth;

protected String[] packages;

protected String to;

protected String from;

protected String subject;

protected String smtpHost;

protected int bufferSize = 512;

protected boolean locationInfo = false;

public void setSmtpUsername(String smtpUsername) {
this.smtpUsername = smtpUsername;
}

public void setSmtpPassword(String smtpPassword) {
this.smtpPassword = smtpPassword;
}

public void setSmtpAuth(String smtpAuth) {
this.smtpAuth = smtpAuth;
}

public void setTo(String to) {
this.to = to;
}

public void setPackages(String packages) {
this.packages = packages.split(",");
}

public void setFrom(String from) {
this.from = from;
}

public void setSubject(String subject) {
this.subject = subject;
}

public void setSmtpHost(String smtpHost) {
this.smtpHost = smtpHost;
}

public void setBufferSize(int bufferSize) {
this.bufferSize = bufferSize;
}

public void setLocationInfo(boolean locationInfo) {
this.locationInfo = locationInfo;
}

/**
* 在日志加入集合过程中进行处理
*/
public void append(LoggingEvent event) {
if (!checkEntryConditions()) {
return;
}

event.getThreadName();
event.getNDC();
if (locationInfo) {
event.getLocationInformation();
}
//包过滤
if(packages!=null&&packages.length>0){
String clazz = event.getMDC(LogUtils.PACKAGES_).toString();
for(int i=0;i<packages.length;i++){
if(clazz.startsWith(packages[i])){
cb.add(event);
break;
}
}
}
else{
cb.add(event);
}
if (evaluator.isTriggeringEvent(event)) {
if (cb.length() >= bufferSize) { //添加缓存判断
sendBuffer();
}
}
}

/**
* 初始化邮件对象并进行权限认证
*/
public void activateOptions() {
Properties props = new Properties(System.getProperties());
if (smtpHost != null) {
props.put("mail.smtp.host", smtpHost);
// 邮件默认端口号是25,gmail邮件服务商用是465端口,需要手动处理
if (smtpHost.indexOf("smtp.gmail.com") >= 0) {
props.setProperty("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.port", "465");
props.setProperty("mail.smtp.socketFactory.port", "465");
}
}

Authenticator authenticator = null;

if (smtpAuth != null && smtpAuth.trim().equals("true")) {
props.put("mail.smtp.auth", "true");
authenticator = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(smtpUsername,
smtpPassword);
}
};
}

Session session = Session.getInstance(props, authenticator);
msg = new MimeMessage(session);

try {
if (from != null)
msg.setFrom(getAddress(from));// 设置发件人
else
msg.setFrom();
msg.setRecipients(Message.RecipientType.TO, parseAddress(to));// 设置收件人
if (subject != null){
String context = WebFrameUtils.getWebContextPath();
context = StringUtils.isBlank(context)?subject:context.replace("/", "")+" "+subject;
msg.setSubject(context);
}

} catch (MessagingException e) {
LogLog.error("Could not activate SMTPAppender options.", e);
}
}

/**
*
* @function:获得地址
* @param addressStr
* @return
* @author: mengqingyu 2013-4-10 下午02:38:30
*/
protected InternetAddress getAddress(String addressStr) {
try {
return new InternetAddress(addressStr);
} catch (AddressException e) {
errorHandler.error("Could not parse address [" + addressStr + "].",
e, ErrorCode.ADDRESS_PARSE_FAILURE);
return null;
}
}

/**
*
* @function:转换地址
* @param addressStr
* @return
* @author: mengqingyu 2013-4-10 下午02:38:52
*/
protected InternetAddress[] parseAddress(String addressStr) {
try {
return InternetAddress.parse(addressStr, true);
} catch (AddressException e) {
errorHandler.error("Could not parse address [" + addressStr + "].",
e, ErrorCode.ADDRESS_PARSE_FAILURE);
return null;
}
}
}

import org.apache.log4j.HTMLLayout;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.helpers.Transform;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;

/**
*
* 类功能描述:log4j 日志模板,重写此类解决中文乱码和自定义模板问题
*
* @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a>
* @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $
* Create: 2013-4-11 下午01:46:43
*/
public class HTMLCustomLayout extends HTMLLayout {

protected StringBuffer sbuf = new StringBuffer(BUF_SIZE);

protected static String TRACE_PREFIX = "<br>    ";

protected boolean locationInfo = false;

protected String title = "Log4J Log Messages";

public void setLocationInfo(boolean flag) {
locationInfo = flag;
}

public boolean getLocationInfo() {
return locationInfo;
}

public void setTitle(String title) {
this.title = title;
}

public String getTitle() {
return title;
}

/**
* 格式化HTML头部模板
*/
public String getHeader() {
StringBuffer sbuf = new StringBuffer();
sbuf.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">"
+ Layout.LINE_SEP);
sbuf.append("<html>" + Layout.LINE_SEP);
sbuf.append("<head>" + Layout.LINE_SEP);
sbuf.append("<title>" + title + "</title>" + Layout.LINE_SEP);
sbuf.append("<style type=\"text/css\">" + Layout.LINE_SEP);
sbuf.append("<!--" + Layout.LINE_SEP);
sbuf.append("body, table {font-family: arial,sans-serif; font-size: x-small;}"
+ Layout.LINE_SEP);
sbuf.append("th {background: #336699; color: #FFFFFF; text-align: left;}"
+ Layout.LINE_SEP);
sbuf.append("-->" + Layout.LINE_SEP);
sbuf.append("</style>" + Layout.LINE_SEP);
sbuf.append("</head>" + Layout.LINE_SEP);
sbuf.append("<body bgcolor=\"#FFFFFF\" topmargin=\"6\" leftmargin=\"6\">"
+ Layout.LINE_SEP);
sbuf.append("<hr size=\"1\" noshade>" + Layout.LINE_SEP);
sbuf.append("Log session start time " + new java.util.Date() + "<br>"
+ Layout.LINE_SEP);
sbuf.append("<br>" + Layout.LINE_SEP);
sbuf.append("<table cellspacing=\"0\" cellpadding=\"4\" border=\"1\" bordercolor=\"#224466\" width=\"100%\">"
+ Layout.LINE_SEP);
sbuf.append("<tr>" + Layout.LINE_SEP);
sbuf.append("<th>登录名</th>" + Layout.LINE_SEP);
sbuf.append("<th>用户名</th>" + Layout.LINE_SEP);
sbuf.append("<th>级别</th>" + Layout.LINE_SEP);
sbuf.append("<th>类名称</th>" + Layout.LINE_SEP);
if (locationInfo) {
sbuf.append("<th>File:Line</th>" + Layout.LINE_SEP);
}
sbuf.append("<th>方法名称</th>" + Layout.LINE_SEP);
sbuf.append("</tr>" + Layout.LINE_SEP);
return sbuf.toString();
}

/**
* 格式化HTML模板
*/
public String format(LoggingEvent event) {
if (sbuf.capacity() > MAX_CAPACITY) {
sbuf = new StringBuffer(BUF_SIZE);
} else {
sbuf.setLength(0);
}

sbuf.append(Layout.LINE_SEP + "<tr>" + Layout.LINE_SEP);

sbuf.append("<td>");
sbuf.append(event.getMDC("LOG_NAME_"));
sbuf.append("</td>" + Layout.LINE_SEP);

sbuf.append("<td>");
sbuf.append(event.getMDC("USER_NAME_"));
sbuf.append("</td>" + Layout.LINE_SEP);

sbuf.append("<td title=\"Level\">");
if (event.getLevel().equals(Level.DEBUG)) {
sbuf.append("<font color=\"#339933\">");
sbuf.append(event.getLevel());
sbuf.append("</font>");
} else if (event.getLevel().isGreaterOrEqual(Level.WARN)) {
sbuf.append("<font color=\"#993300\"><strong>");
sbuf.append(event.getLevel());
sbuf.append("</strong></font>");
} else {
sbuf.append(event.getLevel());
}
sbuf.append("</td>" + Layout.LINE_SEP);

sbuf.append("<td>");
sbuf.append(event.getMDC("CLASS_"));
sbuf.append("</td>" + Layout.LINE_SEP);

if (locationInfo) {
LocationInfo locInfo = event.getLocationInformation();
sbuf.append("<td>");
sbuf.append(Transform.escapeTags(locInfo.getFileName()));
sbuf.append(':');
sbuf.append(locInfo.getLineNumber());
sbuf.append("</td>" + Layout.LINE_SEP);
}

sbuf.append("<td>");
sbuf.append(event.getMDC("METHOD_NAME_"));
sbuf.append("</td>" + Layout.LINE_SEP);
sbuf.append("</tr>" + Layout.LINE_SEP);

if (event.getNDC() != null) {
sbuf.append("<tr><td bgcolor=\"#EEEEEE\" style=\"font-size : xx-small;\" colspan=\"6\" title=\"Nested Diagnostic Context\">");
sbuf.append("NDC: " + Transform.escapeTags(event.getNDC()));
sbuf.append("</td></tr>" + Layout.LINE_SEP);
}

Object methodParam = event.getMDC("METHOD_PARAM_");
if(methodParam!=null){
sbuf.append("<tr><td style=\"font-size : xx-small;\" colspan=\"6\">");
sbuf.append("方法参数:"+methodParam.toString().replace("\\r\\n", "  "));
sbuf.append("</td></tr>" + Layout.LINE_SEP);
}

sbuf.append("<tr><td style=\"font-size : xx-small;\" colspan=\"6\">");
sbuf.append("异常摘要:"+event.getMessage());
sbuf.append("</td></tr>" + Layout.LINE_SEP);

String[] s = event.getThrowableStrRep();
if (s != null) {
sbuf.append("<tr><td bgcolor=\"#993300\" style=\"color:White; font-size : xx-small;\" colspan=\"6\">");
appendThrowableAsHTML(s, sbuf);
sbuf.append("</td></tr>" + Layout.LINE_SEP);
}

return sbuf.toString();
}

/**
*
* @function:拼装异常内容
* @param s
* @param sbuf
* @author: mengqingyu 2013-4-11 下午01:49:29
*/
protected void appendThrowableAsHTML(String[] s, StringBuffer sbuf) {
if (s != null) {
int len = s.length;
if (len == 0)
return;
sbuf.append(Transform.escapeTags(s[0]));
sbuf.append(Layout.LINE_SEP);
for (int i = 1; i < len; i++) {
sbuf.append(TRACE_PREFIX);
sbuf.append(Transform.escapeTags(s[i]));
sbuf.append(Layout.LINE_SEP);
}
}
}

/**
* 中文编码
*/
public String getContentType() {
return "text/html;charset=GBK";
}
}

注:在类或方法上通过注解的方式来进行描述
@LogDiscription(method = "立即发布",param = "任务ID, 主键, 创建时间")
@Override
public void insertOrUpdateMysqlDatas(JSONArray datas, String tableName, String pkName){}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值