tomcat日誌集中採集、分析與展示的幾種方法

天府雲創發表於2018-03-13

大家在做分散式web系統的時候,比如那麼多個tomcat,每天都會產生很多的日誌(雖然已經按小時進行日誌拆分了,但日誌內容還是很大,vim查日誌的時候很慢),而且那麼多個tomcat,每個tomcat都要去查詢,這樣日誌查詢會很麻煩,效率很低,想請教大家是如何處理的呢?我趕腳這是個系統設計問題,不知道大家是用的什麼架構和元件來解決這樣的問題的?

一、簡單的方法:Linux下擷取Tomcat日誌,按天擷取日誌內容

tail -f catalina.out 【單機簡單萬能好使,如果要特定條件直接加|grep **即可】

搜尋指定日期日誌檔案: 

sed -n '/^起始日期/,/^結束日期/p' 日誌檔案 > 新檔案(輸出檔案) 

例如:查詢2018-02-15這天的所有日誌內容: 
sed -n '/^2018-02-15/,/^2018-02-16/p' catalina.out > catalina_20180215.out 

前提是catalina.out日誌中的每行都是以日期格式開頭的! 

二、Tomcat日誌配置遠端Syslog(現在升級是Rsyslog)採集

第一步:初始化日誌採集環境
先確保系統中的/var/spool/rsyslog 目錄已存在:
mkdir -v /var/spool/rsyslog
if [ "$(grep Ubuntu /etc/issue)" != "" ]; then
  chown -R syslog:adm /var/spool/rsyslog
fi
第二步:建立Tomcat日誌檔案採集配置
新建Rsyslog的子配置檔案,他通常在/etc/rsyslog.d下,需要/etc/rsyslog.conf去包含這個目錄下的子配置檔案:
vim /etc/rsyslog.d/tomcat-biglog.conf
複製以下內容到tomcat-biglog.conf,注意註釋部分的修改:
$ModLoad imfile
$InputFilePollInterval 10
$WorkDirectory /var/spool/rsyslog
$PrivDropToGroup adm
## 指定日誌格式模板:
$template BiglogFormatTomcat,"%msg%\n"
## Tomcat的catalina.log路徑,根據實際情況修改:
$InputFileName /var/log/tomcat6/catalina.log
$InputFileTag catalina-log
$InputFileStateFile stat-catalina-log
$InputFileSeverity info
$InputFilePersistStateInterval 25000
$InputRunFileMonitor
## Tomcat的catalina.out路徑,根據實際情況修改:
$InputFileName /var/log/tomcat6/catalina.out
$InputFileTag catalina-out
$InputFileStateFile stat-catalina-out
$InputFileSeverity info
$InputFilePersistStateInterval 25000
$InputRunFileMonitor
## Tomcat的host-manager.log路徑,根據實際情況修改:
$InputFileName /var/log/tomcat6/host-manager.log
$InputFileTag host-manager
$InputFileStateFile stat-host-manager
$InputFileSeverity info
$InputFilePersistStateInterval 25000
$InputRunFileMonitor
## Tomcat的initd.log路徑,根據實際情況修改:
$InputFileName /var/log/tomcat6/initd.log
$InputFileTag initd
$InputFileStateFile stat-initd
$InputFileSeverity info
$InputFilePersistStateInterval 25000
$InputRunFileMonitor
## Tomcat的localhost.log路徑,根據實際情況修改:
$InputFileName /var/log/tomcat6/localhost.log
$InputFileTag localhost-log
$InputFileStateFile stat-localhost-log
$InputFileSeverity info
$InputFilePersistStateInterval 25000
$InputRunFileMonitor
## Tomcat的manager.log路徑,根據實際情況修改:
$InputFileName /var/log/tomcat6/manager.log
$InputFileTag manager
$InputFileStateFile stat-manager
$InputFileSeverity info
$InputFilePersistStateInterval 25000
$InputRunFileMonitor
## 注意syslog日誌伺服器接收地址,根據實際情況修改:
if $programname == 'catalina-log' then @10.x.x.x:514;BiglogFormatTomcat
if $programname == 'catalina-log' then ~
if $programname == 'catalina-out' then @10.x.x.x:514;BiglogFormatTomcat
if $programname == 'catalina-out' then ~
if $programname == 'host-manager' then @10.x.x.x:514;BiglogFormatTomcat
if $programname == 'host-manager' then ~
if $programname == 'initd' then @10.x.x.x:514;BiglogFormatTomcat
if $programname == 'initd' then ~
if $programname == 'localhost-log' then @10.x.x.x:514;BiglogFormatTomcat
if $programname == 'localhost-log' then ~
if $programname == 'manager' then @10.x.x.x:514;BiglogFormatTomcat
if $programname == 'manager' then ~
注:通過Rsyslog配置日誌接收端的時候,如上示例@10.x.x.x:514,用於指定接收日誌的伺服器的協議、IP地址和埠號。使用@代表走UDP協議,使用@@代表走TCP協議,冒號後面的514代表接收埠。
第三步:重啟Rsyslog服務,日誌採集開始工作
service rsyslog restart
此時可以通過觀察系統中的Rsyslog日誌,確定是否正常工作。
cat /var/log/messages |grep rsyslog

