iBatis使用log4j2输出日志

原文链接这里

iBatis是一个老项目,2.3.4.726版本发布之后,项目改名为MyBatis,项目主页目前为http://mybatis.github.io/。

我从08年开始接触iBatis,一直使用2.3.4.726版本,直至当前的项目。iBatis恰到好处的满足了项目组在ORM、SQL维护方面的需求,所以也一直懒得换成其它同类开源软件,比如MyBatis。

最近参与新的项目开发,一切都要从零开始。为了节省时间,我直接把原项目中数据库相关操作的代码拿过来使用,发现遇到一个问题。新项目基于log4j2来输出日志,我按照求配置了iBatis相关的日志记录器之后,发现SQL执行时没有任何日志输出。iBatis在日志中输出拼装后的SQL、绑定的变量、查询返回的结果等,这对我来说是极为有用的特性,现在新项目中相关的日志都消失了,那分析SQL的正确性时就只好靠猜了。项目进度比较紧,我一开始没有时间去仔细考虑日志的问题。

好在紧急需求很快就搞定了,我终于有相对充足的时间来解决这个iBatis日志不输出的问题。项目里使用的log4j2配置文件不方便直接贴出来,精简之后如下

<?xml version="1.0" encoding="UTF-8"?>

<configuration status="OFF">

<appenders>

<Console name="Console" target="SYSTEM_OUT">

<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>

</Console>

</appenders>

<loggers>

<logger name="java.sql" level="debug" additivity="false">

<appender-ref ref="Console"/>

</logger>

<root level="debug">

<appender-ref ref="Console"/>

</root>

</loggers>

</configuration>

根据官网的资料,我反复对比过几次,确认配置文件没有问题,应该是其它地方出了问题。

找到iBatis的源码,打开iBatis创建日志记录器的类com.ibatis.common.logging.LogFactory,这个类是日志记录器的构造器工厂类,有如下的一段代码,用来定义查找日志记录器的顺序。

static

{

tryImplementation("org.apache.commons.logging.LogFactory", "com.ibatis.common.logging.jakarta.JakartaCommonsLoggingImpl");

tryImplementation("org.apache.log4j.Logger", "com.ibatis.common.logging.log4j.Log4jImpl");

tryImplementation("java.util.logging.Logger", "com.ibatis.common.logging.jdk14.Jdk14LoggingImpl");

tryImplementation("java.lang.Object", "com.ibatis.common.logging.nologging.NoLoggingImpl");

}

从这段代码可以看出,iBatis支持四种记录器,分别是:

  • commons-logging
  • apache-log4j
  • JDK原生的Log系统
  • 空记录器,不记录日志

看到这段代码的时候,我秀逗的大脑突然快速转动起来。在之前的项目时,iBatis和log4j配合可以正常输出日志,原因是iBatis针对log4j实现了专门的日志记录器构造工厂;当前的这个项目基于log4j2,iBatis没有专门定制的日志记录器工厂类,所以日志无法正常输出。想到这里,日志不能输出的原因找到了,但怎么让iBatis的日志恢复正常,我踌躇了好久。考虑要不要修改iBatis的源码,仿照com.ibatis.common.logging.log4j.Log4jImpl新写一个新的日志记录器的构造器。犹豫了半天,想想还是算了,我倒是不害怕修改iBatis的源码,之前参与过的一个项目里,已经为了修改另外的问题修改过iBatis的源码,编译环境什么的都还在;为了新项目修改点源码根本不是事情,但是考虑到项目正式发布时可能要做开源软件扫描和整改,我就怂了,还是少给自己找点事情吧。

重新回到iBatis创建日志记录器工厂类的代码,琢磨半天,猜想commons-logging也许是一个突破口。假如能够通过扩展commons-logging的构造工厂来搞定问题的话,项目里不需要增加新的依赖,因为项目的lib目录下已经有commons-logging相关的jar文件了。

感谢CSDN上不知名的热心网友,我找到一份commons-logging的配置说明,按照说明在项目的代码根路径下增加了commons-logging.properties文件,内容如下

org.apache.commons.logging.Log=ibatis.Log4j2Impl

这个ibatis.Log4j2Impl类先占位,具体实现网友的那份说明里没写,唯一了解的信息是类Log4j2Impl需要实现接口org.apache.commons.logging.Log,但如何实现不清楚。好在项目里有一些开源软件使用commons-logging来记录日志,在eclipse里针对org.apache.commons.logging.Log接口按F4,查找当前已实现了接口的类,发现commons-logging自带的org.apache.commons.logging.impl.Jdk14Logger可供参考,所以直接把相关的代码抄到ibatis.Log4j2Impl里,解决掉几个编译问题之后,工厂类就大功告成,接下来就是验证iBatis是否可以正常输出。

基于iBatis写个简单的测试类,代码如下

package ibatis;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import org.apache.logging.log4j.LogManager;

import org.apache.logging.log4j.Logger;

import com.ibatis.sqlmap.client.SqlMapClient;

