天天看點

awstats CGI模式下動态生成頁面緩慢的改進

首先再來總結下awstats的處理過程以及檢視分析結果的兩種方式,來看官方版說明:

Process logs: Building/updating statistics database,建立/更新統計資料庫(包含統計結果的文本檔案)指令如下

  perl awstats.pl -config=mysite -update

Run reports: Building and reading reports(生成并閱讀報告)

1.The first option is to build the main reports, in a static HTML page, from the command line, using the following syntax

  第一種方式,通過指令行生成html檔案,然後浏覽器展示。指令如下

  perl awstats.pl -config=mysite -output -staticlinks > awstats.mysite.html

2.The second option is to dynamically view your statistics from a browser.  To do this, use the URL:

  第二種方式,通過如下的url“動态”的生成該站點的分析報告

  http://www.myserver.mydomain/awstats/awstats.pl?config=mysite

  總體思路就是,既然“動态生成”這個過程耗時,那就在伺服器上定時通過curl 請求每個站點對應的url将生成的html頁面存儲到特定位置,然後浏覽器通路時直接讀取html檔案即可(可能有同學要問了,這麼費事,那為啥不直接用上面的第一種方式,用awstats.pl提供的參數直接生成html檔案呢?這也就回歸到上篇文章中讨論過的兩種方式的差别了,awstats.pl生成的靜态html頁面從易用性和美觀性都不如通過CGI動态生成的html頁面)

  思路有了,接下來就是“嘗試”和“分析特征”。我們直接以

1

<code>curl  -o </code><code>/tmp/mysite</code><code>.html http:</code><code>//www</code><code>.myserver.mydomain</code><code>/awstats/awstats</code><code>.pl?config=mysite</code>

得到的頁面源代碼如下

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<code>&lt;</code><code>html</code> <code>&gt;</code>

<code>&lt;</code><code>head</code><code>&gt;</code>

<code>&lt;</code><code>meta</code> <code>name</code><code>=</code><code>"generator"</code> <code>content</code><code>=</code><code>"AWStats 7.4 (build 20150714) from config file awstats./usr/local/awstats/etc/www.conf.conf (http://www.awstats.org)"</code><code>&gt;</code>

<code>&lt;</code><code>meta</code> <code>name</code><code>=</code><code>"robots"</code> <code>content</code><code>=</code><code>"noindex,nofollow"</code><code>&gt;</code>

<code>&lt;</code><code>meta</code> <code>http-equiv</code><code>=</code><code>"content-type"</code> <code>content</code><code>=</code><code>"text/html; charset=utf-8"</code><code>&gt;</code>

<code>&lt;</code><code>meta</code> <code>http-equiv</code><code>=</code><code>"expires"</code> <code>content</code><code>=</code><code>"Wed Apr 27 11:09:58 2016"</code><code>&gt;</code>

<code>&lt;</code><code>meta</code> <code>http-equiv</code><code>=</code><code>"description"</code> <code>content</code><code>=</code><code>"Awstats - Advanced Web Statistics for www.dddd.com (2015-08) - main"</code><code>&gt;</code>

<code>&lt;</code><code>title</code><code>&gt;Statistics for www.mysite.com (2015-08) - main&lt;/</code><code>title</code><code>&gt;</code>

<code>&lt;/</code><code>head</code><code>&gt;</code>

<code>&lt;</code><code>frameset</code> <code>cols</code><code>=</code><code>"240,*"</code><code>&gt;</code>

<code>&lt;</code><code>frame</code> <code>name</code><code>=</code><code>"mainleft"</code> <code>src</code><code>=</code><code>"awstats.pl?config=mysite&amp;amp;framename=mainleft"</code> <code>noresize</code><code>=</code><code>"noresize"</code> <code>frameborder</code><code>=</code><code>"0"</code> <code>/&gt;</code>

<code>&lt;</code><code>frame</code> <code>name</code><code>=</code><code>"mainright"</code> <code>src</code><code>=</code><code>"awstats.pl?config=mysite&amp;amp;framename=mainright"</code> <code>noresize</code><code>=</code><code>"noresize"</code> <code>scrolling</code><code>=</code><code>"yes"</code> <code>frameborder</code><code>=</code><code>"0"</code> <code>/&gt;</code>

<code>&lt;</code><code>noframes</code><code>&gt;&lt;</code><code>body</code><code>&gt;Your browser does not support frames.&lt;</code><code>br</code> <code>/&gt;</code>

<code>You must set AWStats UseFramesWhenCGI parameter to 0</code>

<code>to see your reports.&lt;</code><code>br</code> <code>/&gt;</code>

<code>&lt;/</code><code>body</code><code>&gt;&lt;/</code><code>noframes</code><code>&gt;</code>

<code>&lt;/</code><code>frameset</code><code>&gt;</code>

<code>&lt;/</code><code>html</code><code>&gt;</code>

可以看到動态生成的頁面實際上是一個包含了兩個frame(mainleft和mainright)的html檔案,也就是說,如果我們想還原一個動态生成的報告頁面,需要通過如下三條指令來生成對應的三個檔案

<code>curl -s -o main.html </code><code>"http://www.myserver.mydomain/awstats/awstats.pl?config=mysite"</code>    <code>#取得首頁面</code>

<code>curl -s -o left.html </code><code>"http://www.myserver.mydomain/awstats/awstats.pl?config=mysite&amp;framename=mainleft"</code>    <code>#取得左frame</code>

<code>curl -s -o right.html </code><code>"http://www.myserver.mydomain/awstats/awstats.pl?config=mysite&amp;framename=mainright"</code>    <code>#取得右frame</code>

然後,需要在 main.html中修改mainleft和mainright兩個frame的src屬性,将其指定到我們生成的left.html和right.html。如此我們就實作了将動态頁面靜态化(實際上是把動态生這個等待時間放到腳本裡定時執行了)。

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

<code>#!/bin/sh</code>

<code>#awstats日志分析</code>

<code>basedir=</code><code>/usr/local/awstats-7</code><code>.4</code>

<code>date_y_m=$(</code><code>date</code> <code>+%Y%m -d </code><code>'1 day ago'</code><code>)    </code><code>#因為該腳本是第二天淩晨分析前一天的日志</code>

<code>year=`</code><code>echo</code> <code>${date_y_m:0:4}`</code>

<code>month=`</code><code>echo</code> <code>${date_y_m:4:5}`</code>

<code>cd</code> <code>$basedir</code>

<code>#循環更新所有站點日志統計資訊</code>

<code>echo</code> <code>-e </code><code>"\e[1;31m-------`date "</code><code>+%F %T</code><code>"`    開始處理---------\n\e[0m"</code> <code>&gt;&gt;logs</code><code>/cron</code><code>.log</code>

<code>for</code> <code>i </code><code>in</code> <code>`</code><code>ls</code> <code>result/`</code>

<code>do</code>

<code>    </code><code>echo</code> <code>-e </code><code>"\e[1;32m -----`date "</code><code>+%F %T</code><code>"`  處理 $i 日志-----\e[0m"</code> <code>&gt;&gt;logs</code><code>/cron</code><code>.log</code>

<code>    </code><code>perl wwwroot</code><code>/cgi-bin/awstats</code><code>.pl -config=etc/$i.conf -lang=cn -update &amp;&gt;&gt;logs</code><code>/cron</code><code>.log</code>

<code>    </code><code>#将動态頁面靜态化,檢視展示頁面結構可得:首頁面基本沒内容,主要靠左右兩個frame來生成内容</code>

<code>    </code><code>#是以可以将每一個站點的展示頁分為三部分來緩存</code>

<code>    </code><code>echo</code> <code>-e </code><code>"\e[1;32m -----`date "</code><code>+%F %T</code><code>"` 分析 $i 生成靜态頁面-----\n\e[0m"</code> <code>&gt;&gt;logs</code><code>/cron</code><code>.log</code>

<code>    </code><code>cd</code> <code>wwwroot</code>

<code>    </code><code>if</code> <code>[ ! -d $i/$date_y_m ];</code><code>then</code> <code>mkdir</code> <code>-p $i/$date_y_m;</code><code>fi</code>

<code>    </code><code>cd</code> <code>$i/$date_y_m</code>

<code>    </code><code>curl -s -o main.html\    </code><code>#首頁面</code>

<code>        </code><code>"http://127.0.0.1/cgi-bin/awstats.pl?month=$month&amp;year=$year&amp;output=main&amp;config=/usr/local/services/awstats-7.4/etc/$site.conf&amp;framename=index"</code>

<code>    </code><code>curl -s -o left.html\    </code><code>#左頁面</code>

<code>        </code><code>"http://127.0.0.1/cgi-bin/awstats.pl?month=$month&amp;year=$year&amp;output=main&amp;config=/usr/local/services/awstats-7.4/etc/$site.conf&amp;framename=mainleft"</code>

<code>    </code><code>curl -s -o right.html\    </code><code>#右頁面</code>

<code>        </code><code>"http://127.0.0.1/cgi-bin/awstats.pl?month=$month&amp;year=$year&amp;output=main&amp;config=/usr/local/services/awstats-7.4/etc/$site.conf&amp;framename=mainright"</code>

<code>    </code><code>#修改main.html裡關于左右兩個frame的引用</code>

<code>    </code><code>sed</code> <code>-i -e </code><code>'s/awstats.pl.*left/left.html/g'</code> <code>-e </code><code>'s/awstats.pl.*right/right.html/g'</code> <code>main.html</code>

