awkを通じてログファイルを毎日統計してMySQLに入庫する過程の説明


インターネット会社は毎日ログファイルを統計し、ソフトウェアのインストール量、活躍度など、欲しい情報を掘り起こす.これらの情報はすべて入庫し、展示する必要があります.以下、この実現過程について説明する.
具体的なプロセスは、次のステップに分けられます.
(1)awk統計ログファイル、統計結果をsql文につづる.
(2)shellスクリプトを書き、これらのsql文をライブラリに入れる.
(3)shellスクリプトをlinuxの計画タスクに追加し、毎日未明にタイミングよく実行させ、毎日自動的にログを分析し、ライブラリに入れる.
以下、手順に分けて説明します.
一.awk統計ログファイルをsql文に結合
awkはログファイルの分析に有効なコマンドで、ログを統計することによって、アクティブなユーザー数、アクティブなインストールid、ユーザーのオンライン時間、1日の保存率、および2日の保存率を計算します.1日の留保率は、昨日のログのユーザーが今日のログに残っていることを示します.このうち2日間の保存率は、2日前のログのユーザーが今日のログに表示されていることを示しています.つまり、2日前のユーザーが今日もソフトウェアを使用しています.
ログのフォーマットは次のとおりです.
時間ipバージョンユーザー行動インストールシリアル番号ユーザーidインストールチャネルにインストールされたオペレーティングシステムがソフトウェア上で操作する領域のオペレーティング領域での動作
次に、ログ・データの例をいくつか示します.
23:55:00    211.11.21.81    1.0.0    getActiveUser    00-00-00-00-00-00-01    000000001    web    Windows XP     23:55:05    221.21.31.91   2.0.1   sendMsgClient    00-00-00-00-00-00-02    100000000    web    Windows XP     23:55:05    231.31.41.98   2.0.5   uploadPPimlog    00-00-00-00-00-00-03    000000020    web    Windows 7    main    recent
次はawkコマンドの上記のログファイルの統計です.統計の結果はsql文として出力されます.ファイル名はPP_sql.sh
#!/bin/sh
yesterday=`date -d "-1 day" +%Y-%m-%d` 

if [ "$1" != "" ]; then
	logfile=$1
else
	logfile="/data/PP-log/*PPIm.access.log.$yesterday"
fi

gawk -F"\t" '
	#function getTitle(name){
	#	if(name == "main_user") return "    ";
	#	else return "  ";
	#}
	($3 ~ /^[0-9]+\.[0-9]+\.[0-9]+$/){ #     
	if($4 == "getActiveUser"){
		#       
		user[$3"_"$6] ++;
		#    id  
		install[$3"_"$5] ++;
	}else if($9 == "onlineTime"){
		#        
		tmp = ($11 - $10)/1000;
		if(tmp > 0 && tmp < 86400){
			onlineCount[$3] ++;
			onlineTime[$3] += tmp;
		}
	}
}END{
	for(k in user){
		split(k, arr, "_");
		userOnly[arr[1]] ++;
	}
	for(k in install){
		split(k, arr, "_");
		installOnly[arr[1]] ++;
	}
	#     :  ,    ,     
	for(k in userOnly){
		if(k != "total")
			print "insert into danalysis(analysisdate,version,useractive,installactive) values(\047'$yesterday'\047,\047"k"\047,"userOnly[k]","installOnly[k]")";
	}

	#      :  ,      (s) 
	for(k in onlineTime){
		print "update danalysis set avgonlinetime="onlineTime[k]/onlineCount[k]" where analysisdate=\047'$yesterday'\047 and version=\047"k"\047";
	}

}' $logfile

#             
oneday=`date -d "-2 day" "+%Y-%m-%d"`
twoday=`date -d "-3 day" "+%Y-%m-%d"`
onelogfile="/data/PP-log/*PPIm.access.log.$oneday"
twologfile="/data/PP-log/*PPIm.access.log.$twoday"

