0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Apache】アクセスログをCSV化してグラフ出力

Last updated at Posted at 2025-06-15

はじめに

webサイトへのアクセスがどの時間帯にどのくらいあったのか?
⇒便利なツールが利用できない環境で手作業は時間かかるなぁ
⇒なのでスクリプトでやってみます

動作環境

Raspbian GNU/Linux 10
Apache/2.4.38
perl v5.28.1
Python 3.7.3

コード

  1. まず生ログをCSVに変換

alog.pl

#!/usr/bin/perl
# Format apache log by tab delimiter
#
# Output: IP timestamp request status byte time referer
#
# Usage:
# alog.pl logfile i.e. alog.pl access.log
# alog.pl < logfile > fmt.txt
# zcat logfile.gz | alog.pl
#
# LogFormat:
# pattern1:combined
# "%a %D %u %t \"%r\" %>s %b \"{Referer}i\" \"%{User-Agent}i\" \"-\J"" combined
#127.0.0.1 - - [12/Nov/2021:14:04:13 +0900] "GET /wp-content HTTP/1.0" 200 5021 "http://foo.com/home.htm" "Mozilla/5.0 (Windows NT 5.01; as-IN; rv:1.9.0.20) Gecko/2021-01-10 16:56:07 Firefox/14.0"
#
# pattern1:common
# "%h %l %u %t \"%r\" %>s %b" common
# 127.0.0.1 - - [10/Apr/2021:17:12:42 +0900] "GET /favicon.ico HTTP/1.1" 200 1150
#
use strict;
use warnings;
use Getopt::Long;

my $opt_fmt = "combined";
my $opt_help = 0;

GetOptions(
    "format=s" => \$opt_fmt,
    "help" => \$opt_help,
) or disp_usage();
disp_usage() if $opt_help;

sub disp_usage {
    print "format apacke log by tab delimiter\n";
    print "Usage: $0 [--format=common][--help] <filename> i.e. $0 --format=common access.log\n";
    exit;
}

#print "$opt_fmt\n";

my $fmt = qr/^(\S+) (\S+) (\S+) \[(.*?)\] "(\S+)?(\s\S+)?(\s\S+)?" (\d+) (\d+|-)$/;
if ($opt_fmt eq "combined" ) {
    $fmt = qr/^(\S+) (\S+) (\S+) \[(.*?)\] "(\S+)?(\s\S+)?(\s\S+)?" (\d+) (\d+|-) "([^"]*)" (.*)$/;
}

my ($ip,$ptime,$usr,$ts,$req,$url,$prt,$sts,$sz,$ref,$oth,$rlog);
my $tabstr;
while (<>) {
    if ($_ =~ /$fmt/) {
        if ($opt_fmt eq "combined" ) {
            ($ip,$ptime,$usr,$ts,$req,$url,$prt,$sts,$sz,$ref,$oth) = ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11);
            if (defined $req){
                $tabstr = join("\t",$ip,$ts,$req,$sts,$sz,$ptime,$ref);
            } else {
                $tabstr = join("\t",$ip,$ts,"",$sts,$sz,$ptime,$ref);
            }
        } else {
            ($ip,$rlog,$usr,$ts,$req,$url,$prt,$sts,$sz) = ($1,$2,$3,$4,$5,$6,$7,$8,$9);
            $tabstr = join("\t",$ip,$ts,$req,$sts,$sz);
        }
        print "$tabstr\n";
    } else {
        print "Unmatch* $_";
    }
}

注意:apacheのログフォーマットによるので必要に応じて修正すること

2.CSVファイルからグラフを作成して画像ファイルを出力

aplot.py

#!/usr/bin/env python3
# plot graph for appache log: number of access by hour
# input: access_log
# outout: aplot.png
# usage ./aplot.png 

import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime

df = pd.read_csv('alog.tsv', sep='\t', header=None, names=['ip', 'datetime', 'method', 'status', 'size', 'referer', 'url'])

# convert date (12/Nov/2023:09:42:45 +0900)
df['datetime'] = df['datetime'].apply(lambda x: datetime.strptime(x.split()[0], "%d/%b/%Y:%H:%M:%S"))

# round time by 1h (2023-11-12 09:00:00)
df['hour'] = df['datetime'].dt.floor('H')

# group by time
access_counts = df.groupby('hour').size()

# plot graph
plt.figure(figsize=(12, 6))
access_counts.plot(kind='line', marker='o')
plt.bar(access_counts.index.astype(str), access_counts.values)
plt.title('Accesses per hour')
plt.xlabel('time')
plt.ylabel('number of access')
plt.grid(True)
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('aplot.png')

# if you have GUI
#plt.show()

使い方

アパッチのアクセスログを整形してタブ区切りCSVを生成する
./alog.pl < access_log > alog.tsv

できたCSVからグラフを画像ファイルに出力する
python3 ./aplot.py

Xが使えるなら次のコマンドで画像ファイルを描画
xdg-open aplot.png

おわりに

便利なGUIツールが入れられない場合でもperlは入っていることが多いはず
CSVファイルをインポートしてエクセルの機能でグラフにしてもよい
毎分、IPアドレス毎などでグラフしたい場合は、pythonコードを改良したり、エクセルのテーブルで対応可能

参考リンク

Apache mod_log_config format

github.com/kojimura/apache/blob/main/alog.pl

github.com/kojimura/apache/blob/main/aplot.py

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?