Clojure世界:日志管理——clojure.tools.logging

   处理日志是任何一个产品级的程序都需要仔细处理的模块。在Java中,我们经常使用的是log4j就是一个日志框架。在clojure里,同样有一套日志框架——clojure.tools.logging,它不仅提供了常用的日志输出功能,还屏蔽了Java各种日志框架之间的差异,如slf4j,commons-logging,log4j,java.util.logging等,让你可以透明地使用这些框架来处理日志。

名称:clojure.tools.logging
主页: https://github.com/clojure/tools.logging
依赖:
[org.clojure/tools.logging "0.2.3"]

< dependency >
  
< groupId > org.clojure </ groupId >
  
< artifactId > tools.logging </ artifactId >
  
< version > 0.2.3 </ version >
</ dependency >

使用:
(ns example.core
  (:use [clojure.tools.logging :only (info error)]))

(defn divide [x y]
  (try
    (info "dividing" x "by" y)
    (/ x y)
    (catch Exception ex       (error ex "There was an error in calculation"))))

常用宏和方法:
1.除了上面例子的info和error宏,还可以包括warn,trace,debug,fatal等常用宏,分别对应相应的日志级别。这些方法会自动判断当前logger的级别是否有效,有效的前提下才会输出日志。也就是说在Java里,你经常需要这样:
if  (logger.isDebugEnabled()) {
    logger.debug(x 
+   "  plus  "   +  y  +   "  is  "   +  (x  +  y));
}
在使用 tools.logging的时候是不需要的,因为这些宏帮你做了这个判断。另外,我们在使用log4j的时候需要指定log的namespace,在tools.logging里不需要,默认会取当前的namespace也就是*ns*。
最后,info还有个infof的方法,用于输出格式化日志:
(infof  " %s is %d years old "   " kid "   3 )
日志输出:
2012 - 02 - 12   20 : 23 : 07 , 394  INFO  log: kid is  3  years old
其他方法也有类似的如warnf,debugf等。
2.spy宏,同时输出表达式的form和结果,例如
(spy ( + 1   2 ))
输出日志
2012 - 02 - 12   20 : 11 : 47 , 415  DEBUG log: ( +   1   2 )
=>   3

3.with-logs宏可以在将*out*和*err*流重定向到日志的情况下求值表达式,例如:
(with - logs  * ns *  (prn  " hello world " ))
输出日志:
2012 - 02 - 12   20 : 17 : 32 , 592  INFO  log:  " hello world "
with-logs需要明确指定log-ns,默认out的输出级别是info,而err的级别是error,可以指定输出级别(with-logs [*ns* :info :error] ......)

4.事务中(dosync中)的日志输出,tools.logging做了特殊处理,默认情况下当且仅当事务成功提交的时候并且日志级别是warn或者info会通过agent异步写入日志。tools.logging定义了一个全局的agent——*logging-agent*。当判断当前是在事务中调用log宏,并且日志级别在集合*tx-agent-levels*内,就会在事务提交成功的时候将日志发送给*logging-agent*异步处理。可以通过*tx-agent-levels*改变使用agent输出日志的级别范围,默认是#{:info :warn}。还可以通过改变*force*变量来强制使用direct或者agent的方式输出日志,*force*可以为:agent或者:direct。
(binding [ * force *  :agent]
  (log :info 
" hello world " ))
这里特别使用了log宏,需要明确指定日志级别为info。

5.默认日志框架的是从classpath查找的,查找的顺序是sl4j,commons-logging,log4j,java.util.logging,找到哪个可用就用哪个。如果你的classpath里存在多个日志框架,如同时存在sl4j和commons-logging,那么如果你希望强制使用commons-logging,可以通过改变*logger-factory*变量来使用:
(ns example
  (:use [clojure.tools.logging.impl :only [cl
- factory]]))
(binding [
* logger - factory *  (cl - factory)]
  (info 
" hello world " ))

*logger-factory*是dynamic变量,可以通过binding改变(前面提到的*force*等变量也一样),如果不希望每次都用binding,而是全局改变,则需要特殊处理:
(alter - var - root (var  * logger - factory * ) (constantly (cl - factory)))

其他logger factory还包括slf4j-factory,log4j-factory,jul-factory。

6.每个日志框架的配置跟使用java没有什么两样,比如你用log4j,就需要在classpath下放置一个log4j.properties等。如果你希望用编程的方式配置,可以使用clj-logging-config

文章转自庄周梦蝶  ,原文发布时间2012-02-12

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值