<code>    </code><code>#接下來修改上面三個檔案中的超連結部分</code>

<code>    </code><code>sed</code> <code>-i -e </code><code>'s#awstats.pl#http://123.123.123.123/cgi-bin/awstats.pl#g'</code><code>\    #123.123.123.123為公網ip</code>

<code>           </code><code>-e </code><code>'s/charset=.*/charset=utf-8"&gt;/g'</code><code>\</code>

<code>           </code><code>-e </code><code>'s/lang="cn"//g'</code><code>\</code>

<code>           </code><code>main.html left.html right.html</code>

<code>    </code><code>#剩下的事就是去修改nginx index.html頁面的超連結指向</code>

<code>    </code><code>cd</code> <code>$basedir</code>

<code>done</code>

<code>echo</code> <code>-e </code><code>"\e[1;33m-------`date "</code><code>+%F %T</code><code>"`  處理完成---------\n\e[0m"</code> <code>&gt;&gt;logs</code><code>/cron</code><code>.log</code>

<code>#####</code>

<code>#原始請求樣式,</code>

<code>#http://127.0.0.1/cgi-bin/awstats.pl?config=/usr/local/awstats-7.4/etc/heibai.conf 這個url通路該站點最新資料,會産生下面三個請求</code>

<code>#http://127.0.0.1/cgi-bin/awstats.pl?config=/usr/local/awstats-7.4/etc/heibai.conf</code>

<code>#http://127.0.0.1/cgi-bin/awstats.pl?config=/usr/local/awstats-7.4/etc/heibai.conf&amp;framename=mainleft</code>

<code>#http://127.0.0.1/cgi-bin/awstats.pl?config=/usr/local/awstats-7.4/etc/heibai.conf&amp;framename=mainright</code>

<code>#選擇年月之後,會産生如下三個請求</code>

<code>#http://127.0.0.1/cgi-bin/awstats.pl?month=05&amp;year=2016&amp;output=main&amp;config=%2Fusr%2Flocal%2Fawstats-7.4%2Fetc%2Fheibai.conf&amp;framename=index 經過編碼的</code>

<code>#http://127.0.0.1/cgi-bin/awstats.pl?month=05&amp;year=2016&amp;output=main&amp;config=/usr/local/awstats-7.4/etc/heibai.conf&amp;framename=mainleft</code>

<code>#http://127.0.0.1/cgi-bin/awstats.pl?month=05&amp;year=2016&amp;output=main&amp;config=/usr/local/awstats-7.4/etc/heibai.conf&amp;framename=mainright</code>

經過腳本處理之後,在wwwroot目錄下,站點目錄與html檔案會是這個樣子

<a href="http://s1.51cto.com/wyfs02/M01/7F/B6/wKioL1cqEOqRhvxzAAAV65JUv4I766.png" target="_blank"></a>

http://www.myserver.mydomain/www/201605    #表示www站2016年5月的統計頁面

  但是,改造到這裡并不算完,在動态生成的頁面裡,有選擇年和月的下拉框,可以檢視指定年月的統計頁面,如下圖

<a href="http://s5.51cto.com/wyfs02/M01/7F/B5/wKioL1cp_hmxFR28AAAMlr8RRXg686.png" target="_blank"></a>

這個功能會産生一個如下的請求

http://www.myserver.mydomain/cgi-bin/awstats.pl?month=04&amp;year=2016&amp;output=main&amp;config=www.conf&amp;framename=index

仍然是動态請求(即仍然會慢),但按照我們的設計,每個月應該都已經生成了靜态檔案,是以是不需要動态生成的。如何将這個功能點修改為也按照上面靜态url的格式呢,這裡作者首先想到了兩個方案:

  一個是通過js擷取年和月的值,然後在表單的action處拼出所需的url

  另一個是通過nginx的rewrite來實作

經過嘗試和對比,第二種方案更适合這裡的場景,因為第一種涉及到對生成的html檔案内容進行修改,且不止一處,實作起來啰嗦一些;而第二種方案隻需要在nginx裡做配置即可(這裡如何從nginx擷取到參數值并且引用該值算是一個小技巧吧)。

  最終,修改之後的nginx配置檔案如下