import com.ibatis.sqlmap.client.SqlMapClientBuilder;

public class Test {

private static Logger logger = LogManager.getLogger(Test.class);

public static void main(String[] args) throws Exception {

SqlMapClient sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(Test.class.getClassLoader().getResourceAsStream("sql-map-config.xml"));

logger.info("before query");

sqlMapClient.queryForList("User.selectSubscriberInfo");

logger.info("succeed to query");

}

}

在eclipse里执行这段代码,终于看到了久违的SQL运行日志。

时间: 2024-10-21 07:59:08

iBatis使用log4j2输出日志的相关文章

ibatis配置log4j输出sql日志信息

为了在开发过程更加直观,我们需要将ibatis日志打开以便观察ibatis运作的细节. ibatis采用Apache common_logging,并结合Apache log4j作为日志输出组件. 在CLASSPATH中新建log4j.properties配置文件,内容如下: log4j.rootLogger=DEBUG,stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layo

记一次项目上线后Log4j2不输出日志的坑

公司项目采用了Log4j2来输出日志,在开发环境和测试环境下均可以输出日志,但在生成环境就没有日志输出.开始毫无头绪,后来通过不断的排查,终于解决了这个问题.在此记录下该问题的解决过程,便于后续查阅. 一.发现问题 p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; line-height: 125%; font-family: "Times New Roman"; font-size: 12.

Spring Boot 使用 Log4j2 &amp; Logback 输出日志到 EKL

文章目录 1.ELK 介绍 2.环境.软件准备 3.ELK 环境搭建 4.Spring Boot 配置示例 4.1.Log4j2 方式配置 4.2.Logback 方式配置 1.ELK 介绍 ELK 是 Elasticsearch , Logstash, Kibana 的缩写,Elasticsearch 是开源分布式搜索引擎,提供搜集.分析.存储数据等功能,Logstash 主要是用来日志的搜集.分析.过滤日志的工具,Kibana 为 Elasticsearch 提供分析和可视化的 Web 平台

log4j2.xml日志文件设置文件路径

笔者最近的项目里使用了spring,spring通过web.xml配置监听器,在web启动时web.root系统变量,以供其他变量使用,例如 在属性文件里使用${web.root}以取得完整路径,项目里使用了log4j2,在设置文件路径的时候也尝试用${web.root}却始终无法 获得属性值,创建的文件夹名字叫${web.root},显然这不符合实际工作环境需要.网上也有${sys:web.root}的说法. 也只会创建${sys:web.root}文件夹,后来在官网上找到相关设置方法Look

普通Java项目中使用Sl4j+Log4j2打印日志

因工作需要,采用JavaFx开发了一个windows窗口程序.在开发过程中,由于没有引入日志框架,只能自己手动在控制台打印些信息,给调试带来了很多麻烦:因此决定引入日志框架.由于之前接触的项目大部分都是javaWeb项目,web项目的日志输出已经难不倒我了.但普通java项目日志输出配置还是第一次接触,因此记录下整个过程,方便后续借鉴. 技术概述:采用Sl4j作为日志门面,Log4j2作为日志输出的具体实现:同时结合lombok插件,减少代码的书写. 一.相关Maven依赖 由于copy jar

SpringBoot+logback实现按业务输出日志到不同的文件

公司有个项目,需要和几个第三方系统对接.这种项目,日志一定要记录详细,不然出了问题就是各种甩锅.虽然项目里面和第三方系统对接相关的业务记录的日志很详细,但是由于整个项目的日志都在一个文件中,排查问题时比较麻烦.因此希望可以把这些和第三方对接的日志生成在另外一个单独的文件.这也就是标题中的实现按业务输出日志到不同的文件,下面开始讲解具体的实现方案. 一.方案 由于需要按业务生成不同的日志文件,看到按业务来区分,我的第一感觉就是业务其实是可以按包名来区分的.所以其实我们只要实现不同的包下面的日志输出

对于Android系统Log输出日志的封装LogUtils

MainActivity如下: package cc.cn.logutil; import android.os.Bundle; import android.app.Activity; /** * Demo描述: * 对于Android系统Log输出日志的封装LogUtils * 1 可修改LogUtils中的LEVEL值觉得哪些级别的日志可以输出. * 所以方便选择性输出日志或者屏蔽日志输出 * 2 输出的日志除了本想输出的信息外还包含了该日志输出时所属 * 的线程,类,方法名,已经在该方法

【转】kettle 的内存设置及输出日志的时间类型

本文转载自:http://blog.csdn.net/dqswuyundong/archive/2010/10/19/5952004.aspx 设置kettle的内存 REM ******************************************************************REM ** Set java runtime options                                     **REM ** Change 256m to high

【转】Log4j按级别输出日志到不同文件配置分析

关于LOG4J 按照级别输出日志,并按照级别输出到不同文件中的说法有很多, 网上贴的最多的log4j.properties的设置是这样的 log4j.rootLogger=info,stdout,info,debug,error log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdou