2011年3月3日 星期四

[Unix] 簡易分析 Squid 產生的 log @ FreeBSD

squid_log


使用 awk 跟 bash 寫了一隻簡單的 script ,用來分析 squid 產生的 log。不過也發現網路上還滿多分析的工具,但我只需要在 cmd mode 下呈現簡單的資訊,如某個 IP 連線次數、起始時間、最後使用時間,這樣的資訊而以,最後就想到用 awk 能很方便處理,因為 squid log 得格式很簡單,更正確來說,在我的需求面上都很簡單 XD 只要透過 awk 建一個 hash 來記錄 IP 出現的次數、使用時間等,就完成收工了,如:awk '{ if( ip_hash[$3]) ip_hash[$3]++ ; else ip_hash[$3] = 1; } END { for( ip in ip_hash ) print ip , ip_hash[ip]; }' access.log。然而,就突然想要複習一下 bash 提供多一點參數,不小心就跌入萬丈深淵啦,說真的乾脆直接用 Perl、Python 做就好了!不過某總管長輩說,在 FreeBSD 系統預設是沒有裝那種東西的,所以 bash 還是佔有一席之地啊。此程式僅適用於 FreeBSD 系統吧?至少 Ubuntu 因為 date 指令不適用,其他相關筆記:[Unix] 透過指令進行 date 與 timestamp 轉換 @ FreeBSD[Unix] awk 與 bash script 的使用 @ FreeBSD


此程式接受 3 個參數,必要的 access.log 檔案,兩個次要的參數是 -date 跟 -range ,其中 -date 是指定要從此刻時間分析,而 -range 是與起始時間相距的秒數,可用來限定最多分析到哪個時間點,例如:



  • 分析全部記錄:

    • # sh slog.sh access.log



  • 分析 2011-03-01 起的記錄:

    • # sh slog.sh -date "2011-03-01 00:00:00" access.log



  • 分析 2011-03-01 到 2011-03-02 之間的記錄:

    • # sh slog.sh -date "2011-03-01 00:00:00" -range 86400 access.log




冗長的程式碼:


#!/bin/bash