awk -F"\t" 'BEGIN{d=0;}($3 ~ /^[0-9]+\.[0-9]+\.[0-9]+$/){ #     
	split(FILENAME, date, "."); #         ,  FILENAME          
	len = length(date);
	if(d == 0 || two[0] == date[len]){ #        (twologfile)
		two[0] = date[len];
		d = 1;
		two[$3"_"$6] ++;
	}else if(d == 1 || one[0] == date[len]){ #        (onelogfile)
		d = 2;
		one[0] = date[len];
		one[$3"_"$6] ++;
	}else{ #       (logfile)
		thisday[$6] ++;
	}
}END{
	delete two[0];
	delete one[0];
	for(k in two){
		split(k, arr, "_");
		total[arr[1]] ++;
		t[arr[1]] ++;
		if(arr[2] in thisday) remain[arr[1]] ++;
	}

	for(k in one){
		split(k, arr, "_");
		if(arr[2] in thisday) remain2[arr[1]] ++;
		total2[arr[1]] ++;
		t[arr[1]] ++;
	}
	#     :  ,    ,    
	for(k in t){
		onerate = "-";
		tworate = "-"
		if(k in total2) onerate=remain2[k]/total2[k];
		if(k in total) tworate=remain[k]/total[k];
		print "update danalysis set onedayexist="onerate",twodayexist="tworate" where analysisdate=\047'$yesterday'\047 and version=\047"k"\047";
	}
 
}' $twologfile $onelogfile $logfile
注:047は、一重引用符で表されます.2番目のawkは複数のファイルを読み出し、複数のファイルを読み出すと各ファイルを順番に読み出し、現在のファイルに対してすべての行を処理した後、次のファイルを処理します.
二.shellスクリプトによるsql文のライブラリ化
上記ではawkによってログファイルの統計結果をsql文に変換しました.次に、これらのsql文を読み取り、実行するだけで、統計結果がデータベースに入力されます.入庫のshellコマンドは次のとおりです.
mysql -u$user -p$pass -D $db -e “insert into t_table values(xxx,xxx,xxx);”
具体的なshell:PP_insert_db.sh、以下のようにする.
#!/bin/sh
/bin/sh /home/lincheung/PP_sql.sh | while read line
do 
  #echo $line;
  mysql -h192.168.111.111 -umysqlroot -p123456 -D mysqldb -e "$line" --default-character-set=utf8
done
リファレンスリンク:http://blog.csdn.net/jiedushi/article/details/6448740
ここでsql文の入庫はプライマリ・ライブラリから行われ、これらのinsert文を実行すると、読み出し分離エージェントはこれらのsql操作がライト・データベース操作であると判断し、データベースのプライマリ・ライブラリに書き込まれます.しかし、ユーザがデータベースの読み取りを要求する場合、すなわちselect操作であり、読み出し分離エージェントはselectが読み取り操作であると判断し、ユーザ要求をライブラリから転送するので、読み出したデータはライブラリから読み出す.すなわち,書き込みはメインライブラリに書き,読み出しはライブラリから読み出す.
参照リンク:http://www.cnblogs.com/yangligogogo/articles/1939938.html
三.shellスクリプトをlinuxの計画タスクに追加する
shelスクリプトをlinuxの計画タスクに追加すると、contrab-eコマンドで実現できます.このコマンドで現在のユーザーの計画タスクエディタを開くことができます.ユーザーはここで自分がいつ実行したいかのコマンドを入力するだけでいいです.linuxは定期的にファイルからコマンドを読み出して実行します.
まず、コマンド:contrab-eを入力します.
エディタが開き、次のコマンドを入力します.
0 5 * * * cd/home/lincheung; sh PP_insert_db.sh
後で保存して終了すればいいです.これによりlinuxの計画タスクに参加し、上記のコマンドは毎日午前5時に実行されます.
参照リンク:http://blog.csdn.net/21aspnet/article/details/6798179