[SLF4J官方文档]SLF4J-FAQ 多见疑问解答-Java-优质IT资源分享社区

admin
管理员
管理员
  • UID1
  • 粉丝27
  • 关注4
  • 发帖数581
  • 社区居民
  • 忠实会员
  • 原创写手
阅读:172回复:0

[SLF4J官方文档]SLF4J-FAQ 多见疑问解答

楼主#
更多 发布于:2016-05-19 16:18

 [SLF4J官方文档]SLF4J-FAQ 多见疑问解答

 一般性疑问

啥是SLF4J?

啥时分应当运用SLF4J?

SLF4J仍是另一个日志外观吗?

假如SLF4J可修正JCL,那为啥不在JCL里参加修正而是创立一个新项目?

运用SLF4J时,我有必要从头编译我的运用以变换到一个不相同的日志体系吗?

SLF4J的恳求是啥?

SLF4J向后兼容版别吗?

运用SLF4J时遇到拜访权限过错,要素是啥?

为啥SLF4J是在X11类型答应证下答应而不是Apache软件答应?

10.在哪里能取得特定的SLF4J绑定?

11.我的库应当测验装备logging吗?

12.为了减小咱们软件的依托库数量,咱们想让SLF4J变成一个可挑选的依托包。这个是好主意吗?

13.Maven传递依托怎么?

14.怎么扫除依托Maven的commons-logging?

关于SLF4J API

为啥日志器接口的打印办法不接纳方针类型的音讯,但只收String类型音讯?

我能够输出一个没有音讯的反常日志吗?

输出日志(封闭日志)的最快办法是啥?

怎么打印独自(也许是杂乱的)方针的字符串内容日志?

为啥slf4j.Logger接口没有FATAL等级的办法?

为啥TRACED等级的日志只在SLF4J

1.4.0版别介绍?

SLF4J日志API支撑I18N(国际化)吗?

不经过LoggerFactory里的静态办法,能够从头获取日志器吗?

存在过错/抛出反常时,能够参数化日志声明吗?

完结SLF4J API

怎么使我的日志底层SLF4J可兼容?

怎么使我的日志体系增加支撑Marker接口?

SLF4J的版别检查机制怎么作业?

关于日志的一般性疑问

1.类的日志器成员变量应当声明为静态变量吗?

2.类里的声明日志器有引荐的习语吗?

一般性疑问

1.啥是SLF4J?

SLF4J是一个简略的日志体系外观,它答应终端用户在布置时植入所需日志体系。

2.啥时分应当运用SLF4J?

简略而言,为库和别的嵌入组件的日志需求,它们应当思考下SLF4J,因为库不能强加终端用户日志结构的挑选。别的,独立运用运用SLF4J不一定有意义。独立运用能够直接征引他们挑选的日志结构。关于logback,疑问是没有实践意义的,因为logback经过SLF4J露出它的logger

API。

SLF4J仅仅个外观,意味着它不供给一个完好的日志计划。例如装备输出源或许设置日志等级的操作不能和SLF4J履行。因而,在某个时刻点上,任何微乎其微的运用将需求直接征引底层日志体系。换句话说,彻底敌对的API底层日志体系是不行能给独立运用程序运用的。可是,SLF4J减少这种依托的影响到无痛苦等级。

假定你的CRM运用用log4j来记载日志。然后,你的一个主要客户端恳求日志要经过JDK1.4履行日志记载。假如你的运用充斥着数以千计的直接log4j调用,转移到JDK1.4的调用将相对是一个冗长和简略犯错的进程。更糟的是,你也许需求保护两个版别的CRM软件。你现已引证SLF4J

API而不失log4J,经过更换二者的jar文件,迁移可在几分钟内完结。

SLF4J答应组件开发人员推延终端用户的日志体系的挑选,但终究仍需求做出一个挑选。

3.SLF4J仍是另一个日志外观吗?

SLF4J在概念上和JCL十分相似。因而它能够被以为是另一个日志外观。可是,SLF4J在规划上更简略和更强健。简而言之,SLF4J防止了植入JCL的类加载疑问。

4.假如SLF4J可修正JCL,那为啥不在JCL里参加修正而是创立一个新项目?

这是十分好的疑问。首要,SLF4J静态绑定办法十分简略,乃至很可笑。很难说服开发者这个办法的有用性。仅仅在SLF4J发布后和开端变得被接纳后,它才在有关社区里取得尊敬。

其次,SLF4J提出2个改善手法,这都趋向被轻视了。用务实的办法,参数化日志音讯处理了一个跟日志功能联络的主要疑问。符号方针,由org.slf4j.Logger接口支撑,为高档日志体系的选用铺路,假如必要的话,一起让铺开转回更多传统日志体系的大门。

