设为首页 收藏本站
查看: 1235|回复: 0

[经验分享] Java Web App: 选择与配置日志库

[复制链接]

尚未签到

发表于 2017-3-1 07:37:05 | 显示全部楼层 |阅读模式
  Java世界里,日志库就和许多其他库[1]一样,你有多个选择,多个还不错的选择,比如log4j, java.util.logging, logback, 另外还有一些统一的log api,比如slf4j, common-logging等 。 而C++感觉开源的好用的有口碑的日志库并不是那么丰富[2]。
  选择
  Java的日志库分为两种,一种是提供统一的api,如slf4j, common-logging;一种是提供真正的实现,如log4j, java.util.logging以及logback。前者可以自由搭配后面真正的实现库。
  会出现这种情况的原因是java日志库百家争鸣,这会有这么一个问题:假设我的程序使用到两个库,第一个使用了log4j,而第二个使用了java.util.logging,两个log库同时工作,肯定不是好事:


  • 日志输出格式可能不一致,增加阅读,分析难度;
  • 加载两份同样功能的库对classpath的整洁以及内存使用会产生影响;
  • 甚至还有可能两者无法兼容,运行时出现问题。
  • 限制了我的程序对日志库的选择 - 我依赖的库已经用了A日志库了,我最好也是用A吧,虽然我很喜欢B
  所以出现了提供统一api的日志库(不过这玩意多了,还是会回到原来的问题),供公用的库写日志都要这些统一的api,用户程序也是用这些统一的api,然后用户可以部署自己喜欢的实际功能日志库,提供真正写日志的功能。
  我选择使用slf4j + logback的组合,虽然我写的不是一个公用库,但这种使用方式使我将来可以非常容易的替换日志库实现。
  因为我的应用暂时还没有什么特殊的要求,所以选择相对来讲不是很细致,大概是:


  • 选择slf4j而不是common-logging,因为slf4j更新更酷,且解决了选择性格式化输出[3]与classloader[4]的问题。
  • 选择logback,因为log4j将被logback替代;因为logback和slf4j是同一个作者写的(即log4j的作者),相信他们会合作的更好
  配置
  首先是在ivy中加入对slf4j和logback的依赖:



<dependency org="org.slf4j" name="slf4j-api" rev="1.6.6"  conf="runtime->default" />
<dependency org="ch.qos.logback" name="logback-classic" rev="1.0.6" conf="runtime->default" />
<dependency org="ch.qos.logback" name="logback-core" rev="1.0.6" conf="runtime->default" />
  因为logback内置了与slf4j的binder,你无需像使用log4j或者java.util.Logging时那样提供额外的binder jar包。
  然后,对logback做一些配置,提供一个logback的配置文件:



<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<contextName>interviewerportal</contextName>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<target>System.out</target>
<!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{20} - %msg%n
</pattern>
</encoder>
</appender>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>output/logs/interviewerportal.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>output/logs/interviewerportal.%i.log
</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>9</maxIndex>
</rollingPolicy>
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<!-- allow all log messages to be written to log file -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>TRACE</level>
</filter>
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{20} - %msg%n
</pattern>
</encoder>
</appender>
<!-- global logger: to both console & file -->
<root level="trace">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>
  这里配置了两个输出:一个标准输出,一个文件输出,标准输出只显示INFO及以上级别的log;而文件输出显示所有级别的log。对于文件输出,同时还定义了文件替换策略:当当前日志文件大于某个数值时,开始写到一个新的日志文件中去。
  把这个文件放到classpath的根目录下, 见(https://github.com/lzprgmr/interviewerportal/blob/master/interviewerportal/src/logback.xml),logback在启动时会自动读取该文件并应用配置。
  使用非常简单:



package interviewerportal.domain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SLF4JTest {
private static final Logger logger = LoggerFactory.getLogger(SLF4JTest.class);
public static void main(String[] args) {
logger.error("Hello, error");
logger.warn("Hello, warn");
logger.info("Hello, info");
logger.debug("Hello, debug");
logger.trace("Hello, trace");
logger.info("{} + {}", 1, 2);
}
}

  [1] 比如web MVC框架有Stuts, Spring MVC, JSF(JavaServer Faces, J2EE提供), 详细见此; 前端显示的有freemarker, jsp(jstl)等;web server有tomcat, jetty等;application server有GlassFish, JBoss, WebSphere, WebLogic, TomEE等,详细见此。
  [2] C++的日志库其实也不少,有google的glog, apache的log4cxx(log4j的兄弟版本), pantheios, 以及boost.log(该库已经被接受进入boost, 但目前还未包含进boost的发布中,可能会在2012年末?)
  [3] slf4j支持一种高效的格式化输出字符串:loger.info("{} + {}", 1, 2)。如果当前的log level没有被打开,则该条信息不会被log,而且该字符串格式化也不会执行,从而提高了效率;而以前,为了避免此种情况,你往往需要写出丑陋的if:if(logger.isInfoEnabled()) loger.info("{} + {}", 1, 2)
  [4] common-logging是通过classloader加载真正的日志库实现的,如果代码中有多份classloader,就可能出现问题,详细见此。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348513-1-1.html 上篇帖子: 众多Android 开源项目再次推荐,学习不可错过 下篇帖子: WebService 开发入门 基于CXF框架
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表