案例十9、分析Tomcat日誌

若是大家公司服務器上跑的是java的代碼,那多半會使用Tomcat,而Tomcat出現問題,咱們就不得不去查看Tomcat日誌。Tomcat有一個總日誌叫catalina out,它記錄了Tomcat相關的信息,包括正確的和錯誤的。該案例的需求背景是:html

服務器上跑着4個Tomcat實例,目錄結構以下:java

/opt/TOMCAT/
├── crontabs
├── t1
├── t2
├── t3
└── t4

而catalina out所在路徑以下:web

/opt/TOMCAT/t1/logs/catalina.out
/opt/TOMCAT/t2/logs/catalina.out
/opt/TOMCAT/t3/logs/catalina.out
/opt/TOMCAT/t4/logs/catalina.out

具體需求以下:shell

1)腳本能夠取Tomcat實例t1-t4的日誌,經過參數指定是哪個。apache

2)腳本能夠自定義取日誌的起始位置,好比取今天早上10點以後到如今的日誌,要求提供的時間爲24小時制。vim

3)腳本能夠自定義取日誌的起始和結束位置,好比取今天早上9點到20點的日誌,要求提供的時間爲24小時制。tomcat

4)第一個參數爲哪個Tomcat(t一、t二、t三、t4),第二個參數爲起始時間點(只考慮當天的時間),第三個參數爲結束時間點,能夠省略,若是省略則爲當前時間點。bash

5)提供的時間點須要判斷合法性,即必須爲12:00:00這種格式。服務器


日誌片斷以下:oracle

Aug 22,2019 15:58:33 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Aug 22,2019 16:38:23 PM org.apahce.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Aug 22,2019 16:45:46 PM org.apahce.catalina.startup.Catalina start
INFO: Server startup in 2102 ms



知識點一:Tomcat介紹和安裝

Tomcat是一個web容器,咱們主要用它來運行servlet和JSP。Tomcat自己也是一個http服務器,它能夠像Apache或者Nginx那樣解析HTML網頁、JS、CSS以及圖片等元素,但它最主要的功能是用來運行Servlet或JSP。關於Tomcat涉及到一些JAVA相關的概念,下面簡單作一個羅列。

JAVAEE  Java Plateform Enterprise Edition   企業版本,用來作網站的
JAVASE  Java Plateform Standard Edition   標準版本,用來作電腦上運行的軟件的
JAVAME  Java Plateform Micro Edition      微型版本,作手機軟件的
JDK    Java Development kit       Java的開發和運行環境,JDK=Java開發工具+JRE
JRE    Java Runtime Environment   Java程序的運行環境,包括Java運行所須要的類庫和JVM
JVM    Java虛擬機
jar  (Java application archive)包含class和一些資源和配置文件的壓縮包
war  (web application archive)與jar基本相同,會包含所有的web應用程序,Tomcat會自動將其部署

上面提到了Servlet和JSP,它們兩者的區別主要有如下幾點:

1)在html代碼中內嵌Java代碼就是jsp,而servlet是純Java代碼寫的。

2)jsp主要用來展示頁面效果,而servlet主要負責邏輯控制。

3)用戶第一次運行jsp時,會自動轉換爲servlet代碼,因此說jsp本質上就是一種servlet。

4)第一次訪問servlet時,會將其編譯爲類文件,後續能夠直接訪問類文件。


關於Tomcat的安裝,這裏簡單列一下步驟,供參考:

1.安裝jdk(如下方法二選一)

方法一:yum安裝java-1.8.0-openjdk

# yum install -y java-1.8.0-openjdk

方法二:安裝Oracle官方版jdk

1)到https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 下載jdk8

2)解壓並更名/usr/local/jdk1.8

3)編輯配置文件/etc/profile,增長以下內容到最後:

JAVA_HOME=/usr/local/jdk1.8/
JAVA_BIN=/usr/local/jdk1.8/bin
JRE_HOME=/usr/local/jdk1.8/jre
PATH=$PATH:/usr/local/jdk1.8/bin:/usr/local/jdk1.8/jre/bin
CLASSPATH=/usr/local/jdk1.8/jre/lib:/usr/local/jdk1.8/lib:/usr/local/jdk1.8/jre/lib/charsets.jar