<code>server {</code>

<code>    </code><code>listen   800;</code>

<code>    </code><code>root /usr/local/awstats/wwwroot;</code>

<code>    </code><code>access_log /tmp/awstats_access_log access;</code>

<code>    </code><code>error_log /tmp/awstats_nginx.error_log notice;</code>

<code>    </code><code>location / {</code>

<code>        </code><code>index index.html main.html;</code>

<code>    </code><code>}</code>

<code>    </code><code># Static awstats files: HTML files stored in DOCUMENT_ROOT/awstats/</code>

<code>    </code><code>location /awstats/classes/ {</code>

<code>        </code><code>alias classes/;</code>

<code>    </code><code>location /awstats/css/ {</code>

<code>        </code><code>alias css/;</code>

<code>    </code><code>location /awstats/icon/ {</code>

<code>        </code><code>alias icon/;</code>

<code>    </code><code>location /awstats-icon/ {</code>

<code>    </code><code>location /awstats/js/ {</code>

<code>        </code><code>alias js/;</code>

<code>    </code><code># Dynamic stats.</code>

<code>    </code><code>location ~ ^/cgi-bin/(awredir|awstats)\.pl.* {</code>

<code>        </code><code>gzip off;</code>

<code>        </code><code>fastcgi_pass 127.0.0.1:9000;</code>

<code>        </code><code>fastcgi_param SCRIPT_FILENAME $document_root/cgi-bin/fcgi.php;</code>

<code>        </code><code>fastcgi_param X_SCRIPT_FILENAME $document_root$fastcgi_script_name;</code>

<code>        </code><code>fastcgi_param X_SCRIPT_NAME $fastcgi_script_name;</code>

<code>        </code><code>include fastcgi_params;</code>

<code>        </code><code>fastcgi_send_timeout 300;</code>

<code>        </code><code>#為了讓頂部根據時間篩選功能也能用上之前生成的靜态頁面, 其中%2F部分為url編碼後的/,為了取得站點名</code>

<code>        </code><code>if ($query_string ~* "^month=(\d+)&amp;year=(\d+)&amp;output=main&amp;config=.+etc%2F(.+)\.conf&amp;framename=index$") {</code>

<code>            </code><code>set $month $1;</code>

<code>            </code><code>set $year $2;</code>

<code>            </code><code>set $site $3;</code>

<code>            </code><code>rewrite  ^/cgi-bin/awstats\.pl  /$site/$year$month? permanent;</code>

<code>        </code><code>}</code>

<code>    </code><code>expires 12h;</code>

<code>}</code>

最後一點,不要忘了修改“入口檔案”`index.html`哦,js自動生成的超連結要修改,增加及修改下面内容

<code>/*... 省略 ...*/</code>

<code>//一個能計算昨天明天等日期的函數</code>

<code>            </code><code>function GetDateStr(AddDayCount) {</code>

<code>                </code><code>var dd = new Date();</code>

<code>                </code><code>dd.setDate(dd.getDate()+AddDayCount);//擷取AddDayCount天後的日期</code>

<code>                </code><code>var y = dd.getFullYear();</code>

<code>                </code><code>var m = dd.getMonth()+1;//擷取目前月份的日期</code>

<code>                </code><code>var d = dd.getDate();</code>

<code>                </code><code>if (m&lt;</code><code>10</code><code>) {</code>

<code>                    </code><code>return y+"0"+m;    //格式自定義</code>

<code>                </code><code>} else {</code>

<code>                    </code><code>return y+''+m;</code>

<code>                </code><code>}</code>

<code>            </code><code>}</code>

<code>            </code><code>var </code><code>yesterday</code><code>=</code><code>GetDateStr</code><code>(-1);   //計算昨天日期  格式  201604</code>

<code>            </code><code>//向表格填充内容</code>

<code>            </code><code>for (var </code><code>tdid</code><code>=</code><code>0</code><code>;tdid&lt;num;tdid++) {</code>

<code>                </code><code>//依順序擷取各td元素</code>

<code>                </code><code>var </code><code>tdnode</code><code>=</code><code>document</code><code>.getElementById(tdid+1);</code>

<code>                </code><code>//取出每個域名裡的主機名,伺服器端配置檔案命名方式為 “主機名.conf”</code>

<code>                </code><code>var </code><code>hostname</code><code>=</code><code>vhost</code><code>[tdid].split(".abc",1);</code>

<code>                </code><code>//向表格插入域名并且設定超連結</code>

<code>                </code><code>tdnode.innerHTML</code><code>=</code><code>"&lt;a href=\"</code><code>"+hostname+"/"+yesterday+"\"&gt;" +vhost[tdid] +"&lt;/</code><code>a</code><code>&gt;";</code>

<code>      </code><code>/*... 省略 ...*/</code>

<a href="http://s4.51cto.com/wyfs02/M02/89/1B/wKiom1gHghmgIYaYAAEeOgYQVZ8009.png" target="_blank"></a>

主要修改如下圖

ok,到這裡整個改進過程完畢。每個月份的統計結果的首頁面都已經實作了靜态化,檢視時再也不用經曆漫長的等待了!

  PS: 工具再好,也不見得完全适合或者滿足自己的需求,大部分情況下作為“軟體使用者”的運維同胞,應該有這個意識:不隻會用,必要時還能改。共勉!

     本文轉自kai404 51CTO部落格,原文連結:http://blog.51cto.com/kaifly/1770137,如需轉載請自行聯系原作者

繼續閱讀