diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2011-12-21 10:53:32 +0100 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2011-12-21 10:53:32 +0100 |
commit | 0faf072a9e8c76f2f8884e88264b87753784437f (patch) | |
tree | 3601c4bff35134b2825cfc85fc36099abe3e4d08 | |
download | squlogan-0faf072a9e8c76f2f8884e88264b87753784437f.tar.bz2 squlogan-0faf072a9e8c76f2f8884e88264b87753784437f.tar.xz |
initial commit
-rw-r--r-- | squlogan | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/squlogan b/squlogan new file mode 100644 index 0000000..b337351 --- /dev/null +++ b/squlogan @@ -0,0 +1,174 @@ +#!/usr/bin/lua + +function parseline(line) + local word + local words = {} + for word in string.gmatch(line, "%S+") do + words[#words+1] = word + end + + return { + logdatetime=words[1], + elapsed=words[2], + clientip=words[3], + code=string.match(words[4] or "", "^[^/]*"), + status=string.match(words[4] or "", "[^/]*$"), + bytes=words[5], + method=words[6], + URL=words[7], + site = string.match(words[7], "^(%a+://[^/]*)"), + clientuserid=words[8], + peerstatus=string.match(words[9] or "", "^[^/]*"), + peerhost=string.match(words[9] or "", "[^/]*$"), + squarkcategory=string.match(words[11] or "", "^[^,]*"), + squarkaction=string.match(words[11] or "", ",([^,]+)$") + } + +end + +function add_by_key(tbl, key, entry) + if tbl[key] == nil then + tbl[key] = { + lines = entry.lines, + bytes = entry.bytes, + elapsed = entry.elapsed, + } + return tbl + end + tbl[key].lines = (tbl[key].lines or 0) + 1 + tbl[key].bytes = tbl[key].bytes + entry.bytes + tbl[key].elapsed = tbl[key].elapsed + entry.elapsed + return tbl +end + + +function add_stats(total, entry) + add_by_key(total.code, entry.code, entry) + add_by_key(total.category, entry.squarkcategory, entry) + if entry.squarkaction then + add_by_key(total.action, entry.squarkaction, entry) + end +-- inc_key(total.squark, entry.squark) + + total.elapsed = total.elapsed + entry.elapsed + total.bytes = total.bytes + entry.bytes + total.lines = total.lines + 1 + return total +end + +local function newstats(keyname) + return { + bytes = 0, lines = 0, elapsed = 0, + code = {}, category = {}, action = {}, + key = keyname, + } +end + +local function add_stats_by_key(tbl, key, entry) + if tbl[key] == nil then + tbl[key] = newstats(key) + end + add_stats(tbl[key], entry) + return tbl +end + +function collect_stats(stats, entry) + add_stats(stats.total, entry) + add_stats_by_key(stats.user, entry.clientuserid, entry) + add_stats_by_key(stats.code, entry.code, entry) + add_stats_by_key(stats.site, entry.site, entry) + return stats +end + +function parsefile(file) + local numlines = 0 + local f = assert(io.open(file)) + local stats = { + total = newstats(), + user = {}, + site = {}, + code = {}, + } + local line + for line in f:lines() do + collect_stats(stats, parseline(line)) + end + f:close() + return stats +end + +function dump_tbl(header, tbl) + io.write(header..":\n") + local k,v + for k,v in pairs(tbl) do + print("\t"..k..":", v.lines, v.bytes, v.elapsed) + end +end + +function print_totals(header, tbl) + local k, v + print("Totals for "..header..":") + for k,v in pairs(tbl) do + if type(v) == "table" then + dump_tbl(k, v) + else + io.write(k..": "..v.."\n") + end + end + io.write("\n") +end + +function sort_by_key(tbl, key) + local t = {} + for k, v in pairs(tbl) do + table.insert(t, v) + end + table.sort(t, function(a,b) + return a[key] > b[key] + end) + return t +end + +function top_n_by_key(tbl, n, key) + sorted = sort_by_key(tbl, key) + local i + for i = 1, #sorted do + print(sorted[i].key, sorted[i][key]) + if i > n then + break + end + end + print() +end + +stats = parsefile(arg[1] or "/var/log/squid/access.log") + +--[[ +numusers = 0 +for user,tbl in pairs(stats.user) do + print_totals("user "..user, tbl) + numusers = numusers + 1 +end +--]] + + +--[[ +numsites = 0 +for site, tbl in pairs(stats.site) do + print_totals("site "..site, tbl) + numsites = numsites + 1 +end +--]] + +print("Top 10 sites by hits") +top_n_by_key(stats.site, 10, "lines") +print() + + +print("Top 10 sites by bytes") +top_n_by_key(stats.site, 10, "bytes") +print() + +print("Top 5 users by bytes") +top_n_by_key(stats.user, 5, "bytes") +print() |