高级日志输出有什么用什么意思

logger4j能将不同的方法(不是类)的日志输出不同的文件吗
[问题点数:40分]
本版专家分:0
CSDN今日推荐
本版专家分:16
本版专家分:0
匿名用户不能发表回复!
其他相关推荐本文转自:
logback支持类似于占位符的变量替换功能,即如果输出的msg里面带有{}符号且括号中间不带其他字符,那么logback在构造LoggingEvent的时候,会用MessageFormat类来格式化msg,将{}替换成具体的参数值。
示例如下:
logger.info("{},it's
OK.","Hi");
则输出结果如下:
Hi,it's OK.
支持多JVM同时操作同一个日志文件
如果多个jvm同时操作同一个日志文件,则需要使用下面的方式
有几点要注意:
1.如果多JVM同时操作同一个文件,则会出现日志不回滚、打出的日志串掉的场景。
2.如果按小时来回滚,并且一个小时内并没有业务日志输出,那么这个小时的日志文件是不会生成的,会跳过这个小时的日志文件的生成。&maxHistory&也是同样的,如果隔一段时间没有输出日志,前面过期的日志不会被删除,只有再重新打印日志的时候,会触发删除过期日志的操作。
3.官方给的说明如下:如果使用prudent模式,FileAppender将安全的写入到指定文件,即使存在运行在不同机器上的、其他JVM中运行的其他FileAppender实例。Prudent模式更依赖于排他文件锁,经验表明加了文件锁后,写日志的开始是正常的3倍以上。当prudent模式关闭时,每秒logging event的吞吐量为100,000,当prudent模式开启时,大约为每秒33,000。
4.如果日志打印较多,则可能会出现将硬盘撑爆的情况,还是建议使用FixedWindowRollingPolicy回滚策略,这种策略固定了日志文件大小,超出则回滚。业务上出现了多个jvm同时操作同一个日志文件,仍建议每个jvm只操作一个日志文件。
logback--过滤器+补充
logback高级特性使用(三)
logback和slf4j的使用chapter2
logback 配置和占位符
logback maxhistory
logback 异步日志配置
Logback高级用法
没有更多推荐了,我是异次猿的小猿2号, 欢迎加入我们, 微信公众号【异次猿】
最近开发的模块中日志文件的输出很郁闷基于配置的先不说好坏至少个人很不适应那种配置方式所以今天谈一下日志分层控制输出
在开发中大多都基于一定的框架模式框架模式降低了模块间的耦合性、提高了代码的重用性、部署快、成本低,而且代码的维护性高例如中常用的框架模式
实例中结合框架模式谈谈如何将程序中各个层的日志归类输出
步骤一创建项目在文件中添加日志文件的配置监听
&!-- 日志文件 --&
&context-param&
&param-name&log4jConfigLocation&/param-name&
&param-value&/WEB-INF/context/log4j.properties&/param-value&
&/context-param&
&context-param&
&param-name&log4jRefreshInterval&/param-name&
&param-value&3000&/param-value&
&/context-param&
&listener&
&listener-class&org.springframework.web.util.Log4jConfigListener&/listener-class&
&/listener&
第二步日志的属性文件配置
#log4j.rootLogger=INFO,console,file
log4j.rootLogger=INFO,console,file
#用logger时给它一个自定义的名字(如这里的"ctrlLog"),程序中public final static Logger job=Logger.getLogger("ctrlLog");
#然后在log4j.properties中做出相应配置即可,example:log4j.appender.ctrl=org.apache.log4j.DailyRollingFileAppender
log4j.logger.ctrlLog=INFO,ctrl
log4j.logger.serviceLog=INFO,service
log4j.logger.daoLog=INFO,dao
log4j.logger.indexLog=INFO,index
log4j.logger.jobLog=INFO,job
log4j.logger.searchLog=INFO,search
#定义console输出到控制台
log4j.appender.console=org.apache.log4j.ConsoleAppender
#定义console控制台的布局模式为PaternLayout
log4j.appender.console.layout=org.apache.log4j.PatternLayout
#定义console控制台的输出格式
log4j.appender.console.layout.ConversionPattern=%p %d{HH:mm:ss.SSS} [%X{ip}] - %l %m%n
#定义file输出到文件
log4j.appender.file=org.apache.log4j.RollingFileAppender
#定义file输出到哪个文件
log4j.appender.file.File=/var/log/vms/vms.log
#定义file输出文件的最大长度
log4j.appender.file.MaxFileSize = 1024KB
#定义file的备份文件数
log4j.appender.file.MaxBackupIndex = 3
#定义file的布局模式为PatternLayout
log4j.appender.file.layout=org.apache.log4j.PatternLayout
#定义file的输出模式
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd hh:mm:ss}:%p %t %c - %m%n
#mybatis操作日志配置
log4j.logger.com.ibatis=ERROR
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=ERROR
log4j.logger.com.ibatis.sqlmap.engine.cache.CacheModel=ERROR
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientImpl=ERROR
log4j.logger.com.ibatis.sqlmap.engine.builder.xml.SqlMapParser=ERROR
log4j.logger.com.ibatis.common.util.StopWatch=ERROR
log4j.logger.java.sql.Connection=ERROR
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
#将控制层的日志打印到controller.log文件中
log4j.appender.ctrl=org.apache.log4j.DailyRollingFileAppender
log4j.appender.ctrl.File=/var/log/vms/controller.log
log4j.appender.ctrl.layout=org.apache.log4j.PatternLayout
log4j.appender.ctrl.DatePattern='_'yyyy-MM-dd
log4j.appender.ctrl.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}]:%X{ip} [%-5p] %m%n
#将业务层的日志打印到service.log文件中
log4j.appender.service=org.apache.log4j.DailyRollingFileAppender
log4j.appender.service.File=/var/log/vms/service.log
log4j.appender.service.layout=org.apache.log4j.PatternLayout
log4j.appender.service.DatePattern='_'yyyy-MM-dd
log4j.appender.service.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}]:%X{ip} [%-5p] %m%n
#将持久层的日志打印到dao.log文件中
log4j.appender.dao=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dao.File=/var/log/vms/dao.log
log4j.appender.dao.layout=org.apache.log4j.PatternLayout
log4j.appender.dao.DatePattern='_'yyyy-MM-dd
log4j.appender.dao.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}]:%X{ip} [%-5p] %m%n
#将定时作业的日志打印到job.log文件中
log4j.appender.job=org.apache.log4j.DailyRollingFileAppender
log4j.appender.job.File=/var/log/vms/job.log
log4j.appender.job.layout=org.apache.log4j.PatternLayout
log4j.appender.job.DatePattern='_'yyyy-MM-dd
log4j.appender.job.layout.ConversionPattern=[%d{yyyy-MM-dd HH\:mm\:ss}] [%-5p] %m%n
#将索引的日志打印到index.log文件中
log4j.appender.index=org.apache.log4j.DailyRollingFileAppender
log4j.appender.index.File=/var/log/vms/index.log
log4j.appender.index.layout=org.apache.log4j.PatternLayout
log4j.appender.index.DatePattern='_'yyyy-MM-dd
log4j.appender.index.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}]:%X{ip} [%-5p] %m%n
#将搜索操作日志打印到search.log文件中
log4j.appender.search=org.apache.log4j.DailyRollingFileAppender
log4j.appender.search.File=/var/log/vms/search.log
log4j.appender.search.layout=org.apache.log4j.PatternLayout
log4j.appender.search.DatePattern='_'yyyy-MM-dd
log4j.appender.search.layout.ConversionPattern=[%d{yyyy-MM-dd HH\:mm\:ss}]\:%X{ip} [%-5p] %m%n
日志文件根据需要配置其输出级别实例中配置的为级别正式环境下可配置为级别因为大量的日志记录会耗费不必要的磁盘空间
关于日志文件的配置可以参看这篇
第三步程序中分离各层输出控制
package com.bae.vms.
import java.io.PrintW
import java.io.StringW
import org.apache.log4j.L
* description:
* @author &a href='mailto:'& Cn.pudp (En.dennisit)&/a& Copy Right since
* com.bae.vms.util.LogUtil.java
public class LogUtil {
* 一般日志log
public final static Logger log=Logger.getLogger(LogUtil.class);
public static void logDebug(String s){
log.debug(s);
public static void logInfo(String s){
log.info(s);
public static void logError(String s){
log.error(s);
public static void logError(String s,Exception e){
log.error(s,e);
* 索引日志
public final static Logger indexLog=Logger.getLogger("indexLog");
public static void indexLogDebug(String s){
indexLog.debug(s);
public static void indexLogInfo(String s){
indexLog.info(s);
public static void indexLogError(String s){
indexLog.error(s);
public static void indexLogError(String s,Exception e){
indexLog.error(s,e);
* controller日志
public final static Logger ctrl=Logger.getLogger("ctrlLog");
public static void ctrlLogDebug(String s){
ctrl.debug(s);
public static void ctrlLogInfo(String s){
ctrl.info(s);
public static void ctrlLogError(String s){
ctrl.error(s);
public static void ctrlLogError(String s,Exception e){
ctrl.error(s,e);
* 业务逻辑层日志
public final static Logger service=Logger.getLogger("serviceLog");
public static void serviceLogDebug(String s){
service.debug(s);
public static void serviceLogInfo(String s){
service.info(s);
public static void serviceLogError(String s){
service.error(s);
public static void serviceLogError(String s,Exception e){
service.error(s,e);
* 数据操作层日志
public final static Logger dao=Logger.getLogger("daoLog");
public static void daoLogDebug(String s){
dao.debug(s);
public static void daoLogInfo(String s){
dao.info(s);
public static void daoLogError(String s){
dao.error(s);
public static void daoLogError(String s,Exception e){
dao.error(s,e);
* 数据操作层日志
public final static Logger job=Logger.getLogger("jobLog");
public static void jobLogDebug(String s){
job.debug(s);
public static void jobLogInfo(String s){
job.info(s);
public static void jobLogError(String s){
job.error(s);
public static void jobLogError(String s,Exception e){
job.error(s,e);
* 搜索操作层日志
public final static Logger search=Logger.getLogger("searchLog");
public static void searchLogDebug(String s){
search.debug(s);
public static void searchLogInfo(String s){
search.info(s);
public static void searchLogError(String s){
search.error(s);
public static void searchLogError(String s,Exception e){
search.error(s,e);
* @param logger
* @param s
* @param e
public static void error(Logger logger,String s,Exception e){
logger.error(s,e);
* 获取异常的堆栈信息
* @param t
public static void getStackTrace(Throwable t){
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
log.error(sw.toString());
pw.close();
第四步各层控制输出
dao层日志捕获
public Page&AdvPosition& find(Integer pageNum, Integer pageSize,
String where, Object[] queryParams, Map&String, String& orderBy)throws ServiceException {
LogUtil.dao.info("AdvPositionDao.find(...) finished.");
return this.advPositionDao.find(pageNum, pageSize, where, queryParams, orderBy);
} catch (DaoException e) {
LogUtil.dao.error("AdvPositionDao.find(...)" + e.getMessage(),e);
e.printStackTrace();
return null;
业务层日志捕获
* 分页展示广告位置列表
* @author &a href='mailto:'&Cn.Pudp(En.dennisit)&/a& Copy Right since
下午01:07:40
* @param request
* @param response
* @param pageNum
@RequestMapping(value={"/advinfoes.html","/advinfoes"},method={RequestMethod.GET,RequestMethod.POST})
public ModelAndView advInfoList(HttpServletRequest request, HttpServletResponse response){
Map&String,Object& map = new HashMap&String,Object&();
Map&String,String& orderBy = new HashMap&String, String&();
orderBy.put("id", "desc");
//按照id降序排列
//查找所有的广告位置列表,查询10条,按照Id降序排列
Page&AdvInfo& page = this.advInfoService.find(1, BaseMultiController.DEFAULT_PAGE_SIZE, orderBy);
map.put("page", page);
LogUtil.ctrl.info("AdvInfoService.find(..) info:" + page);
} catch (ServiceException e) {
LogUtil.service.error("AdvInfoService.find(..) error:" + e.getMessage());
e.printStackTrace();
return toView("vms/adv_info_list", map);
这样就可以将各层日志输出到各层对应的日志文件记录中了输出位置可以通过文件配置转载请注明出处:[]
阅读(...) 评论()日志输出_百度百科
清除历史记录关闭
声明:百科词条人人可编辑,词条创建和修改均免费,绝不存在官方及代理商付费代编,请勿上当受骗。
日志输出运行环境
支持Android 2.1
日志输出应用类型
系统安全类软件
日志输出应用介绍
将显示日志信息输出的操作系统和应用程序。这个程序是Android应用程序开发人员喜欢的。除了正常功能,配备日志叠加功能。这个应用程序是免费的。
清除历史记录关闭文章来源于公司的大牛
1 Log的用途
不管是使用何种编程语言,日志输出几乎无处不再。总结起来,日志大致有以下几种用途:
问题追踪:通过日志不仅仅包括我们程序的一些bug,也可以在安装配置时,通过日志可以发现问题。
状态监控:通过实时分析日志,可以监控系统的运行状态,做到早发现问题、早处理问题。
安全审计:审计主要体现在安全上,通过对日志进行分析,可以发现是否存在非授权的操作。
2 记录Log的基本原则
2.1 日志的级别划分
Java日志通常可以分为:error、warn、info、debug、trace五个级别。在J2SE中预定义的级别更多,分别为:SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST。两者的对应大致如下:
Log4j、slf4j
问题已经影响到软件的正常运行,并且软件不能自行恢复到正常的运行状态,此时需要输出该级别的错误日志。
与业务处理相关的失败,此次失败不影响下次业务的执行,通常的结果为外部的输入不能获得期望的结果。
系统运行期间的系统运行状态变化,或关键业务处理记录等用户或管理员在系统运行期间关注的一些信息。
系统配置、系统运行环境信息,有助于安装实施人员检查配置是否正确。
软件调试信息,开发人员使用该级别的日志发现程序运行中的一些问题,排除故障。
基本同上,但显示的信息更详尽。
基本同上,但显示的信息更详尽。
2.2 日志对性能影响
不管是多么优秀的日志工具,在日志输出时总会对性能产生或多或少的影响,为了将影响降低到最低,有以下几个准则需要遵守:
如何创建Logger实例:创建Logger实例有是否static的区别,在log4j的早期版本,一般要求使用static,而在高版本以及后来的slf4j中,该问题已经得到优化,获取(创建)logger实例的成本已经很低。所以我们要求:对于可以预见的多数情况下单例运行的class,可以不添加static前缀;对于可能是多例居多,尤其是需要频繁创建的class,我们要求要添加static前缀。
判断日志级别:
n对于可以预见的会频繁产生的日志输出,比如for、while循环,定期执行的job等,建议先使用if对日志级别进行判断后再输出。
n对于日志输出内容需要复杂的序列化,或输出的某些信息获取成本较高时,需要对日志级别进行判断。比如日志中需要输出用户名,而用户名需要在日志输出时从数据库获取,此时就需要先判断一下日志级别,看看是否有必要获取这些信息。
优先使用参数,减少字符串拼接:使用参数的方式输出日志信息,有助于在性能和代码简洁之间取得平衡。当日志级别限制输出该日志时,参数内容将不会融合到最终输出中,减少了字符串的拼接,从而提升执行效率。
2.3 什么时候输出日志
日志并不是越多越详细就越好。在分析运行日志,查找问题时,我们经常遇到该出现的日志没有,无用的日志一大堆,或者有效的日志被大量无意义的日志信息淹没,查找起来非常困难。那么什么时候输出日志呢?以下列出了一些常见的需要输出日志的情况,而且日志的级别基本都是&=INFO,至于Debug级别日志的使用场景,本节没有专门列出,需要具体情况具体分析,但也是要追求“恰如其分”,不是越多越好。
2.3.1 系统启动参数、环境变量
系统启动的参数、配置、环境变量、System.Properties等信息对于软件的正常运行至关重要,这些信息的输出有助于安装配置人员通过日志快速定位问题,所以程序有必要在启动过程中把使用到的关键参数、变量在日志中输出出来。在输出时需要注意,不是一股脑的全部输出,而是将软件运行涉及到的配置信息输出出来。比如,如果软件对jvm的内存参数比较敏感,对最低配置有要求,那么就需要在日志中将-Xms -Xmx -XX:PermSize这几个参数的值输出出来。
2.3.2 异常捕获处
在捕获异常处输出日志,大家在基本都能做到,唯一需要注意的是怎么输出一个简单明了的日志信息。这在后面的问题问题中有进一步说明。
2.3.3 函数获得期望之外的结果时
一个函数,尤其是供外部系统或远程调用的函数,通常都会有一个期望的结果,但如果内部系统或输出参数发生错误时,函数将无法返回期望的正确结果,此时就需要记录日志,日志的基本通常是warn。需要特别说明的是,这里的期望之外的结果不是说没有返回就不需要记录日志了,也不是说返回false就需要记录日志。比如函数:isXXXXX(),无论返回true、false记录日志都不是必须的,但是如果系统内部无法判断应该返回true还是false时,就需要记录日志,并且日志的级别应该至少是warn。
2.3.4 关键操作
关键操作的日志一般是INFO级别,如果数量、频度很高,可以考虑使用DEBUG级别。以下是一些关键操作的举例,实际的关键操作肯定不止这么多。
删除:删除一个文件、删除一组重要数据库记录……
添加:和外系统交互时,收到了一个文件、收到了一个任务……
处理:开始、结束一条任务……
2.4 日志输出的内容
ERROR:错误的简短描述,和该错误相关的关键参数,如果有异常,要有该异常的StackTrace。
WARN:告警的简短描述,和该错误相关的关键参数,如果有异常,要有该异常的StackTrace。
INFO:言简意赅地信息描述,如果有相关动态关键数据,要一并输出,比如相关ID、名称等。
DEBUG:简单描述,相关数据,如果有异常,要有该异常的StackTrace。
在日志相关数据输出的时要特别注意对敏感信息的保护,比如修改密码时,不能将密码输出到日志中。
2.5 什么时候使用J2SE自带的日志
我们通常使用slf4j或log4j这两个工具记录日志,那么还需要使用J2SE的日志框架吗?当然需要,在我们编写一些通用的工具类时,为了减少对第三方的jar包的依赖,首先要考虑使用java.util.logging。
考虑到slf4j等日志框架提供了日志bridge工具,为java.util.logging提供了Handler,所以普通应用的开发过程中也可以考虑使用J2SE自有日志,这样不但可以减少项目的编译依赖,同时在应用实施时可以更灵活的选择日志的输出工具包。
3 典型问题分析
3.1 该用日志的地方不用
上图对异常的处理直接使用e.printStackTrace()显然是有问题的,正确的做法是:要么通过日志方式输出错误信息,要么直接抛出异常,要么创建新的自定义异常抛出。
另:对于静态工具类函数中的异常处理,最简单的方式就是不捕获、不记录日志,直接向上抛出,如果认为异常类型太多,或者意义不明确,可以抛出自定义异常类的实例。
3.2 啰嗦重复、没有重点
首先上面不应该有error级别的日志。
其次在日志中直接输出e.toString(),为定位问题提供的信息太少。
另外需要明确一点:日志系统是一个多线程公用的系统,在两行日志输出之间有可能会被插入其他线程的日志记录,不会按照我们的意愿顺序输出,后面有更典型的例子。
最后,上面的日志可以简化为:
logger.debug(“从properties中...{}...{}...”,name, value, e);
logger.warn(“从properties中获取{}发生错误:{}”,name, e.toString());
或者直接一句:
logger.warn(“从properties中...{}...{}...”,name, value, e);
或者更完美的:
if(logger.isDebugEnabled()){
logger.warn(“从properties中...{}...”, name, e);
logger.warn(“从properties中获取{}发生错误:{}”, name, e.toString());
3.3 日志和异常处理的关系
首先上面的日志信息不够充分,级别定义不够恰当。
另外,既然将异常捕获并记录的日志,就不应该重新将一个一模一样的异常再次抛出去了。如果将异常再次抛出,那在上层肯定还需要对该异常进行处理,并记录日志,这样就重复了。如果没有特别原因,此处不应该捕获异常。
3.4 System.out方式的日志
上面的日志形式十分随意,只适合临时的代码调试,不允许提交到正式的代码库中。
对于临时调试日志,建议在日志的输出信息中添加一些特殊的连续字符,也可以用自己的名称、代号,这样可以在调试完毕后,提交代码之前,方便地找到所有临时代码,一并删除。
3.5 日志信息不明确
上面的“添加任务出错。。。”既没有记录任务id,也没有任务名称,软件部署后发现错误后,根据该日志记录不能确认哪一条任务错误,给进一步的分析原因带来困难。
另外第二个红圈中的问题有:要使用参数;一行日志就可以了。
还有一些其他共性的错误,就不多说了。
3.6 忘记日志输出是多线程公用的
如果有另外一个线程正在输出日志,上面的记录就会被打断,最终显示输出和预想的就会不一致。正确的做法应是将这些信息放到一行,如果需要换行可以考虑使用“\r”,如果内容较多,考虑增加if (logger.isDebugEnabled())进行判断。而第二个例子中的输出有System.out的习惯,相关内容应该一行完成。
3.7 多个参数的处理
对于多参的日志输出,可以考虑:
void debug(String
format, Object... arguments);
但是在使用多参时,会创建一个对象数组,也会有一定的消耗,为此,在对性能敏感的场景,可以增加对日志级别的判断。
*log日志输出用处用法等
Log日志框架的学习.正确使用日志的10个技巧
没有更多推荐了,

我要回帖

更多关于 开发者选项最佳设置 的文章

 

随机推荐