2012-05-05 53 views
15

我在我的war文件lib文件夾中部署了logback,並且在classes文件夾中有以下logback.xml。Tomcat WAR - 將Logback配置爲在路徑中使用應用程序名稱

<?xml version="1.0" encoding="UTF-8" ?> 
<configuration> 
    <property name="destination" value="${catalina.base:-./temp}/logs/${appName:-myapp}" /> 

    <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
    <file>${destination}.log</file> 
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 
     <!-- rollover daily --> 
     <fileNamePattern>${destination}-%d{yyyy-MM-dd}.%i.log</fileNamePattern> 
     <!-- Keep logs for 7 days --> 
     <maxHistory>7</maxHistory> 

     <timeBasedFileNamingAndTriggeringPolicy 
      class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> 
     <!-- or whenever the file size reaches 100MB --> 
     <maxFileSize>100MB</maxFileSize> 
     </timeBasedFileNamingAndTriggeringPolicy> 
    </rollingPolicy> 
    <encoder> 
     <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> 
    </encoder> 
    </appender> 

    <root level="error"> 
    <appender-ref ref="ROLLING" /> 
    </root> 
</configuration> 

在第3行我有一些變量替換爲我的日誌文件創建路徑。

<property name="destination" value="${catalina.base:-./temp}/logs/${appName:-myapp}" /> 

我想讓它這樣部署${appName}評估戰爭文件的當前名稱。

所以,如果我的web應用程序的文件夾看起來像這樣

webapps 
- myapp.war 
- myapp-dev.war 

${destination}屬性myapp.war將評估爲.../logs/myapp和MYAPP-dev.war將評估爲.../logs/myapp-dev。有沒有JNDI屬性或我可以訪問的appName訪問?我想避免不得不手動重新配置記錄器。

謝謝!

+0

我不知道有這樣做的方法。 JULI(Tomcat的內置日誌記錄)有一個增強請求:https://issues.apache.org/bugzilla/show_bug.cgi?id=43682 –

+1

這是一篇關於這個問題的另一個解決方案的博客文章:https ://0x0a14.de/adding-the-context-root-to-a-logback-config-file-path/ –

回答

10

編輯2013-06:我已將此Listener作爲Maven Central上的OSS提供。檢查出project homepage

是的,這是可行的。首先,你總是可以依靠catalina.base,因爲沒有它,Tomcat將無法運行。爲了將上下文名稱注入爲屬性。編寫一個上下文listener,它將把上下文名稱放入JNDI上下文中並在關閉時刪除。完成之後,可以使用logback直接使用JNDI檢索值。有直接的支持。把它寫在contextName元素中,你就完成了。

我已經實現了這個對我自己和它的作品對我所有的項目。如果您或其他人有興趣,我可以在星期一分享整個代碼。

編輯,這裏是代碼:

import org.apache.catalina.Context; 
import org.apache.catalina.Lifecycle; 
import org.apache.catalina.LifecycleEvent; 
import org.apache.catalina.LifecycleListener; 
import org.apache.catalina.deploy.ContextEnvironment; 
import org.apache.commons.lang.StringUtils; 
import org.apache.juli.logging.Log; 
import org.apache.juli.logging.LogFactory; 

public class LogbackContextNameListener implements LifecycleListener { 

    private static final Log logger = LogFactory 
      .getLog(LogbackContextNameListener.class); 
    private Context context; 

    private String name = "logback/contextName"; 

