網站伺服器日誌是網站管理的重要依據,Apache 的 access_log 和 error_log 分別記錄了網站的存取情況和錯誤資訊。透過分析這些日誌,可以瞭解網站的流量來源、使用者行為、錯誤型別等關鍵資訊,進而最佳化網站效能、提升使用者經驗並及時排除故障。本文提供的 Shell 指令碼可以自動化這些分析過程,有效提升伺服器管理效率。此外,定期備份伺服器資料也是網站管理的重要環節,本文也提供了一個遠端備份指令碼,可以將重要檔案封裝壓縮後郵寄到指定信箱,確保資料安全。

網站伺服器管理:分析Apache存取日誌

網站伺服器管理與網站內容設計和管理的工作往往是分開的。上一章節提供了主要導向網頁開發者和內容管理者的工具,本章節則展示如何分析網頁伺服器日誌檔、映象網站以及監控網路健康狀態。

解析Apache存取日誌

如果您正在執行Apache或類別似的使用通用日誌格式(Common Log Format)的網頁伺服器,您可以使用Shell指令碼進行大量的快速統計分析。在標準組態中,伺服器會為網站寫入access_logerror_log檔案(通常位於/var/log,但這可能取決於系統)。如果您擁有自己的伺服器,您絕對應該存檔這些寶貴的資訊。

access_log檔案的欄位

欄位
1存取伺服器的主機IP
2-3HTTPS/SSL連線的安全資訊
4特定請求的日期和時區偏移
5呼叫的方法
6請求的URL
7使用的協定
8結果程式碼
9傳輸的位元組數
10參照者(Referrer)
11瀏覽器識別字串

access_log中的典型一行看起來像這樣:

65.55.219.126 - - [04/Jul/2016:14:07:23 +0000] "GET /index.rdf HTTP/1.0" 301 310 "-" "msnbot-UDiscovery/2.0b (+http://search.msn.com/msnbot.htm)"

結果程式碼(第8欄位)301表示請求被視為成功。參照者(第10欄位)表示使用者在請求頁面之前正在存取的頁面的URL。十年前,這將是前一頁的URL;現在,由於隱私原因,它通常是"-",如您所見。

統計日誌檔

可以透過對日誌檔進行行數統計來確定網站的點選次數,並且可以透過比較第一行和最後一行來確設定檔案中條目的日期範圍。

$ wc -l access_log
7836 access_log
$ head -1 access_log ; tail -1 access_log
69.195.124.69 - - [29/Jun/2016:03:35:37 +0000] ...
65.55.219.126 - - [04/Jul/2016:14:07:23 +0000] ...

webaccess指令碼

清單10-1中的指令碼從Apache格式的access_log檔案中生成許多有用的統計資訊。該指令碼期望我們在第1章編寫的scriptbcnicenumber指令碼在PATH中。

#!/bin/bash
# webaccess--分析Apache格式的access_log檔案,提取有用且有趣的統計資訊
bytes_in_gb=1048576

# 您需要更改以下內容以符合您自己的主機名,以幫助篩選出內部參照的點選。
host="intuitive.com"