if [ $# -lt 1 ]; then
echo "Usage> $0 [-date|-range] file"
echo " -date  \"2011-02-14 00:30:40\""
echo " -range \"86400\""
echo
echo "Other Info:"
echo " # date -j -f \"%Y-%m-%d %H:%M:%S\" \"2011-02-14 00:30:40\" \"+%s\""
exit
fi

#date_begin
#date_range
#date_end
#target_file

while [ -n "$1" ]
do
if [ "$1" = "-date" ]; then
shift
if [ -z "$1" ]; then
echo "ERROR: -date BeginDate "
exit
fi
date_begin=$1
elif [ "$1" = "-range" ]; then
shift
if [ -z "$1" ]; then
echo "ERROR: -range Offset"
exit
fi
date_range=$1
else
target_file=$1
fi
shift
done
#
# checking
#
if [ -n "$date_begin" ]; then
echo "[SYS] Data Begin Input: $date_begin"
date_begin=`date -j -f "%Y-%m-%d %H:%M:%S" "$date_begin" "+%s"`
echo "[SYS] Data Begin Timestamp: $date_begin"
fi
if [ -n "$date_range" ]; then
echo "[SYS] Data Range Input: $date_range"
date_end=$(($date_begin+$date_range))
echo "[SYS] Date Begin: $date_begin"
echo "[SYS] Date Finsh: $date_end"
fi
if [ -z "$target_file" ]; then
echo "ERROR: No file"
exit
fi
if [ -f "$target_file" ]; then
else
echo "ERROR: '$target_file' file not exists."
exit
fi

#
# awk profile
#
awk_profile="BEGIN{"
if [ -n "$date_begin" ]; then
awk_profile=$awk_profile"begin_timestamp=$date_begin;"
else
awk_profile=$awk_profile"begin_timestamp=-1;"
fi
if [ -n "$date_end" ]; then
awk_profile=$awk_profile"end_timestamp=$date_end;"
else
awk_profile=$awk_profile"end_timestamp=-1;"
fi


awk_profile=$awk_profile"}\
{\
record_time=\$1;\
record_ip=\$3;\
if((begin_timestamp==-1||record_time>=begin_timestamp)&&(end_timestamp==-1||record_time<=end_timestamp))\
{\
if(ip_hash[record_ip])\
{\
ip_hash[record_ip]++;\
time_end[record_ip]=int(record_time);\
}\
else\
{\
ip_hash[record_ip]=1;\
                        time_begin[record_ip]=int(record_time);\
                        time_end[record_ip]=int(record_time);\
}\
}\
}\
END\
{\
printf \"%20s %10s %30s %30s\\n\",\"IP\",\"Count\",\"Begin Time\",\"End Time\";\
for(ip in ip_hash)\
{\
                record_time_begin = 0 ; record_time_end = 0 ;\
\"date -j -f \\\"%s\\\" \" time_begin[ip] | getline record_time_begin; close(\"date -j -f \\\"%s\\\" \" time_begin[ip]); \
\"date -j -f \\\"%s\\\" \" time_end[ip] | getline record_time_end; close(\"date -j -f \\\"%s\\\" \" time_end[ip]); \
printf \"%20s,%10d,%30s,%30s\\n\",ip,ip_hash[ip],record_time_begin,record_time_end;\
}\
}"


awk_profile_path=`mktemp -t squid.awk.profile` || exit
awk_output_path=`mktemp -t squid.awk.output` || exit
echo "[SYS] Create awk profile: $awk_profile_path"
echo $awk_profile > $awk_profile_path


#cmd="awk '$awk_profile' \"$target_file\""
cmd="awk -f $awk_profile_path $target_file"
echo "[SYS] Execute: $cmd"
echo "[SYS] Save: $awk_output_path"
`$cmd > $awk_output_path` || exit
echo "[Result]"
cat $awk_output_path
echo 
echo "[SYS] Remove logs: rm $awk_profile_path $awk_output_path"


rm $awk_profile_path $awk_output_path


[Unix] 透過指令進行 date 與 timestamp 轉換 @ FreeBSD

記得每次要把日期轉成 timestamp 或是把 timestampe 轉成看得懂的日期時,這時候都是跑去 Google timestamp wiki,接著從那邊找到 web service ,直接跑去用查詢的,而最勤勞的情況就是寫 PHP 去轉 XD 


最近我忍不住了,先 man date 一下,但還是看不出個所以然,於是跑去問 Randy 總管,他馬上跟我說有啊,就用 date 即可,後來還真的發現 FreeBSD 上的 date 有支援,但 Ubuntu 10.04 上的 date 沒有對應的 -j 跟 -f 指令。



  • 將此刻的日期轉成 timestamp

    • # date "+%s"



  • 把指定的日期轉成 timestamp

    • # date -j -f "%Y-%m-%d %H:%M:%S" "2011-03-03 00:00:00" "+%s"
      1299081600



  • 把指定的 timestamp 轉成可讀日期

    • # date -j -f "%s" 1299081600
      Thu Mar  3 00:00:00 CST 2011




上述例子是在 FreeBSD 8.1-RELEASE amd64 的機器上執行。


[Unix] awk 與 bash script 的使用 @ FreeBSD

想說簡單分析一下 squid 產生的 logs ,於是就想到用 bash 與 awk ,不過,過程不是很順利,發現一些 script 使用上的問題,給他筆記一下。



























awk 與 bash script,在 FreeBSD 8.1-RELEASE amd64

#!/bin/sh
touch /tmp/access.log
echo "=== CASE 1 ==="
cmd="awk \"BEGIN{a=1;b=2;}{}END{}\" /tmp/access.log"
echo
echo $cmd
echo
dd=`$cmd`

=== CASE 1 ===


awk "BEGIN{a=1;b=2;}{}END{}" /tmp/access.log


#!/bin/sh
touch /tmp/access.log
echo "=== CASE 2 ==="
cmd="awk 'BEGIN{a=1;b=2;}{}END{}' /tmp/access.log"
echo
echo $cmd
echo
dd=`$cmd`

=== CASE 2 ===


awk 'BEGIN{a=1;b=2;}{}END{}' /tmp/access.log


awk: syntax error at source line 1
 context is
         >>> ' <<<
awk: bailing out at source line 1


#!/bin/sh
touch /tmp/access.log
echo "=== CASE 3 ==="
cmd="awk 'BEGIN{\
        a=1;\
        b=2;\
}{}END{}'
/tmp/access.log"
echo
echo $cmd
echo
dd=`$cmd`


=== CASE 3 ===


awk 'BEGIN{ a=1; b=2;}{}END{}' /tmp/access.log


awk: syntax error at source line 1
 context is
         >>> ' <<<
        missing }
awk: bailing out at source line 1



#!/bin/sh
touch /tmp/access.log
echo "=== CASE 4 ==="
cmd="awk \"BEGIN{\
        a=1;\
        b=2;\
}{}END{}\"
/tmp/access.log"
echo
echo $cmd
echo
dd=`$cmd`


=== CASE 4===


awk "BEGIN{ a=1; b=2;}{}END{}" /tmp/access.log


