log4j如何关闭某个类的log4j 日志输出出

温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(626)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'Log4j 指定类并输出到文件配置',
blogAbstract:'--------------------------------------------------------------------------------------------------------------------------------------------------Log4j 指定类或者包,并输出到文件配置样例:# 文件输出log4j.appender.fileout=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.fileout.layout=org.apache.log4j.PatternLayoutlog4j.appender.fileout.Append=true',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:0,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:true,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}下次自动登录
现在的位置:
& 综合 & 正文
log4j指定类单独输出到一个日志文件
log4j.additivity.com.trip.utils.MyLog=false
log4j.logger.com.trip.utils.MyLog= INFO, myLog
log4j.appender.myLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.myLog.File=../logs/tripCount.log
log4j.appender.myLog.layout=org.apache.log4j.PatternLayout
log4j.appender.myLog.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}_-_%m%n
   log4j.additivity.com.trip.utils.MyLog = true时, 这个日志会同步输出到其它日志里。为false时,就会只输出到这一个文件里。
public class MyLog {
private static Logger log =
Logger.getLogger(MyLog.class);
【上篇】【下篇】拒绝访问 | www.ggdoc.com | 百度云加速
请打开cookies.
此网站 (www.ggdoc.com) 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(43bf-ua98).
重新安装浏览器,或使用别的浏览器扫一扫体验手机阅读
改善Log4j日志输出——将日志输出改为静态方法
Logger4j 一般使用方法:1.定义配置文件:log4j.properties2.在需要输出日志的类里获取Logger实例:Logger loger = Logger.getLogger(AAA.class);3.输出日志:loger.debug("test");大家这么做都已经轻车熟路了,但是这样做有两个问题:(1)每个需要输出日志信息的类里,都要引入log4j的包,都要定义一个Logger实例。(2)如果一旦系统由log4j改为别的日志输出方式,如System.out 或common-logging,则要修改N多个类的代码。以上两点,使得业务代码和log4j的耦合太大。所以,如果我们能将日志输出定义为一个静态工具方法,改变这种情况。定义一个静态工具类:import org.apache.log4j.Lpublic class Logs{private static Logger logger = Logger.getLogger(Logs.class);//debug方法,其他error、warn类似定义public static void debug(Object obj){&&& //如果更改日志出工工具,只需修改该行代码即可。如:可改为 System.out.println(obj);&& logger.debug(obj);}}这样我们就可以在其他类里用直接 Logs.debug("test"); 进行日志输出了。而且,一旦我们改变了日志输出工具,只要修改 Logs类即可,其他业务类不必修改。也许很多人也都能想到这么做,同时也有很多人会意识到这么做带来的另一个问题:源代码定位。Log4j的日志信息,能够进行源代码定位——也就是说,能够在日志信息中输出,调用日志的类、方法及代码所在的行。而当我们按上面方法改为静态输出后,就不能进行源代码定位了——虽然仍有源代码信息,但都是指向了Logs类。这对程序员调试,以及跟踪、解决问题都不方便了。不过既然Log4j能做到源代码定位,相信我们也会有办法做到,如果您有兴趣请继续看:-------------------------------------------------------------------Log4j能准确捕获源代码的所在的类、方法、行。但java并没有提供响应的方法,这似乎很神奇。上网搜一下 “Log4j 行号” 已经有高人指出:Log4j是通过java错误堆栈来实现的,也就是说通过new一个异常Throwable,然后在捕获,从而得到堆栈信息,在进行分析就可以得到行号等了。所以,有人提出象log4j那样,抛出一个异常,然后捕获分析,从而在我们自己的静态日志工具里实现源代码定位,但是这样就多抛出一次异常,效率肯定底了。而且抛出异常过多,引起额外事故也是个重大问题。不管怎么说,这毕竟是一个思路,我尝试着找其他能得到堆栈信息的方法,最后在Thread类里找到了一个getStackTrace();这个方法是jdk1.5版本以后才有的,幸亏我用的是1.5。我没有深入研究,但感觉用这个方法得到堆栈应该比抛出异常好多了。于是我对静态日志工具类,进行了一番改造,自我感觉还是不错的,下面贴出源码,欢迎讨论。说明:该类有main方法以供测试。-----------------------------------------/*** 日志输出代理类。* &p&* 主要完成业务代码和日志工具间的解耦,使切换日志工具更加方便。* &p&* 如:将Log4j改为common-logging或自己的独立实现,则只需调整该类即可。* &p&* 简化了调用方式:如使用log4j,通常用法是先生成一个实例,再调用输出方法。* 现在,只需直接使用 Logs.debug();等静态方法即可*&* @author yangzi&p&*&&&&&&&& * @version 1.0&* @since 1.5*/public class Logs {/*** 是否打印日志,true表示打印日志,false表示不打印。* &p&* 开发阶段可以将其设为ture,运行阶段可以设为false*/private static final boolean enabled =/** 是否进行源代码定位,ture表示输出源代码所在类以及代码行 */private static boolean showLocSrc =/** 指定的日志级别 */private static int level = 1;/** 日志级别:普通 */private static final int info = 1;/** 日志级别:调试 */private static final int debug = 2;/** 日志级别:警告 */private static final int warn = 3;/** 日志级别:错误 */private static final int error = 4;/** 消息所属和消息内容的分隔符 */private static final String msgSplit = ":";/** 该类的名称,用于识别该类的堆栈 */private static final String thisClassName = Logs.class.getName();/** 默认输出日志的日志工具:log4j */private static org.apache.log4j.Logger logger =public Logs() {}static {&& // 可以单独指定log4j的配置文件,也可以使用默认。&& // org.apache.log4j.PropertyConfigurator.configure("log4j.properties");&& // 得到logger实例,作为输出工具。&& // 此句作用是用一个输出实例,取代每个类里面的: Logger.getLogger(X.class)&& logger = org.apache.log4j.Logger.getLogger("");}/*** 测试*&* @param args*/public static void main(String args[]) {&& Logs.debug("调试信息");}/*** 根据日志级别,输出日志。* &p&* 如果要改变日志输出工具,* &p&* 如:由原来的log4j改为System.out.println()或logging,则只需改动此类即可。*&* @param level*&&&&&&&&&&& 日志级别* @param message*&&&&&&&&&&& 日志消息* @param ste*&&&&&&&&&&& 堆栈信息。*&&&&&&&&&&& &p&*&&&&&&&&&&& 如果不需要输出源代码信息,则只需将静态成员属性 showLocSrc设为false即可。*/private static void log(int level, Object message, StackTraceElement[] ste) {&& if (ste != null) {&&& // 加入源代码定位&&& message = getStackMsg(ste) + msgSplit +&& }&& // 转入具体实现,此处为log4j,可以改为其他不同的日志实现。&& switch (level) {&& case info:&&& logger.info(message);&&&&& case debug:&&& logger.debug(message);&&&&& case warn:&&& logger.warn(message);&&&&& case error:&&& logger.error(message);&&&&& default:&&& logger.debug(message);&& }}/*** 根据堆栈信息得到源代码行信息* &p&* 原理:本工具类的堆栈下一行即为源代码的最原始堆栈。*&* @param ste*&&&&&&&&&&& 堆栈信息* @return 调用输出日志的代码所在的类.方法.代码行的相关信息*&&&&&&&& &p&*&&&&&&&& 如:com.MyClass 类里的 fun()方法调用了Logs.debug("test");*&&&&&&&& &p&*&&&&&&&& 则堆栈信息为: com.MyClass.fun(MyClass.java 代码行号)*/private static String getStackMsg(StackTraceElement[] ste) {&& if (ste == null)&&&&& boolean srcFlag =&& for (int i = 0; i & ste. i++) {&&& StackTraceElement s = ste[i];&&& // 如果上一行堆栈代码是本类的堆栈,则该行代码则为源代码的最原始堆栈。&&& if (srcFlag) {&&&& return s==null?"":s.toString();&&& }&&& // 定位本类的堆栈&&& if (thisClassName.equals(s.getClassName())) {&&&& srcFlag =&&& }&& }&&}/*** 输出info信息*&* @param message*/public static void info(Object message) {&& // 如果禁止日志或者输出级别不符,则返回。&& if (!enabled || info & level)&&&&& if (showLocSrc) {&&& log(info, message, Thread.currentThread().getStackTrace());&& } else {&&& log(info, message, null);&& }}/*** 输出debug信息*&* @param message*/public static void debug(Object message) {&& // 如果禁止日志或者输出级别不符,则返回。&& if (!enabled || debug & level)&&&&& if (showLocSrc) {&&& log(debug, message, Thread.currentThread().getStackTrace());&& } else {&&& log(debug, message, null);&& }}/*** 输出warn信息*&* @param message*/public static void warn(Object message) {&& // 如果禁止日志或者输出级别不符,则返回。&& if (!enabled || warn & level)&&&&& if (showLocSrc) {&&& log(warn, message, Thread.currentThread().getStackTrace());&& } else {&&& log(warn, message, null);&& }}/*** 输出error信息*&* @param message*/public static void error(Object message) {&& // 如果禁止日志或者输出级别不符,则返回。&& if (!enabled || error & level)&&&&& if (showLocSrc) {&&& log(error, message, Thread.currentThread().getStackTrace());&& } else {&&& log(error, message, null);&& }}}
<span type="1" blog_id="392487" userid='
分享到朋友圈
关注作者,不错过每一篇精彩&&&&&&&&&&&&&&&&&&
posts - 187,comments - 96,trackbacks - 0
一:测试环境与一样,这里不再重述
二:先看栗子再来下结论
import org.apache.log4j.*;
import test.log4j.bean.P
//by godtrue
public class UseLog4j {
//日志记录器
private static Logger LOGGER = LogManager.getLogger(UseLog4j.class);
//循环次数
private static long CYCLE = 102;
//程序入口——主函数
public static void main(String[]args){
long startTime = System.currentTimeMillis();
* 使用自定义的log4j的环境配置
* 一:定义日志信息的格式化方式,Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:
* 1)%t 用来输出生成该日志事件的线程的名称
* 2)%p 用于输出日志事件的优先级,即DEBUG,INFO,WARN,ERROR,FATAL
* 3)%r 用于输出从layout(布局)的构建到日志事件创建所经过的毫秒数
* 4)%c 用于输出日志事件的category(类别),通常就是所在类的全名
* 5)%F 用于输出被发出日志记录请求,其中的文件名
* 6)%d 用于输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2日 22:10:28,921
* 7)%L 用于输出日志事件的发生位置,即在代码中的行数。举例:10
* 8)%l 用于输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
* 9)%% 用于输出%标志
* 10)%M 用于输出打印该条日志的方法名
* 11)%m 用于输出代码中指定的消息
* 12)%n 用于输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
* 当我们运行程序后发现,因为输出的日志信息长短不一,所以对不齐,看起来不好看,那么有什么法子呢?log4j也发现这个问题,并且为我们提供了格式修饰符
* 格式修饰符:可以控制输出字段的最小字段宽度、最大字段宽度、字段对齐格式,如下所示:
* 序号 格式修饰符
备注(对%c来使用格式修饰符,所以改变的是类别名称)
用空格右垫,如果类别名称少于20个字符长
用空格左垫,如果类别名称少于20个字符长
从开始截断,如果类别名称超过30个字符长
用空格右侧垫,如果类别名称短于20个字符。但是,如果类别名称长度超过30个字符,那么从开始截断。
用空格左侧垫,如果类别名称短于20个字符。但是,如果类别名称长度超过30个字符,那么从开始截断。
//试验,并查看日志格式化后的效果
//String pattern = "[1]%t - [2]%p - [3]%r - [4]%c - [5]%F - [6]%d
- [7]%L - [8]%l - [9]%% - [10]%M
- [11]%m[12]%n"; //运行程序看看,是不是我们期待的日志输出样子
//试验,并查看日志格式化后的效果
String pattern = "[1]%-10p - [2]%10p - [3]%.3p
- [4]%-10.3p - [5]%10.3p 。 %n"; //运行程序看看,是不是我们期待的日志输出样子
* 二:定义日志输出的风格样式,日志输出的风格主要有以下几种(通过官方文档我们会发现还有其他的):
* 1)org.apache.log4j.HTMLLayout(以HTML表格形式布局),
* 2)org.apache.log4j.PatternLayout(可以灵活地指定布局模式,这个在我的实际工作中是最常用的),
* 3)org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
* 4)org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
Layout layout = new PatternLayout(pattern);
* 三:定义日志输出的目的地,日志输出的目的地主要中以下几种(通过官方文档我们会发现还有好多种类的):
* 1)org.apache.log4j.ConsoleAppender(控制台),
* 2)org.apache.log4j.FileAppender(文件),
* 3)org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
* 4)org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件,这个在我的实际工作中也是最常用的),
* 5)org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
Appender appender= new ConsoleAppender(layout);
//配置日志输出的定义,主要有三点:1:输出什么级别的日志信息,2:将日志信息输出到那里,3:输出的日志以什么格式展示
BasicConfigurator.configure(appender);
* 日志输出的级别,主要有以下几种:
各级包括自定义级别。
* 2)TRACE
最详细的信息。一般这些信息只记录到日志文件中。自版本1.2.12[3]。
* 3)DEBUG
流经系统的详细信息。一般这些信息只记录到日志文件中。
令人感兴趣的运行时事件(启动/关闭)。一般这些信息将立即呈现在状态控制台上,因而要保守使用,并保持到最低限度。
使用已过时的API,API的滥用,潜在错误,其他不良的或意外的运行时的状况(但不一定是错误的)。一般这些信息将立即呈现在状态控制台上。
* 6)ERROR
其他运行时错误或意外情况。一般这些信息将立即呈现在状态控制台上。
* 7)FATAL
导致应用程序提前终止的严重错误。一般这些信息将立即呈现在状态控制台上。
最高级别,用于关闭日志记录。
* 日志的级别之间的大小关系如右所示:ALL & TRACE & DEBUG & INFO & WARN & ERROR & FATAL & OFF
for(int i=0;i&CYCLE;i++){
if(i&100){
LOGGER.info(new Person("godtrue",100/i,'M'));//打印对象的信息
}catch(Exception e){
LOGGER.error(i+"岁的小孩还不存在嘛!");//打印对象的信息
LOGGER.warn("现在大部分人的年龄都在0到100岁之间的!");//打印对象的信息
LOGGER.info("我是一棵树,我今年活了"+i+"岁!哈哈,我厉害吧!");//打印对象的信息
LOGGER.debug("此程序的运行时间是:"+(System.currentTimeMillis()-startTime));//打印程序运行的时间
& & & 1)如果将上述代码中的注释全部去掉,你会发现这段代码其实是相当的简单的,注释是试验的时候添加上的,也是我想记住的知识点,它们就是使用log4j框架控制日志输出的方式了
& & & 2)上面的代码有以下几部分构成
& & & & & &2-1)控制日志信息输出格式的——pattern
& & & & & &2-2)控制日志信息输出样式的——layout
& & & & & &2-3)控制日志信息输出目的地的——appender
& & & & & &2-4)控制日志信息输出的——LOGGER,他可以调用不同级别的日志输出方法,然后根据配置的日志输出级别来控制什么方法会被调用,这个后面会再次讲到的
& & & &3)无论是通过配置文件控制,还是通过程序本身控制,我们想控制的基本是 &2) 所描述的这些部分,这些功能也是一个日志框架提供的最基本的功能
阅读(...) 评论()

我要回帖

更多关于 log4j 日志输出 的文章

 

随机推荐