Skip to content

Instantly share code, notes, and snippets.

@furu
Created July 23, 2014 17:32
Show Gist options
  • Save furu/928f52717a37bf01edd9 to your computer and use it in GitHub Desktop.
Save furu/928f52717a37bf01edd9 to your computer and use it in GitHub Desktop.
apache_log_analysis らしい。何かあった。
# coding: utf-8
module AccessLog
CLF_REGEXP = /
\A (?# 行頭)
(\S+)\s (?# 1 address)
(\S+)\s (?# 2 ident)
(\S+)\s (?# 3 authuser)
\[([^\]]+)\]\s (?# 4 time)
"(\S+)\s(\S+)\s(\S+)"\s (?# 5 6 7 method url version)
(\d+)\s (?# 8 status)
(\d+|-)\s (?# 9 bytes)
"([^"]*)"\s (?# 10 referer)
"([^"]*)" (?# 11 user-agent)
\Z (?# 行末)
/x
Entry = Struct.new(
:address, :ident, :user, :time,
:method, :url, :version, :status, :byte,
:referer, :user_agent
)
module_function
def each_entry(file)
file.each_line do |line|
if entry = parse(line)
yield(entry)
end
end
end
def parse(line)
if m = CLF_REGEXP.match(line)
return Entry.new(*m.captures)
end
$stderr.puts("parse failure: #{line.dump}")
return nil
end
end
# coding: utf-8
require './access_log'
entries = []
task :load do
logfile = ENV["LOGFILE"] || "access_log"
puts "loading #{logfile}."
File.open(logfile) do |log|
AccessLog.each_entry(log) do |entry|
entries << entry
end
end
end
desc "Bus Timerのアクセス数を集計する"
task bus_timer: [:load] do
bt_count = Hash.new(0)
entries.each do |entry|
if /"common\/bt\/"/ =~ entry.url
bt_count[entry.url] += 1
end
end
ranking = bt_count.sort_by {|url, count| -count }
ranking.each do |url, count|
printf("%d: %p\n", count, url)
end
end
desc "時間帯別のアクセス数を集計する"
task time: [:load] do
hour_count = Hash.new(0)
entries.each do |entry|
times = entry.time.split(/[:\/ ]/) # 時刻を分割する
hour_count[times[3]] += 1 # 「時」のカウントを追加する
end
hours = hour_count.keys.sort
hours.each do |h|
printf("%s: %s\n", h, "#" * (hour_count[h] / 3))
end
end
desc "URL別にアクセス数を集計する"
task url: [:load] do
url_count = Hash.new(0)
entries.each do |entry|
url_count[entry.url] += 1
end
ranking = url_count.sort_by {|url, count| -count }
ranking.each do |url, count|
printf("%d: %p\n", count, url)
end
end
desc "エラーになったアクセスを表示する"
task error: [:load] do
entries.each do |entry|
if /^[45]/ =~ entry.status # ステータスが4xxか5xxなら表示する
printf("%p %p %p\n", entry.time, entry.status, entry.url)
end
end
end
task default: [:time, :url, :error]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment