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; } }
相关推荐
3. **日志事件**:`LogEvent`是Log4j中的关键数据结构,它封装了日志信息,如时间戳、级别、logger名、消息和异常等。日志事件通过`Appender`发送到指定的输出目标。 4. **日志布局与模板**:Log4j提供了多种布局...
6. **事件数据结构**:Log4j2使用LogEvent对象封装日志信息,使其更易于处理和过滤。 7. **日志级别的优先级**:Log4j2允许设置每个Logger的优先级,便于控制日志输出的详细程度。 8. **自动重加载配置**:如果...
4. **API**:Log4j 2的API设计得更为简洁和强大,提供Logger接口进行日志记录,Event对象用于封装日志信息,以及ContextDataListener监听上下文数据。 5. **配置**:配置是Log4j的核心部分,用户可以通过XML、JSON...
SpringMVC、iBatis和Log4j是Java Web开发中的三个重要组件,它们共同构建了一个高效、灵活的Web应用程序架构。在这个“纯净版SpringMVC+Ibatis+log4j环境”中,我们将深入探讨这三个组件的核心概念、功能以及它们...
【标题】"raven-log4j-3.1.zip" 提供的是 Raven 与 Log4j 的集成版本,其中 Raven 是一个用于收集和发送日志数据到各种后端服务(如 Sentry)的库,而 Log4j 是一个广泛使用的 Java 日志框架。这个压缩包可能包含了 ...
标题中的"Log4jjar.zip日志文件包,主要为Java web而生"指出了我们讨论的核心是Log4j,一个针对Java Web应用的日志记录工具,它被封装在一个名为"Log4jjar.zip"的压缩文件中。描述进一步解释了这个压缩包的内容,即...
在本项目实例中,我们将深入探讨如何利用Spring Boot、Mybatis和Log4j这三大核心框架构建一个实际的Web应用程序。Spring Boot简化了Spring应用程序的初始设置和配置,Mybatis作为轻量级的持久层框架提供了灵活的SQL...
`log4net` 支持多个日志级别,包括`DEBUG`、`INFO`、`WARN`、`ERROR`、`FATAL`和`ALL`。开发者可以根据需要设置不同级别的日志,便于调试和问题追踪。 2. **配置方式** `log4net` 的配置可以通过XML文件、程序...
在LogDemox的场景中,Log4j作为数据源(Source),生成的日志信息被写入到一个或多个Channel中。Channel是内存或磁盘上的临时存储区域,用于缓冲待处理的数据。最后,Sink负责将数据从Channel取出并转发到下一个目的地...
本文将深入解析标题为“一个功能比较完整的log封装类”的日志系统,探讨其在C++中的实现,特别是其多线程支持和临界区保护特性。我们将讨论日志的重要性、如何封装日志类、多线程环境下日志安全的实现以及按日期和...
log4cpp是一个流行的C++日志库,灵感来源于Java的log4j。它提供了灵活的日志记录机制,支持多种日志级别(如DEBUG、INFO、WARN、ERROR、FATAL),并可自定义输出格式和目的地,如控制台、文件、网络等。log4cpp的...
本实战项目旨在帮助开发者掌握Web应用程序的实现,包括使用MVC设计模式、数据源(DataSource)、数据传输对象(DTO)、数据访问对象(DAO)、电子邮件发送以及日志管理工具Log4J的配置。此外,还将涉及文件上传功能...
然而,在这个特定版本中,Mina的源代码已经去除了对SLF4J的依赖,这可能是因为开发者希望让用户自由选择自己的日志实现,或者是为了减少依赖性,提高构建的灵活性。 Mina 2.0.7的核心组件包括以下几个关键部分: 1...
"一个写log的封装类,含工程文件" 提供了一个专门用于日志记录的类,这个类设计得简单高效,并且具有多线程安全性和日期时间管理功能。下面我们将深入探讨这些关键知识点。 首先,**日志封装类** 是一种常见的设计...
通过创建一个抽象的、虚拟的数据源(DynamicDataSource),它可以作为一个代理,封装数据源选择逻辑。客户端只需提供必要的上下文信息,如用户ID,然后由虚拟数据源根据这些信息决定使用哪个实际的数据源。 以下是...
最后,还需要配置log4j来控制log4jdbc的日志级别。下面是一个简单的配置示例: ```properties log4j.logger.jdbc.sqlonly=OFF log4j.logger.jdbc.sqltiming=INFO log4j.logger.jdbc.audit=OFF log4j.logger.jdbc....
- `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-...
本项目是一个基于Struts2、Spring2.5、Hibernate3.5的整合示例,其中还引入了c3p0作为数据库连接池,并使用了日志工具Log4j。这个项目的目的是帮助开发者理解如何在实际开发中快速、有效地整合这四个关键组件,从而...
在Windows操作系统中,事件日志(Event Log)是一种记录系统、应用程序和其他服务中发生事件的重要机制。它提供了详细的错误信息、警告以及成功审核,帮助管理员监控系统状态并诊断问题。本教程将通过一个使用Visual...
2. 日志框架:如Python的logging库,Java的log4j,或者.NET的NLog等,它们提供了方便的日志记录和管理接口。 3. 日志解析:日志格式可能不统一,解析日志时可能需要针对特定格式编写解析逻辑。 4. 数据清洗:去除...