`
lumingming1987
  • 浏览: 117106 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

log4j-database appender

 
阅读更多

1.log4j配置

<appender name="DATABASE" class="com.sf.core.log4j.DataSourceAppender">
		<filter class="org.apache.log4j.varia.LevelRangeFilter" >
			<param name="levelMin" value="error"/>
		</filter>
	</appender>
    <root>
        <level value="INFO"/>
        <appender-ref ref="CONSOLE"/>
		<appender-ref ref="DATABASE"/>      
    </root>

 2.自己定义Appender类,这里使用spring提供的JdbcTemplate批量插入日志.

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.sf.core.log4j;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;

import org.apache.log4j.Level;
import org.apache.log4j.MDC;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;

import com.sf.core.util.AppUtil;
import com.sf.core.util.UniqueIdUtil;


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

	


	protected String sqlStatement = "";

	/**
	 * size of LoggingEvent buffer before writting to the database. Default is
	 * 1.
	 */
	protected int bufferSize = 1;
	
	protected int maxBuffSize = 10000;

	/**
	 * ArrayList holding the buffer of Logging Events.
	 */
	protected ArrayList buffer;

	/**
	 * Helper object for clearing out the buffer
	 */
	protected ArrayList removes;

	private boolean locationInfo = false;

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

	/**
	 * Gets whether the location of the logging request call should be captured.
	 * 
	 * @since 1.2.16
	 * @return the current value of the <b>LocationInfo</b> option.
	 */
	public boolean getLocationInfo() {
		return locationInfo;
	}

	/**
	 * The <b>LocationInfo</b> option takes a boolean value. By default, it is
	 * set to false which means there will be no effort to extract the location
	 * information related to the event. As a result, the event that will be
	 * ultimately logged will likely to contain the wrong location information
	 * (if present in the log format).
	 * <p/>
	 * <p/>
	 * Location information extraction is comparatively very slow and should be
	 * avoided unless performance is not a concern.
	 * </p>
	 * 
	 * @since 1.2.16
	 * @param flag
	 *            true if location information should be extracted.
	 */
	public void setLocationInfo(final boolean flag) {
		locationInfo = flag;
	}

	/**
	 * Adds the event to the buffer. When full the buffer is flushed.
	 */
	public void append(LoggingEvent event) {
		event.getNDC();
		event.getThreadName();
		// Get a copy of this thread's MDC.
		event.getMDCCopy();
		

		if (locationInfo) {
			event.getLocationInformation();
		}
		event.getRenderedMessage();
		event.getThrowableStrRep();
		buffer.add(event);

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

	/**
	 * By default getLogStatement sends the event to the required Layout object.
	 * The layout will format the given pattern into a workable SQL string.
	 * 
	 * Overriding this provides direct access to the LoggingEvent when
	 * constructing the logging statement.
	 * 
	 */
	protected String getLogStatement(LoggingEvent event) {
		String statement =  getLayout().format(event);
		return statement;
	}

	/**
	 * Closes the appender, flushing the buffer first then closing the default
	 * connection if it is open.
	 */
	public void close() {
		flushBuffer();

		this.closed = true;
	}

	/**
	 * loops through the buffer of LoggingEvents, gets a sql string from
	 * getLogStatement() and sends it to execute(). Errors are sent to the
	 * errorHandler.
	 * 
	 * If a statement fails the LoggingEvent stays in the buffer!
	 */
	@SuppressWarnings("unchecked")
	public void flushBuffer() {
		removes.ensureCapacity(buffer.size());
		try {
			if (AppUtil.getContext() != null && AppUtil.getServletContext()!=null) {
				removes.addAll(buffer);
				JdbcTemplate jdbcTemplate = (JdbcTemplate) AppUtil.getBean("jdbcTemplateLog4j");
				try{
					String sql = "INSERT INTO SYS_LOG4J_MSG("+ 
					"ID_,"+
					"CLAZZ," +
					"PRIORITY," +
					"MESSAGE," +
					"LOG_DATE," +
					"USER_ID," +
					"USER_NAME," +
					"USER_ACCOUNT) "
				+"values(?," +
						"?," +
						"?," +
						"?," +
						"?," +
						"?," +
						"?," +
						"?)"; 
					jdbcTemplate.batchUpdate(sql,new BatchPreparedStatementSetter() {
						@Override
						public void setValues(PreparedStatement ps, int i) throws SQLException {
							LoggingEvent logEvent = (LoggingEvent) buffer.get(i);
							String clazz = logEvent.getLocationInformation().getClassName();
							String level = getLogLevelH(logEvent.getLevel());
							String message = logEvent.getMessage().toString();
							Timestamp time = new Timestamp(logEvent.getTimeStamp());
							Long userId = (Long) MDC.get("current_user_id");
							String userName = (String) MDC.get("current_user_name");
							String userAccount = (String) MDC.get("current_user_account");
							ps.setLong(1, UniqueIdUtil.genId());
							ps.setString(2, clazz);
							ps.setString(3, level);
							ps.setString(4, message);
							ps.setTimestamp(5,time);
							ps.setLong(6, userId==null?0L:userId);
							ps.setString(7, userName);
							ps.setString(8, userAccount);
						}
						@Override
						public int getBatchSize() {
							return buffer.size();
						}
					});
				}catch (Exception e) {
					e.printStackTrace();
				}
			}else{
				if(buffer.size()>maxBuffSize){
					removes.addAll(buffer.subList(0, maxBuffSize/10));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
		buffer.removeAll(removes);
		removes.clear();
	}

	
	private String getLogLevelH(Level l){
		String ls="";
		
		if(l.toInt()==Level.ALL.toInt()){
			ls="ALL";
		}else if(l.toInt()==Level.DEBUG.toInt()){
			ls="DEBUG";
		}else if(l.toInt()==Level.ERROR.toInt()){
			ls="ERROR";
		}else if(l.toInt()==Level.FATAL.toInt()){
			ls="FATAL";
		}else if(l.toInt()==Level.INFO.toInt()){
			ls="INFO";
		}else if(l.toInt()==Level.OFF.toInt()){
			ls="OFF";
		}else if(l.toInt()==Level.TRACE.toInt()){
			ls="TRACE";
		}else if(l.toInt()==Level.WARN.toInt()){
			ls="WARN";
		}
		return ls;
	}
	
	
	/** closes the appender before disposal */
	public void finalize() {
		close();
	}

	/**
	 * JDBCAppender requires a layout.
	 * */
	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);
		}
	}

	/**
	 * Returns pre-formated statement eg: insert into LogTable (msg) values
	 * ("%m")
	 */
	public String getSql() {
		return sqlStatement;
	}


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


	public int getBufferSize() {
		return bufferSize;
	}

}

 3.建立数据表

-- Create table
create table SYS_LOG4J_MSG
(
  CLAZZ        VARCHAR2(512),
  PRIORITY     VARCHAR2(64),
  LOG_DATE     TIMESTAMP(6),
  MESSAGE      VARCHAR2(2000),
  USER_ID      NUMBER(18),
  USER_NAME    VARCHAR2(256),
  USER_ACCOUNT VARCHAR2(256),
  ID_          NUMBER(18) not null
);
-- Add comments to the table 
comment on table SYS_LOG4J_MSG
  is 'log4j消息';
-- Add comments to the columns 
comment on column SYS_LOG4J_MSG.CLAZZ
  is '类型名';
comment on column SYS_LOG4J_MSG.PRIORITY
  is '级别';
comment on column SYS_LOG4J_MSG.LOG_DATE
  is '时间截';
comment on column SYS_LOG4J_MSG.MESSAGE
  is '消息内容';
comment on column SYS_LOG4J_MSG.USER_ID
  is '用户ID';
comment on column SYS_LOG4J_MSG.USER_NAME
  is '用户名';
comment on column SYS_LOG4J_MSG.USER_ACCOUNT
  is '账号';
comment on column SYS_LOG4J_MSG.ID_
  is 'ID';
-- Create/Recreate primary, unique and foreign key constraints 
alter table SYS_LOG4J_MSG
  add constraint PK_LOG4J_MSG primary key (ID_);

 

分享到:
评论

相关推荐

    log4j日志驱动包

    log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n') log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout log4j.appender....

    mysql和log4j的jar包

    log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n # 在应用中记录数据库操作的日志 log4j.logger....

    log4j-java

    ### 四、配置文件`log4j.properties` `log4j.properties`是Log4j的主要配置文件,用于定义日志级别、目的地和格式。以下是一个基本的配置示例: ```properties # 设置全局日志级别为INFO log4j.rootLogger=INFO, ...

    log4j2 jdbc appender 实现将日志保存到 mysql。

    然后,配置Log4j2的`log4j2.xml`或`log4j2.json`文件,添加JDBC Appender。这里我们以XML为例: ```xml &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;ConnectionFactory class="org.apache.logging.log4j.core....

    c3p0&log4j配置文件及说明

    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n # 文件输出 log4j.appender.R=org.apache.log4j....

    日志配置到文件,数据库

    - `log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender`:指定了数据库输出的Appender类型为`JDBCAppender`。 - `log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/log4j`:连接数据库的URL。 ...

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

    首先,我们需要在`log4j2.xml`配置文件中定义一个使用JDBC Appender的配置: ```xml &lt;ConnectionFactory class="org.apache.logging.log4j.core.jdbc.DriverManagerConnectionFactory"&gt; ...

    log4j配置详解与使用方法说明

    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ``` - **File Appender**:将日志写入文件。 ```...

    Log4j+MongoDB 完整实例

    log4j.appender.MongoDBAppender.Database=logdb log4j.appender.MongoDBAppender.Collection=logcollection log4j.appender.MongoDBAppender.Pattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n ``` 在这个...

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

    Log4j由三个主要组件构成:Logger(日志器)、Appender(输出端)和Layout(格式化器)。Logger负责生成日志事件,Appender负责接收这些事件并将其输出到指定的目标,如控制台、文件或数据库。Layout则用于定义日志...

    使用log4j 记录日志到数据库

    log4j.appender.db=org.apache.log4j.jdbc.JDBCAppender log4j.appender.db.URL=jdbc:mysql://localhost:3306/testdb log4j.appender.db.Driver=com.mysql.jdbc.Driver log4j.appender.db.User=root log4j....

    log4j的配置文件.zip

    6. **配置文件结构**:`log4j.properties`文件通常采用键值对的形式,如`log4j.rootLogger=DEBUG, Console, File`表示根Logger的日志级别为DEBUG,并将其输出到Console和File两个Appender。Appender的配置会紧接着...

    Log4J.xml的模板

    标题中的“Log4J.xml”指的是Apache Log4j框架的配置文件。Log4j是Java平台上广泛使用的日志记录工具,它允许程序员以灵活和可配置的方式控制应用程序的日志输出。XML格式的配置文件提供了更高级别的结构和可读性,...

    Log4j+MongoDB

    log4j.appender.MongoDBAppender.Database=logdb log4j.appender.MongoDBAppender.Collection=logcollection ``` 4. **MongoDBAppender实现** `MongoDBAppender`是一个自定义的日志处理器,需要继承`org.apache...

    log4j.xml

    &lt;appender name="console" class="org.apache.log4j.ConsoleAppender"&gt; &lt;layout class="org.apache.log4j.PatternLayout"&gt; &lt;param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %c{1}:%L - %m%n" /&gt; &lt;/...

    log4j日志的数据库管理

    因此,本文将深入探讨如何利用数据库对Log4j日志进行高效管理,特别是通过DBCP(Database Connection Pooling)和MySQL数据库的结合,实现日志的集中式存储和查询,同时添加用户名等附加信息,增强日志的可追溯性和...

    JDBC驱动-oracle 10g,sqlserver 2008还带一个Log4j

    5. 插件和布局:Log4j支持多种Appender(如ConsoleAppender、FileAppender等)和Layout(如PatternLayout、XMLLayout等)。 总的来说,这个压缩包包含了开发Java应用程序时与Oracle和SQL Server数据库交互所需的...

    azkaban-3.38安装包(已编译)

    log4j.appender.server.layout=org.apache.log4j.PatternLayout log4j.appender.server.File=logs/azkaban-execserver.log log4j.appender.server.layout.ConversionPattern=%d{yyyy/MM/dd HH:mm:ss.SSS Z} %p [%...

    C#Log4net操作记录错误

    &lt;appender name="FileAppender" type="log4net.Appender.FileAppender"&gt; &lt;file value="logs/application.log" /&gt; &lt;layout type="log4net.Layout.PatternLayout"&gt; &lt;conversionPattern value="%date - %message%...

    log4jjdbc.jar

    只需要在类路径中包含log4jdbc3-1.2beta2.jar,并在Log4j的配置文件中指定适当的Appender,即可开始收集SQL日志。同时,附带的`license.txt`文件提供了关于软件许可的详细信息,确保了合法合规的使用。 log4jjdbc....

Global site tag (gtag.js) - Google Analytics