5.运用SLF4J时,我有必要从头编译我的运用以变换到一个不相同的日志体系吗?

不,你不需求从头编译你的运用。你能够经过移除之前的SLF4J绑定,然后将它更换为你挑选的绑定,就能变换到不相同的日志体系了。

例如,假如你在运用NOP完结,希望变换到log4j

1.2版别,在你的类目录下用 slf4j-log4j12.jar 更换slf4j-nop.jar,但也别忘了增加log4j-1.2.x.jar 。像变换到JDK

1.4 logging?只需用slf4j-jdk14.jar更换slf4j-log4j12.jar。

6.SLF4J的恳求是啥?

1.7.0版别SLF4J需求JDK1.5以上。前期的SLF4J版别,像SLF4J

1.4,1.5和1.6,恳求JDK1.4。

BindingRequirements

slf4j-nopJDK 1.5

slf4j-simpleJDK 1.5

slf4j-log4j12JDK 1.5, plus any

other library dependencies required by the log4j appenders in

use参加任何别的所需的依托包取决于运用的log4j输出源

slf4j-jdk14JDK 1.5 or later

logback-classicJDK 1.5 or later,

plus any other library dependencies required by the logbackappenders in

use参加任何别的所需的依托包取决于运用的log4j输出源

7.SLF4J向后兼容版别吗?

从客户端视点,SLF4J

API对一切版别都向后兼容。这意味着你能从SLF4J版别1.0升级到任何今后的版别,没有任何疑问。关于slf4j-api版别N和slf4j-api

版别M,

版别N编译的代码将和版别M编译的代码一同正常运作。迄今为止, slf4j-api里的二进制兼容性从来没有被打破。

可是,从客户端视点,SLF4J

API十分稳定时,SLF4J绑定,比方slf4j-simple.jar

或slf4j-log4j12.jar,需求一个特定版别的SLF4J-API。混合不相同版别的slf4j也许会呈现疑问和强烈不发起的。例如,假如你正在运用slf4j-api-1.5.6.jar,然后你也应当运用slf4j-simple-1.5.6.jar,运用slf4j-simple-1.4.2.jar将不会作业。

在初始化不时,假如SLF4J估测也许有版别不匹配疑问,它将宣布一个关于不匹配的正告。

8.运用SLF4J时遇到拜访权限过错,要素是啥?

如下是过错概况:

Exception in thread "main"

java.lang.IllegalAccessError: tried to access

fieldorg.slf4j.impl.StaticLoggerBinder.SINGLETON from

classorg.slf4j.LoggerFactory  

 atorg.slf4j.LoggerFactory.(LoggerFactory.java:60)

这个疑问是由LoggerFactory类的静态初始化测验直接拜访org.slf4j.impl.StaticLoggerBinder的单例变量形成的。这在SLF4J

1.5.5和之前的版别答应,在1.5.6及今后的版别,单例变量现已被符号为私有拜访权限了。

假如你遇到了上述的过错,你能够用老版别的slf4j-api,比方1.4.3,一起运用一个新版别的slf4j绑定,比方1.5.6。一般,当你的Maven

pom.xml文件运用hibernate 3.3.0,在slf4j-api

1.4.2版别上声明一个依托时,将发作上述反常。假如你的pom.xml在slf4j绑定上声明依托,比方说slf4j-log4j12

版别1.5.6,你会触发非法拜访过错。

检查Maven里那个slf4j-api版别被拉入,用下述maven依托植入。

mvndependency:tree

假如你运用Eclipse,请不要依托m2eclipse显现的联系树。

假如你的pom.xml清晰在slf4j-api上声明晰依托,这个版别的api匹配已声明的绑定,将使这个疑问不见。

也请读向后兼容性的FAQ,以取得更多普遍性解说。

9.为啥SLF4J是在X11类型答应证下答应而不是Apache软件答应?

SLF4J是在X11类型答应证下答应而不是Apache软件答应,这是因为X11答应是被Apache软件基金会以及自由软件基金会的各自答应以为是科兼容的。

10.在哪里能取得特定的SLF4J绑定?

给SimpleLogger、NOPLogger、og4jLoggerAdapter和JDK14LoggerAdapter

的SLF4J绑定包含在slf4j-nop.jar, slf4j-simple.jar,slf4j-log4j12.jar, and

slf4j-jdk14.jar文件里。

给logback-classic的绑定顺便在logback