    @Override 
    public void lifecycleEvent(LifecycleEvent le) { 

     if (le.getLifecycle() instanceof Context) 
      context = (Context) le.getLifecycle(); 
     else 
      return; 

     if (le.getType().equals(Lifecycle.START_EVENT)) { 
      ContextEnvironment ce = new ContextEnvironment(); 
      ce.setName(getName()); 
      ce.setOverride(false); 
      ce.setType("java.lang.String"); 
      String value = StringUtils.remove(context.getServletContext() 
        .getContextPath(), '/'); 
      ce.setValue(value); 
      logger.debug(String.format("Adding env entry '%s' with value '%s'", 
        getName(), value)); 
      context.getNamingResources().addEnvironment(ce); 
     } 

     if (le.getType().equals(Lifecycle.STOP_EVENT)) { 
      logger.debug(String.format("Removing env entry '%s'", getName())); 
      context.getNamingResources().removeEnvironment(name); 
     } 

    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     if (StringUtils.isEmpty(name)) 
      throw new IllegalArgumentException(
        "Parameter 'name' cannot be empty"); 

     this.name = name; 
    } 

} 

合適的配置是這樣的:

<configuration scan="true" scanPeriod="30 minutes"> 

    <insertFromJNDI env-entry-name="java:comp/env/logback/contextName" as="contextName" /> 
    <contextName>${contextName}</contextName> 

    <appender name="FILE" 
     class="ch.qos.logback.core.rolling.RollingFileAppender"> 
     <file>${catalina.base}/logs/${CONTEXT_NAME}.log</file> 
     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 
      <!-- daily rollover --> 
      <fileNamePattern>${catalina.base}/logs/${CONTEXT_NAME}.log.%d.gz</fileNamePattern> 
      <maxHistory>30</maxHistory> 
     </rollingPolicy> 
     <encoder> 
      <pattern>%-27(%d{HH:mm:ss.SSS} [%.-12thread]) %-5level %logger{36} - %msg%n</pattern> 
     </encoder> 
    </appender> 

    <root level="INFO"><!-- WARN --> 
     <appender-ref ref="FILE" /> 
    </root> 

</configuration> 

這完美的作品在Tomcat的6我想,這將在Tomcat 7運行W/o變化。

+1

雖然我認爲這種方法運行良好,但它需要我將tomcat添加爲依賴項。有沒有辦法用ServletContextListener來完成它? – HaxElit

+0

您不需要依賴關係。這不屬於你的應用程序,而是屬於tomcat/lib中的獨立JAR。不,這不能從應用程序中完成。 JDNI上下文在應用程序內是隻讀的。 –

+0

哦,謝謝澄清。你還可以包括我需要做的配置更改讓tomcat使用我的偵聽器嗎?謝謝 – HaxElit

4

這建立在Michael-O的答案上。考慮到在Tomcat下運行時catalina.base始終是一個定義的系統屬性,我們只需要擔心定義appName。 Logback提供對retrieving variables from JNDI的支持。如果應用程序名稱在JNDI定義,你的配置文件就變成了:

<configuration> 
    <!-- retrieve appName from JNDI to set the variable appName --> 
    <insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" /> 
    <!-- let the context name be the applicaiton name --> 
    <contextName>${appName}</contextName> 

    <property name="destination" 
      value="${catalina.base:-./temp}/logs/${CONTEXT_NAME:-myapp}" /> 

    <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
    <file>${destination}.log</file> 
    ... remainder of config file omitted for brevity 
    </appender> 
</configuration> 

我想提一提,你也只是直接logback.xml,而不是在JNDI定義程序的名字。 (畢竟,logback.xml文件隨您的web-app提供,其名稱已經建立,但您的問題明確排除了這個假設)。xml文件可以簡化爲:

<configuration> 
    <contextName>the_name_of_your_webapp</contextName> 
    <property name="destination" 
      value="${catalina.base:-./temp}/logs/${CONTEXT_NAME:-myapp}" /> 
    ... the rest omitted for brevity 
</configuration? 

BTW,一旦你找到一個滿意的解決方案,不要猶豫張貼的logback用戶列表分享。

+0

Ceki,如果你願意,我可以打開一個JIRA票將我的'Listener'捐給LogBack。它非常有用。 –

+0

當然,我一直在尋找貢獻。 – Ceki

+0

Ticket created:http://jira.qos.ch/browse/LBCLASSIC-329 –

0

maxHistory並不意味着日誌文件的數量。這意味着數月。

相關問題