`
hn_archer
  • 浏览: 134141 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类
最新评论

让Log4j支持数据源--国外高手的封装

 
阅读更多
package nl.iprofs.blogs.log4j.databaselogging;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
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:
 * <pre>
 *   <appender name="database" class="nl.iprofs.blogs.log4j.databaselogging.JndiCapableJdbcAppender">
 *     <param name="jndiDataSource" value="java:comp/jdbc/datasource" />
 *     <layout class="org.apache.log4j.PatternLayout">
 *       <param name="ConversionPattern" value="INSERT INTO logging (timestamp, level, location, message) VALUES ('%d{yyyy-MM-dd HH:mm:ss.sss}','%p','%c{1}','%m')" />
 *     </layout>
 *   </appender>
 * </pre>
 *
 * @author Bart Bakker
 */
public class JndiCapableJdbcAppender extends JDBCAppender {
 
    private static final Pattern SQL_VALUE_PATTERN = Pattern.compile("'(.*?)'(?=\\s*[,)])", Pattern.MULTILINE);
    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 {
            Context context = new InitialContext();
            return (DataSource) context.lookup(jndiDataSource);
        } catch (NamingException e) {
            throw new RuntimeException("Cannot find JNDI DataSource: " + jndiDataSource, e);
        }
    }
 
    /** {@inheritDoc} */
    @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 getJndiDataSource() {
        return jndiDataSource;
    }
 
    public void setJndiDataSource(String jndiDataSource) {
        this.jndiDataSource = jndiDataSource;
    }
}

 

分享到:
评论

相关推荐

    apache-log4j-2.9.0-src.zip

    3. **日志事件**:`LogEvent`是Log4j中的关键数据结构,它封装了日志信息,如时间戳、级别、logger名、消息和异常等。日志事件通过`Appender`发送到指定的输出目标。 4. **日志布局与模板**:Log4j提供了多种布局...

    log4j2-2.3

    6. **事件数据结构**:Log4j2使用LogEvent对象封装日志信息,使其更易于处理和过滤。 7. **日志级别的优先级**:Log4j2允许设置每个Logger的优先级,便于控制日志输出的详细程度。 8. **自动重加载配置**:如果...

    log4j-users-guide.pdf

    4. **API**:Log4j 2的API设计得更为简洁和强大,提供Logger接口进行日志记录,Event对象用于封装日志信息,以及ContextDataListener监听上下文数据。 5. **配置**:配置是Log4j的核心部分,用户可以通过XML、JSON...

    纯净版SpringMVC+Ibatis+log4j环境

    SpringMVC、iBatis和Log4j是Java Web开发中的三个重要组件,它们共同构建了一个高效、灵活的Web应用程序架构。在这个“纯净版SpringMVC+Ibatis+log4j环境”中,我们将深入探讨这三个组件的核心概念、功能以及它们...

    raven-log4j-3.1.zip

    【标题】"raven-log4j-3.1.zip" 提供的是 Raven 与 Log4j 的集成版本,其中 Raven 是一个用于收集和发送日志数据到各种后端服务(如 Sentry)的库,而 Log4j 是一个广泛使用的 Java 日志框架。这个压缩包可能包含了 ...

    Log4jjar.zip日志文件包,主要为Java web而生

    标题中的"Log4jjar.zip日志文件包,主要为Java web而生"指出了我们讨论的核心是Log4j,一个针对Java Web应用的日志记录工具,它被封装在一个名为"Log4jjar.zip"的压缩文件中。描述进一步解释了这个压缩包的内容,即...

    Spring boot+Mybatis+log4j项目实例

    在本项目实例中,我们将深入探讨如何利用Spring Boot、Mybatis和Log4j这三大核心框架构建一个实际的Web应用程序。Spring Boot简化了Spring应用程序的初始设置和配置,Mybatis作为轻量级的持久层框架提供了灵活的SQL...

    log4net日志以及压缩源代码

    `log4net` 支持多个日志级别,包括`DEBUG`、`INFO`、`WARN`、`ERROR`、`FATAL`和`ALL`。开发者可以根据需要设置不同级别的日志,便于调试和问题追踪。 2. **配置方式** `log4net` 的配置可以通过XML文件、程序...

    LogDemox 收集信息通过log4j直接打到flume中

    在LogDemox的场景中,Log4j作为数据源(Source),生成的日志信息被写入到一个或多个Channel中。Channel是内存或磁盘上的临时存储区域,用于缓冲待处理的数据。最后,Sink负责将数据从Channel取出并转发到下一个目的地...

    一个功能比较完整的log封装类

    本文将深入解析标题为“一个功能比较完整的log封装类”的日志系统,探讨其在C++中的实现,特别是其多线程支持和临界区保护特性。我们将讨论日志的重要性、如何封装日志类、多线程环境下日志安全的实现以及按日期和...

    Log-lib20201116.zip

    log4cpp是一个流行的C++日志库,灵感来源于Java的log4j。它提供了灵活的日志记录机制,支持多种日志级别(如DEBUG、INFO、WARN、ERROR、FATAL),并可自定义输出格式和目的地,如控制台、文件、网络等。log4cpp的...

    Web 式样书,Log4J,发送Email

    本实战项目旨在帮助开发者掌握Web应用程序的实现,包括使用MVC设计模式、数据源(DataSource)、数据传输对象(DTO)、数据访问对象(DAO)、电子邮件发送以及日志管理工具Log4J的配置。此外,还将涉及文件上传功能...

    Mina2.0.7原代码,去掉slf4j代码

    然而,在这个特定版本中,Mina的源代码已经去除了对SLF4J的依赖,这可能是因为开发者希望让用户自由选择自己的日志实现,或者是为了减少依赖性,提高构建的灵活性。 Mina 2.0.7的核心组件包括以下几个关键部分: 1...

    一个写log的封装类,含工程文件

    "一个写log的封装类,含工程文件" 提供了一个专门用于日志记录的类,这个类设计得简单高效,并且具有多线程安全性和日期时间管理功能。下面我们将深入探讨这些关键知识点。 首先,**日志封装类** 是一种常见的设计...

    Spring多数据源解决方案

    通过创建一个抽象的、虚拟的数据源(DynamicDataSource),它可以作为一个代理,封装数据源选择逻辑。客户端只需提供必要的上下文信息,如用户ID,然后由虚拟数据源根据这些信息决定使用哪个实际的数据源。 以下是...

    Java实训教程 Java软件开发实战 Java开发框架 log4jdbc 共5页.pptx

    最后,还需要配置log4j来控制log4jdbc的日志级别。下面是一个简单的配置示例: ```properties log4j.logger.jdbc.sqlonly=OFF log4j.logger.jdbc.sqltiming=INFO log4j.logger.jdbc.audit=OFF log4j.logger.jdbc....

    SSH2搭建说明配置

    - `slf4j-log4j12-1.5.0.jar`:SLF4J的日志适配器,桥接Log4j日志库。 - `log4j-1.2.15.jar`:Log4j日志框架。 - `slf4j-api-1.5.0.jar`:简单日志门面(Simple Logging Facade for Java)的API。 - `spring-...

    sturts2+spring2.5+hibernate3.5+c3p0+log4j整合示例项目

    本项目是一个基于Struts2、Spring2.5、Hibernate3.5的整合示例,其中还引入了c3p0作为数据库连接池,并使用了日志工具Log4j。这个项目的目的是帮助开发者理解如何在实际开发中快速、有效地整合这四个关键组件,从而...

    Write Eventlog in Windows

    在Windows操作系统中,事件日志(Event Log)是一种记录系统、应用程序和其他服务中发生事件的重要机制。它提供了详细的错误信息、警告以及成功审核,帮助管理员监控系统状态并诊断问题。本教程将通过一个使用Visual...

    LOG-SK-3_log_excel_源码.zip

    2. 日志框架:如Python的logging库,Java的log4j,或者.NET的NLog等,它们提供了方便的日志记录和管理接口。 3. 日志解析:日志格式可能不统一,解析日志时可能需要针对特定格式编写解析逻辑。 4. 数据清洗:去除...

Global site tag (gtag.js) - Google Analytics