log4j保存到oracle,log4j 实现日志存入数据库

o

增加配置:

增加java类:

public class AccessLogFactory {

private static final String ACCESSLOG_CATEGORY = "accesslog_category";

static {

DOMConfigurator.configure("./resource/log4j.xml");

}

public static Log getLog() {

Log logger = null;

try {

logger = LogFactory.getLog(ACCESSLOG_CATEGORY);

} catch (LogConfigurationException e) {

e.printStackTrace();

}

return logger;

}

}

增加java类:

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

/**

* URL of the DB for default connection handling

*/

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

/**

* User to connect as for default connection handling

*/

protected String databaseUser = "me";

/**

* User to use for default connection handling

*/

protected String databasePassword = "mypassword";

/**

* Connection used by default. The connection is opened the first time it is

* needed and then held open until the appender is closed (usually at

* garbage collection). This behavior is best modified by creating a

* sub-class and overriding the getConnection and

* closeConnection methods.

*/

protected Connection connection = null;

/**

* Stores the string given to the pattern layout for conversion into a SQL

* statement, eg: insert into LogTable (Thread, Class, Message) values

* ("%t", "%c", "%m").

*

* Be careful of quotes in your messages!

*

* Also see PatternLayout.

*/

protected String sqlStatement = "";

/**

* size of LoggingEvent buffer before writting to the database. Default is

* 1.

*/

protected int bufferSize = 1;

/**

* 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 JDBCAppender() {

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 LocationInfo option.

*/

public boolean getLocationInfo() {

return locationInfo;

}

/**

* The LocationInfo 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).

*

*

* Location information extraction is comparatively very slow and should be

* avoided unless performance is not a concern.

*

*

* @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) {

return getLayout().format(event);

}

/**

*

* Override this to provide an alertnate method of getting connections (such

* as caching). One method to fix this is to open connections at the start

* of flushBuffer() and close them at the end. I use a connection pool

* outside of JDBCAppender which is accessed in an override of this method.

*/

protected void execute(String sql) throws SQLException {

Connection con = null;

Statement stmt = null;

try {

con = getConnection();

stmt = con.createStatement();

stmt.executeUpdate(sql);

} finally {

if (stmt != null) {

stmt.close();

}

closeConnection(con);

}

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

}

/**

* Override this to return the connection to a pool, or to clean up the

* resource.

*

* The default behavior holds a single connection open until the appender is

* closed (typically when garbage collected).

*/

protected void closeConnection(Connection con) {

}

/**

* Override this to link with your connection pooling system.

*

* By default this creates a single connection which is held open until the

* object is garbage collected.

*/

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;

}

/**

* Closes the appender, flushing the buffer first then closing the default

* connection if it is open.

*/

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;

}

/**

* 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!

*/

public void flushBuffer() {

// Do the actual logging

removes.ensureCapacity(buffer.size());

for (Iterator i = buffer.iterator(); i.hasNext();) {

LoggingEvent logEvent = (LoggingEvent) i.next();

try {

Connection con = getConnection();

PreparedStatement stmt = con.prepareStatement(getSql());

stmt.setString(1, DateUtil.formatCurDate().concat(DateUtil.formatCurTime()));

stmt.setString(2, logEvent.getThreadName());

stmt.setString(3, logEvent.getLevel().toString());

stmt.setString(4, logEvent.getLoggerName());

stmt.setString(5, logEvent.getMessage().toString());

stmt.executeUpdate();

} catch (SQLException e) {

errorHandler.error("Failed to excute sql", e, ErrorCode.FLUSH_FAILURE);

} finally {

removes.add(logEvent);

}

}

// remove from the buffer any events that were reported

buffer.removeAll(removes);

// clear the buffer of reported events

removes.clear();

}

/** closes the appender before disposal */

public void finalize() {

close();

}

/**

* JDBCAppender requires a layout.

*/

public boolean requiresLayout() {

return true;

}

/**

*

*/

public void setSql(String sql) {

sqlStatement = sql;

if (getLayout() == null) {

this.setLayout(new PatternLayout(sql));

} else {

((PatternLayout) getLayout()).setConversionPattern(sql);

}

}

/**

* Returns pre-formated statement eg: insert into LogTable (msg) values

* ("%m")

*/

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;

}

/**

* Ensures that the given driver class has been loaded for sql connection

* creation.

*/

public void setDriver(String driverClass) {

try {

Class.forName(driverClass);

} catch (Exception e) {

errorHandler.error("Failed to load driver", e, ErrorCode.GENERIC_FAILURE);

}

}

}

增加表:

create table T_LOG

(

currtime   VARCHAR2(20) not null,

currthread CHAR(100),

currlevel  CHAR(10),

currcode   CHAR(20),

currmsg    CHAR(200)

)

调用:

Log logger = AccessLogFactory.getLog();

logger.debug("XXXX")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值