三、使用ELK等開源軟體進行對tomcat的日誌採集

開源實時日誌分析 ELK 平臺能夠完美的解決我們上述的問題, ELK 由 ElasticSearch 、 Logstash 和 Kiabana 三個開源工具組成,本文件詳細的介紹了ELK軟體安裝步驟以及tomcat日誌收集

ELK+Redis 收集tomcat日誌檔案

Kibana 使用與Tomcat、Nginx 日誌格式處理-https://www.cnblogs.com/zhang-shijie/p/5384624.html

可以採用flume + kafka + storm (Hadoop)來做日誌實時監控或者分析

四、藉助於tomcat日誌分析工具或者軟體

例如awstats和日誌易等  Java程式設計師須知的七個日誌管理工具 - ImportNew http://www.importnew.com/12383.html

五、自己定期研發開發適合自己需求的tomcat日誌分

如何把Tomcat的日誌實時輸出到Web頁面上

    最近做了一個Web版的自動釋出系統。實現了一個把Tomcat的catlina.out日誌輸出到Web頁面的功能,做出來後,生活美好了一點。碼農們不會再為了看日誌來煩我了,以後有時間了準備擴充套件一下,把日誌統一收集,過濾,讓碼農自己玩去,哈哈。作為一個運維狗,自動化一切,然後就有更多時間……了。省略號內容自行腦補。

先看效果

在部署狀態頁面點選檢視日誌,將會開啟日誌頁面,下個圖就是日誌的輸出頁面。

如何把Tomcat的日誌實時輸出到Web頁面上

簡約時尚小清新的日誌頁面出來了,是不是很想一個terminal,有沒有覺得俺弄的頁面很漂亮。哈哈哈哈,寫不好前端的運維不是好DBA。

如何把Tomcat的日誌實時輸出到Web頁面上

剛開始拿到這個需求,咋覺得很難。因為在伺服器上我們看一個日誌,經常會tail -f 看著刷屏的感覺倍爽。如何在web頁面上實現tailf的效果呢?

後來想想這樣實現是可行的。前端寫一個js定時器,不斷的發ajax請求到後臺,每回取出一段日誌。後臺取日誌可以直接呼叫系統命令,或者直接調取shell指令碼,取日誌,判斷日誌檔案是否存在,是否為空,返回資料的起始位置等,都可以交給shell來做。事實上我就是這麼幹的。後臺程式寫一堆shell命令呼叫有點彆扭。想到解決方案之後,實現的過程就比較簡單了。我的開發環境是基於python的Django框架來做的,現在就展示這個功能的實現過程。

Django部分

點選檢視日誌的連結之後會調到views裡的ajxGetLog方法,該方法需要兩個引數,專案id和主機id,這兩個引數主要是用來確定日誌檔案的位置。該方法返回行號。

execcommand是封裝的一個subprocess.Popen的一個工具函式,返回一個列表分別是標準輸出,錯誤輸出和shell returncode

