﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-星游领地</title><link>http://www.blogjava.net/watchzerg/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 12 May 2026 11:37:26 GMT</lastBuildDate><pubDate>Tue, 12 May 2026 11:37:26 GMT</pubDate><ttl>60</ttl><item><title>logback_doc_manual_01_introduction_to_logback</title><link>http://www.blogjava.net/watchzerg/archive/2014/07/13/415757.html</link><dc:creator>王星游</dc:creator><author>王星游</author><pubDate>Sun, 13 Jul 2014 11:04:00 GMT</pubDate><guid>http://www.blogjava.net/watchzerg/archive/2014/07/13/415757.html</guid><wfw:comment>http://www.blogjava.net/watchzerg/comments/415757.html</wfw:comment><comments>http://www.blogjava.net/watchzerg/archive/2014/07/13/415757.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/watchzerg/comments/commentRss/415757.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/watchzerg/services/trackbacks/415757.html</trackback:ping><description><![CDATA[<div>最近把logback的文档翻了一遍，弄了些半笔记半翻译的文字出来，本来打算仅仅存在evernote里的，但还是费点功夫发出来吧，可能为别人提供些参考。</div><div>看我这文章标题起的，对搜索引擎拆词极端的不友好，哇哈哈哈哈&#8230;&#8230;<br /></div><div></div><div>链接：</div><div>slf4j笔记</div><div><a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415746.html">http://www.blogjava.net/watchzerg/archive/2014/07/13/415746.html</a></div><div>logback_doc_manual_01_introduction_to_logback<br /><div><a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415757.html">http://www.blogjava.net/watchzerg/archive/2014/07/13/415757.html</a></div></div><div></div><div>logback_doc_manual_02_architecture</div><div><a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415747.html">http://www.blogjava.net/watchzerg/archive/2014/07/13/415747.html</a></div><div>logback_doc_manual_03_configuration</div><div><a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415748.html">http://www.blogjava.net/watchzerg/archive/2014/07/13/415748.html</a></div><div>logback_doc_manual_04_appenders</div><div><a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415749.html">http://www.blogjava.net/watchzerg/archive/2014/07/13/415749.html</a></div><div>logback_doc_manual_05_encoders</div><div><a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415750.html">http://www.blogjava.net/watchzerg/archive/2014/07/13/415750.html</a></div><div>logback_doc_manual_06_layouts</div><div><a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415751.html">http://www.blogjava.net/watchzerg/archive/2014/07/13/415751.html</a></div><div>logback_doc_manual_07_filters</div><div><a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415752.html">http://www.blogjava.net/watchzerg/archive/2014/07/13/415752.html</a></div><div>logback_doc_manual_08_mapped_diagnostic_contexts</div><div><a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415753.html">http://www.blogjava.net/watchzerg/archive/2014/07/13/415753.html</a></div><div>logback_doc_manual_09_logging_separation</div><div><a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415754.html">http://www.blogjava.net/watchzerg/archive/2014/07/13/415754.html</a></div><div>logback_eclipse_plugin_beagle</div><div><a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415755.html">http://www.blogjava.net/watchzerg/archive/2014/07/13/415755.html</a></div><div>logback_config_demo</div><div><a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415756.html">http://www.blogjava.net/watchzerg/archive/2014/07/13/415756.html<br /><br /></a></div><div></div><div></div><div>logback-demo项目：</div><div>&nbsp; &nbsp; &nbsp;http://logback.qos.ch/demo.html</div><div>&nbsp; &nbsp; &nbsp;遇到有问题的，就把这个项目拔下来看看。</div><div>&nbsp; &nbsp; &nbsp;例如CyclicBufferAppender，在文档里貌似没有描述过，在appender这一章也找不到。</div><div>&nbsp; &nbsp; &nbsp;示例项目里，实现&#8220;在web页面上查看最近512条日志&#8221;，是手写的Servlet：ViewLastLog.java</div><div></div><div>logback-access:</div><div>&nbsp; &nbsp; &nbsp;http://logback.qos.ch/access.html&nbsp;</div><div>&nbsp; &nbsp; &nbsp;可以集成到jetty或者tomcat中，提供强大的http-access日志。</div><div>&nbsp; &nbsp; &nbsp;依赖于logback-core（不依赖slf4j和logback-classic）</div><div>&nbsp; &nbsp; &nbsp;如果与tomcat6.x集成，可能会崩溃哦～，建议用tomcat7.x。实在想用tomcat6.x，可以用logback-access版本0.9.30</div><div>&nbsp; &nbsp; &nbsp;可以拦截和打印每个http的request和response。</div><div></div><div>&nbsp; &nbsp; &nbsp;Apache Tomcat中的日志是通过借助Apache Commons Logging库实现的，这个库对不同的日志框架做了一个简单包装。使Tomcat有能力记录跨日志级别的多层次日志，而且不需要依赖特定的日志框架。</div><div>&nbsp; &nbsp; &nbsp;从Tomcat 6.0开始，Tomcat引入一个对Apache Commons Logging重命名包后的私有实现，从而允许web应用使用他们自己独立的原Apache Commons Logging库的lib包。在默认的发布包中，Apache Commons Logging私有实现是简单被硬编码到java.util.logging框架。</div><div>&nbsp; &nbsp; &nbsp;实际使用中，通过配置org.apache.catalina.valves.AccessLogValve可以让tomcat打印访问日志（默认禁用掉的）</div><img src ="http://www.blogjava.net/watchzerg/aggbug/415757.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/watchzerg/" target="_blank">王星游</a> 2014-07-13 19:04 <a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415757.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>logback_config_demo</title><link>http://www.blogjava.net/watchzerg/archive/2014/07/13/415756.html</link><dc:creator>王星游</dc:creator><author>王星游</author><pubDate>Sun, 13 Jul 2014 11:03:00 GMT</pubDate><guid>http://www.blogjava.net/watchzerg/archive/2014/07/13/415756.html</guid><wfw:comment>http://www.blogjava.net/watchzerg/comments/415756.html</wfw:comment><comments>http://www.blogjava.net/watchzerg/archive/2014/07/13/415756.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/watchzerg/comments/commentRss/415756.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/watchzerg/services/trackbacks/415756.html</trackback:ping><description><![CDATA[我自己常用的一个logback配置框架，有需要再在上面添加：<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">&lt;?</span><span style="color: #FF00FF; ">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="color: #0000FF; ">?&gt;</span><br /><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;&lt;configuration&nbsp;scan="true"&nbsp;scanPeriod="60&nbsp;seconds"&gt;&nbsp;&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">configuration</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;print&nbsp;configuration&nbsp;status&nbsp;on&nbsp;console&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">statusListener&nbsp;</span><span style="color: #FF0000; ">class</span><span style="color: #0000FF; ">="ch.qos.logback.core.status.OnConsoleStatusListener"</span><span style="color: #0000FF; ">/&gt;</span><br /><span style="color: #008080; ">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="color: #008080; ">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;Beagle:&nbsp;eclipse&nbsp;plugin&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">consolePlugin&nbsp;</span><span style="color: #0000FF; ">/&gt;</span><br /><span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;log&nbsp;path&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">property&nbsp;</span><span style="color: #FF0000; ">name</span><span style="color: #0000FF; ">="LOG_PATH"</span><span style="color: #FF0000; ">&nbsp;value</span><span style="color: #0000FF; ">="d:/log"</span><span style="color: #FF0000; ">&nbsp;</span><span style="color: #0000FF; ">/&gt;</span><br /><span style="color: #008080; ">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;&lt;property&nbsp;resource="resource1.properties"&nbsp;/&gt;&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;console&nbsp;appender&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">appender&nbsp;</span><span style="color: #FF0000; ">name</span><span style="color: #0000FF; ">="STDOUT"</span><span style="color: #FF0000; ">&nbsp;class</span><span style="color: #0000FF; ">="ch.qos.logback.core.ConsoleAppender"</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">16</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">encoder</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">pattern</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%d{HH:mm:ss.SSS}&nbsp;[%t]&nbsp;%-5p&nbsp;&nbsp;%c{1}&nbsp;-&nbsp;%m%n<br /><span style="color: #008080; ">19</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">pattern</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">encoder</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">21</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">appender</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="color: #008080; ">23</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;default&nbsp;appender&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">appender&nbsp;</span><span style="color: #FF0000; ">name</span><span style="color: #0000FF; ">="COMMON-DEFAULT-APPENDER"</span><span style="color: #FF0000; ">&nbsp;class</span><span style="color: #0000FF; ">="ch.qos.logback.core.rolling.RollingFileAppender"</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">25</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">File</span><span style="color: #0000FF; ">&gt;</span>${LOG_PATH}/common-default.log<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">File</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">26</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">rollingPolicy&nbsp;</span><span style="color: #FF0000; ">class</span><span style="color: #0000FF; ">="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">27</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">FileNamePattern</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">28</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${LOG_PATH}/common-default.%d.log.gz<br /><span style="color: #008080; ">29</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;${LOG_PATH}/%d{yyyy-MM,aux}/common-default.%d.log.gz&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">30</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">FileNamePattern</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">31</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">rollingPolicy</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">32</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">encoder</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">33</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Pattern</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">34</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%d&nbsp;[%t]&nbsp;%-5p&nbsp;&nbsp;%c{1}&nbsp;-&nbsp;%m%n<br /><span style="color: #008080; ">35</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Pattern</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">36</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">encoder</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">37</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;&lt;immediateFlush&gt;false&lt;/immediateFlush&gt;&nbsp;&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">38</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">appender</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">39</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="color: #008080; ">40</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;error&nbsp;appender&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">41</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">appender&nbsp;</span><span style="color: #FF0000; ">name</span><span style="color: #0000FF; ">="COMMON-ERROR-APPENDER"</span><span style="color: #FF0000; ">&nbsp;class</span><span style="color: #0000FF; ">="ch.qos.logback.core.rolling.RollingFileAppender"</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">42</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">filter&nbsp;</span><span style="color: #FF0000; ">class</span><span style="color: #0000FF; ">="ch.qos.logback.classic.filter.ThresholdFilter"</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">43</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">level</span><span style="color: #0000FF; ">&gt;</span>ERROR<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">level</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">44</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">filter</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">45</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">File</span><span style="color: #0000FF; ">&gt;</span>${LOG_PATH}/common-error.log<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">File</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">46</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">rollingPolicy&nbsp;</span><span style="color: #FF0000; ">class</span><span style="color: #0000FF; ">="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">47</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">FileNamePattern</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">48</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${LOG_PATH}/common-error.%d.log.gz<br /><span style="color: #008080; ">49</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;${LOG_PATH}/%d{yyyy-MM,aux}/common-error.%d.log.gz&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">50</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">FileNamePattern</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">51</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">rollingPolicy</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">52</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">encoder</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">53</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">Pattern</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">54</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%d&nbsp;[%t]&nbsp;%-5p&nbsp;&nbsp;%c{1}&nbsp;-&nbsp;%m%n<br /><span style="color: #008080; ">55</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">Pattern</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">56</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">encoder</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">57</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;&lt;immediateFlush&gt;false&lt;/immediateFlush&gt;&nbsp;&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">58</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">appender</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">59</span>&nbsp;<br /><span style="color: #008080; ">60</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">&lt;!--</span><span style="color: #008000; ">&nbsp;root&nbsp;logger&nbsp;</span><span style="color: #008000; ">--&gt;</span><br /><span style="color: #008080; ">61</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">root</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">62</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">level&nbsp;</span><span style="color: #FF0000; ">value</span><span style="color: #0000FF; ">="DEBUG"</span><span style="color: #0000FF; ">/&gt;</span><br /><span style="color: #008080; ">63</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">appender-ref&nbsp;</span><span style="color: #FF0000; ">ref</span><span style="color: #0000FF; ">="STDOUT"</span><span style="color: #0000FF; ">/&gt;</span><br /><span style="color: #008080; ">64</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">appender-ref&nbsp;</span><span style="color: #FF0000; ">ref</span><span style="color: #0000FF; ">="COMMON-DEFAULT-APPENDER"</span><span style="color: #0000FF; ">/&gt;</span><br /><span style="color: #008080; ">65</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">appender-ref&nbsp;</span><span style="color: #FF0000; ">ref</span><span style="color: #0000FF; ">="COMMON-ERROR-APPENDER"</span><span style="color: #0000FF; ">/&gt;</span><br /><span style="color: #008080; ">66</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">root</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">67</span>&nbsp;<br /><span style="color: #008080; ">68</span>&nbsp;<span style="color: #0000FF; ">&lt;/</span><span style="color: #800000; ">configuration</span><span style="color: #0000FF; ">&gt;</span><br /><span style="color: #008080; ">69</span>&nbsp;</div><img src ="http://www.blogjava.net/watchzerg/aggbug/415756.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/watchzerg/" target="_blank">王星游</a> 2014-07-13 19:03 <a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415756.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>logback_eclipse_plugin_beagle</title><link>http://www.blogjava.net/watchzerg/archive/2014/07/13/415755.html</link><dc:creator>王星游</dc:creator><author>王星游</author><pubDate>Sun, 13 Jul 2014 11:01:00 GMT</pubDate><guid>http://www.blogjava.net/watchzerg/archive/2014/07/13/415755.html</guid><wfw:comment>http://www.blogjava.net/watchzerg/comments/415755.html</wfw:comment><comments>http://www.blogjava.net/watchzerg/archive/2014/07/13/415755.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/watchzerg/comments/commentRss/415755.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/watchzerg/services/trackbacks/415755.html</trackback:ping><description><![CDATA[<div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"><a href="http://logback.qos.ch/beagle/index.html">http://logback.qos.ch/beagle/index.html</a></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">先安装依赖插件：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">http://download.eclipse.org/technology/nebula/snapshot &nbsp; &nbsp;(注意这个是稳定的release版的地址，只需要安装&#8220;Nubula Release Individual Widgets&#8221;中的&#8220;Nebula Grid Feature&#8221;即可)</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">再安装logback-beagle插件：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">http://logback.qos.ch/p2/ ( "Logback" "Logback Beagle" "SLF4J"这三个都得选)</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">完成后按&#8220;alt-shift-Q,Q&#8221;弹出view选择框，找到beagle打开即可（之后需要在logback-test.xml里配置&lt;consolePlugin /&gt;，参见logback文档）。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">在logback-test.xml里加上配置&lt;consolePlugin /&gt;即可</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;configuration debug="true"&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp;&lt;!-- sends logs to logback-beagle --&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp;&lt;consolePlugin /&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;/configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&#8212;&#8212;实际上这个配置会自动创建一个SocketAppender，并把日志发到本机的4321端口。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">单击停止滚动，双击开始滚动</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">右键菜单可以跳转到调用行，也可以查看最多8行调用栈</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">配置：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">eclipse的preference里:</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;Run/Debug -&nbsp;Beagle</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 在这里可以自定义控制台输出的pattern</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;General - Appearance - Colors and Fonts</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 可以单独对Beagle设置字体</div></div><img src ="http://www.blogjava.net/watchzerg/aggbug/415755.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/watchzerg/" target="_blank">王星游</a> 2014-07-13 19:01 <a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415755.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>logback_doc_manual_09_logging_separation</title><link>http://www.blogjava.net/watchzerg/archive/2014/07/13/415754.html</link><dc:creator>王星游</dc:creator><author>王星游</author><pubDate>Sun, 13 Jul 2014 11:00:00 GMT</pubDate><guid>http://www.blogjava.net/watchzerg/archive/2014/07/13/415754.html</guid><wfw:comment>http://www.blogjava.net/watchzerg/comments/415754.html</wfw:comment><comments>http://www.blogjava.net/watchzerg/archive/2014/07/13/415754.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/watchzerg/comments/commentRss/415754.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/watchzerg/services/trackbacks/415754.html</trackback:ping><description><![CDATA[<div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"><a href="http://logback.qos.ch/manual/loggingSeparation.html">http://logback.qos.ch/manual/loggingSeparation.html</a></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">主要处理多个应用程序运行在同一个web容器，并且每个应用使用各自独立的日志环境。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&#8212;&#8212;想想一个tomcat运行了多个项目&#8212;&#8212;也就是&#8220;一个JVM，多个ClassLoader，每个ClassLoader拥有自己独立的Logger Context&#8221;的问题。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Context Selectors</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;调用LoggerFactory.getLogger("foo")的时候，会要求SLF4J绑定一个ILoggerFactory，如果SLF4J使用的是logback，那么&#8220;绑定ILoggerFactory&#8221;的方法，会代理给一个ContextSelector实例，该实例会根据情况返回最合适的LoggerContext对象&#8212;&#8212;这个对象实现了ILoggerFactory接口。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;默认总是返回DefaultContextSelector，可以在系统属性里通过logback.ContextSelector属性指定自己的类。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">ContextJNDISelector</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;根据JNDI查找Selector&#8212;&#8212;这样可以在各个项目的web.xml里配置自己的JNDI环境变量。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;为了在单个web项目重启和关闭的时候，对应的logger Context可以被回收，最好配置ContextDetachingSCL监听器</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;不过每次获取logger都查找JNDI太慢，可以配置LoggerContextFilter过滤器来避免&#8212;&#8212;会在每个http请求到来的时候把logger context放在线程内部，从而允许之后跳过JNDI搜索。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;此时最好把logger全声明成static的，减少logger的获取总次数。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Taming static references in shared libraries</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;如果有一个类属于共享包，被两个web项目同时引用</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1，当这个类使用非静态logger时，一切良好，来自两个web项目的调用，会返回各自的logger context。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2，当这个类使用静态logger时，会错误的返回首次调用它的web项目的logger context&#8212;&#8212;对这个问题ContextJNDISelector无能为力（eluded a solution for eons... 哈哈哈哈）</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;对于上述的&#8220;来自共类的静态logger，获取不同的logger context&#8221;的问题，有几个的办法：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1，共享类改成非静态logger&#8212;&#8212;一般不现实，因为共享类的源码往往不受项目控制。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2，把共享类挪到web项目里&#8212;&#8212;也够呛，一个两个类还好，那么多第三方依赖咋弄？</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3，所以还有一种取巧的办法：用SiftingAppender，根据JNDI信息把不同的日志分别输出到不同的文件里去（logback提供了JNDIBasedContextDiscriminator帮助做这事儿）&#8212;&#8212;也就是说，两个项目分享同一个logger，等到其关联的appender需要把event输出到文件时，再临时决定输出到哪个文件。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;上述第3种方法有一个问题：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;假如项目A和项目B都使用共享包S。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 项目A启动并调用S的时候，就已经把S的logger context设置为A了，日志会写入A.log中。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; B启动并调用S的时候logger contex依然是A（不过因为配置了SiftingAppender的存在，B的日志依然可以写到正确的B.log中）</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#8212;&#8212;也就是说，共享logger的问题并没有实质解决，这个logger还是只能属于A或者B其中之一，只不过logger在写日志前根据MDC里的JNDI可以将日志写到正确的文件中去。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;而初始化了两个不同的logger context都指向B.log，存在多个线程写同一个文件的不安全问题&#8212;&#8212;需要对appender配置prudent参数来解决（会影响性能）。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;（正常使用都是一个web container部署一个web项目，很少遇到上述情况。这部分文档看的很蛋疼&#8230;&#8230;）</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div></div><img src ="http://www.blogjava.net/watchzerg/aggbug/415754.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/watchzerg/" target="_blank">王星游</a> 2014-07-13 19:00 <a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415754.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>logback_doc_manual_07_filters</title><link>http://www.blogjava.net/watchzerg/archive/2014/07/13/415752.html</link><dc:creator>王星游</dc:creator><author>王星游</author><pubDate>Sun, 13 Jul 2014 10:59:00 GMT</pubDate><guid>http://www.blogjava.net/watchzerg/archive/2014/07/13/415752.html</guid><wfw:comment>http://www.blogjava.net/watchzerg/comments/415752.html</wfw:comment><comments>http://www.blogjava.net/watchzerg/archive/2014/07/13/415752.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/watchzerg/comments/commentRss/415752.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/watchzerg/services/trackbacks/415752.html</trackback:ping><description><![CDATA[<div><a href="http://logback.qos.ch/manual/filters.html" style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">http://logback.qos.ch/manual/filters.html</a><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">logback-classic有两种filter：Regular filters和turbo filters，挂在appender上</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Regular filters</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;只有一个decide()方法，返回DENY, NEUTRAL or ACCEPT</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">LevelFilter</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;filter class="ch.qos.logback.classic.filter.LevelFilter"&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &lt;level&gt;INFO&lt;/level&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &lt;onMatch&gt;ACCEPT&lt;/onMatch&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &lt;onMismatch&gt;DENY&lt;/onMismatch&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;/filter&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">ThresholdFilter</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;高于或等于指定日志级别的记录，会返回NEUTRAL</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;filter class="ch.qos.logback.classic.filter.ThresholdFilter"&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &lt;level&gt;INFO&lt;/level&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;/filter&gt;&nbsp; &nbsp; &nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">EvaluatorFilter</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;EventEvaluator的实现判断某个条件是否满足。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;GEventEvaluator</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 接受groovy语法的布尔表达式作为判断条件，需要依赖Groovy运行时，表达式语句在配置的时候完成编译。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logback会自动将目标事件作为一个变量传进来，可以用&#8220;event&#8221;或者&#8220;e&#8221;来引用。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;TRACE, DEBUG, INFO, WARN and ERROR这些级别也引入了，所以可以这样判断相等：&nbsp;"event.level == DEBUG" 。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 其他比较符，大于小于，需要转换成int再比较。</div><blockquote style="color: #000000; font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&nbsp; &nbsp; &lt;filter class="ch.qos.logback.core.filter.EvaluatorFilter"&gt; &nbsp; &nbsp; &nbsp;</div><div>&nbsp; &nbsp; &nbsp; &lt;evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator"&gt;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &lt;expression&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;e.level.toInt() &gt;= WARN.toInt() &amp;amp;&amp;amp; &nbsp;&lt;!-- Stands for &amp;&amp; in XML --&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;!(e.mdc?.get("req.userAgent") =~ /Googlebot|msnbot|Yahoo/ )</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &lt;/expression&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;/evaluator&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;OnMismatch&gt;DENY&lt;/OnMismatch&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;OnMatch&gt;NEUTRAL&lt;/OnMatch&gt;</div><div>&nbsp; &nbsp; &lt;/filter&gt;</div></blockquote><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;JaninoEventEvaluator</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 使用java表达式，使用上比基于groovy的GEventEvaluator繁琐，但执行速度更快。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 详情略。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Matchers</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;执行上面的过滤器时，可以调用String.matches()方法，但代价是每次需要重编译一个正则Pattern对象。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;所以可以预先定义和编译一个，以便复用。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;详情略。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">TurboFilters</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;跟普通过滤器功能一样，但是：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1，TurboFilter是跟logging context关联的，而不是跟appender关联。作用域更大。不仅在指定appender使用时，而且在每次logging请求时都会被调用。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2，他们是在LoggingEvent对象创建之前被调用，过滤时不需要event实例做参数，所以性能更高（因为在event创建之前就已经执行过滤了）。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;内置了一些TurboFilter：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;MDCFilter &nbsp; &nbsp; 测试指定的值是否存在于MDC中</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;DynamicThresholdFilter &nbsp; &nbsp; 基于MDC的key和level来限流</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;MarkerFilter &nbsp; &nbsp; 测试指定的marker是否出现在请求中</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DuplicateMessageFilter</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;自动过滤相同的消息。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 使用简单的字符串比对&#8212;&#8212;即使两个字符串基本相同，相差一两个字母：也会被认为不同。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 仅比较raw字符串，用{}转义过的字符串不去比较。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 可以通过AllowedRepetitions设置允许的重复上限，超过上限的会被抛弃。默认大小为5</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 需要通过一个内部cache来保存老的消息以便判断，可以通过CacheSize设置缓存大小，默认100.</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">在evaluator的expression里，将logging时间与项目启动时间对比，可以控制仅输出&#8220;项目启动后20秒内的某类型日志&#8221;&#8212;&#8212;这个对于&#8220;确认某个定时任务在启动时是运行状态&#8221;很有用，例如：</div><blockquote style="color: #000000; font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&lt;filter class="ch.qos.logback.core.filter.EvaluatorFilter"&gt;</div><div>&nbsp; &lt;evaluator name="loggingTaskEval"&gt;</div><div>&nbsp; &nbsp; &lt;expression&gt;</div><div>&nbsp; &nbsp; &nbsp; logger.getName().contains("LoggingTask") &amp;amp;&amp;amp;</div><div>&nbsp; &nbsp; &nbsp; message.contains("Howdydy-diddly-ho") &amp;amp;&amp;amp;</div><div>&nbsp; &nbsp; &nbsp; (timeStamp - event.getStartTime()) &gt;= 20000</div><div>&nbsp; &nbsp; &lt;/expression&gt;</div><div>&nbsp; &lt;/evaluator&gt;</div><div>&nbsp; &lt;OnMatch&gt;DENY&lt;/OnMatch&gt;</div><div>&lt;/filter&gt;</div></blockquote><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div></div><img src ="http://www.blogjava.net/watchzerg/aggbug/415752.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/watchzerg/" target="_blank">王星游</a> 2014-07-13 18:59 <a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415752.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>logback_doc_manual_08_mapped_diagnostic_contexts</title><link>http://www.blogjava.net/watchzerg/archive/2014/07/13/415753.html</link><dc:creator>王星游</dc:creator><author>王星游</author><pubDate>Sun, 13 Jul 2014 10:59:00 GMT</pubDate><guid>http://www.blogjava.net/watchzerg/archive/2014/07/13/415753.html</guid><wfw:comment>http://www.blogjava.net/watchzerg/comments/415753.html</wfw:comment><comments>http://www.blogjava.net/watchzerg/archive/2014/07/13/415753.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/watchzerg/comments/commentRss/415753.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/watchzerg/services/trackbacks/415753.html</trackback:ping><description><![CDATA[<div><a href="http://logback.qos.ch/manual/mdc.html" style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">http://logback.qos.ch/manual/mdc.html</a><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">MDC（注意这个类在org.slf4j包里）</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;基于&#8220;多个线程同步处理多个请求&#8221;的假设来设计的，上下文信息记录。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#8212;&#8212;子线程会自动拷贝双亲线程的这类信息。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#8212;&#8212;如果没有附加处理的话，放入线程池处理的任务会丢失MDC上下文。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 该设计假定向MDC放数据的速度不会太快。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">最常用的web场景，是集成在一个servlet的Filter中，在请求时载入MDC信息，doFilter处理完成后卸载MDC信息。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&#8212;&#8212;最好在&#8220;验证用户&#8221;这个Filter之后（或者之中）进行，这样可以把用户验证信息（包括但不限于用户名）写入MDC。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">交给线程池处理(submit)之前：MDC.getCopyOfContextMap()，把返回的map当作参数传给任务线程</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">线程池处理代码的第一行：MDC.setContextMapValues()，把接到的map参数设置到本线程的MDC中（别忘了最后清除掉）</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">MDCInsertingServletFilter</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;将web请求常用信息设置到MDC中：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req.remoteHost as returned by the getRemoteHost() method</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req.xForwardedFor value of the "X-Forwarded-For" header</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req.requestURI &nbsp; &nbsp; &nbsp; as returned by getRequestURI() method</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req.requestURL as returned by getRequestURL() method</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req.queryString as returned by getQueryString() method</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req.userAgent &nbsp; &nbsp; &nbsp;value of the "User-Agent" header</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;web.xml中的配置</div><blockquote style="color: #000000; font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&lt;filter&gt;</div><div>&nbsp; &lt;filter-name&gt;MDCInsertingServletFilter&lt;/filter-name&gt;</div><div>&nbsp; &lt;filter-class&gt;</div><div>&nbsp; &nbsp; ch.qos.logback.classic.helpers.MDCInsertingServletFilter</div><div>&nbsp; &lt;/filter-class&gt;</div><div>&lt;/filter&gt;</div><div>&lt;filter-mapping&gt;</div><div>&nbsp; &lt;filter-name&gt;MDCInsertingServletFilter&lt;/filter-name&gt;</div><div>&nbsp; &lt;url-pattern&gt;/*&lt;/url-pattern&gt;</div><div>&lt;/filter-mapping&gt;&nbsp;</div></blockquote><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;注意filter顺序，经过该filter过滤之后，其它filter才能打印出MDC信息（特别是struts之类依赖filter处理主逻辑的）</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;使用例子：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;%X{req.remoteHost} %X{req.requestURI}%n%d - %m%n</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&#8212;&#8212;其实没多大意义，还是自己写这个filter，挑选自己的有效信息比较好。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div></div><img src ="http://www.blogjava.net/watchzerg/aggbug/415753.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/watchzerg/" target="_blank">王星游</a> 2014-07-13 18:59 <a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415753.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>logback_doc_manual_05_encoders</title><link>http://www.blogjava.net/watchzerg/archive/2014/07/13/415750.html</link><dc:creator>王星游</dc:creator><author>王星游</author><pubDate>Sun, 13 Jul 2014 10:58:00 GMT</pubDate><guid>http://www.blogjava.net/watchzerg/archive/2014/07/13/415750.html</guid><wfw:comment>http://www.blogjava.net/watchzerg/comments/415750.html</wfw:comment><comments>http://www.blogjava.net/watchzerg/archive/2014/07/13/415750.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/watchzerg/comments/commentRss/415750.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/watchzerg/services/trackbacks/415750.html</trackback:ping><description><![CDATA[<div><a href="http://logback.qos.ch/manual/encoders.html" style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">http://logback.qos.ch/manual/encoders.html</a><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Encoder</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;负责将事件对象转换为字节数组.</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;目前只有PatternLayoutEncoder是唯一有用的Encoder。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">LayoutWrappingEncoder</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;兼容的包装器（因为老版本的logback是跳过Encoder直接依赖Layout的）</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">PatternLayoutEncoder</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;针对PatternLayout（最常用的layout）定制的兼容包装器。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;immediateFlush属性：是否将日志立刻写入磁盘，默认为true。将这个选项设为false可以达高4到5倍的吞吐量。</div><blockquote style="color: #000000; font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&lt;appender name="FILE" class="ch.qos.logback.core.FileAppender"&gt;&nbsp;</div><div>&nbsp; &lt;file&gt;foo.log&lt;/file&gt;</div><div>&nbsp; &lt;encoder&gt;</div><div>&nbsp; &nbsp; &lt;pattern&gt;%d %-5level [%thread] %logger{0}: %msg%n&lt;/pattern&gt;</div><div>&nbsp; &nbsp; &lt;!-- this quadruples logging throughput --&gt;</div><div>&nbsp; &nbsp;&nbsp;<strong>&lt;immediateFlush&gt;false&lt;/immediateFlush&gt;</strong></div><div>&nbsp; &lt;/encoder&gt;&nbsp;</div><div>&lt;/appender&gt;</div></blockquote><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;outputPatternAsHeader属性：在日志文件的顶部输出一行字符串样式，默认flase。</div><blockquote style="color: #000000; font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&lt;appender name="FILE" class="ch.qos.logback.core.FileAppender"&gt;&nbsp;</div><div>&nbsp; &lt;file&gt;foo.log&lt;/file&gt;</div><div>&nbsp; &lt;encoder&gt;</div><div>&nbsp; &nbsp; &lt;pattern&gt;%d %-5level [%thread] %logger{0}: %msg%n&lt;/pattern&gt;</div><div>&nbsp; &nbsp;&nbsp;<strong>&lt;outputPatternAsHeader&gt;true&lt;/outputPatternAsHeader&gt;</strong></div><div>&nbsp; &lt;/encoder&gt;&nbsp;</div><div>&lt;/appender&gt;</div></blockquote><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;输出结果：</div><blockquote style="color: #000000; font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>#logback.classic pattern: %d [%thread] %-5level %logger{36} - %msg%n</div><div>2012-04-26 14:54:38,461 [main] DEBUG com.foo.App - Hello world</div><div>2012-04-26 14:54:38,461 [main] DEBUG com.foo.App - Hi again</div></blockquote><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div></div><img src ="http://www.blogjava.net/watchzerg/aggbug/415750.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/watchzerg/" target="_blank">王星游</a> 2014-07-13 18:58 <a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415750.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>logback_doc_manual_06_layouts</title><link>http://www.blogjava.net/watchzerg/archive/2014/07/13/415751.html</link><dc:creator>王星游</dc:creator><author>王星游</author><pubDate>Sun, 13 Jul 2014 10:58:00 GMT</pubDate><guid>http://www.blogjava.net/watchzerg/archive/2014/07/13/415751.html</guid><wfw:comment>http://www.blogjava.net/watchzerg/comments/415751.html</wfw:comment><comments>http://www.blogjava.net/watchzerg/archive/2014/07/13/415751.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/watchzerg/comments/commentRss/415751.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/watchzerg/services/trackbacks/415751.html</trackback:ping><description><![CDATA[<div><a href="http://logback.qos.ch/manual/layouts.html" style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">http://logback.qos.ch/manual/layouts.html</a><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">PatternLayout</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;转换模式类似于C语言里的printf()。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">转移字符：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;c{length}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;lo{length}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;logger{length}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 其中的length代表输出的logger长度。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 设为0的话例外，仅输出最右边的logger名。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 其余情况会自动计算，尽量使得输出的总字符串长度小于指定长度&#8212;&#8212;但是，最右边的logger名称无论如何会完整保留，同时前面的每一级logger，最少会被精简到1个字符。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#8212;&#8212;%c{1}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;C{length}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;class{length}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 打印调用者的类名称，设置方法与上面一样。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 性能不高。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;contextName</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;cn</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 打印logger在event最初绑定的logger context的名称。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;d{pattern}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;date{pattern}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;d{pattern, timezone}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;date{pattern, timezone}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 输入日志时间，使用java.text.SimpleDateFormat的日期格式化方法。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 如果不指定日期格式，默认使用ISO8601，也就是2006-10-20 14:06:49,812这种形式。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#8212;&#8212;%d</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;F / file</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 输出java源文件的名称。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 性能不高。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;caller{depth}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;caller{depth, evaluator-1, ... evaluator-n}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 打印日志事件的调用堆栈。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 使用评估器evaluator决定是否打印。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;L</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;line</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 输出日志记录请求发起的行数。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 性能不高。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;m</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;msg</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;message</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 日志正文</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#8212;&#8212;%m</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;M</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;method</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 日志调用方法名。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 性能不高</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;n</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 操作系统对应的换行符</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#8212;&#8212;%n</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;p</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;le</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;level</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 日志等级</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;r</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;relative</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 应用程序启动到日志创建的相对时间</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;t</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;thread</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 线程名</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#8212;&#8212;%t</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;X{key:-defaultVal}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;mdc{key:-defaultVal}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MDC信息</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;ex{depth}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;exception{depth}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;throwable{depth}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;ex{depth, evaluator-1, ..., evaluator-n}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;exception{depth, evaluator-1, ..., evaluator-n}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;throwable{depth, evaluator-1, ..., evaluator-n}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 输出异常堆栈深度（如果有的话），默认full全部输出。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 可以指定的参数值：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;short：打印堆栈的第一行</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;full：打印所有行</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;任何数字：指定行数</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;使用评估器evaluator决定是否打印。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;xEx{depth}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;xException{depth}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;xThrowable{depth}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;xEx{depth, evaluator-1, ..., evaluator-n}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;xException{depth, evaluator-1, ..., evaluator-n}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;xThrowable{depth, evaluator-1, ..., evaluator-n}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 跟上面的类似，但是附加了包信息。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;如果包信息不准确（是猜测的），那么会自动在包信息前面附加一个&#8220;~&#8221;字符。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 如果在日志信息模式里，未指定任何异常格式，那么系统会自动在末尾加上一个%xEx。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;如果不想打印包信息（例如netbean里会出问题），那么在日志模式的末尾明确指定%ex即可，就会输出不包含包信息的堆栈。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;如果想不打印任何异常堆栈信息，可以使用%nopex。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#8212;&#8212;%xEx</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;nopex&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;nopexception&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 加上%nopex可以阻止系统自动在日志模式末尾添加%xEx&#8212;&#8212;也就是完全禁止异常堆栈打印。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;marker</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 输出关联的marker信息，如果marker多级关联，会都打印出来。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;property{key}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 输出key关联的属性&#8212;&#8212;定义在logger context或者system properties里面。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;replace(p){r, t}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 将p中的所有符合r正则的字符串，都替换成t。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 例如%replace(%logger%msg){'\.', '/'}，会将输出的logger和msg信息中的点号都替换成斜杠。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;rEx{depth}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;rootException{depth}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;rEx{depth, evaluator-1, ..., evaluator-n}&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;rootException{depth, evaluator-1, ..., evaluator-n}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 类似于xEx，也会打印异常的包信息，但是会将root exception打印到前面，跟普通的异常打印顺序是反着的。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;转义百分号： \%</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;正常情况下转义字符会被正确分割，但有些时候例外，例如%date%nHello，系统会解析%nHello失败。如果真的需要在%n后紧跟一个Hello，可以这样：%date%n{}Hello</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;我一般用这个：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;%d [%t] %-5p &nbsp;%c{1} - %m%n</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">------------------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Format modifiers</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;控制数据段的补齐。<br /> &nbsp; &nbsp; &nbsp;例如 %20.30logger&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 如果logger长度小于20，则从左边用空格补齐；如果logger长度大于30，则从开头(左边)切去多余字符。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 如果20或者30前面有负号，则左右颠倒。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;假如想给日志级别只输出1个字符（T,D,W,I,E），不需要自己写一个Converter，而只需要配置一下即可：%.-1level</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">转义选项：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;如果转义选项里面包含特殊字符（特别是在使用正则表达式的时候），例如大小括号、逗号、空格，那么可以用单引号或双引号括起来，例如：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;pattern&gt;%-5level - %replace(%msg){'\d{14,16}', 'XXXX'}%n&lt;/pattern&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&#8212;&#8212;这个可以把14到16位的数字（信用卡号）转换为XXXX。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">------------------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">括号的特殊作用：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;%-30(%d{HH:mm:ss.SSS} [%thread]) %-5level %logger{32} - %msg%n</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;可以让括号里的两个表达式联合起来按照30个字符补齐。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;括号可以用反斜杠转义：\(%d{HH:mm:ss.SSS} [%thread]\)</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">------------------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Coloring</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;着色，window需要引其它包，linux和mac os本身支持着色。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;样例：&lt;pattern&gt;[%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n&lt;/pattern&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; %highlight会将ERROR设为红色加粗，WARN设为红色，INFO设为蓝色，其余默认。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; %cyan会将logger名称设为蓝绿色。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">------------------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Evaluators</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;EventEvaluator类的实现，用来评估一个事件是否符合打印条件。</div><blockquote style="color: #000000; font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&nbsp; &lt;evaluator name="DISP_CALLER_EVAL"&gt;</div><div>&nbsp; &nbsp; &lt;expression&gt;logger.contains("chapters.layouts") &amp;amp;&amp;amp; \</div><div>&nbsp; &nbsp; &nbsp; message.contains("who calls thee")&lt;/expression&gt;</div><div>&nbsp; &lt;/evaluator&gt;</div><div></div><div>&nbsp; &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"&gt;&nbsp;</div><div>&nbsp; &nbsp; &lt;encoder&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;pattern&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; %-4relative [%thread] %-5level - %msg%n%caller{2, DISP_CALLER_EVAL}</div><div>&nbsp; &nbsp; &nbsp; &lt;/pattern&gt;</div><div>&nbsp; &nbsp; &lt;/encoder&gt;</div><div>&nbsp; &lt;/appender&gt;</div></blockquote><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;注意因为xml的关系，要用&amp;amp;转义&amp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;应用场景：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 例如，如果日志级别是WARN以上，并且logger是来自一个财务模块&#8212;&#8212;那么就打印caller信息。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;注意：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 在%caller转义模式中，当Evaluators返回true的时候才输出。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 在%ex转义模式中，当Evaluatorstrue的时候不输出。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;例如下面的配置，当异常对象为TestException时，不输出。</div><blockquote style="color: #000000; font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&nbsp; &lt;evaluator name="DISPLAY_EX_EVAL"&gt;</div><div>&nbsp; &nbsp; &lt;expression&gt;throwable != null &amp;amp;&amp;amp; throwable instanceof &nbsp;\</div><div>&nbsp; &nbsp; &nbsp; chapters.layouts.TestException&lt;/expression&gt;</div><div>&nbsp; &lt;/evaluator&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"&gt;</div><div>&nbsp; &nbsp; &lt;encoder&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;pattern&gt;%msg%n%ex{full, DISPLAY_EX_EVAL}&lt;/pattern&gt;</div><div>&nbsp; &nbsp; &lt;/encoder&gt;</div><div>&nbsp; &lt;/appender&gt;</div></blockquote><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">------------------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Creating a custom conversion specifier</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;略</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">------------------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">HTMLLayout</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;使用html表格来布局日志信息。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;可以使用普通的pattern转义符，但转义字符之前，不许用包括空格在内的任何字符分隔。</div><blockquote style="color: #000000; font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&nbsp; &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender"&gt;</div><div>&nbsp; &nbsp; &lt;encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"&gt;</div><div>&nbsp; &nbsp; &nbsp;&nbsp;<strong>&lt;layout class="ch.qos.logback.classic.html.HTMLLayout"&gt;</strong></div><div><strong>&nbsp; &nbsp; &nbsp; &nbsp; &lt;pattern&gt;%relative%thread%mdc%level%logger%msg&lt;/pattern&gt;</strong></div><div><strong>&nbsp; &nbsp; &nbsp; &lt;/layout&gt;</strong></div><div>&nbsp; &nbsp; &lt;/encoder&gt;</div><div>&nbsp; &nbsp; &lt;file&gt;test.html&lt;/file&gt;</div><div>&nbsp; &lt;/appender&gt;</div></blockquote><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;HTMLLayout会自动创建一个DefaultThrowableRenderer，将异常信息打印到完整的一行里。如果不想这样，可以指定一个NOPThrowableRenderer。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">用CSS指定表格的样式：略</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">该Layout最常见的用法是配合SMTPAppender，发送html格式的日志邮件。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">------------------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Logback access</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;略</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div></div><img src ="http://www.blogjava.net/watchzerg/aggbug/415751.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/watchzerg/" target="_blank">王星游</a> 2014-07-13 18:58 <a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415751.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>logback_doc_manual_04_appenders</title><link>http://www.blogjava.net/watchzerg/archive/2014/07/13/415749.html</link><dc:creator>王星游</dc:creator><author>王星游</author><pubDate>Sun, 13 Jul 2014 10:57:00 GMT</pubDate><guid>http://www.blogjava.net/watchzerg/archive/2014/07/13/415749.html</guid><wfw:comment>http://www.blogjava.net/watchzerg/comments/415749.html</wfw:comment><comments>http://www.blogjava.net/watchzerg/archive/2014/07/13/415749.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/watchzerg/comments/commentRss/415749.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/watchzerg/services/trackbacks/415749.html</trackback:ping><description><![CDATA[<div><a href="http://logback.qos.ch/manual/appenders.html" style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">http://logback.qos.ch/manual/appenders.html</a><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Appender都集成ch.qos.logback.core.Appender接口。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">每个Appender可以绑定若干个Filter。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">每个Appender可以将任务代理给Layout或者Encoder。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">每个Layout或者Encoder只能属于1个Appender。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Appener也可以不包含Layout或者encoder，例如SocketAppender，直接把Event序列化传输。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">ch.qos.logback.core.AppenderBase这是一个抽象类，对Appender接口提供了骨架实现，线程安全。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">ch.qos.logback.core.UnsynchronizedAppenderBase是对应的线程不安全的类，但是可以将线程安全性委托给下一层的类（例如OutputStream）</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">OutputStreamAppender是文件输出和控制台输出Appender的父类，类层次结构如下：<br /><img src="http://www.blogjava.net/images/blogjava_net/watchzerg/logback-4-1.png" width="724" height="596" alt="" /><br /><br /><div><div>ConsoleAppender</div><div>&nbsp; &nbsp; &nbsp;输出到System.out or System.err</div><div></div><div>可配置属性：</div><div>&nbsp; &nbsp; &nbsp;encoder</div><div>&nbsp; &nbsp; &nbsp;target: &nbsp; &nbsp; 默认是System.out</div><div>&nbsp; &nbsp; &nbsp;withJansi： &nbsp; &nbsp; 默认false，用来在windows中支持控制台色彩的</div><div></div><div>样例：</div><div>&nbsp; &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"&gt;</div><div>&nbsp; &nbsp; &lt;encoder&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;pattern&gt;%-4relative [%thread] %-5level %logger{35} - %msg %n&lt;/pattern&gt;</div><div>&nbsp; &nbsp; &lt;/encoder&gt;</div><div>&nbsp; &lt;/appender&gt;</div><div></div><div>----------------------------------------------------------</div><div>FileAppender</div><div>&nbsp; &nbsp; &nbsp;写入到文件（新消息到来，写入前，才会判断是否该分割文件等）</div><div></div><div>可配置属性：</div><div>&nbsp; &nbsp; &nbsp;append： &nbsp; &nbsp; 文件追加，默认为true</div><div>&nbsp; &nbsp; &nbsp;encoder： &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp;file： &nbsp; &nbsp; 文件路径和名词（如果windows下，记得分隔符转义）</div><div>&nbsp; &nbsp; &nbsp;prudent： &nbsp; &nbsp; 谨慎模式，不同JVM（甚至存在于不同主机上）安全的写入同一个文件。默认关闭。</div><div></div><div>默认每行都flush到磁盘，可以修改Encoder的immediateFlush属性来改变这一行为。</div><div></div><div>样例：</div><div>&nbsp; &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender"&gt;</div><div>&nbsp; &nbsp; &lt;file&gt;testFile.log&lt;/file&gt;</div><div>&nbsp; &nbsp; &lt;append&gt;true&lt;/append&gt;</div><div>&nbsp; &nbsp; &lt;encoder&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;pattern&gt;%-4relative [%thread] %-5level %logger{35} - %msg%n&lt;/pattern&gt;</div><div>&nbsp; &nbsp; &lt;/encoder&gt;</div><div>&nbsp; &lt;/appender&gt;</div><div></div><div>唯一名词的记录文件（通过启动时间戳）：</div><div>&nbsp; &lt;timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/&gt;</div><div>&nbsp; &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender"&gt;</div><div>&nbsp; &nbsp; &lt;file&gt;log-${bySecond}.txt&lt;/file&gt;</div><div>&nbsp; &nbsp; &lt;encoder&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;pattern&gt;%logger{35} - %msg%n&lt;/pattern&gt;</div><div>&nbsp; &nbsp; &lt;/encoder&gt;</div><div>&nbsp; &lt;/appender&gt;</div><div>&#8212;&#8212;这样就可以在每次项目启动时生成一个新的文件。</div><div>默认是使用xml解析的时间，也可以指定使用log context的创建时间：</div><div>&nbsp; &nbsp; &nbsp;&lt;timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;timeReference="contextBirth"/&gt;</div><div></div><div>----------------------------------------------------------</div><div>RollingFileAppender</div><div>&nbsp; &nbsp; &nbsp;滚动记录日志文件</div><div>&nbsp; &nbsp; &nbsp;有两个子组件：</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RollingPolicy &#8212;&#8212;接管&#8220;滚动&#8221;操作，控制该操作如何发生</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TriggeringPolicy &#8212;&#8212;决定滚动操作是否发生，何时发生</div><div>&nbsp; &nbsp; &nbsp;默认情况下，必须同时含有上述两个组件。不过有的RollingPolicy也实现了后者的接口，那么可以身兼2职。</div><div></div><div>可配置属性：</div><div>&nbsp; &nbsp; &nbsp;file：</div><div>&nbsp; &nbsp; &nbsp;append：</div><div>&nbsp; &nbsp; &nbsp;encoder：</div><div>&nbsp; &nbsp; &nbsp;rollingPolicy：</div><div>&nbsp; &nbsp; &nbsp;triggeringPolicy：</div><div>&nbsp; &nbsp; &nbsp;prudent：</div><div></div><div>RollingPolicy</div><div>&nbsp; &nbsp; &nbsp;包含的操作：将当前的日志文件归档（并重命名），压缩（如果需要）</div><div></div><div>TimeBasedRollingPolicy</div><div>&nbsp; &nbsp; &nbsp;最常用的，基于时间滚动，同时实现了RollingPolicy和TriggeringPolicy</div><div>&nbsp; &nbsp; &nbsp;可配置属性：</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fileNamePattern： &nbsp; &nbsp; 文件名匹配格式</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;文件名+日期定义器&#8220;%d&#8221;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;日期定义器的格式在SimpleDateFormat中定义</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;滚动周期是通过日期定义器推断出来的</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;其父元素RollingFileAppender中file属性可以省略（因为可以用fileNamePattern猜测出当前时间的日志名）</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 也可以不省略，这样可以为&#8220;当前日志文件&#8221;和&#8220;归档日志文件&#8221;分别制定不同的路径</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;日志定义器中的正反斜杠都会被认为是目录分隔符</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;可以指定多个日期定义器，但只能有1个是主要的，其余的必须标记为aux（辅助的）</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; maxHistory： &nbsp; &nbsp; 最大文件数</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cleanHistoryOnStart： &nbsp; &nbsp; 启动时清除历史归档日志</div><div></div><div>&nbsp; &nbsp; &nbsp;对fileNamePattern的更详细的解释和示例：</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;/wombat/foo.%d &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;按天分隔日志</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;未指定格式，所以默认为yyyy-MM-dd（按天滚动）</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;如果在RollingFileAppender中指定了file（默认日志文件名）：</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 今天日志为 /wombat/foo.2006-11-24</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 昨天日志为 /wombat/foo.2006-11-23</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;如果没有在RollingFileAppender中指定file为&#8220;/wombat/foo.txt&#8221;，</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 今天日志为 /wombat/foo.txt</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 昨天日志为 /wombat/foo.2006-11-23</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#8212;&#8212;其实不指定默认日志文件名的方式更好，因为避免了滚动时重命名操作，也就避免了潜在异常。</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;/wombat/%d{yyyy/MM}/foo.txt</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;按&#8220;年/月&#8221;分两级文件夹，文件名固定为&#8220;foo.txt&#8221;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;如果在RollingFileAppender中指定了file（默认日志文件名）：</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2006年10月日志为&nbsp;/wombat/2006/10/foo.txt</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2006年11月日志为&nbsp;/wombat/2006/11/foo.txt</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;如果没有在RollingFileAppender中指定file为&#8220;/wombat/foo.txt&#8221;，</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 当前正在写的日志永远为&nbsp;/wombat/foo.txt</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 归档的日志格式为&nbsp;/wombat/2006/10/foo.txt</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;/wombat/foo.%d{yyyy-ww}.log</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;每个星期归档一个新文件（注意具体&#8220;哪天算是一个星期的第一天&#8221;取决于系统locale属性）</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;/wombat/foo%d{yyyy-MM-dd_HH}.log</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;每小时一次归档</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;/wombat/foo%d{yyyy-MM-dd_HH-mm}.log</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;每分钟一次归档</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;/foo/%d{yyyy-MM,aux}/%d.log</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;每天一次归档，但每个月一个新文件夹</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div>&nbsp; &nbsp; &nbsp;如果fileNamePattern文件名是以.gz或者.zip结尾的，那么TimeBasedRollingPolicy会自动压缩：</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;/wombat/foo.%d.gz</div><div></div><div>&nbsp; &nbsp; &nbsp;日志归档是&#8220;记录日志的事件&#8221;触发的，所以有一定延迟。例如第二天的第一条日志是临晨01:00才过来，那么这个时候才会归档前一天的日志。</div><div></div><div>配置样例：</div><div>&nbsp; &lt;appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"&gt;</div><div>&nbsp; &nbsp; &lt;file&gt;logFile.log&lt;/file&gt;</div><div>&nbsp; &nbsp; &lt;rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;fileNamePattern&gt;logFile.%d{yyyy-MM-dd}.log&lt;/fileNamePattern&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;maxHistory&gt;30&lt;/maxHistory&gt;</div><div>&nbsp; &nbsp; &lt;/rollingPolicy&gt;</div><div></div><div>&nbsp; &nbsp; &lt;encoder&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;pattern&gt;%-4relative [%thread] %-5level %logger{35} - %msg%n&lt;/pattern&gt;</div><div>&nbsp; &nbsp; &lt;/encoder&gt;</div><div>&nbsp; &lt;/appender&gt;</div><div></div><div>----------------------------------------------------------</div><div>FixedWindowRollingPolicy</div><div>&nbsp; &nbsp; &nbsp;可配置属性：</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;minIndex:</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;maxIndex:</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;fileNamePattern: &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;必须包含&#8220;%i&#8221;占位符，用来表示将当前索引值插入什么位置。</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;例如&#8220;MyLogFile%i.log&#8221;配合&#8220;最小1，最大3&#8221;，表示文件名为：MyLogFile1.log, MyLogFile2.log, MyLogFile3.log</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;同样加上zip或gz后缀可以启用压缩</div><div>&nbsp; &nbsp; &nbsp;因为每次需要很多重命名操作（重命名次数等于window size），所以如果设置size超过20，会被强制指定为20.</div><div></div><div>&nbsp; &nbsp; &nbsp;配置样例：</div><div>&nbsp; &lt;appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"&gt;</div><div>&nbsp; &nbsp; &lt;file&gt;test.log&lt;/file&gt;</div><div></div><div>&nbsp; &nbsp; &lt;rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;fileNamePattern&gt;tests.%i.log.zip&lt;/fileNamePattern&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;minIndex&gt;1&lt;/minIndex&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;maxIndex&gt;3&lt;/maxIndex&gt;</div><div>&nbsp; &nbsp; &lt;/rollingPolicy&gt;</div><div></div><div>&nbsp; &nbsp; &lt;triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;maxFileSize&gt;5MB&lt;/maxFileSize&gt;</div><div>&nbsp; &nbsp; &lt;/triggeringPolicy&gt;</div><div>&nbsp; &nbsp; &lt;encoder&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;pattern&gt;%-4relative [%thread] %-5level %logger{35} - %msg%n&lt;/pattern&gt;</div><div>&nbsp; &nbsp; &lt;/encoder&gt;</div><div>&nbsp; &lt;/appender&gt;</div><div>----------------------------------------------------------</div><div>SizeAndTimeBasedFNATP（File Naming And Triggering Policy）&#8212;&#8212;是TimeBasedRollingPolicy的一个子组件</div><div>&nbsp; &nbsp; &nbsp;配置样例：</div><div>&nbsp; &lt;appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender"&gt;</div><div>&nbsp; &nbsp; &lt;file&gt;mylog.txt&lt;/file&gt;</div><div>&nbsp; &nbsp; &lt;rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;!-- rollover daily --&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;fileNamePattern&gt;mylog-%d{yyyy-MM-dd}.%i.txt&lt;/fileNamePattern&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;timeBasedFileNamingAndTriggeringPolicy</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &lt;!-- or whenever the file size reaches 100MB --&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &lt;maxFileSize&gt;100MB&lt;/maxFileSize&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;/timeBasedFileNamingAndTriggeringPolicy&gt;</div><div>&nbsp; &nbsp; &lt;/rollingPolicy&gt;</div><div>&nbsp; &nbsp; &lt;encoder&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;pattern&gt;%msg%n&lt;/pattern&gt;</div><div>&nbsp; &nbsp; &lt;/encoder&gt;</div><div>&nbsp; &lt;/appender&gt;</div><div>&nbsp; &nbsp; &nbsp;&#8212;&#8212;每天滚动一个文件，如果文件体积达到100M，则也拆分。</div><div>&nbsp; &nbsp; &nbsp;&#8212;&#8212;也支持自动删除老文件，可以通过maxHistory指定保存的最多文件数（每天最多这么多，还是一共最多这么多？）</div><div></div><div>----------------------------------------------------------</div><div>SizeBasedTriggeringPolicy&#8212;&#8212;一般配合FixedWindowRollingPolicy使用</div><div>&nbsp; &nbsp; &nbsp;指定文件超过&#8220;maxFileSize&#8221;指定大小时，上层RollingFileAppender触发滚动操作。</div><div>&nbsp; &nbsp; &nbsp;默认&#8220;10MB&#8221;，可以指定各种后缀：KB,MB,GB</div><div></div><div>----------------------------------------------------------</div><div>----------------------------------------------------------</div><div></div><div>SocketAppender and SSLSocketAppender</div><div>以及后面关于网络，数据库，远程日志服务器，JNDI等&#8230;&#8230;省略&#8230;&#8230;</div><div></div><div>----------------------------------------------------------</div><div>SiftingAppender</div><div>&nbsp; &nbsp; &nbsp;可以根据指定的变量分割文件。例如根据用户ID，则每个用户一个日志文件。</div><div>&nbsp; &nbsp; &nbsp;</div><div>&nbsp; &nbsp; &nbsp;可配置参数：</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;timeout：如果一个关联的appender如果超过默认30分钟没有被访问，则被SiftingAppender卸载掉。</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;maxAppenderCount：可以最大追踪的关联appender数量，默认int最大值。</div><div>&nbsp; &nbsp; &nbsp;这个Appener会把日志记录动作代理给关联的appender。</div><div>&nbsp; &nbsp; &nbsp;选择条件由Discriminator指定，默认为MDCBasedDiscriminator。</div><div></div><div>&nbsp; &nbsp; &nbsp;示例，假设应用程序这样设置了MDC信息：</div><blockquote style="color: #000000; text-align: -webkit-auto; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>logger.debug("Application started");</div><div>MDC.put("userid", "Alice");</div><div>logger.debug("Alice says hello");&nbsp;</div></blockquote><div>&nbsp; &nbsp; &nbsp;然后这样配置：</div><div>&nbsp; &lt;appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender"&gt;</div><div>&nbsp; &nbsp; &lt;!-- in the absence of the class attribute, it is assumed that the</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;desired discriminator type is</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ch.qos.logback.classic.sift.MDCBasedDiscriminator --&gt;</div><div>&nbsp; &nbsp; &lt;discriminator&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;key&gt;userid&lt;/key&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;defaultValue&gt;unknown&lt;/defaultValue&gt;</div><div>&nbsp; &nbsp; &lt;/discriminator&gt;</div><div>&nbsp; &nbsp; &lt;sift&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;appender name="FILE-${userid}" class="ch.qos.logback.core.FileAppender"&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &lt;file&gt;${userid}.log&lt;/file&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &lt;append&gt;false&lt;/append&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &lt;layout class="ch.qos.logback.classic.PatternLayout"&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;pattern&gt;%d [%thread] %level %mdc %logger{35} - %msg%n&lt;/pattern&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &lt;/layout&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;/appender&gt;</div><div>&nbsp; &nbsp; &lt;/sift&gt;</div><div>&nbsp; &lt;/appender&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div></div><div>&nbsp; &nbsp; &nbsp;因为确定timeout和maxAppenderCount比较困难，所以如果程序可以知道&#8220;执行到某个地方很可能应该关闭对应的appender&#8221;，那么可以明确指定一个FINALIZE_SESSION的marker。这样siftingAppender关联的对应appender，会在接到这个marker的几秒钟后关闭。例如：</div><div>import static ch.qos.logback.classic.ClassicConstants.FINALIZE_SESSION_MARKER;</div><div>&nbsp; void job(String jobId) {</div><div>&nbsp; &nbsp; MDC.put("jobId", jobId);</div><div>&nbsp; &nbsp; logger.info("Starting job.");</div><div>&nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; // will cause the nested appender reach end-of-life. It will</div><div>&nbsp; &nbsp; // linger for a few seconds.</div><div>&nbsp; &nbsp; logger.info(FINALIZE_SESSION_MARKER, "About to end the job");</div><div></div><div>&nbsp; &nbsp; try {</div><div>&nbsp; &nbsp; &nbsp; .. perform clean up</div><div>&nbsp; &nbsp; } catch(Exception e); &nbsp;</div><div>&nbsp; &nbsp; &nbsp; // This log statement will be handled by the lingering appender.&nbsp;</div><div>&nbsp; &nbsp; &nbsp; // No new appender will be created.</div><div>&nbsp; &nbsp; &nbsp; logger.error("unexpected error while cleaning up", e);</div><div>&nbsp; &nbsp; }</div><div>&nbsp; }</div><div></div><div>----------------------------------------------------------</div><div>SMTPAppender</div><div>&nbsp; &nbsp; &nbsp;将日志事件缓存指定的数量，被特定事件触发后，异步发送邮件。</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;smtpHost &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;smtpPort &nbsp; &nbsp; 默认25</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;to &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;发送目标，多个联系人可以用逗号隔开，也可以用多个&lt;to&gt;元素</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; from &nbsp; &nbsp; &nbsp;发送者邮箱，如果想包含名字，可以用特定格式&#8220;Adam Smith &amp;lt;smith@moral.org&amp;gt;&#8221;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;subject &nbsp; &nbsp; 邮件标题，可以使用PatternLayout的转义字符，会用&#8220;触发该邮件的日志事件&#8221;的信息替换转义字符</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;discriminator &nbsp; &nbsp; 默认只有一个缓存。通过指定该属性，可以有多个缓存，这样可以根据事件信息发给不同的人或者ip</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;evaluator &nbsp; &nbsp; 声明一个&lt;EventEvaluator/&gt;元素，通过class属性指定类型。默认为OnErrorEvaluator，也可以自己指定OnMarkerEvaluator,JaninoEventEvaluator,GEventEvaluator</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;cyclicBufferTracker &nbsp; &nbsp; 环形缓存跟踪器，基于discriminator的返回值工作。默认保存缓存大小为256</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;username &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;password &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;STARTTLS &nbsp; &nbsp; 如果开启，会发起STARTTLS命令，导致连接转换为SSL。连接默认是不使用加密的。默认为false</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;SSL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;如果开启，那么使用SSL连接。默认false。</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;charsetEncoding &nbsp; &nbsp; 默认UTF-8</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;localhost &nbsp; &nbsp; 如果SMTP发送方的hostname没配置好，邮件服务器可能拒绝请求，这个时候可以设置这个值为客户端全名。</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;asynchronousSending &nbsp; &nbsp; 异步发送，默认true。特定情况下需要设置为false，例如应用程序发送完邮件就会立即关闭。</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;includeCallerData &nbsp; &nbsp; 包含调用者信息，默认为false。</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;sessionViaJNDI &nbsp; &nbsp; logback依赖javax.mail.Session来发送邮件。该属性默认为false，SMTPAppender会根据配置构建新的Session。如果设为true，会去web容器寻找Session对象，此时应用程序不应该再依赖mail.jar等</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;jndiLocation &nbsp; &nbsp; 查找JNDI的路径，例如"java:comp/env/mail/Session"</div><div></div><div>&nbsp; &nbsp; &nbsp;最多保存256条日志事件，否则内存消耗太大（不建议自己指定其它值）。</div><div>&nbsp; &nbsp; &nbsp;发邮件依赖JavaMail API (mail.jar)和JavaBeans Activation Framework (activation.jar) &#8212;&#8212;maven里引入前者会自动依赖后者。</div><div></div><div>&nbsp; &nbsp; &nbsp;发送者和接收者都可以是动态属性：</div><blockquote style="color: #000000; text-align: -webkit-auto; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender"&gt;</div><div>&nbsp; &lt;smtpHost&gt;${smtpHost}&lt;/smtpHost&gt;</div><div>&nbsp; &lt;to&gt;<strong>${to}</strong>&lt;/to&gt;</div><div>&nbsp; &lt;from&gt;<strong>${from}</strong>&lt;/from&gt;</div><div>&nbsp; &lt;layout class="ch.qos.logback.classic.html.HTMLLayout"/&gt;</div><div>&lt;/appender&gt;</div></blockquote><div>&nbsp; &nbsp; &nbsp;注意上面的layout也可以用patternLayout：</div><blockquote style="color: #000000; text-align: -webkit-auto; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&nbsp; &nbsp; &lt;layout class="ch.qos.logback.classic.PatternLayout"&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;pattern&gt;%date %-5level %logger{35} - %message%n&lt;/pattern&gt;</div><div>&nbsp; &nbsp; &lt;/layout&gt;</div></blockquote><div></div><div>触发事件：</div><div>&nbsp; &nbsp; &nbsp;默认是OnErrorEvaluator，但可以自己定制。SMTPAppender仅维护一个Evaluator，这个Evaluator可以自己维护状态，例如可以实现一个CounterBasedEvaluator。</div><div>&nbsp; &nbsp; &nbsp;</div><div>基于标记Marker的事件触发：</div><blockquote style="color: #000000; text-align: -webkit-auto; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>Marker notifyAdmin = MarkerFactory.getMarker("NOTIFY_ADMIN");</div><div>logger.error(notifyAdmin,</div><div>&nbsp; "This is a serious an error requiring the admin's attention",</div><div>&nbsp; &nbsp;new Exception("Just testing"));</div></blockquote><div></div><blockquote style="color: #000000; text-align: -webkit-auto; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&nbsp; &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender"&gt;</div><div>&nbsp; &nbsp; &lt;evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator"&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;marker&gt;NOTIFY_ADMIN&lt;/marker&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;!-- you specify add as many markers as you want --&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;marker&gt;TRANSACTION_FAILURE&lt;/marker&gt;</div><div>&nbsp; &nbsp; &lt;/evaluator&gt;</div><div>&nbsp; &lt;/appender&gt;</div></blockquote><div></div><div>还可以使用更加通用的JaninoEventEvaluator或者GEventEvaluator，他们提供更复杂更强大的甄别功能（也包含了OnMarkerEvaluator的功能）。</div><div></div><div>身份验证/STARTTLS/SSL</div><div>&nbsp; &nbsp; &nbsp;SMTPAppender支持用户名和密码的加密验证。</div><div>&nbsp; &nbsp; &nbsp;STARTTLS方式是先使用非加密方式建立连接，然后切换到SSL（常用于server-server交互）。</div><div>&nbsp; &nbsp; &nbsp;SSL方式是直接建立SSL连接（一般用于client-sever交互）。</div><div></div><div>Appender configuration for Gmail (SSL)</div><blockquote style="color: #000000; text-align: -webkit-auto; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender"&gt;</div><div>&nbsp; &nbsp; &lt;smtpHost&gt;smtp.gmail.com&lt;/smtpHost&gt;</div><div>&nbsp; &nbsp; &lt;smtpPort&gt;465&lt;/smtpPort&gt;</div><div>&nbsp; &nbsp; &lt;SSL&gt;true&lt;/SSL&gt;</div><div>&nbsp; &nbsp; &lt;username&gt;YOUR_USERNAME@gmail.com&lt;/username&gt;</div><div>&nbsp; &nbsp; &lt;password&gt;YOUR_GMAIL_PASSWORD&lt;/password&gt;&nbsp; &nbsp;</div><div>&nbsp; &lt;/appender&gt;</div></blockquote><div></div><div>SMTPAppender for Gmail (STARTTLS)</div><blockquote style="color: #000000; text-align: -webkit-auto; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&nbsp; &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender"&gt;</div><div>&nbsp; &nbsp; &lt;smtpHost&gt;smtp.gmail.com&lt;/smtpHost&gt;</div><div>&nbsp; &nbsp; &lt;smtpPort&gt;587&lt;/smtpPort&gt;</div><div>&nbsp; &nbsp; &lt;STARTTLS&gt;true&lt;/STARTTLS&gt;</div><div>&nbsp; &nbsp; &lt;username&gt;YOUR_USERNAME@gmail.com&lt;/username&gt;</div><div>&nbsp; &nbsp; &lt;password&gt;YOUR_GMAIL_xPASSWORD&lt;/password&gt;&nbsp; &nbsp;&nbsp;</div><div>&nbsp; &lt;/appender&gt;</div></blockquote><div></div><div>Discriminator</div><div>&nbsp; &nbsp; &nbsp;用MDCBasedDiscriminator做示例，根据MDC的值，维护多个缓存</div><blockquote style="color: #000000; text-align: -webkit-auto; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&nbsp; &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender"&gt;</div><div><strong>&nbsp; &nbsp; &lt;discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator"&gt;</strong></div><div><strong>&nbsp; &nbsp; &nbsp; &lt;key&gt;req.remoteHost&lt;/key&gt;</strong></div><div><strong>&nbsp; &nbsp; &nbsp; &lt;defaultValue&gt;default&lt;/defaultValue&gt;</strong></div><div><strong>&nbsp; &nbsp; &lt;/discriminator&gt;</strong></div><div>&nbsp; &nbsp; &lt;subject&gt;${HOSTNAME} --&nbsp;<strong>%X{req.remoteHost}</strong>&nbsp;%msg"&lt;/subject&gt;</div><div>&nbsp; &nbsp; &lt;layout class="ch.qos.logback.classic.html.HTMLLayout"&gt;</div><div>&nbsp; &nbsp; &nbsp; &lt;pattern&gt;%date%level%thread%<strong>X{req.remoteHost}</strong>%X{req.requestURL}%logger%msg&lt;/pattern&gt;</div><div>&nbsp; &nbsp; &lt;/layout&gt;</div><div>&nbsp; &lt;/appender&gt;</div></blockquote><div>&nbsp; &nbsp; &nbsp;上面的例子先利用了MDCInsertingServletFilter把请求方的hostname或ip设置到MDC中。</div><div>&nbsp; &nbsp; &nbsp;每一个remoteHost都有一个自己的buffer，一旦某个remoteHost触发了发送邮件的请求，那么该buffer里的256条信息会被发送出去。</div><div></div><div>Buffer管理：</div><div>&nbsp; &nbsp; &nbsp;上面的例子，每一个远程地址都有自己的buffer，会极大的消耗内存。</div><div>&nbsp; &nbsp; &nbsp;默认情况下，logback内部最多允许64个buffer同时存在，LRU算法换出。超过30分钟未使用的buffer也会被换出。该值可以通过maxNumberOfBuffers来设置。<br /><div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 这里有问题，通过各种手段都无法设置此值，貌似是个bug，我在尽我所能查遍所有资料后，在stackoverflowh和官方jira上提了这个问题：</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<a href="http://stackoverflow.com/questions/24836151">http://stackoverflow.com/questions/24836151</a></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<a href="http://jira.qos.ch/browse/LOGBACK-996">http://jira.qos.ch/browse/LOGBACK-996</a>&nbsp;</div></div></div><div>&nbsp; &nbsp; &nbsp;在高强度系统中，上面的2个保护机制不够，需要加入手工管理：通过明确指定&#8220;FINALIZE_SESSION&#8221;这个Marker，来告诉logback去释放对应的buffer，这样就可以安全的将maxNumberOfBuffers设置为512乃至1024。（具体设置办法参照SiftingAppender里描述的）</div><div></div><div>这里是官方的一个SMTPAppender的例子：</div><div><a href="http://logback.qos.ch/recipes/emailPerTransaction.html">http://logback.qos.ch/recipes/emailPerTransaction.html</a></div><div>注意Marker可以叠加，所以如果有必要，可以把&#8220;发送邮件的Marker&#8221;和&#8220;终结Session（以便清理buffer）的Marker&#8221;关联在一起。</div><div>&nbsp; &nbsp; &nbsp;Marker SMTP_TRIGGER = MarkerFactory.getMarker("SMTP_TRIGGER");</div><div>&nbsp; &nbsp; &nbsp;SMTP_TRIGGER.add(FINALIZE_SESSION_MARKER);</div><div>----------------------------------------------------------</div><div>AsyncAppender</div><div>&nbsp; &nbsp; &nbsp;类似于单独的一个事件分发器，所以必须引用另一个appender。</div><div>&nbsp; &nbsp; &nbsp;用一个BlockingQueue缓冲事件，然后创建一个线程，从队列里获取事件并分发给引用的appender。</div><div>&nbsp; &nbsp; &nbsp;默认情况下，如果队列达到80%的容量，则丢弃TRACE,DEBUG,INFO级别的日志。</div><div>&nbsp; &nbsp; &nbsp;应用程序停止的时候，会通知LoggerContext停止，在停止各个Appender时，AsyncAppender会停止接收日志，并将信息flush到磁盘。</div><div></div><div>&nbsp; &nbsp; &nbsp;配置参数：</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;queueSize：默认256</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;discardingThreshold：默认队列20%可用的时候开始选择性抛弃信息，设为0表示不抛弃</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;includeCallerData：是否包括调用者信息（重开销），默认只复制线程名和MDC信息（因为切换了线程，其余信息会丢失）</div><div>&nbsp; &nbsp; &nbsp;队列全满的时候，写日志动作会被block，直到队列有可用空间。</div><div>----------------------------------------------------------</div><div>自定义Appender</div><div>&nbsp; &nbsp; &nbsp;略</div><div>---------------------------------------------------------- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div>----------------------------------------------------------</div><div>Logback Access</div><div>&nbsp; &nbsp; &nbsp;大部分Appender，在logback-classic与logback-access中使用方式类似。</div></div><br /><br /></div></div><img src ="http://www.blogjava.net/watchzerg/aggbug/415749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/watchzerg/" target="_blank">王星游</a> 2014-07-13 18:57 <a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>logback_doc_manual_03_configuration</title><link>http://www.blogjava.net/watchzerg/archive/2014/07/13/415748.html</link><dc:creator>王星游</dc:creator><author>王星游</author><pubDate>Sun, 13 Jul 2014 10:56:00 GMT</pubDate><guid>http://www.blogjava.net/watchzerg/archive/2014/07/13/415748.html</guid><wfw:comment>http://www.blogjava.net/watchzerg/comments/415748.html</wfw:comment><comments>http://www.blogjava.net/watchzerg/archive/2014/07/13/415748.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/watchzerg/comments/commentRss/415748.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/watchzerg/services/trackbacks/415748.html</trackback:ping><description><![CDATA[<div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"><a href="http://logback.qos.ch/manual/configuration.html">http://logback.qos.ch/manual/configuration.html</a></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">-------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">与spring的配置：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">貌似官网上没有介绍，但是作者在github上建立了一个扩展项目用于logback与spring结合。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"><a href="https://github.com/qos-ch/logback-extensions">https://github.com/qos-ch/logback-extensions</a></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">目前最新版本是0.1.2，很多maven公开库里已经有了。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">maven配置：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;dependency&gt; &nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;groupId&gt;org.logback-extensions&lt;/groupId&gt; &nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;artifactId&gt;logback-ext-spring&lt;/artifactId&gt; &nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;version&gt;0.1.2&lt;/version&gt; &nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;/dependency&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">web.xml配置日志框架启动监听器：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;!-- logback配置文件 --&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;context-param&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;param-name&gt;logbackConfigLocation&lt;/param-name&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;param-value&gt;/WEB-INF/classes/logback.xml&lt;/param-value&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;/context-param&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;!-- logback加载监听器 --&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;listener&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;listener-class&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ch.qos.logback.ext.spring.web.LogbackConfigListener</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;/listener-class&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;/listener&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">-------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">logback中的配置：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">可以用java程序配置，也可以用xml或者groovy脚本配置。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">使用 http://logback.qos.ch/translator/ 可以把log4j的配置自动转换过来。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">logback内部查找配置的过程：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;1，在classpath查找&#8220;logback.groovy&#8221;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;2，在classpath查找&#8220;logback-test.xml&#8221;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;3，在classpath查找&#8220;logback.xml&#8221;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;4，使用自身的BasicConfigurator做基本配置，所有日志被输出到控制台。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&#8212;&#8212; 一般把&#8220;logback-test.xml&#8221;放到maven的测试路径，把&#8220;logback.xml&#8221;放到maven的正式路径，前者优先级更高。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">logback的状态，加载配置文件的过程：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;代码打印：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StatusPrinter.print(lc);</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;配置文件形式打印：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;configuration debug="true"&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; ...&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;/configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;也可以通过设置StatusListener来监听logback的启动和打印状态&#8212;&#8212;在生产环境挺有用，因为配置文件路径挺深。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">通过在系统变量里加入"logback.configurationFile"指定logback配置文件路径：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;java -Dlogback.configurationFile=/path/to/config.xml chapters.configuration.MyApp1</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">设置自动扫描和遇到变更时重新加载配置文件（不指定周期的话默认每1分钟）：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;configuration scan="true" scanPeriod="30 seconds"&gt;&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp;...&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;/configuration&gt;&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;每当N个（logback会自动调节）日志请求，logback会检查一下扫描周期是否已经到达，如到达再检查配置文件。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">通过web访问状态信息：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">在web.xml配置：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;servlet&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;servlet-name&gt;ViewStatusMessages&lt;/servlet-name&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;servlet-class&gt;ch.qos.logback.classic.ViewStatusMessagesServlet&lt;/servlet-class&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &lt;/servlet&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &lt;servlet-mapping&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;servlet-name&gt;ViewStatusMessages&lt;/servlet-name&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;url-pattern&gt;/lbClassicStatus&lt;/url-pattern&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &lt;/servlet-mapping&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">然后访问：http://host/yourWebapp/lbClassicStatus</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">注册控制台状态监听器：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;java代码方式：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();&nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StatusManager statusManager = lc.getStatusManager();</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OnConsoleStatusListener onConsoleListener = new OnConsoleStatusListener();</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; statusManager.add(onConsoleListener);</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;用配置文件方式：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /&gt; &nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;系统变量方式：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; java -Dlogback.statusListenerClass=ch.qos.logback.core.status.OnConsoleStatusListener</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">停止logback：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;java代码方式：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; loggerContext.stop();</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;web应用：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;ServletContextListener.contextDestroyed()会自动调用上面的stop方法。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">-------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">配置文件格式：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;最外层是&lt;configuration&gt;元素，里面有&lt;appender&gt;&lt;logger&gt;&lt;root&gt;元素</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;logger&gt;元素：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;level属性可以这些值：TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF，也可以明确指定继承：INHERITED或者NULL</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;包含若干&lt;appender-ref&gt;元素，指定appender的名字。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">从DEBUG改为INFO级别：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;!-- encoders are assigned the type</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;encoder&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &lt;pattern&gt;%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n&lt;/pattern&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;/encoder&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;/appender&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;logger name="chapters.configuration" level="INFO"/&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;!-- Strictly speaking, the level attribute is not necessary since --&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;!-- the level of the root level is set to DEBUG by default. &nbsp; &nbsp; &nbsp; --&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;root level="DEBUG"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;appender-ref ref="STDOUT" /&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;/root&gt; &nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;/configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">-------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">配置Appender：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;name和class属性</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;内嵌0个或1个layout元素，0个或多个encoder元素，0个或多个filter元素。还可以内嵌任意数量的appdenter类的属性（例如自定义的appender类）。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;layout元素应该内嵌具体的layout类，但是默认就是PatternLayoutEncoder。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">Appender的累加性：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;logger会记录在所有绑定在它自身的appender，同时也会记录在该logger祖先的appender上，所以有可能重复记录！</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">配置Logger Context（可以用在&#8220;多个项目写入同一个日志文件&#8221;这种情况）：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;contextName&gt;myAppName&lt;/contextName&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; ...</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;/configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">-------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">变量替换：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;property name="USER_HOME" value="/home/sebastien" /&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender"&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;file&gt;${USER_HOME}/myApp.log&lt;/file&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; ...</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;/appender&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp;...</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;/configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&#8212;&#8212;上面的变量定义在系统属性里也可以：java -DUSER_HOME="/home/sebastien" MyApp2</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">变量也可以定义在文件里：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;property file="src/main/java/chapters/configuration/variables1.properties" /&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;appender name="FILE" class="ch.qos.logback.core.FileAppender"&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;file&gt;${USER_HOME}/myApp.log&lt;/file&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;...</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp;&lt;/appender&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp;...</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;/configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&#8212;&#8212;对应路径的文件里应该加入&#8220;USER_HOME=/home/sebastien&#8221;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">（这路径挺诡异啊，是maven的结构，那打包后岂不是不能用了？）</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">像这样引用classpath的还靠谱些：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;property resource="resource1.properties" /&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">变量可以指定作用域：local，context，system</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">变量可以相互引用：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;USER_HOME=/home/sebastien</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;fileName=myApp.log</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;destination=${USER_HOME}/${fileName}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">命名引用：如果"userid"会被替换为"alice"，那么"${${userid}.password}"会被替换为"alice.password"对应的值。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">变量可以指定默认值：${aName:-golden} &nbsp;&#8212;&#8212;这就指定了默认值golden</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">变量的默认值也可以引用变量：&nbsp;"${id:-${userid}}</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">预置变量：HOSTNAME,CONTEXT_NAME</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">可以通过timestamp元素定义一个当前的日期和时间的动态元素。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">可以自己继承PropertyDefiner实现动态生成属性，现在内置了2个动态属性生成器：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;FileExistsPropertyDefiner &nbsp; &nbsp; 如果指定路径文件存在，则将指定属性设为&#8220;true&#8221;，反之亦然</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;ResourceExistsPropertyDefiner &nbsp; &nbsp; 如果指定资源存在，则将指定属性设为&#8220;true&#8221;，反之亦然</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">条件语句：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp;&lt;!-- if-then form --&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp;&lt;if condition="some conditional expression"&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;then&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; ...</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;/then&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;/if&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;!-- if-then-else form --&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;if condition="some conditional expression"&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;then&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; ...</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;/then&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;else&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; ...</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;/else&gt; &nbsp; &nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;/if&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">判断条件只支持context变量和system变量，用property()或者p()来引用&#8212;&#8212;如果没有设定对应变量，这两个方法会返回空串（而不是null）</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">isDefine()和isNull()分别判断变量是否设置和变量是否为空。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;if condition='property("HOSTNAME").contains("torino")'&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;...</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;/if&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">可以从JNDI读取变量值（作用域为local）。也可以将从JNDI读取的变量存入另一个不同作用域的变量。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp;&lt;insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" /&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp;...</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;/configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">-------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">文件包含（可以使用相对路径。当前路径已经在当前项目中定义，所以没必要与配置文件路径关联）：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;configuration&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;include file="src/main/java/chapters/configuration/includedConfig.xml"/&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; ...</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;/configuration&gt;&nbsp; &nbsp; &nbsp;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">被包含的文件必须用&lt;include&gt;标签包裹：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;included&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender"&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;encoder&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp; &lt;pattern&gt;"%d - %m%n"&lt;/pattern&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &lt;/encoder&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &lt;/appender&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&lt;/included&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">还可以关联资源（例如classpath下的某个文件）：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;include resource="includedConfig.xml"/&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">还可以关联URL：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;include url="http://some.host.com/includedConfig.xml"/&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">可以指定此次文件包含为&#8220;可选的&#8221;：</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">&nbsp; &nbsp; &nbsp;&lt;include optional="true" ..../&gt;</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">-------------------------------------------------------</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">LoggerContextListener</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;">其中一个实现LevelChangePropagator会监听日志环境的合适的生命周期，并把日志级别的变化传播给JUL，这样JUL关闭的日志不会再传递给slf4j，用这种方式对性能冲击较小，适合jul-to-slf4j的桥接包。</div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div><div style="font-family: Tahoma; line-height: normal; orphans: 2; text-align: -webkit-auto; widows: 2; font-size: medium;"></div></div><img src ="http://www.blogjava.net/watchzerg/aggbug/415748.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/watchzerg/" target="_blank">王星游</a> 2014-07-13 18:56 <a href="http://www.blogjava.net/watchzerg/archive/2014/07/13/415748.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>