2.安裝Tomcat(版本爲9.0)

1)下載二進制包,下載地址爲https://tomcat.apache.org/download-90.cgi

2)解壓並更名/usr/local/tomcat

3)啓動/usr/local/tomcat/bin/startup.sh


知識點二:Tomcat單擊多實例

單擊多實例,就是在一臺服務器上跑多個Tomcat服務。其實想要運行Tomcat,不只須要Tomcat的主程序文件(好比/usr/local/tomcat/bin下的二進制文件),還須要配置文件等輔助類文件。要想跑多個Tomcat服務,能夠只須要一份主程序文件便可,不一樣的Tomcat服務使用不一樣的配置文件便可。因此,要想實現單擊多實例,能夠這樣規劃一下目錄,如圖:

111.png

其中CATALINA_HOME指的是Tomcat安裝目錄(若是你按照個人方法安裝,那麼就是在/usr/local/tomcat),CATALINA_BASE爲實例所在目錄。CATALINA_HOME路徑下只須要包含bin和lib目錄,而CATALINA_BASE只存放conf、webapps、logs等這些文件,這樣部署的好處在於升級方便,配置及安裝文件間互不影響,在不影響Tomcat實例的前提下,替換掉CATALINA_HOME中的安裝文件。


具體的部署步驟以下:

1.建立實例目錄

# mkdir -p /data/tomcat-instance
# mkdir /data/tomcat-instance/www.123.com
# cd !$
# cp -r /usr/local/tomcat/conf /data/tomcat-instance/www.123.com/

2.建立Tomcat服務相關目錄

# mkdir -p /data/tomcat-instance/www.123.com/{common,logs,temp,server,shared,webapps,work}

3.建立啓動和關閉腳本

# cd /data/tomcat-instance/www.123.com
# vim start.sh  //啓動腳本
#!/bin/bash
export CATALINA_HOME=/usr/local/tomcat
export CATALINA_BASE=/data/tomcat-instance/www.123.com
TOMCAT_ID=`ps aux |grep "java"|grep "Dcatalina.base=$CATALINA_BASE "|grep -v "grep"|awk '{ print $2 }'`
if [ -n "$TOMCAT_ID" ]
then
    echo "tomcat(${TOMCAT_ID}) still running now , please shutdown it first";
    exit 2;
else
       $CATALINA_HOME/bin/startup.sh
    if [ "$?" = "0" ]; then
        echo "start succeed"
    else
        echo "start failed"
    fi
fi

# vim shutdown.sh  //關閉腳本
#!/bin/bash
export CATALINA_HOME=/usr/local/tomcat
export CATALINA_BASE=/data/tomcat-instance/www.123.com
TOMCAT_ID=`ps aux |grep "java"|grep "Dcatalina.base=$CATALINA_BASE "|grep -v "grep"|awk '{ print $2}'`
if [ -n "$TOMCAT_ID" ] ; then
    TOMCAT_STOP_LOG=`$CATALINA_HOME/bin/shutdown.sh`
       if [ "$?" = "0" ]; then
        echo "stop succeed"
    else
        echo "stop failed"
    fi
else
    echo "Tomcat instance not found"
    exit
fi

4.編輯配置文件

# cd /data/tomcat-instance/www.123.com/conf
# vim server.xml  //修改三個端口,目的是爲了避免和其餘實例衝突

有了第一個實例後,第二個實例能夠直接複製/data/tomcat-instance/www.123.com目錄,而後修改對應的配置、啓動腳本、中止腳本內容。


知識點三:shell腳本的參數個數

在前面的案例中屢次用到$1,$2,即shell腳本的參數。和參數相關的還有一個經常使用的概念,那就是shell腳本參數的個數。先看示例腳本:

# vim pa_nu.sh
#!/bin/bash
echo "腳本有$#個參數"

執行腳本,過程以下:

