`
wj98127
  • 浏览: 268015 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

log4j输出到文件和数据库

    博客分类:
  • Java
阅读更多

官方API地址:http://logging.apache.org/log4j/1.2/apidocs/index.html?org/apache/log4j/PatternLayout.html

控制台的实现就不说了,这里提供两种实例的配置,一种是输出为文件的(每天输出一个文件),一种为输出到数据库的配置。

1、输出到文件:

log4j.rootCategory=WARN, CONSOLE, FILE

log4j.logger.com.surfilter.bt=FATAL,TOFILE

log4j.appender.TOFILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.TOFILE.Threshold=FATAL
log4j.appender.TOFILE.File=E:/javascpace/bt/logs/union.html
log4j.appender.TOFILE.Append=true
log4j.appender.TOFILE.ImmediateFlush=true
log4j.appender.TOFILE.DatePattern='.'yyyy-MM-dd'.html'
log4j.appender.TOFILE.layout=com.surfilter.bt.util.FormatHTMLLayout

 

这里的com.surfilter.bt.util.FormatHTMLLayout是重写了log4j提供的HTMLLayout类,具体代码如下:

import java.text.SimpleDateFormat;
import java.util.Map;

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;

import com.opensymphony.xwork2.ActionContext;
import com.surfilter.core.Constants;
import com.surfilter.security.domain.User;

public class FormatHTMLLayout extends HTMLLayout {

	public FormatHTMLLayout() {
	}

	protected final int BUF_SIZE = 256;

	protected final int MAX_CAPACITY = 1024;

	static String TRACE_PREFIX = "<br>&nbsp;&nbsp;&nbsp;&nbsp;";

	// output buffer appended to when format() is invoked
	private StringBuffer sbuf = new StringBuffer(BUF_SIZE);
	
	String title="系统操作日志";

	/**
	 * A string constant used in naming the option for setting the the HTML
	 * document title. Current value of this string constant is <b>Title</b>.
	 */
	public static final String TITLE_OPTION = "Title";

	// Print no location info by default
	boolean locationInfo = true;
	
	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(String.valueOf(i));
		sbuf.append("</td>" + Layout.LINE_SEP);
*/		
		sbuf.append("<td>");
		sbuf.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()));
		sbuf.append("</td>" + Layout.LINE_SEP);

	/*	String escapedThread = Transform.escapeTags(event.getThreadName());
		sbuf.append("<td title=\"" + escapedThread + " thread\">");
		sbuf.append(escapedThread);
		sbuf.append("</td>" + Layout.LINE_SEP);
	*/
		sbuf.append("<td title=\"级别\">");
		if (event.getLevel().equals(Level.FATAL)) {
			sbuf.append("<font color=\"#339933\">");
			sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));
			sbuf.append("</font>");
		} else if (event.getLevel().isGreaterOrEqual(Level.WARN)) {
			sbuf.append("<font color=\"#993300\"><strong>");
			sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));
			sbuf.append("</strong></font>");
		} else {
			sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));
		}
		sbuf.append("</td>" + Layout.LINE_SEP);
		
/*		String escapedLogger = Transform.escapeTags(event.getLoggerName().substring(event.getLoggerName().lastIndexOf(".")));
		sbuf.append("<td title=\"类名\">");
		sbuf.append(escapedLogger);
		sbuf.append("</td>" + Layout.LINE_SEP);
*/
		if (locationInfo) {
			LocationInfo locInfo = event.getLocationInformation();
			sbuf.append("<td title=\"行号\">");
			sbuf.append(Transform.escapeTags(locInfo.getFileName()));
			sbuf.append(':');
			sbuf.append(locInfo.getLineNumber());
			sbuf.append("</td>" + Layout.LINE_SEP);
		}
		Map session = ActionContext.getContext().getSession();
		if(session!=null){
			User user = (User) session.get(Constants.USER_IN_SESSION);
			sbuf.append("<td>"+user.getName()+"</td>");
		}else{
			sbuf.append("<td>&nbsp;</td>");
		}
		sbuf.append("<td title=\"日志信息\">");
		sbuf.append(Transform.escapeTags(event.getRenderedMessage()));
		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);
		}

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

	private 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);
			}
		}
	}

	/**
	 * Returns appropriate HTML headers.
	 */
	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("<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">");
		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: 12px;}" + 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 SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new java.util.Date()) + "<br>" + Layout.LINE_SEP);
	//	sbuf.append("<p>" + 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>所在行</th>" + Layout.LINE_SEP);
		}
		sbuf.append("<th>操作人</th>");
		sbuf.append("<th>信息</th>" + Layout.LINE_SEP);
		sbuf.append("</tr>" + Layout.LINE_SEP);
		sbuf.append("<br></br>" + Layout.LINE_SEP);
		return sbuf.toString();
	}

}

注,上面输出里包含了从当前session里取到的用户信息,只需要重写getHeader,format,appendThrowableAsHTML三个方法就可以了。LoggingEvent 提供的方法可以获取各种日志信息。 

 

2、输入到数据库,现在配置是将日志信息同时输出到文件和数据库

log4j.rootCategory=WARN, CONSOLE, FILE

log4j.logger.com.surfilter.bt=FATAL,TOFILE,JDBC

log4j.appender.TOFILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.TOFILE.Threshold=FATAL
log4j.appender.TOFILE.File=E:/javascpace/bt/logs/union.html
log4j.appender.TOFILE.Append=true
log4j.appender.TOFILE.ImmediateFlush=true
log4j.appender.TOFILE.DatePattern='.'yyyy-MM-dd'.html'
log4j.appender.TOFILE.layout=com.surfilter.bt.util.FormatHTMLLayout
log4j.appender.JDBC=org.apache.log4j.jdbc.JDBCAppender
#log4j.appender.JDBC=com.surfilter.bt.util.Log4jToDBAppender 
log4j.appender.JDBC.Threshold=FATAL
log4j.appender.JDBC.URL=jdbc:oracle:thin:@127.0.0.1:1521:orcl
log4j.appender.JDBC.driver=oracle.jdbc.driver.OracleDriver
log4j.appender.JDBC.user=db_user
log4j.appender.JDBC.password=db_password
log4j.appender.JDBC.sql=insert into sys_log(id,loginid,PRIORITY,LOGDATE,CLASS,METHOD,MSG) values (seq_sys_log.nextval,'0','%p','%d{yyyy-MM-dd HH:mm:ss}','%c{1}','%-10.50l','%m')
log4j.appender.JDBC.layout=org.apache.log4j.PatternLayout

 

 以上配置将会同时输出到文件和数据库,注意这里有一行注释掉的实现com.surfilter.bt.util.Log4jToDBAppender,如果你要使用连接池可以继承JDBCAppender重写实现,下面是JDBCAppender的实现源码,可以从log4j官网上down到:

package org.apache.log4j.jdbc;

import org.apache.log4j.spi.*;
import org.apache.log4j.PatternLayout;

import java.util.ArrayList;
import java.util.Iterator;

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.SQLException;

public class JDBCAppender extends org.apache.log4j.AppenderSkeleton
    implements org.apache.log4j.Appender {

  protected String databaseURL = "jdbc:odbc:myDB";

  protected String databaseUser = "me";

  protected String databasePassword = "mypassword";

  protected Connection connection = null;

  protected String sqlStatement = "";

  protected int bufferSize = 1;

  protected ArrayList buffer;

  protected ArrayList removes;

  public JDBCAppender() {
    super();
    buffer = new ArrayList(bufferSize);
    removes = new ArrayList(bufferSize);
  }

  public void append(LoggingEvent event) {
    buffer.add(event);

    if (buffer.size() >= bufferSize)
      flushBuffer();
  }

  protected String getLogStatement(LoggingEvent event) {
    return getLayout().format(event);
  }

  protected void execute(String sql) throws SQLException {

    Connection con = null;
    Statement stmt = null;

    try {
        con = getConnection();

        stmt = con.createStatement();
        stmt.executeUpdate(sql);
    } catch (SQLException e) {
       if (stmt != null)
	     stmt.close();
       throw e;
    }
    stmt.close();
    closeConnection(con);

    //System.out.println("Execute: " + sql);
  }

  protected void closeConnection(Connection con) {
  }

  protected Connection getConnection() throws SQLException {
      if (!DriverManager.getDrivers().hasMoreElements())
	     setDriver("sun.jdbc.odbc.JdbcOdbcDriver");

      if (connection == null) {
        connection = DriverManager.getConnection(databaseURL, databaseUser,
					databasePassword);
      }

      return connection;
  }

  public void close()
  {
    flushBuffer();

    try {
      if (connection != null && !connection.isClosed())
          connection.close();
    } catch (SQLException e) {
        errorHandler.error("Error closing connection", e, ErrorCode.GENERIC_FAILURE);
    }
    this.closed = true;
  }

  public void flushBuffer() {
    //Do the actual logging
    removes.ensureCapacity(buffer.size());
    for (Iterator i = buffer.iterator(); i.hasNext();) {
      try {
        LoggingEvent logEvent = (LoggingEvent)i.next();
	    String sql = getLogStatement(logEvent);
	    execute(sql);
        removes.add(logEvent);
      }
      catch (SQLException e) {
	    errorHandler.error("Failed to excute sql", e,
			   ErrorCode.FLUSH_FAILURE);
      }
    }
    
    // remove from the buffer any events that were reported
    buffer.removeAll(removes);
    
    // clear the buffer of reported events
    removes.clear();
  }

  public void finalize() {
    close();
  }

  public boolean requiresLayout() {
    return true;
  }

  public void setSql(String s) {
    sqlStatement = s;
    if (getLayout() == null) {
        this.setLayout(new PatternLayout(s));
    }
    else {
        ((PatternLayout)getLayout()).setConversionPattern(s);
    }
  }

  public String getSql() {
    return sqlStatement;
  }


  public void setUser(String user) {
    databaseUser = user;
  }

  public void setURL(String url) {
    databaseURL = url;
  }

  public void setPassword(String password) {
    databasePassword = password;
  }

  public void setBufferSize(int newBufferSize) {
    bufferSize = newBufferSize;
    buffer.ensureCapacity(bufferSize);
    removes.ensureCapacity(bufferSize);
  }

  public String getUser() {
    return databaseUser;
  }

  public String getURL() {
    return databaseURL;
  }

  public String getPassword() {
    return databasePassword;
  }

  public int getBufferSize() {
    return bufferSize;
  }

  public void setDriver(String driverClass) {
    try {
      Class.forName(driverClass);
    } catch (Exception e) {
      errorHandler.error("Failed to load driver", e,
			 ErrorCode.GENERIC_FAILURE);
    }
  }
}

 
然后说一下PatternLayout里的ConversionPattern主要的格式化输开形式,Log4J采用类似C语言中的printf函数的打印,格式化日志信息,打印参数如下:

 %m 输出代码中指定的消息


 %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL


 %r 输出自应用启动到输出该log信息耗费的毫秒数


 %c 输出所属的类目,通常就是所在类的全名,例%c{1}: 类名"a.b.c" 时输出 "c"


 %t 输出产生该日志事件的线程名


 %n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”

 %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比 如:%d{yyyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921

 %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。

分享到:
评论
2 楼 悲剧了 2011-07-20  
刚好用到,谢了
1 楼 duduwei 2009-06-11  
真复杂 ~

相关推荐

    log4j输出日志到数据库表中

    **标题解析:** "log4j输出日志到数据库表中" 指的是使用Log4j这个流行的Java日志框架,将日志记录存储在数据库的特定表中,而不是默认的文本文件或控制台。这通常是出于日志管理、分析和长期存储的需求。 **描述...

    log4j2.xml记录日志到到数据库

    总结,Log4j2通过XML配置文件实现了与MySQL数据库的集成,允许开发者将日志信息存储在数据库中,便于长期保存和分析。理解Log4j2的配置和使用是每个Java开发者必备的技能,这对于日后的故障排查和系统维护至关重要。...

    log4j的eclipse工程,输出到文件的方式配置log4j

    标题"log4j的eclipse工程,输出到文件的方式配置log4j"表明我们关注的是在Eclipse开发环境中如何利用log4j框架将日志信息输出到文件。Log4j是Apache的一个开源项目,它提供了一个灵活的日志系统,允许开发者在运行时...

    log4j添加日志到数据库和文件中

    在"log4j添加日志到数据库和文件中"的场景中,我们首先需要理解Log4j的基本架构。它主要由三个组件构成:Logger(日志器)、Appender(输出器)和Layout(布局)。Logger负责生成日志事件,Appender则负责将这些事件...

    Log4j 日志信息存储到数据库中

    Apache Log4j 是一个流行的 Java 日志框架,它提供了灵活的日志记录机制,并支持将日志信息存储到不同的目的地,如控制台、文件或数据库等。 本文主要介绍如何使用 Log4j 将日志信息存储到 MySQL 数据库中。通过...

    log4j使用与java中log4j记录日志如何写入数据库

    1. **配置文件**:Log4j的配置文件通常是`log4j.properties`或`log4j.xml`,它定义了日志的级别(如DEBUG、INFO、WARN、ERROR、FATAL)、输出目的地(控制台、文件、数据库等)以及布局格式。 2. **日志类**:在...

    mybatis,log4j打印日志到后台和文件

    本文将深入探讨如何在 MyBatis 中配置 Log4j,实现日志同时输出到后台控制台和文件。 1. **日志框架集成** 在 MyBatis 中,我们通常会依赖日志框架如 Log4j、Logback 或 JDK 内置的日志系统。Log4j 以其强大的功能...

    log4j多文件输出打印

    在"Log4j多文件输出打印"的场景下,我们通常会配置多个Appender,每个Appender对应一个不同的输出文件。这样,不同的日志信息可以被分别写入不同的文件,便于管理和分析。例如,在`log4j.properties`配置文件中,...

    日志配置到文件,数据库

    - `log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout`:定义输出到数据库的日志格式。 **5. 按天滚动的日志文件配置** - `log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender`:指定...

    log4j的详细配置,log4j.xml和log4j.properties,日志输出到文件,邮件,数据库,控制台等

    总之,Log4j通过其灵活的配置,可以满足不同场景下的日志需求,无论是简单地输出到控制台,还是复杂地发送邮件或存入数据库,都能轻松实现。对于开发和运维人员来说,理解和掌握Log4j的配置方法是十分重要的,它能极...

    使用log4j 记录日志到数据库

    这篇博客“使用log4j记录日志到数据库”将介绍如何配置和使用Log4j,以便将日志信息存储到数据库中,而非传统的文本文件。数据库存储的日志便于进行结构化查询,有助于进行长期的数据分析和管理。 首先,理解Log4j...

    log4j.jar包,和log4j.properties配置文件下载

    在"Log4j.jar包,和log4j.properties属性文件打包下载"中,我们有两个关键组成部分: 1. **Log4j.jar**:这是Log4j的主要库文件,包含了所有必需的类和方法,使得程序员能够方便地在代码中插入日志语句。它提供了...

    如何借助log4j把日志写入数据库中

    本文将深入讲解如何利用Log4j将日志信息存储到数据库中。 首先,我们需要理解Log4j的基本架构。Log4j由三个主要组件构成:Logger(日志器)、Appender(输出端)和Layout(格式化器)。Logger负责生成日志事件,...

    Log4J_全能配置文件.pdf

    - `log4j.appender.FILE=org.apache.log4j.FileAppender`:指定了名为`FILE`的appender用于文件输出。 - `log4j.appender.FILE.File=file.log`:指定日志文件名称为`file.log`。 - `log4j.appender.FILE.Append=...

    日志配置文件log4j.xml以及MySql数据库驱动文件

    本篇文章将深入探讨这两个关键组件:日志配置文件`log4j.xml`和MySQL数据库驱动文件`mysql-connector-java-5.1.39-bin.jar`。 首先,我们来了解`log4j.xml`。Log4j是Apache组织提供的一款开源的日志记录框架,广泛...

    log4j使用jar包和log4j.properties配置文件

    Log4j是一个开源的日志组件,支持多种输出格式,如控制台、文件、数据库等。它的核心概念包括Logger、Appender、Layout和Level,这些组件协同工作,使得日志信息的记录、收集和格式化变得简单易行。 ### 2. 使用Log...

    log4j及配置文件

    Log4j的核心理念是提供一种层次化的日志记录机制,可以方便地调整日志输出级别,同时支持多种输出方式,如控制台、文件、数据库等。它的主要组件包括Logger(日志器)、Appender(输出端)和Layout(格式化器)。 ...

    Log4j写入数据库详解

    2. **多样化的输出目的地**:除了标准的控制台输出和文件输出外,Log4j还支持输出至数据库、邮件系统、网络套接字等多种途径。 #### 三、Log4j与数据库集成 在众多日志输出目标中,将日志写入数据库是一种常见且...

    log4j需要的jar以及properties文件

    1. **日志级别配置**:例如`log4j.rootLogger=DEBUG, Console, File`,这定义了日志的默认级别为DEBUG,并将日志输出到控制台(Console)和文件(File)。 2. **Appender配置**:Appender是日志输出的目的地。例如...

    log4j写入数据库配置

    总结来说,Log4j写入数据库的配置涉及到创建适应的数据库表结构、配置`log4j.properties`文件以指定数据库连接信息和日志格式,并通过`JDBCAppender`将日志数据持久化到数据库中。这样的配置有助于收集和分析大量...

Global site tag (gtag.js) - Google Analytics