if [ $# -eq 0 ] ; then
  echo "用法:$(basename $0) 日誌檔" >&2
  exit 1
fi

if [ ! -r "$1" ] ; then
  echo "錯誤:日誌檔 $1 未找到。" >&2
  exit 1
fi

firstdate="$(head -1 "$1" | awk '{print $4}' | sed 's/\[//')"
lastdate="$(tail -1 "$1" | awk '{print $4}' | sed 's/\[//')"

echo "分析日誌檔 $1 的結果"
echo ""
echo " 起始日期:$(echo $firstdate|sed 's/:/ 在 /')"
echo " 結束日期:$(echo $lastdate|sed 's/:/ 在 /')"
hits="$(wc -l < "$1" | sed 's/[^[:digit:]]//g')"
echo " 點選次數:$(nicenumber $hits) (總存取量)"
pages="$(grep -ivE '(.gif|.jpg|.png)' "$1" | wc -l | sed 's/[^[:digit:]]//g')"
echo " 頁面瀏覽量:$(nicenumber $pages) (點選次數減去圖形檔案)"
totalbytes="$(awk '{sum+=$10} END {print sum}' "$1")"
/bin/echo -n " 已傳輸:$(nicenumber $totalbytes) 位元組 "
if [ $totalbytes -gt $bytes_in_gb ] ; then
  echo "($(/usr/local/bin/scriptbc $totalbytes / $bytes_in_gb) GB)"
elif [ $totalbytes -gt 1024 ] ; then
  echo "($(/usr/local/bin/scriptbc $totalbytes / 1024) MB)"
else
  echo ""
fi

# 現在讓我們從日誌檔中抓取一些有用的資料。
echo ""
echo "前10個最受歡迎的頁面是:"
awk '{print $7}' "$1" | grep -ivE '(.gif|.jpg|.png)' | sed 's/\/$//g' | sort | uniq -c | sort -rn | head -10
echo ""
echo "前10個最常見的參照者URL是:"
awk '{print $11}' "$1" | grep -vE "(^\"-\"$|/www.$host|/$host)" | sort | uniq -c | sort -rn | head -10
echo ""
exit 0

#### 程式碼解析:

  • 首先,該指令碼檢查是否提供了日誌檔作為引數,並驗證該檔案是否存在且可讀。
  • 然後,它提取日誌檔的第一個和最後一個日期,分別代表起始和結束日期。
  • 接著,計算總點選次數和頁面瀏覽量(排除圖形檔案)。
  • 再來,計算總傳輸位元組數,並根據大小轉換為GB或MB。
  • 之後,指令碼提取最受歡迎的頁面和最常見的參照者URL,並進行排序和統計。

結果範例

執行該指令碼後,您將獲得類別似以下的結果:

$ webaccess /web/logs/intuitive/access_log
分析日誌檔 access_log 的結果

 起始日期:01/May/2016 在 07:04:49
 結束日期:04/May/2016 在 01:39:04
 點選次數:12,345 (總存取量)
 頁面瀏覽量:6,789 (點選次數減去圖形檔案)
 已傳輸:123,456,789 位元組 (12.3 GB)

前10個最受歡迎的頁面是:
   1234 /index.html
   567 /about.html
   ...

前10個最常見的參照者URL是:
   901 http://www.google.com/search?q=...
   234 http://www.example.com/referrer.html
   ...

網站伺服器管理中的搜尋引擎流量分析

在網站伺服器的管理中,瞭解訪客的來源和行為對於最佳化網站內容和提升使用者經驗至關重要。其中,分析搜尋引擎流量可以提供寶貴的資訊,幫助網站管理者瞭解哪些搜尋引擎帶來了流量,以及使用者使用了哪些關鍵字來找到網站。

搜尋引擎流量分析指令碼

為了實作這一目標,我們可以使用一個名為 searchinfo 的 shell 指令碼。該指令碼的目的是從 Apache 日誌檔案中提取和分析搜尋引擎的流量資訊。

程式碼解析

#!/bin/bash
# searchinfo--Extracts and analyzes search engine traffic indicated in the
# referrer field of a Common Log Format access log
host="intuitive.com" # 變更為你的網域名稱
maxmatches=20
count=0
temp="/tmp/$(basename $0).$$"
trap "$(which rm) -f $temp" 0
if [ $# -eq 0 ] ; then
  echo "Usage: $(basename $0) logfile" >&2
  exit 1
fi
if [ ! -r "$1" ] ; then
  echo "Error: can't open file $1 for analysis." >&2
  exit 1
fi

for URL in $(awk '{ if (length($11) > 4) { print $11 } }' "$1" | \
             grep -vE "(/www.$host|/$host)" | grep '?')
do
  searchengine="$(echo $URL | cut -d/ -f3 | rev | cut -d. -f1-2 | rev)"
  args="$(echo $URL | cut -d\? -f2 | tr '&' '\n' | \
          grep -E '(^q=|^sid=|^p=|query=|item=|ask=|name=|topic=)' | \
          sed -e 's/+/ /g' -e 's/%20/ /g' -e 's/"//g' | cut -d= -f2)"
  if [ ! -z "$args" ] ; then
    echo "${searchengine}: $args" >> $temp
  else
    # 若非已知格式,則顯示整個 GET 字串
    echo "${searchengine} $(echo $URL | cut -d\? -f2)" >> $temp
  fi
  count="$(( $count + 1 ))"
done

echo "Search engine referrer info extracted from ${1}:"
sort $temp | uniq -c | sort -rn | head -$maxmatches | sed 's/^/ /g'
echo ""
echo Scanned $count entries in log file out of $(wc -l < "$1") total.
exit 0

#### 內容解密:

  1. 主迴圈處理:指令碼透過 for 迴圈遍歷日誌檔案中的每個 URL,篩選出包含有效參照網址(referrer)且長度大於 4 的記錄。
  2. 搜尋引擎識別:透過 cutrev 命令組合來提取參照網址的網域名稱。
  3. 搜尋引數提取:使用 grepsed 命令來提取和清理搜尋查詢引數,轉換特殊字元並去除引號。
  4. 結果輸出:將提取的資訊寫入臨時檔案,並最終排序、去重、計數後輸出前 maxmatches 個結果。

使用與結果

執行 searchinfo 指令碼時,只需指定 Apache 日誌檔案的路徑作為引數。指令碼會掃描日誌檔案,提取相關資訊,並輸出搜尋引擎流量分析結果。

範例輸出:

Search engine referrer info extracted from access_log:
   4 online reputation management akado
   4 Names Hawaiian Flowers
   3 norvegian star
   3 disneyland pirates of the caribbean
   3 disney california adventure
   3 colorado railroad
Scanned 771 entries in log file out of 1000 total.

網路伺服器管理中的錯誤日誌分析

網路伺服器的錯誤日誌(error_log)是管理員診斷和解決伺服器問題的重要依據。與存取日誌(access_log)不同,錯誤日誌記錄了伺服器在處理請求過程中遇到的錯誤和異常情況。

錯誤日誌的格式與特點

錯誤日誌的格式與存取日誌有所不同。錯誤日誌的日期格式佔用五個欄位,而存取日誌的日期則是一個緊湊的欄位。此外,錯誤日誌中的錯誤描述部分長度不固定,這使得解析錯誤日誌變得更加複雜。

$ head -1 error_log
[Mon Jun 06 08:08:35 2016] [error] [client 54.204.131.75] File does not exist: /var/www/vhosts/default/htdocs/clientaccesspolicy.xml

錯誤描述的多樣性

錯誤日誌中的錯誤描述多種多樣,可以透過以下命令觀察:

$ awk '{print $9" "$10" "$11" "$12 }' error_log | sort -u
File does not exist:
Invalid error redirection directive:
Premature end of script
execution failure for parameter
premature EOF in parsed
script not found or
malformed header from script

分析錯誤日誌的指令碼

為瞭解析錯誤日誌並提取有用的資訊,可以使用以下的 Bash 指令碼(weberrors):

程式碼解析

#!/bin/bash
# weberrors--掃描Apache錯誤日誌,報告最重要的錯誤,然後列出其他條目
temp="/tmp/$(basename $0).$$"

# 為了使指令碼更好地工作,請根據您的安裝自定義以下三行。
htdocs="/usr/local/etc/httpd/htdocs/"
myhome="/usr/home/taylor/"
cgibin="/usr/local/etc/httpd/cgi-bin/"

sedstr="s/^/ /g;s|$htdocs|[htdocs] |;s|$myhome|[homedir] "
sedstr=$sedstr"|;s|$cgibin|[cgi-bin] "
screen="(File does not exist|Invalid error redirect|premature EOF"
screen=$screen"|Premature end of script|script not found)"
length=5 # 每類別顯示的條目數

checkfor()
{
    grep "${2}:" "$1" | awk '{print $NF}' \
    | sort | uniq -c | sort -rn | head -$length | sed "$sedstr" > $temp
    if [ $(wc -l < $temp) -gt 0 ] ; then
        echo ""
        echo "$2 errors:"
        cat $temp
    fi
}

trap "$(which rm) -f $temp" 0

if [ "$1" = "-l" ] ; then
    length=$2; shift 2
fi

if [ $# -ne 1 -o ! -r "$1" ] ; then
    echo "用法: $(basename $0) [-l len] error_log" >&2
    exit 1
fi

echo "輸入檔案 $1$(wc -l < "$1") 個條目。"
start="$(grep -E '\[.*:.*:.*\]' "$1" | head -1 \
| awk '{print $1" "$2" "$3" "$4" "$5 }')"
end="$(grep -E '\[.*:.*:.*\]' "$1" | tail -1 \
| awk '{print $1" "$2" "$3" "$4" "$5 }')"

#### 內容解密:

  1. temp="/tmp/$(basename $0).$$" 該行程式碼建立了一個臨時檔案,用於儲存中間結果。basename $0取得指令碼名稱,$$代表當前程式ID,以確保臨時檔案的唯一性。
  2. 自定義變數(htdocs、myhome、cgibin): 這三個變數分別代表Apache伺服器中htdocs、使用者主目錄和cgi-bin的路徑,需要根據實際安裝進行調整。
  3. sedstrscreen sedstr用於在輸出中隱藏敏感路徑資訊,而screen變數包含了一組常見的錯誤型別,用於過濾錯誤日誌中的關鍵錯誤。
  4. checkfor() 函式: 此函式用於檢查特定型別的錯誤。它透過grep篩選出相關錯誤,然後使用awksortuniq -c統計錯誤出現的次數,並按頻率排序,最後輸出前$length個結果。
  5. trap 命令: 當指令碼離開時,自動刪除臨時檔案,避免留下垃圾檔案。
  6. 引數處理: 指令碼支援一個可選引數-l len,用於指定每類別錯誤輸出的數量。
  7. 輸入檔案檢查: 如果輸入檔案不存在或不可讀,指令碼會輸出用法提示並離開。

網路伺服器管理自動化指令碼詳解

概述

本文將探討兩個用於網路伺服器管理的Bash指令碼:weberrorsremotebackup。這兩個指令碼分別用於分析Apache錯誤日誌和將重要檔案備份到遠端伺服器。

weberrors指令碼詳解

功能描述

weberrors指令碼用於分析Apache錯誤日誌,識別常見的錯誤型別並統計其出現頻率。

程式碼解析

checkfor "$1" "File does not exist"
checkfor "$1" "Invalid error redirection directive"
checkfor "$1" "Premature EOF"
checkfor "$1" "Script not found or unable to stat"
checkfor "$1" "Premature end of script headers"

內容解密:

  • checkfor函式用於檢查特定的錯誤訊息是否存在於日誌檔案中。
  • $1代表傳遞給指令碼的第一個引數,即日誌檔案的路徑。
  • 指令碼檢查五種常見的Apache錯誤型別。
X grep -vE "$screen" "$1" | grep "\[error\]" | grep "\[client " \
| sed 's/\[error\]/\`/' | cut -d\` -f2 | cut -d\ -f4- \
Y | sort | uniq -c | sort -rn | sed 's/^/ /' | head -$length > $temp

內容解密:

  • 這段程式碼提取日誌中的錯誤訊息並進行統計。
    1. grep -vE "$screen" "$1":排除包含特定畫面輸出的日誌行。
    2. grep "\[error\]" | grep "\[client ":過濾出包含[error][client的日誌行。
    3. sed 's/\[error\]/\/’ | cut -d` -f2 | cut -d\ -f4-`:處理錯誤訊息的格式,提取必要的資訊。
    4. sort | uniq -c | sort -rn:對錯誤訊息進行排序、計數並按計數結果降序排列。
    5. head -$length > $temp:將結果輸出到臨時檔案,限制輸出行數為$length

remotebackup指令碼詳解

功能描述

remotebackup指令碼用於將指定的檔案和目錄封裝壓縮並郵寄到遠端信箱,實作重要資料的異地備份。

程式碼解析

outfile="/tmp/rb.$$.tgz"
outfname="backup.$(date +%y%m%d).tgz"
infile="/tmp/rb.$$.in"
trap "$(which rm) -f $outfile $infile" 0

內容解密:

  • 設定輸出檔案和輸入檔案的名稱,並使用trap命令確保在指令碼離開時刪除臨時檔案。
X while read entry; do
echo "$entry" | sed -e 's/ /\\ /g' >> $infile
done < "$1"

內容解密:

  • 將輸入檔案列表中的檔名進行處理,轉義檔名中的空格,以確保後續命令正確處理檔名。
Y tar czf - $(cat $infile) | \
uuencode $outfname | \
mail -s "${3:-Backup archive for $(date)}" "$2"

內容解密:

  • 將處理後的檔案列表封裝壓縮並郵寄到指定的遠端信箱。
    1. tar czf - $(cat $infile):封裝並壓縮檔案列表中的檔案。
    2. uuencode $outfname:將二進位制壓縮檔編碼為可郵寄的文字格式。
    3. mail -s "${3:-Backup archive for $(date)}" "$2":將編碼後的檔案郵寄到指定的信箱,附帶主題。