tomcat中的幾種log catalina localhost

體會

catalina.out

catalina.log 是tomcat的標準輸出(stdout)和標準出錯(stderr)


cataliana.{yyyy-MM-dd}.log和localhost.{yyyy-MM-dd}.log

是通過logging.properties配置的tomcat自己運行的一些日誌

catalina.log 是tomcat自己運行的一些日誌

localhost.{yyyy-MM-dd}.log主要是應用初始化(listener, filter, servlet)未處理的異常最後被tomcat捕獲而輸出的日誌


日誌是程序員居家旅行必備,哦不對,是定位問題,修復bug,甚至是驗證應用是否正常的必備利器。甚至很多時候,我們做一次部署僅僅是爲了加一行log。雖然現在有各種各樣的問題診斷工具,但是在定位線上問題時,我們很多時候還是希望有打印良好的log。


打印良好的log很重要,但是知道我們需要的log在哪裏也很重要。因爲各種各樣的原因,我們經常會將log打到不同的文件中,這樣就導致了出問題找幾個日誌文件的情況。


這不,默認情況下tomcat就會生成幾個日誌文件:catalina.out, catalina.{yyyy-MM-dd}.log, localhost.{yyyy-MM-dd}.log。(嗯,這裏說的是默認情況下,這些都是可以配置修改的)。


這幾個不同的日誌文件裏的內容也不盡相同,查問題也要看不同的日誌文件,如果沒找到文件,甚至都無法瞭解真正的問題是什麼。

我們先來看看這幾個日誌都是怎麼產生的,然後來了解一下什麼樣子的東西會出現在哪個日誌文件。


catalina.out

catalina.out其實是tomcat的標準輸出(stdout)和標準出錯(stderr),這是在tomcat的啓動腳本里指定的,如果沒有修改的話stdout和stderr會重定向到這裏。所以我們在應用裏使用System.out打印的東西都會到這裏來。另外,如果我們在應用裏使用其他的日誌框架,配置了向Console輸出的,則也會在這裏出現。比如以logback爲例,如果配置ch.qos.logback.core.ConsoleAppender則會輸出到catalina.out裏。


cataliana.{yyyy-MM-dd}.log和localhost.{yyyy-MM-dd}.log

這兩個日誌都是通過logging.properties配置的(默認情況下,啓動腳本里指定了java.util.logging.config.file和java.util.logging.manager兩個變量)。一個典型的logging.properties可能如下所示:

handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler

1catalina.org.apache.juli.FileHandler.level = INFO
1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.FileHandler.prefix = catalina.

2localhost.org.apache.juli.FileHandler.level = FINE
2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
2localhost.org.apache.juli.FileHandler.prefix = localhost.

java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler

這個文件大致的意思是,root輸出到catalina和console。而這裏的catalina按照配置對應的是catalina.{yyyy-MM-dd}.log,這裏的console最終會輸出到catalina.out。這就是我們看到catalina.{yyyy-MM-dd}.log和catalina.out的日誌很多都是一樣的原因。


配置文件中還有一個localhost,所有logname或parent logname爲org.apache.catalina.core.ContainerBase.[Catalina].[localhost]的都會輸出到localhost.{yyyy-MM-dd}.log文件。而這個logname又代表着什麼呢?在tomcat中有一個server.xml的配置文件,其中有這麼一個片段:

<Engine name="Catalina" defaultHost="localhost">
 <Host name="localhost"  appBase="webapps"
       
unpackWARs="false" autoDeploy="false">
 </Host>
</Engine>

我們可以這麼簡單的理解: 一個Tomcat進程對應着一個Engine,一個Engine下可以有多個Host(Virtual Host),一個Host裏可以有多個Context,比如我們常常將應用部署在ROOT下還是webapps裏其他目錄,這個就是Context。


這其中Engine對應着tomcat裏的StandardEngine類,Host對應着StandardHost類,而Context對應着StandardContext。這幾個類都是從ContainerBase派生。這些類裏打的一些跟應用代碼相關的日誌都是使用ContainerBase裏的getLogger,而這個這個logger的logger name就是: org.apache.catalina.core.ContainerBase.[current container name].[current container name]...


而我們一個webapp裏listener, filter, servlet的初始化就是在StandardContext裏進行的,比如ROOT裏有一個listener初始化出異常了,打印日誌則logger name是org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/]。這其中Catalina和localhost是上面xml片段裏的Engine和Host的name,而[/]是ROOT對應的StandardContext的name。所以listener, filter, servlet初始化時的日誌是需要看localhost.{yyyy-MM-dd}.log這個日誌的。比如現在我們使用Spring,Spring的初始化我們往往是使用Spring提供的一個listener進行的,而如果Spring初始化時因爲某個bean初始化失敗,導致整個應用沒有啓動,這個時候的異常日誌是輸出到localhost中的,而不是cataina.out中。所以有的時候我們應用無法啓動了,然後找catalina.out日誌,但最後也沒有定位根本原因是什麼,就是因爲我們找的日誌不對。但有的時候catalina.out裏也有我們想要的日誌,那是因爲我們的應用或使用的一些組件自己捕獲了異常,然後將其打印了,這個時候如果恰好這些日誌被我們配置成輸出到console,則這些日誌也會在catalina.out裏出現了。


總結

那麼總結起來,catalina.out即標準輸出和標準出錯,所有輸出到這兩個位置的都會進入catalina.out,這裏包含tomcat運行自己輸出的日誌以及應用裏向console輸出的日誌。catalina.{yyyy-MM-dd}.log是tomcat自己運行的一些日誌,這些日誌還會輸出到catalina.out,但是應用向console輸出的日誌不會輸出到catalina.{yyyy-MM-dd}.log。localhost.{yyyy-MM-dd}.log主要是應用初始化(listener, filter, servlet)未處理的異常最後被tomcat捕獲而輸出的日誌,而這些未處理異常最終會導致應用無法啓動。


最後想想,這裏分幾個日誌文件其實不利於問題查找,爲啥不乾脆都輸出到catalina.out裏呢?我想tomcat作爲通用容器本身,可能考慮到Engine下有多個Host,每個Host的日誌還是要輸出到不同的文件。而實際中我們往往是單容器,單Host,甚至是隻有一個ROOT的Context。所以對於這種情況,我覺得是可以將所有日誌都輸出到catalina.out方便查問題,特別是那些還不知道初始化失敗應該去看localhost日誌的同學。嗯,可以和運維商量一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章