distribution(http://logback.qos.ch/download.html)上。关于别的一切的绑定,logback-classice绑定需求slf4j-api.jar。

11.我的库应当测验装备logging吗?

嵌入的组件,比方库,不进不需求装备底层日志结构,它们也不应当做这些。它们应当引进SLF4j来记载日志,但也应当让终端用户装备日志环境。当嵌入的组件测验在自个装备日志时,它们常常会掩盖终端用户的志愿。在一天的完毕时,终端用户不得不读日志,处理日志。她应当是决议自个想要的日志装备的人。

12.为了减小咱们软件的依托库数量,咱们想让SLF4J变成一个可挑选的依托包。这个是好主意吗?

当一个软件工程抵达它需求规划日志战略的点时,这个疑问会提起

让Wombat变成一个具有极少依托的软件库。假如SLF4J被选作为Wombat的日志API,那么一个新的slf4j-api.jar依托库将被参加带Wombat的依托包列表中。因为写日志的包装并不难,一些开发者冒险包装SLF4J,只需当它现已呈现在类途径中时链接它,使得SLF4J变成Wombat的一个可挑选的依托库。为了处理这个依托疑问,包装将被从SLF4J的API中阻隔Wombat,以保证Wombat中的日志不会过时的。

别的,任何SLF4J-包装都取决于SLF4J得界说。它们一定有相同的通用api。在将来,假如呈现一个新的、显着不相同的日志API,和直接运用SLF4J的代码相同,运用包装器的代码也将相同很难移植到新的API.因而,包装器不行能是面向未来的代码,但在SLF4J上增加了一个额定的直接衔接,使得这更杂乱,这本身即是一中直接衔接。

脆弱性增加实践上比这个还遭。包装器需求依托随时改动的一些内部SLF4J接口,这违反了面向客户端API永不改动的准则。因而,包装器一般依托一些同他们一同编译的首要版别。关于SLF4J

1.5.x版别编译的包装器将不会同SLF4J 版别1.6作业,可是运用org.slf4j.Logger, LoggerFactory,

MarkerFactory, org.slf4j.Marker和MDC的客户端代码将和任何版别SLF4J

1.0及今后的版别正常作业。合理地假定在大有些工程中,Wombat将是很多依托库中的一个。假如每个依托库有自个日志包装器,那么大约每个包装器需求独立装备。因而,不仅仅处理SLF4J的日志结构,Wombat的用户也有必要处理Wombat的日志包装器。

为了使SLF4J可挑选,每个结构提出的自个的包装器将加重这个疑问。(装备或处理5个不相同的日志包装器将很不开心,也不招人喜欢)

Velocity项目采纳的日志战略

是一个“自界说日志笼统”反办法的好比如。经过选用一个独立的日志笼统的战略,Velocity开发者现已使自个的开发更杂乱,但更主要的是,他们让开发对他们的用户更难。

一些项目试着在类路劲上检查SLF4J的存在性,假如存在的话就变换到SLF4J.虽然这个办法看上去满足的通明,可是它将致使过错的方位信息。底层日志结构将打印包装器的方位(类名和行数)而不是打印真实调用者的方位。还有即是除了参数化日志、像SLF4J支撑MDC和符号的API掩盖疑问。虽然有人能够在数小时内提出一个好像可运转的SLF4J包装器,跟着时刻的推移,很多技术疑问将呈现,这是Wombat开发者不得不处理的疑问。留意SLF4J现已开展了好几年了,有260个bug陈述提起它。

根据以上要素,结构的开发者应当反抗自个写的日志包装的引诱。

它不仅是浪费开发者时刻,对上述日志的用户,这实践上让开发更艰难,使日志代码自相矛盾地更简略改动。

13.Maven传递依托怎么?

作为运用Maven构建库作者,你也许想运用绑定来测验你的运用程序,比方SLF4J-log4j12或的logback经典,对用户不强制log4j或logback-classic作为依托。

这是对比简略做到的。

根据你的库的代码依托于SLF4J

API,你需求声明SLF4J的API作为一个编译时(默许规模)的依托。

org.slf4jslf4j-api1.7.21

经过声明SLF4J绑定依托为“测验”的规模,能够完结限制在测验绑定运用的SLF4J的传递。例如:

org.slf4jslf4j-log4j121.7.21test

因而,至于你的用户要导出SLF4J的API作为库的传递依托,但不是任何SLF4J绑定或任何底层日志体系。

需求留意的是因为SLF4J

1.6版,在没有SLF4J绑定,SLF4J的API将默许为无无操作完结。

14.怎么扫除依托Maven的commons-logging?

代替1清晰扫除

很多运用Maven的软件项目声明commons-logging作为一个依托。因而,假如你希望迁移到SLF4J或运用jcl-over-slf4j,你需求扫除项目中一切依托里的comms-logging,这些依托库传递依托common-logging。依托扫除

在Maven文件里已有描绘。为散布在几个pom.xml里的多个依托清晰地扫除common-logging,也许是一个粗笨的和相对简略犯错的进程。

代替2规矩的规模

在项目的pom.xml文件中所供给的规模内,经过声明Commons-logging,它能够像依托相同简略、便利地扫除。实践的commons-logging类将由jcl-over-slf4j供给。

这转化为以下POM文件片段:

commons-loggingcommons-logging1.1.1providedorg.slf4jjcl-over-slf4j1.7.21

第一依托性声明实质规矩commons-logging会经过你的环境“以某种办法”供给。第二个声明引进jcl-over-slf4j到你的项目中。

作为jcl-over-slf4j是commons-logging完美的二进制兼容更换,第一个断语为真。

意外的是,虽然在规矩规模内声明的commons-logging能够完结使命,你的IDE,比方Eclipse中,仍将在项目的类途径上放置commons-logging.jar,经过你的IDE能够看到。

您将需求保证jcl-over-slf4j前,您的IDE 的commons-logging.jar的是可见的。

代替3空构件

另一种办法是依托一个空的commons-logging.jar构件。这个聪明的办法首要

由Erik van Oosten想出和开端支撑。

空构件可从一个http://version99.qos.ch高可用性Maven库房,仿制在坐落不相同地域的多个主机。

下面的声明增加version99库设定的Maven的查找长途资源库。

该存储库中包含的commons-logging和log4j的空构件。 趁便说一句,假如你运用的version99库,请在给咱们一行。

version99http://version99.qos.ch/

在你的项目里的有些,声明99-empty版别中的commons-logging的将为commons-logging指向一切传递的依托以输入版别9999-empty,然后极好地处理的commons-logging排挤疑问。关于commons-logging的类将由jcl-over-slf4j供给。

以下行声明的commons-logging版别99-empty(在依托办理有些),并声明jcl-over-slf4j作为一个依托。

commons-loggingcommons-logging99-empty...

other declarations...

org.slf4jjcl-over-slf4j1.7.21...

other dependency declarations

关于SLF4J API

1.为啥日志器接口的打印办法不接纳方针类型的音讯,但只接纳String类型音讯?

在SLF4J 1.0beta4版里,Logger

interface 中例如debug(),info(),warn()的打印办法被修改以用于只接纳String类型的音讯,而不是Object类型的音讯。

因而,DEBUG等级的打印办法设置变为:

debug(Stringmsg);debug(String

format,Objectarg);debug(String format,Object arg1,Object

arg2);debug(Stringmsg,Throwable t);

之前,上述办法中的第一个参数是Object类型。

这个改动强制使人以为日志体系是关于装修和处理String类型音讯,而不是关于任何(Object)类型。

相同主要的是,新的一套签名办法供给重载办法间的通明差异,而以前挑选

被调用的Java办法,因为Java的重载规矩一般老是不易遵从。

很简略犯过错。例如,之前这么写是合法的:

logger.debug(newException("some

error"));

意外的是,上述调用不会打印堆栈盯梢的反常。因而,潜在的要害信息片也许会丢掉。当第一个参数被限制为String类型时,只需如下办法:

debug(Stringmsg,Throwable t);

可用于记载反常,留意,此办法可保证每个日志反常是伴跟着一个描绘性的音讯。

2.我能够输出一个没有随同音讯的反常日志吗?

简言之,不能够。

假如e是一个反常,你想输出一个ERROR等级的反常,你有必要增加一个随同音讯。例如:

logger.debug(newException("some

error"));

你也许合理地辩解不是一切的反常都有一个有意义的音讯伴跟着它们。此外,杰出的反常应当现已包含一个自我解说阐明。因而,随同的音讯能够被以为是剩余的。

当这些参数是有用参数时,有3个相反的参数也是值得思考的。首要,在很多场合,但不是一切场合,随同音讯能够极好滴传达有用的信息,在反常里弥补描绘。一般状况下,在其间反常日志点,开发者取得比在反常被抛出点更多的上下文信息。其次,很难或多或少幻想一般音讯,例如”Exception

caught”, “Exception follows”,也许会用作给过错调用的第一个参数(String msg,Throwable

t)。第三,很多日志输出格局显现一行音讯,在紧跟着的一行输出反常。因而,音讯行没有音讯,看起来不一致。

简言之,假如答运用户打印一个没有随同音讯的反常,这将是日志体系的作业:发明一个音讯。这实践上是java.util.logging包中的throwing办法(String

sourceClass, String sourceMethod, Throwable thrown)

所做的。(它取决于本身的随同音讯是字符串“THROW”。)

开端时也许会古怪地恳求一个随同音讯以记载一个反常。

可是,这是在一切的log4j的衍生体系,如java.util.logging,logkit等,当然还有的log4j本身的通行做法。

如此看来,现在的共识以为需求一个随同的音讯是一个极好的做法(TM)。

3.输出日志(封闭日志)的最快办法是啥?

SLF4J提出一个叫参数化日志的高档特色,能够显着提高有缺陷的日志句子的日志功能。

关于一些Logger logger,写作,

logger.debug("Entry number:

"+i+" is "+String.valueOf(entry));

导致结构音讯参数的开支,即是变换integer

i和entry为String,和衔接中间的字符串。这一点,不管音讯是不是记载。

一种也许的办法,以防止结构参数的开支是经过测验中包裹日志句子。例如

if(logger.isDebugEnabled()){logger.debug("Entry

number: "+i+" is "+String.valueOf(entry));}

假如logger封闭调试,这么的话就不会导致结构参数的开支。在另一方面,假如logger对DEBUG等级敞开,不管logger是不是敞开,都会导致开支,并且是两次:一次是debugEnable开支,一次是debug里的开支。这是微乎其微的开支,因为评价日志器花费的时刻不到实践进程中记载句子的时刻的1%。

非常好的是,运用参数化的音讯

这里存在一个根据音讯格局的很便利的挑选。假定entry是一个方针,你能够这么写:

Object entry

=newSomeObject();logger.debug("The entry is {}.", entry);

在评价是不是记载日志后,只需当结论是必定的时分,日志器完结将格局化音讯,并将’{}’更换为entry的字符值。换句话说,假定日志声明是封闭的,这个格局不会导致构建参数的开支,

下面两行代码将发作切当相同的输出。可是,假定封闭日志声明,第二种办法将将最少超越第一种办法的30倍。

logger.debug("The new entry is

"+entry+".");logger.debug("The new entry is {}.", entry);

双参数 版别也是可用的。例如,你能够这么写:

logger.debug("The new entry is

"+entry+".");logger.debug("The new entry is {}.", entry);

假如需求传递3个或更多的参数时,你要运用Object…variant

打印办法。例如,你能够这么写:

logger.debug("The new entry is

{}. It replaces {}.", entry,oldEntry);

这中办法导致躲藏的构建一个Objec[](方针数组)的开支,一般状况下这个开支是很小的。一个和两个参数版别的这种办法不会导致这个躲藏的开支,一起因为这个要素(功率)会彻底存在。只需Object…variant的状况下,Slf4j-api会更小/更简练。

数组办法的参数,包含多维数组,也是支撑的。

SLF4J运用本身的音讯格局完结,这个和java渠道的格局化输出是不相同的。已被证实的事实是:SLF4J的完结渠道功能是java渠道的十倍,但开支会无规范,弹性也会更小。

脱节“{}”对

“{}”对叫做格局化锚。它用于指定方位:指定需求用音讯款式更换的参数的当地。

SLF4J值关怀格局化锚,这即是“{”字符当即跟着字符“}”。因而,假如你的音讯包含“{”或“}”字符,不需求做任何格外处理,除非“}”当即跟着“}”字符。例如:

logger.debug("Set {1,2} differs

from {}","3");

这将打印“Set {1,2} differs from

3”。

在极端稀有的状况下,“{}”对很自然地呈现在你的文本中,你希望禁用格局化锚的格外意义,你需求将“{”字符更换为“”,即是反斜杠字符。

只需“”应当更换。不需求更换“}”字符。例如:

logger.debug("Set \\{} differs

from {}","3");

将会打印为“Set {} differs from

3”。留意在java代码里,反斜杠字符需求写为“”。

在罕见的状况下:“{}”在音讯中呈现,你能够运用两个反斜杠,这么它才会坚持它本来的意义。例如:

logger.debug("File name is

C:\\\\{}.","file.zip");

将会打印“File name is

C:\file.zip”。

4.怎么打印独自(也许是杂乱的)方针的字符串内容日志?

需求以字符串格局记载方针的音讯,这是相对罕见的格局,那么能够运用恰当等级的参数化打印办法。假定complexObject是一个已断定杂乱度的方针,关于一个DEBUG等级的日子句子。你能够这么写:

logger.debug("{}",complexObject);

在日志体系已查明日志体系已敞开后,它将调用complexObject.toString()办法。不然,complexObject.toString()变换的开支将有力地防止。

5.为啥org.slf4j.Logger接口没有FATAL等级的办法?

符号接口,是org.slf4j包的一有些,指出FATAL等级很大程度上是剩余的。假如一个给定的过错需求的留意超越了分配给普经过错的留意,运用格外指定的符号来简略符号日志句子就能够命名“FATAL”或别的你喜欢的姓名.

例如:

import org.slf4j.Logger;import

org.slf4j.LoggerFactory;import org.slf4j.Marker;import

org.slf4j.MarkerFactory;classBar{ void foo(){   Marker fatal

=MarkerFactory.getMarker("FATAL");  

Loggerlogger=LoggerFactory.getLogger("aLogger");   try{     ... obtain a JDBC

connection   }catch(JDBException e){     logger.error(fatal,"Failed to obtain

JDBC connection", e);   } }}

虽然符号是SLF4J

API的一有些,只需logback支撑现成的符号。例如,假如你增加%marker变换字到它的款式中,logback的PatterenLayout将增加符号数据到它的输出口。符号数据能够用于过滤音讯

,或许乃至在单个业务完毕后 宣布 电子邮件。

在日志结构的组合体中,例如log4j和java.util.logging,是不支撑符号的。符号数据将被默默地疏忽掉。

比较于五个值,即过错、正告、信息,调试和盯梢,这是所答应的日志等级,为了处理日志句子,符号增加了一个新的具有无限也许值的维度。现在。只需logback支撑符号数据。可是,没有啥阻挠别的日志结构运用符号数据。

6.为啥TRACED等级的日志只在SLF4J

1.4.0版别介绍?

增加TRACED等级已变成频频和剧烈评论的恳求。经过研讨各种项目,咱们得出TRACE等级被用于某些类禁用日志输出,而不需求为这些类装备日志。实践上,在log4j和logback里,TRACE等级默许是制止,这在大有些别的日志体系中也是制止的。在装备文件里增加适宜的指令,相同的成果也能够取得到。

因而,在很多状况下,TRACE等级像DEBUG等级相同带有相同的语意意义。在这些状况下,TRACE等级仅仅保留一些装备指令。在别的更风趣的场合,TRACE等级比较于DEBUG等级带有不相同的意义,Marker方针能够用于传递所需的意义。可是,假如用符号你不被打扰,希望运用比DEBUG等级低的日志等级,那么TRACE等级能够完结这个使命。

留意,虽然评价禁用日志恳求的开支是在几纳秒内。在密布的循环中,运用TRACE等级(或此种业务下的任何别的日志等级)是不鼓舞的,这里日志恳求也许被计算数百万次。假如日志恳求是敞开的,那么它将用很多输出来吞没方针方位。假如恳求被禁用,它将浪费资源。

简言之,虽然咱们仍不鼓舞运用TRACE等级日志,因为存在可挑选的日志等级,或许在很多状况里,TRACE等级的日志恳求是浪费的,因为大家一直在问它,咱们决议屈服于群众的需求。

7.SLF4J日志API支撑I18N(国际化)吗?

是的,作为的1.5.9版别,SLF4J顺便一个包叫做org.slf4j.cal10n,它增加了本地化/国际化日志记载

的支撑,在内置薄薄的一层CAL10N API .

8.不经过LoggerFactory里的静态办法,能够从头获取日志器吗?

是的,

LoggerFactory实质上是一个环绕ILoggerFactory实例的包装。运用ILoggerFactory实例是由SLF4J底层的静态绑定约好断定的。检查LoggerFactory的getSingletong()

办法获取概况 .

可是,没有啥能阻挠你运用自个的ILoggerFactory实例。留意,经过调用LoggerFactory.getILoggerFactory()

办法,你也能够取得LoggerFactory类运用的ILoggerFactoyr的一个引证。

因而,假如SLF4J绑定约好不符合你的需求,或许你需求额定的拓展性,那么请思考运用ILoggerFactoyrj接口,作为你自个发明的日志API的一个可挑选接口。

9.存在过错/抛出反常时,能够参数化日志声明吗?

是的,像SLF4J1.6.0版别相同,但这之前的版别里不是这么。在反常呈现的当地,SLF4J

API支撑参数化,假定反常时最终的参数吗。因而,

String s = "Hello world";try {

Integer i = Integer.valueOf(s);} catch (NumberFormatException e) {

logger.error("Failed to format {}", s, e); }

如希望的相同,将会打印NumberFormatException,一起也包含它的栈追寻信息。Java编译器将调用传入一个字符串和两个方针变量的error办法

。SLF4J依照程序猿的最大也许目的,将像一个抛出反常相同解说NumberFOrmatException实例,而不是简略的疏忽掉。

假如反常不是最终的变量,它将被以为是一个往常的方针,它的栈信息将不会被打印。当然,这种状况在实践操作中应当不会发作。

完结SLF4J API

1.怎么使我的日志底层结构SLF4J有可兼容性?

为SLF4J增加支撑是So

Easy的一件事。实质上,你仿制一个已存在的绑定,裁剪绑定的一点点就完结这个小手段(如下解说)。

假定你的日志体系有日志器的概念,称为MyLogger,你需求为MyLogger到org.slf4.Logger接口供给一个适配器。参阅slf4j,slf4j-jdk14,和slf4j-log4j12模块中适配器的比如。

一旦你写完一个适宜的适配器,叫MyLoggerAdapter,你需求供给一个工厂类,它完结org.slf4j.IloggerFactory接口。这个工厂应当回来MyLoggerAdater的实例。使MyLoggerFactoyr是你工厂类的姓名。

一旦有了名为MyLoggerAdater的适配器,和一个名为MyLoggerFactoyr的工厂类,最终剩余的进程即是改动StaticLoggerBinder类,这么它会回来一个MyLoggerFactory新实例。你也需求修改loggerFactoryClassStr变量。

关于Marker(符号)或MDC支撑,你能够运用已有的NOP(slf4j.nop.jar是sl4f-api.jar其相应的接口完结)完结中的一个。

综上,为你的日志体系创立一个SLF4J绑定,进程如下:

开端仿制一个已有的模块,

创立一个根据你日志体系和slf4j.Logger接口间的适配器

为上一进程里的适配器创立一个工厂类

修改StatciLoggerBinder类,以运用上一进程创立的工厂类。

2.怎么使我的日志体系增加支撑Marker接口?

符号设立了一个革命性的概念,这是由logback支撑的,但别的已有日志体系是不支撑这个的。所以,SLF4J相容日志体系答应疏忽用户经过符号数据。

可是,即便符号数据也许被疏忽,用户仍有必要被答应指定符号数据。不然,用户将不能在支撑符号的日志体系和不支撑符号的日志体系间切换。

MakrerIgnoringBase类可作为适配器或短少象征支撑的日志体系的本地完结的基类。在MarkerIgnoringBase类里,带有符号数据的办法简略地调用没有符号参数、丢掉作为参数传入的任何符号数据的有关办法,你的SLF4J适配器能够继承MakrerIgnoringBase类来迅速完结org.slf4j.Logger里的办法,org.slf4j.Logger需求符号作为第一个参数。

3.SLF4J的版别检查机制怎么作业?

SLF4J初始化时期,它履行的版别检查是可选进程。相容的SLF4J完结可挑选不不参加,在这种状况下,将不会履行版别检查。

可是,假如SLF4J完结决议参加,那么它需求声明一个叫REQUESTED_API_VERSION的变量,一起得在StaticLoggerBinder类的复制里声明。次变量的值应当等于slf4j-api编译的版别。假如完结被更新到新的slf4j-api版别,那么你也需求更新REQUESTED_API_VERSION的值。

对每一个版别,SLF4J

API都坚持兼容版别的列表。假如恳求的版别在兼容列表中没被找到,SLF4J将宣布一个单本不匹配正告。即便SLF4J绑定比SLF4J有一个不相同的发布,假定每6到12个月,你更新SLF4J版别,你仍能够在没触发版别不匹配的状况下,参加版别检查。例如,logback又一个不相同的发布日程,可是仍然会参加版别检查。

关于SLF4J

1.5.5,一切绑定在SLF4J散布,例如slf4j-log4j12,slf4j-simple和slf4j-jdk14里传递,声明REQUESTED_API_VERSION,它的值等于它们的SLF4J版别。它遵从的是,例如假如slf4j-simple-1.5.8与

slf4k-api-1.6.0,jar混合运用,根据1.5.8不在SLF4J版别1.6.x的兼容列表,将会触发版别不匹配正告。

留意,1.5.5之前的SLF4J版别没有版别检查机制。只需slf4j-api-1.5.5.jar今后的版别可触发版别不匹配正告。

关于日志的一般性疑问

1.类的日志器成员变量应当声明为静态变量吗?

咱们一般引荐的是loggers成员声明为实例变量,而不是静态变量。进一步剖析后,在别的办法上,咱们不再引荐一种办法。

下面是每一个办法的有点和缺陷。

Advantages for declaring

loggers as

static声明logger为静态变量的长处Disadvantages

for declaring loggers as

static声明logger为静态变量的缺陷

1.Possible to take advantage of

repository selectors even for libraries shared between applications. However,

repository selectors only work if the underlying logging system is

logback-classic. Repository selectors do not work for the SLF4J+log4j

combination.2.IOC-friendly1.   通用、极好树立的惯用句子2.  

更小的CPU开支:在主机类初始化进程中,loggers获取和分配只需一次3.   更小的内存开支:logger声明每个类耗费一个引证1.For

libraries shared between applications, not possible to take advantage of

repository selectors. It should be noted that if the SLF4J binding and the

underlying API ships with each application (not shared between applications),

then each application will still have its own logging environment.2.not

IOC-friendly1.在运用间同享库,不能表现库房挑选器的优势。应当留意,假如SLF4J绑定和底层API顺便每一个运用(不在运用间同享),那么每个运用仍将有自个的日志环境。2.IOC不友善

Advantages for declaring

loggers as instance

variables声明loggers为实例变量的优势Disadvantages

for declaring loggers as instance

variables声明loggers为实例变量的缺陷

Possible to take advantage of

repository selectors even for libraries shared between applications. However,

repository selectors only work if the underlying logging system is

logback-classic. Repository selectors do not work for the SLF4J+log4j

combination.

IOC-friendly

1.  

可表现库房挑选器的优势,乃至运用间的同享库。可是,只需底层日志体系是logback-classic的,库房挑选器才起作用。SLF4J+log4j相结合的办法,库房挑选器将不起作用。

2.   IOC友爱1.Less common idiom

than declaring loggers as static variables2.higher CPU overhead: loggers are

retrieved and assigned for each instance of the hosting class

higher memory overhead: logger

declaration will consume one reference per instance of the hosting class

1.   比声明loggers为静态变量有更少的惯用句子

2.  

更高的CPU开支:loggers为主机类的每个实例进行获取和分配

3.  

更高的内存开支:logger声明主机类的每个实例都耗费一个引证

阐明

静态日志成员为类的一切实例花费一个独自的变量引证,而实例日志成员将为类的每个实例花费一个变量引证。对简略的类进行数以千计次的初始化也许呈现一次显着的差异。

可是,最近的日志体系,例如log4j或logback,为每个运转在运用服务器上的运用供给一个不相同的logger上下文。因而,即便一份log4j.jar或logback-classic.jar的单复制有用地运用在服务器上,日志体系能够在运用间进行区分,一起为每个运用供给一个不相同的日志环境。

更格外的是,每次,经过调用LoggerFactory.getLogger()办法能够从头取得logger,底层日志体系将给当时运用回来恰当的实例。请留意,在相同的运用里获取一个给定姓名的logger一般会回来相同的logger.关于给定的姓名,对不相同的运用将回来不相同的logger.

假如logger是静态的,当主机类已加载到内存时,那么它将只被取得一次。假如主机类只在一个运用里运用,那么这里没有太多需求关怀的当地。可是,假如主机类在几个运用间同享,那么一切同享类的实例将记载到运用的上下文里,这都发作在首次加载同享类到内存里的时分-几乎是不被用户希望的做法。

意外的是,关于SLF4J

API的非本地完结,姓名为slf4j-log4j12,log4j的库房挑选器将不能正常地完结它的作业,因为slf4j-log4j12,对错本地SLF4J绑定,将在字典里存储logger,短路循环依托logger上下文从头获取。关于本地SLF4J完结办法,例如logback-classic,库房挑选器将如期作业。

Apache Commons wiki有一篇掩盖这个疑问的文章

Logger序列化

与静态变量相反,实例变量默许是序列化的。关于SLF4J版别1.5.3,

Logger实例变量幸好是初始化的。因而,主机类的初始化不再需求任何格外的指令,即便当loggers被声明为实例变量。在之前的版别里,logger实例需求在主机类里声明为transient类型变量。

总结

综上,声明logger成员为静态变量需求更少的CPU时刻,有一个更小的内存开支。另一方面,声明logger成员为实例变量需求更多的CPU时刻和更高的内存开支。可是,实例变量使得为每一个运用构建一个不相同的logger环境,乃至为同享库里声明的logger变成也许。也许,比之前触及的要素更主要的是,实例变量是IOC友爱的,而静态变量却不是。

检查commons-logging wiki里有关评论

2.类里的声明日志器有引荐的习语吗?

以下是引荐的记载声明成语。要素如上所述,这是留给用户断定记载器是不是被声明为静态变量或没有。

package some.package;import

org.slf4j.Logger;import org.slf4j.LoggerFactory;public class MyClass {   final

(static) Logger logger = LoggerFactory.getLogger(MyClass.class);   ... etc }

意外的是,因为主机类的名称是记载器声明的一有些,上面logger声明习语是不能在类之间反抗剪切和张贴。

优质IT资源分享社区为你提供此文。

本站有大量优质Java教程视频,资料等资源,包含java基础教程,高级进阶教程等等,教程视频资源涵盖传智播客,极客学院,达内,北大青鸟,猎豹网校等等IT职业培训机构的培训教学视频,价值巨大。欢迎点击下方链接查看。

java教程视频

优质IT资源分享社区(www.itziyuan.top)
一个免费,自由,开放,共享,平等,互助的优质IT资源分享网站。
专注免费分享各大IT培训机构最新培训教学视频,为你的IT学习助力!

!!!回帖受限制请看点击这里!!!
!!!资源失效请在此版块发帖说明!!!

[PS:按 CTRL+D收藏本站网址~]

——“优质IT资源分享社区”管理员专用签名~

本版相似帖子

游客