Skip to content

Ahmet Faruk Bişkinler

Java Log4j JNDI Pool Appender
(0 votes, average 0 out of 5)
Java - Web Development
Administrator tarafından yazıldı.   
Pazartesi, 09 Mayıs 2011 10:15
Add weblogic client and oracle client lib to for classpath. For maven add:
		
<dependency>
<groupId>com.oracle.jdbc</groupId>
<artifactId>ojdbc5</artifactId>
<version>11.1.0.7.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>weblogic-server</groupId>
<artifactId>weblogic</artifactId>
<version>8.1.4.0</version>
<optional>true</optional>
</dependency>
Create a table on DB like:
		
DROP TABLE BISKINLER.LOG CASCADE CONSTRAINTS;

CREATE TABLE BISKINLER.LOG
(
LOG_ID NUMBER(19) NOT NULL,
LOG_DATE TIMESTAMP(6),
LOG_FILE VARCHAR2(255 CHAR),
LOG_METHOD VARCHAR2(255 CHAR),
LOG_TEXT CLOB,
LOG_TYPE VARCHAR2(255 CHAR)
)
Write a class like:
package com.biskinler.lo4j.appander;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.log4j.jdbc.JDBCAppender;
import org.apache.log4j.spi.ErrorCode;

/**
* Extension of the log4j {@link JDBCAppender} to allow using a JNDI data source
* rather than a direct connection.
*
* <p>
* Example configuration:
*
* log4j.appender.JNDI=com.biskinler.lo4j.appander.JndiCapableJdbcAppender
* log4j.appender.JNDI.factoryInitial=weblogic.jndi.WLInitialContextFactory
* log4j.appender.JNDI.jndiDataSource=dataSoruce
* log4j.appender.JNDI.jndiProviderURL=t3://10.11.12.13:10000
*
* @author Bart Bakker
* @author Ahmet Faruk Bişkinler
* @email ahmet @ biskinler.com
*/
public class JndiPoolAppender extends JDBCAppender {

private static final Pattern SQL_VALUE_PATTERN = Pattern.compile( "'(.*?)'(?=\\s*[,)])", Pattern.MULTILINE);
private String factoryInitial;
private String jndiProviderURL;
private String jndiDataSource;

/** {@inheritDoc} */
@Override
protected Connection getConnection() throws SQLException {
if (jndiDataSource == null) {
return super.getConnection();
} else {
return lookupDataSource().getConnection();
}
}

/**
* Looks up the datasource in the naming context specified by the
* {@link #jndiDataSource}.
*
* @return the datasource.
*/
private DataSource lookupDataSource() {
try {
Hashtable<String, String> props = new Hashtable<String, String>();
props.put("java.naming.factory.initial", factoryInitial);
props.put("java.naming.provider.url", jndiProviderURL);
Context ctx = new InitialContext(props);
DataSource ds = (DataSource) ctx.lookup(jndiDataSource);

return ds;
} catch (NamingException e) {
throw new RuntimeException("Cannot find JNDI DataSource: " + jndiDataSource, e);
}
}

@Override
protected void closeConnection(Connection con) {
try {
con.close();
} catch (SQLException e) {
errorHandler.error("Failed to close connection", e, ErrorCode.CLOSE_FAILURE);
}
}

/**
* Executes the specified SQL statement, by parsing its values and turning
* them into parameters, so that characters that must be escaped in a SQL
* statement are supported.
*/
@Override
protected void execute(String sql) throws SQLException {
String statement = sql;
ArrayList<String> args = new ArrayList<String>();
Matcher m = SQL_VALUE_PATTERN.matcher(sql);
while (m.find()) {
args.add(m.group(1));
statement = statement.replace(m.group(), "?");
}

executeStatement(statement, args.toArray(new String[args.size()]));
}

/**
* Executes the statement settings its parameters to the specified
* arguments.
*
* @param statement the statement to execute.
* @param args the parameter values.
*/
protected void executeStatement(String statement, String[] args)throws SQLException {
Connection con = getConnection();
PreparedStatement stmt = null;
try {
stmt = con.prepareStatement(statement);
for (int i = 0; i < args.length; i++) {
stmt.setString(i + 1, args[i]);
}
stmt.executeUpdate();
} catch (SQLException e) {
if (stmt != null) {
stmt.close();
}
throw e;
}
stmt.close();
closeConnection(con);
}


public String getFactoryInitial() {
return factoryInitial;
}

public void setFactoryInitial(String factoryInitial) {
this.factoryInitial = factoryInitial;
}

public String getJndiProviderURL() {
return jndiProviderURL;
}

public void setJndiProviderURL(String jndiProviderURL) {
this.jndiProviderURL = jndiProviderURL;
}

public String getJndiDataSource() {
return jndiDataSource;
}

public void setJndiDataSource(String jndiDataSource) {
this.jndiDataSource = jndiDataSource;
}

}
Write log4j.properties:
# JNDI Appender Log Configuration
log4j.appender.JNDI=com.biskinler.testapp.log.JndiPoolAppender
log4j.appender.JNDI.Threshold=INFO
log4j.appender.JNDI.jndiProviderURL=t3://10.11.12.13:10000

#Weblogic
#log4j.appender.JNDI.factoryInitial=weblogic.jndi.WLInitialContextFactory
#log4j.appender.JNDI.jndiDataSource=testapp10g
#Tomcat
log4j.appender.JNDI.factoryInitial=org.apache.naming.java.javaURLContextFactory
log4j.appender.JNDI.jndiDataSource=java:comp/env/testapp10g

log4j.appender.JNDI.layout=org.apache.log4j.PatternLayout
log4j.appender.JNDI.layout.ConversionPattern=insert into log (LOG_DATE, LOG_TYPE, LOG_FILE, LOG_METHOD, LOG_TEXT) values (sysdate, '%p', '%F', '%l', '%m')
Son Güncelleme: Pazar, 05 Şubat 2012 13:49