# sh pa_nu.sh 1 a
腳本有2個參數
# sh pa_nu.sh 
腳本有0個參數
# sh pa_nu.sh a b c
腳本有3個參數

因此,結論就是在shell腳本中用$#表示腳本的參數個數。


知識點四:判斷一個時間是否合法

若是使用傳統的方法,去比對時、分、秒的範圍是能夠作到,可是這樣太繁瑣,有一個簡單的方法,以下:

# date -d "19:60:" +%s
date: 無效的日期"19:60:"
# date -d "19:59" +%s
1566561540

就是用date命令來作。


知識點五:將24小時制的時間轉換爲12小時制

直接看命令,以下:

# date -d "17:13:14" +%r
05:13:14 PM

也能夠直接判斷一個時間是AM仍是PM

# date -d "17:13:14" +%p   //小寫字母p
PM

若是想用小寫的,也能夠作到:

# date -d "9:10:33" +%P  //大寫字母P
am


知識點六:比較兩個時間大小

比較時間大小,只能經過時間戳來實現,以下:

# t1=`date -d "13:22:32" +%s`
# t2=`date -d "15:00:00" +%s`
# if [ $t1 -lt $t2 ]; then echo "t1比t2要早"; else echo "t1比t2要晚"; fi
t1比t2要早
# if [ $t1 -lt $t2 ]; then echo "t1比t2要早"; else echo "t1比t2要晚"; fi
t1比t2要晚


本案例參考腳本

#!/bin/bash
#截取指定Tomcat的日誌片斷
#做者:
#日期:

LANG=en
logfile="/opt/TOM/$1/logs/catalina.out"

#將當天的英文月、數字日期、數字年做爲變量賦值給d_mdy
d_mdy=`date "+%b %d, %Y"`

#判斷參數個數
if [ $# -ne 2 ] && [ $# -ne 3 ]
then
    echo "你提供的參數個數不對,請提供2個或者3個參數。例:sh $0 t1 08:01:00 14:00:00" 
    exit 1
fi

#判斷第一個參數是否符合要求
if ! echo $1|grep -qE '^t1$|^t2$|^t3$|^t4$'
then
    echo "第一個參數必須是t一、t二、t3或t4"
    exit 1
fi

#判斷時間有效性
judge_time()
{
    date -d "$1" +%s &>/dev/null
    if [ $? -ne 0 ]
    then
        echo "你提供的時間$1格式不正確"
        exit 1
    fi
}

#判斷提供的時間點是否在日誌中出現
judge_time_in_log()
{
    if ! grep -q "$d_mdy $(tr_24_12 $1)" $logfile
        then
            echo "你提供的時間$1在日誌$logfile中未曾出現,請換一個時間點"
            exit 1
        fi
}

#將24小時制時間轉換爲12小時
tr_24_12()
{
    date -d "$1" +%r
}

#判斷第2個參數是否合法
judge_time $2

#判斷起始時間點是否出如今日誌裏
judge_time_in_log $2

#若是提供第3個參數
if [ $# -eq 3 ]
then
    #判斷第3個參數是否合法
    judge_time $3

    #判斷起始時間是否早於結束時間
    t1=`date -d "$2" +%s`
        t2=`date -d "$3" +%s`
        if [ $t2 -lt $t1 ]
        then
            echo "你提供的時間$2比$3要晚,應該把早的時間放到前面"
            exit
        fi

        #判斷提供的結束時間點是否出如今日誌中
        judge_time_in_log $3
fi


#取起始時間所在行行號
begin_n=`grep -n "$d_mdy $(tr_24_12 $2)" $logfile|head -1|awk -F ':' '{print $1}'`

#取結束時間所在行行號,並用sed截取日誌內容
if [ $# -eq 3 ]
then
    n=`grep -n "$d_mdy $(tr_24_12 $3)" $logfile|tail -1|awk -F ':' '{print $1}'`
    #結束日期所在行的下一行纔是日誌的內容
    end_n=$[$n+1]
    sed -n "$begin_n,$end_n"p $logfile
else
    sed -n "$begin_n,$"p $logfile
fi
相關文章
相關標籤/搜索