awk: non-terminated string BEGIN{... at source line 1
 context is
         >>>  <<<
awk: giving up
 source line number 2


#!/bin/sh
touch /tmp/access.log
echo "=== CASE 5 ==="
cmd="awk \"BEGIN{\
a=1;\
b=2;\
}{}END{}\"
/tmp/access.log"
echo
echo $cmd
echo
dd=`$cmd`


=== CASE 5===


awk "BEGIN{a=1;b=2;}{}END{}" /tmp/access.log



簡述一下,在 bash script 使用中,對於 awk 內部的敘述部分,要改用雙引號 " 而不是用單引號 ' ,另外則是敘述句裡頭不能有空白或Tab等。所以搞到最後我就改用 profile 的方式:


#!/bin/sh
touch /tmp/access.log
touch /tmp/awk.profile
awk_profile="BEGIN { \
        a=1;\
        b=2;\
}{}END{}"
echo $awk_profile > /tmp/awk.profile

cmd_out=`awk -f /tmp/awk.profile /tmp/access.log` 


2011年3月1日 星期二

使用 xGPS Manager 製作台灣離線地圖 Zoom Level 0-17

先前在 iPod touch 4 上玩了一下 xGPS ,結果發現 GPS 定位有點問題,找了一些討論,看來 iPod touch 並沒 GPS 天線,導致離線使用時,在外頭並無法進行衛星定位!讓我還滿挫折的,原先一直以為 iPod Touch 4 跟 iPhone 就差在相機的像素跟無法打電話的差別,現在又多了一項了!iPod touch 4 還是適合在 wifi 環境下定位,不然只能說附近的衛星訊號強到可以讓你定位成功 XD


回到主題,之前把玩 xGPS 和 xGPS Manager,覺得這整套軟體還不錯,可以製作離線地圖,實在方便,特別是我家那台美版 iPhone 3G,現在終於可以找到一件事給他做 XD 那就當一台簡單的電子地圖吧!只不過 xGPS 這套軟體,唯一的缺點大概是 UI 操作不是很流暢。


這篇主要是要簡單筆記使用 xGPS Manager 下載全台地圖的大小:


xGPS All Taiwan



  •  環境與設定

    • 勾選 0 ~ 17 全部的 zoom levels

    • 網路速度約 5Mb/s 上下傳





  • 時間花費  

    • 分析待下載的地圖大小,過程約 2~2.5 小時,前面會很慢,大概超過 8% 後會變得比較快並且經過 11% 後就會跳得更快,而最後估計結果是需要 4xxx MB 大小

    • 下載地圖,約 3~3.5 小時





  • 成果


    • 產出 xGPS_map.db 約 1.5 GB (1631596544) 大小




這款 xGPS 適用於 JB 過後的 iOS 設備,改天要來試試 Android 上面的好了,我記得找到的相關文章裡,有一種是產出 SQLite 的,不曉得跟 xGPS 產生的 xGPS_map.db 有什麼差別,另外,網路上可以透過關鍵字找到 1.4GB 的下載位置,但試用的結果並非 0-17 的地圖,這次測試的結果,有 0-17 的地圖可看 :D


2011年2月28日 星期一

幾個 AU-4912 無線網卡的使用問題

最近開始比較常用這張網卡,實在是它的體積很小,很吸引人,之前寫了一篇稍為筆記:USB 無線網卡 - SAPIDO AU-4912 超迷你無線N。用了一陣子,開始發現一些問題,這些問題可能是因為我自己的使用問題,環境資訊:



  • Windows 7 64-bit

  • 網卡數目:主機板內建有線網卡 x1、PCI 有線網卡 x1 、VirtualBox 虛擬網卡 x1,另外,就是這張 USB 無線網卡 x1


其中,我的 OS 有架一個 NAT 服務,也就是上述的 PCI 網卡是拿來架 NAT 的。


問題一:


假設把 AU-4912 架起 Soft AP 時,將導致 PCI 提供的 NAT 服務失效。


這邊可能的解釋是:


對外連線使用主機板內建網卡,當 PCI 網卡提供 NAT 模式時,等同於搶了主機板內建網卡的資源,然而,當啟動 Soft AP 時,此時又變成 AU-4912 網卡搶了系統對外連線資源,導致 PCI 提供的 NAT 服務出了問題。


目前我還沒想到好得解法,大概只有把 Soft AP 關掉時,這時候 PCI 網卡的 NAT 服務才能恢復正常


問題二:


AU-4912 + Windows 7 64-bit


出現藍白當機畫面,顯示資訊關鍵字:RTL8192cu.sys


可能的原因以及解法:


這是因為我買了第二張 AU-4912 無線網卡,把第二張插入主機的 USB 孔時,無論怎樣馬上出現藍白畫面!呈現的內容如上圖。


原先有點失落,也準備去購買的店換一下,只不過工程師的直覺,馬上讓我想到可能的出錯問題:驅動程式與資源的存取,於是開始行動!一開始我想透過 devmgmt.msc 來移除舊的驅動程式,但實在不知該移除哪一項,突然腦筋一轉,直接跑去把 C:\Windows\System32\drivers\rtl8192cu.sys 換個位置(移除驅動程式),於是解決了藍白問題。等同於讓他重新抓驅動程式


這個現象可能是第一張 USB 網卡已經將把相關硬體資訊綁在驅動程式裡,結果第二張 USB 網卡插入時,可能會被當成已經設定 ok ,但當要啟用網卡時就產生問題。我不太確定這個是因為 Windows 7 64-bit 的作業系統的問題,還是 AU-4912 無線網卡本身的設計問題,例如 ID 並非 unique 等


總之,這些現象對一般的使用者來說,應該不太會出現,只能說我使用的環境有些特別吧 Orz  在此順便筆記一下。