def ajxGetLog(request,pid,hid): 
    project = Project.objects.get(pk=pid) 
    host = Host.objects.get(pk=hid) 
    scriptname = '%s%s'%(base_path,'get_log.sh') 
    res = execcommand(['sh',scriptname,host.hostname,project.servicename]) 
    #如果錯誤輸出不為空,直接返回錯誤輸出 
    if not res[1]: 
        try: 
            #res[0]為行號,如果大於20行,從當前行的上面20行開始輸出,為了使用者體驗,你懂得 
            if int(res[0]) > 20: 
                line = int(res[0]) - 20
            if int(res[0]) == 0: 
                line = 1
            return render(request,'logs.html',{'pid':pid,'hid':hid,'line':line}) 
        except Exception,e: 
            print e 
            return HttpResponse(e) 
    else: 
        return HttpResponse(res[1])

html部分首席寫一個ajax請求,傳遞到後臺取日誌內容的方法,傳遞三個引數專案id,主機id,和行號,後臺將會返回對應行號的日誌內容。該方法程式碼如下:
 def ajxGetLogHandle(request,pid,hid,line): 
    project = Project.objects.get(pk=pid) 
    host = Host.objects.get(pk=hid) 
    scriptname = '%s%s'%(base_path,'get_log.sh') 
    res = execcommand(['sh',scriptname,host.hostname,project.servicename,line])  
    if not res[1] and res[0].strip(): 
        return HttpResponse(res[0]) 
    else: 
        return HttpResponse(500)

Shell部分
實現返回行號和返回日誌內容的功能是一個shell指令碼,上shell
看到shell 是不是很親切,現在知道傳遞的兩個引數的作用了吧,host 和 專案id就是為了確定日誌檔案的路徑,如果命令列引數沒有傳遞行號就返回行號,如果有行號,就返回該行內容。
#!/bin/bash 
set -e 
HOST=$1 
SERVICENAME=$2 
LINENUM=$3 
LOGFILE="/opt/$SERVICENAME/logs/catalina.out"
if [ $LINENUM ];then
    ssh -A -T root@$HOST "sed -n ${LINENUM}p $LOGFILE"
else
    ssh -A -T root@$HOST "wc -l $LOGFILE|awk '{print \$1}'"
fi

