トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

Linux:JavaScript:awk+cut+sort+uniqでアクセスログを集計し、さらにJavaScriptで集約

Last-modified: 2014-01-21 (火) 16:20:41 (1366d)
Top / Linux:JavaScript:awk+cut+sort+uniqでアクセスログを集計し、さらにJavaScriptで集約

Linux:JavaScript?:awk+cut+sort+uniqでアクセスログを集計し、さらにJavaScript?で集約

apacheのアクセスログは、こんな感じのコマンドで、時間ごとのアクセス数を集計できます。

cat access_log | awk '{print $4}' | cut -b 2-15 | sort | uniq -c

このパターンは定石ですなw

やっていることは以下の通り

  • awkで時間の箇所を抽出
  • cutで時間までの出力をカット
  • uniqするためにsortコマンドをかます
  • uniq -cでユニーク行をカウントし、出力

これで得られる出力は以下の通り

    68 03/Dec/2013:16
   368 03/Dec/2013:17
   141 03/Dec/2013:18
   181 03/Dec/2013:19
    91 03/Dec/2013:20
    15 03/Dec/2013:21
    13 04/Dec/2013:11
    29 04/Dec/2013:13
    21 04/Dec/2013:14
    10 04/Dec/2013:17

サーバが1台だったらこれで終了なんだけど、複数台ある、且つログがまとめられない等の事情で、各サーバで上記コマンドを実行した場合、集約するのが大変だったりします。

出力結果をJavaScript?で集計

こんな感じのHTMLとJavaScript?で集約できます。

■shuukei.html

<html>
<body>

<div id="inputDataArea">
<textarea id="target" rows="10" cols="100">
</textarea>
</div>
<input type="button" id="execute" value="execute"></input>

<div >
<table>
	<thead>
		<tr>
			<th>key</th>
			<th>count</th>
		</tr>
	</thead>
	<tbody id="output">
	</tbody>
</table>

</div>
<script src="./jquery-1.10.2.min.js"></script>
<script src="./shuukei.js"></script>
</body>
</html>

■shuukei.js

$(function(){
	var 
		$target = $('#target'),
		$output = $('#output'),
		$execute = $('#execute'),
		i, pushResult,outputTable;

	$execute.bind("click", function(event){
		var 
			targetList = $target.val().split("\n"),
			sIndex,key,count, keyList,
			result = {};
		for (i=0 ; i < targetList.length ; i++){
			pushResult(targetList[i],result);
		}
		
		outputTable(result);
		event.preventDefault();
	});

	pushResult = function(line,result){
		var tmp,sIndex,key,count;
		//	行のスペースのトリム
		tmp = line.replace(/^\s+/g, "").replace(/\s+$/, "").replace(/\s+/g, " ");
		//	最初のスペースがフィールドの区切り文字
		sIndex = tmp.indexOf(" ");
		//	最初のスペースより左がvalue、右側がkeyとなる
		count = tmp.substring(0,sIndex);
		key = tmp.slice(sIndex+1);

		// 1カラム目が数値でない場合はそのまま返却
		if (isNaN(count)){
			return;
		}
		console.log(key + "\t" + count);
		// resultにcountをプッシュ
		key in result ? result[key] = parseInt(result[key]) + parseInt(count) : result[key] = count;
	}

	outputTable = function(result){
		$output.empty();
		var keyList = Object.keys(result),i;
		for (i=0 ; i < keyList.length; i++ ){
//			console.log(key+ "\t"+result[key]);
			$output.append("<tr><td>" + keyList[i] + "</td><td>"+ result[keyList[i]]+"</td></tr>");
		}
	}

})

「uniq -c」の出力を前提としていますが、ちょっとコードを書き換えるだけでいろいろマージして集計できそうで便利そうw