博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
logback指定日志存放位置
阅读量:5776 次
发布时间:2019-06-18

本文共 4151 字,大约阅读时间需要 13 分钟。

hot3.png

 随着通用日志组件转入 Slf4j,logback 也变成了默认的日志实现,像 log4j 一样,logback.xml 中也可以使用系统属性或环境变量,如 ${catalina.home}。在 log4j.properties 中,如果变量在系统属性和环境变量中找不到的话默认为 "" 空字符串,而到了 logback.xml 中如果某个变量找不到默认就是 "变量名_IS_UNDEFINED" 了,这样就比较奇怪了。

那如何在没有配置 catalina.home 系统属性或环境变量时设置一个默认值呢,例如,没有 catalina.home  时取值为 ".",这时值日志文件的路径就是

./logs/unmi-%d{yyyy-MM-dd}.log

了,也就是生成中当前目录下的 logs 子目录中,这样算是很友好的方式。下面就来分析怎么一步步找到答案的,没耐心或是只求结果的话,直接滚屏到下面就行。

我们的问题是,对于下面那样的 logback.xml 配置:

        < configuration >             < appender name = "stdout" class = "ch.qos.logback.core.ConsoleAppender" >                < encoder charset = "UTF-8" >                    < pattern >%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
                
            
             < appender name = "RollingFile" class = "ch.qos.logback.core.rolling.RollingFileAppender" >                < rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy" >                    < fileNamePattern >${catalina.home}/logs/unmi-%d{yyyy-MM-dd}.log
                    < maxHistory >10
                
                 < encoder >                    < pattern >%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
                
            
             < root level = "DEBUG" >                < appender-ref ref = "stdout" />                < appender-ref ref = "RollingFile" />            
       

因为测试时直接在 Eclipse 或控制台下执行,在未定义 catalina.home 的情况下,一运行就会在当前目录下生成 catalina.home_IS_UNDEFINED 目录,其中有 logs 子目录,再才是 unmi-2014-05-19.log 这个日志文件。

logback-variable-default-value

搜索了网上关于默认值的解决方案,有说在 logback.xml 中写条件表达式,例如:

< if condition = "property('catalina.home')==null" >            < then >                < fileNamePattern >logs/unmi-%d{yyyy-MM-dd}.log
            
            < else >                < fileNamePattern >${catalina.home}/logs/unmi-%d{yyyy-MM-dd}.log
            
       

参考:  和 。

上面的 if-then-else 是有问题的 The FileNamePattern option must be set before using TimeBasedRollingPolicy,需要把 if 的覆盖范围扩大,不过试了也不怎么爽。

回到  IS_UNDEFINED, 它总是有来头的,搜索源代码可找到它出现在 :

final static String _IS_UNDEFINED = "_IS_UNDEFINED";

本文原始链接 , 来自 

还有一处未被使用,这样就有突破口了,再跟踪代码,找到 logback 是怎么取到相对应变量值的 ,handleVariable 方法代码片断:

 
if (n.defaultPart ==  null ) {          stringBuilder.append(key + CoreConstants.UNDEFINED_PROPERTY_SUFFIX);          cycleCheckStack.pop();          return ;       }        Node defaultPart = (Node) n.defaultPart;       StringBuilder defaultPartBuffer =  new StringBuilder();       compileNode(defaultPart, defaultPartBuffer, cycleCheckStack);       cycleCheckStack.pop();       String defaultVal = defaultPartBuffer.toString();       stringBuilder.append(defaultVal);

注:从这个类的 lookupKey(String key) 方法中可以知道  logback 从四个地方取变量值,分别是 propertyContainer0, propertyContrainer1, System, Evn,前两不知道没关系,后两个我们明白先从 System 属性,没有再从环境变量中取。

上面我们会想到  除了有 payload 还有一个 defaultPart 用了设定默认值部分。至于默认值怎么设置,猜测试是 ${catalina.home:abc},没用,不过别急,logback  的测试用例告诉了我们表达式的写法。

见 , 看到这样写代默认值的表达式

${v2:-toto}        //格式是 ${变量名:-默认值},光有冒号还不够,再加条短线后面才是默认值

所以学习它后,前面的日志文件名配置部分就写成

    
       < fileNamePattern >${catalina.home:-.}/logs/unmi-%d{yyyy-MM-dd}.log

        < configuration >             < appender name = "stdout" class = "ch.qos.logback.core.ConsoleAppender" >                < encoder charset = "UTF-8" >                    < pattern >%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
                
            
             < appender name = "RollingFile" class = "ch.qos.logback.core.rolling.RollingFileAppender" >                < rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy" >                    < fileNamePattern >${catalina.home:-.}/logs/unmi-%d{yyyy-MM-dd}.log
                    < maxHistory >10
                
                 < encoder >                    < pattern >%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n
                
            
             < root level = "DEBUG" >                < appender-ref ref = "stdout" />                < appender-ref ref = "RollingFile" />            
       

多看看这 OptionHelperTest 测试用例,还能发现默认值也能用变量,如

${B:-${A}}

转载于:https://my.oschina.net/91jason/blog/364789

你可能感兴趣的文章
一份关于数据科学家应该具备的技能清单
查看>>
机器学习实战_一个完整的程序(一)
查看>>
Web框架的常用架构模式(JavaScript语言)
查看>>
如何用UPA优化性能?先读懂这份报告!
查看>>
这些Java面试题必须会-----鲁迅
查看>>
Linux 常用命令
查看>>
NodeJS 工程师必备的 8 个工具
查看>>
CSS盒模型
查看>>
ng2路由延时加载模块
查看>>
使用GitHub的十个最佳实践
查看>>
脱离“体验”和“安全”谈盈利的游戏运营 都是耍流氓
查看>>
慎用!BLEU评价NLP文本输出质量存在严重问题
查看>>
基于干净语言和好奇心的敏捷指导
查看>>
Node.js 2017企业用户调查结果发布
查看>>
“软”苹果水逆的一周:杂志服务崩溃,新机型遭泄露,芯片首架离职
查看>>
JAVA的优势就是劣势啊!
查看>>
ELK实战之logstash部署及基本语法
查看>>
帧中继环境下ospf的使用(点到点模式)
查看>>
BeanShell变量和方法的作用域
查看>>
LINUX下防恶意扫描软件PortSentry
查看>>