前端部分
這部分就是ajax請求了,取出日誌內容,動態新增到頁面上,唯一的一個坑是,setInterval,我原來寫的是一個while的死迴圈,在迴圈體裡日誌取到最後一行的時候break。我擦,邏輯上很流暢有沒有,死活沒效果,死活不工作。後來知道了,while搞的太快,不等後臺返回,就走到下一次迴圈了。要不while裡面來個sleep。要不弄個定時器,後來上了一個定時器,爽歪歪!
<style type="text/css"> 
html,body{background:#000; color:#090;} 
</style> 
  
{% load staticfiles %} 
<div style="margin-top:10px;"> 
<p id='log'></p> 
</div> 
<script src="/static/plugins/jquery/jquery.min.js"></script> 
<script> 
function myalert(){ 
    alert("伺服器提出了一個問題,請找運維尋求答案!") 

$(function(){ 
var line = {{line}} 
var pid = {{pid}} 
var hid = {{hid}} 
$.ajax({ 
    url: "{% url 'autodeploy:ajx_handle_log' pid=pid hid=hid line=line %}", 
    type: 'GET', 
    success: function(data){  
        if(data != 500){ 
          $('#log').append('<p>'+data+'</p>'); 
          var t  = setInterval(function(){ 
            line++  
            var url = "http://"+location.host + '/autodeploy/ajxloghandle/'+pid + '&' + hid + '&' +line 
            $.ajax({ 
                url: url, 
                type: 'GET', 
                success: function(data){ 
                    if(data != 500){ 
                        $('#log').append('<p>'+data+'</p>'); 
                        window.scrollTo(0,document.body.scrollHeight); 
                    }else{ 
                          clearInterval(t); 
                    } 
                }, 
                error: function(data) { 
                    myalert(); 
                    return false; 
                } 
            }); 
          },200);  
        }else{ 
          myalert(); 
        } 
    }, 
    error: function(data) { 
        myalert(); 
        return false; 
    } 
}); 
}); 
  
</script>


【補充知識】linux日誌檔案及日誌分析

1、linux日誌簡介

     Linux系統擁有非常靈活和強大的日誌功能,可以儲存幾乎所有的操作記錄,並可以從中檢索出我們需要的資訊。

大部分Linux發行版預設的日誌守護程式為 syslog(後續升級rsyslog),位於 /etc/syslog 或 /etc/syslogd,預設配置檔案為 /etc/syslog.conf,任何希望生成日誌的程式都可以向 syslog 傳送資訊。 

Linux系統核心和許多程式會產生各種錯誤資訊、警告資訊和其他的提示資訊,這些資訊對管理員瞭解系統的執行狀態是非常有用的,所以應該把它們寫到日誌檔案中去。完成這個過程的程式就是syslog。syslog可以根據日誌的類別和優先順序將日誌儲存到不同的檔案中。例如,為了方便查閱,可以把核心資訊與其他資訊分開,單獨儲存到一個獨立的日誌檔案中。預設配置下,日誌檔案通常都儲存在“/var/log”目錄下。

2、日誌型別

下面是常見的日誌型別,但並不是所有的Linux發行版都包含這些型別:

型別說明
auth使用者認證時產生的日誌,如login命令、su命令。
authpriv與 auth 類似,但是隻能被特定使用者檢視。
console針對系統控制檯的訊息。
cron系統定期執行計劃任務時產生的日誌。
daemon某些守護程式產生的日誌。
ftpFTP服務。
kern系統核心訊息。
local0.local7由自定義程式使用。
lpr與印表機活動有關。
mail郵件日誌。
mark產生時間戳。系統每隔一段時間向日志檔案中輸出當前時間,每行的格式類似於 May 26 11:17:09 rs2 -- MARK --,可以由此推斷系統發生故障的大概時間。
news網路新聞傳輸協議(nntp)產生的訊息。
ntp網路時間協議(ntp)產生的訊息。
user使用者程式。
uucpUUCP子系統
3、常見日誌檔案

所有的系統應用都會在/var/log 目錄下建立日誌檔案,或建立子目錄再建立日誌檔案。如:

我們可以粗略的分為兩類日誌:系統日誌和應用日誌,系統日誌主要存放系統內建程式或系統核心之類的日誌資訊如alternatives.log 、btmp等,應用日誌主要是安裝的第三方應用產生的日誌如tomcat7 、apache2等。

檔案目錄/日誌名稱

記錄資訊
/var/log/alternatives.log系統的一些更新替代資訊記錄,如系統軟體包升級更新,記錄了程式作用,日期,命令,成功與否的返回碼
/var/log/apport.log應用程式崩潰資訊記錄,暫時這方面日誌資訊
/var/log/apt/history.log使用apt-get安裝解除安裝軟體的資訊記錄,包含時間、安裝命令、版本資訊、結束時間等
/var/log/apt/term.log使用apt-get時的具體操作,如 package 的下載開啟等
/var/log/auth.log登入認證的資訊記錄,包含:日期與 ip 地址的來源以及登陸的使用者與工具
/var/log/boot.log系統啟動時的程式服務的日誌資訊
/var/log/btmp錯誤登陸的資訊記錄
/var/log/Consolekit/history控制檯的資訊記錄
/var/log/dist-upgradedist-upgrade這種更新方式的資訊記錄
/var/log/dmesg啟動時,顯示螢幕上核心緩衝資訊,與硬體有關的資訊
/var/log/dpkg.logdpkg命令管理包的日誌。
/var/log/faillog使用者登入失敗詳細資訊記錄
/var/log/fontconfig.log與字型配置有關的資訊記錄
/var/log/kern.log核心產生的資訊記錄,在自己修改核心時有很大幫助
/var/log/lastlog使用者的最近資訊記錄
/var/log/wtmp登入資訊的記錄。wtmp可以找出誰正在登陸進入系統,誰使用命令顯示這個檔案或資訊等
/var/log/syslog系統資訊記錄

Tomcat訪問日誌分析方法

常使用web伺服器的朋友大都瞭解,一般的web server有兩部分日誌:
    一是執行中的日誌,它主要記錄執行的一些資訊,尤其是一些異常錯誤日誌資訊
    二是訪問日誌資訊,它記錄的訪問的時間,IP,訪問的資料等相關資訊。
    
現在我來和大家介紹一下利用tomcat產生的訪問日誌資料,我們能做哪些有效的分析資料?
首先是配置tomcat訪問日誌資料,預設情況下訪問日誌沒有開啟,配置的方式如下:
    編輯 ${catalina}/conf/server.xml檔案.注:${catalina}是tomcat的安裝目錄
    把以下的註釋(<!-- -->)去掉即可。
            <!--
        <Valve className="org.apache.catalina.valves.AccessLogValve"
                 directory="logs"  prefix="localhost_access_log." suffix=".txt"
                 pattern="common" resolveHosts="false"/>
        -->
    其中 directory是產生的目錄 tomcat安裝${catalina}作為當前目錄
    pattern表示日誌生產的格式,common是tomcat提供的一個標準設定格式。其具體的表示式為 %h %l %u %t "%r" %s %b
    但本人建議採用以下具體的配置,因為標準配置有一些重要的日誌資料無法生。
        %h %l %u %t "%r" %s %b %T  
具體的日誌產生樣式說明如下(從官方文件中摘錄):
    * %a - Remote IP address
    * %A - Local IP address
    * %b - Bytes sent, excluding HTTP headers, or '-' if zero
    * %B - Bytes sent, excluding HTTP headers
    * %h - Remote host name (or IP address if resolveHosts is false)
    * %H - Request protocol
    * %l - Remote logical username from identd (always returns '-')
    * %m - Request method (GET, POST, etc.)
    * %p - Local port on which this request was received
    * %q - Query string (prepended with a '?' if it exists)
    * %r - First line of the request (method and request URI)
    * %s - HTTP status code of the response
    * %S - User session ID
    * %t - Date and time, in Common Log Format
    * %u - Remote user that was authenticated (if any), else '-'
    * %U - Requested URL path
    * %v - Local server name
    * %D - Time taken to process the request, in millis
    * %T - Time taken to process the request, in seconds
There is also support to write information from the cookie, incoming header, the Session or something else in the ServletRequest. It is modeled after the apache syntax:
    * %{xxx}i for incoming headers
    * %{xxx}c for a specific cookie
    * %{xxx}r xxx is an attribute in the ServletRequest
    * %{xxx}s xxx is an attribute in the HttpSession
現在我們回頭再來看一下下面這個配置 %h %l %u %t "%r" %s %b %T 生產的訪問日誌資料,我們可以做哪些事?
先看一下,我們能得到的資料有:
    * %h 訪問的使用者IP地址
    * %l 訪問邏輯使用者名稱,通常返回'-'
    * %u 訪問驗證使用者名稱,通常返回'-'
    * %t 訪問日時
    * %r 訪問的方式(post或者是get),訪問的資源和使用的http協議版本
    * %s 訪問返回的http狀態
    * %b 訪問資源返回的流量
    * %T 訪問所使用的時間
    
有了這些資料,我們可以根據時間段做以下的分析處理(圖片使用jfreechart工具動態生成):
  * 獨立IP數統計
  * 訪問請求數統計
  * 訪問資料檔案數統計
  * 訪問流量統計
  * 訪問處理響應時間統計
  * 統計所有404錯誤頁面
  * 統計所有500錯誤的頁面
  * 統計訪問最頻繁頁面
  * 統計訪問處理時間最久頁面
  * 統計併發訪問頻率最高的頁面













分析工具包括兩大部分,一個是後臺解釋程式,每天執行一次對後臺日誌資料進行解析後儲存到資料庫中。

第二個是顯示程式,從資料庫中查詢資料並生成相應的圖表資訊。

~~~好了,碼字很累,今天就到這裡。歡迎各位網友吐槽。說不定還有更好的解決方案。


相關文章