awk でリファラ解析

どこから来たの?超インスタントなrefererの頻度分析はまさに awk らしい処理ではないでしょうか?

gawk の asort() 関数を使えば以下のようにできます。

#! /usr/bin/gawk -f
# backlink.awk - print back links from apache access log
# http://d.hatena.ne.jp/kgbu/20080711

BEGIN {
    your_site = "http://gauc.no-ip.org/";
    FS = "\"";
}

# apache のログが combined の場合、$4 はリファラを示す
# LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
$4 !~ your_site && $4 != "-" {
    count[$4]++;
    total++;
    referer[$4] = sprintf("%5d %s", count[$4], $4);
}

total > 100 {
    asort(referer);
    for (i = 1; i <= length(referer); i++) {
        print referer[i];
    }
    exit 0;
}

root になって以下のように実行します。

# tac /var/log/httpd/access_log | gawk -f backlink.awk

これはこれで awk らしくまとまっていると思います。

さて、リアルタイムでどんなリンク元からやってきたのかを知りたくないですか? そうした場合には以下のようにします。

# tail -f /var/log/httpd/access_log | \
  gawk -F\" '$4 !~ "http://gauc.no-ip.org/" && $4 != "-" {system("echo リンク元:" $4)}'

ちなみに以下のようにすると tail コマンドからのパイプがフラッシュされないためリアルタイムで取得することができません。

# tail -f /var/log/httpd/access_log | \
  gawk -F\" '$4 !~ "http://gauc.no-ip.org/" && $4 != "-" {print "リンク元:" $4}'

この system() 関数は外部コマンドを実行すると共にパイプをフラッシュしてくれます。

または、以下のようにして fflush() 関数でフラッシュします。

# tail -f /var/log/httpd/access_log | \
  gawk -F\" '$4 !~ "http://gauc.no-ip.org/" && $4 != "-" {fflush();print "リンク元:" $4}'

特に何もなく流れていくだけですが、いろいろなところからリンクされていることが良く分かります。

tag_gawk.pngtag_gawk.png