| 1 |
#!/usr/local/bin/clisp -C |
|---|
| 2 |
|
|---|
| 3 |
(use-package :regexp) |
|---|
| 4 |
|
|---|
| 5 |
(assert (probe-file (first ext:*args*)) nil |
|---|
| 6 |
"Usage: squid-access-log2csv <access.log>") |
|---|
| 7 |
|
|---|
| 8 |
(defvar *uri-hash* (make-hash-table :test #'equal)) |
|---|
| 9 |
(defvar *action/codes* nil) |
|---|
| 10 |
|
|---|
| 11 |
(defun action/code-count (uri action/code) |
|---|
| 12 |
(or (cdr (assoc action/code (gethash uri *uri-hash*))) |
|---|
| 13 |
0)) |
|---|
| 14 |
|
|---|
| 15 |
(defun (setf action/code-count) (count uri action/code) |
|---|
| 16 |
(let ((cons (assoc action/code (gethash uri *uri-hash*)))) |
|---|
| 17 |
(if cons |
|---|
| 18 |
(rplacd cons count) |
|---|
| 19 |
(push (cons action/code count) |
|---|
| 20 |
(gethash uri *uri-hash*))))) |
|---|
| 21 |
|
|---|
| 22 |
(let ((line-count 0)) |
|---|
| 23 |
(with-open-file (in (first ext:*args*)) |
|---|
| 24 |
(with-loop-split (list in " \\+") |
|---|
| 25 |
(when (= 10 (length list)) |
|---|
| 26 |
(incf line-count) |
|---|
| 27 |
(when (zerop (mod line-count 1000)) |
|---|
| 28 |
(format *error-output* "Reading log line ~D...~C" |
|---|
| 29 |
line-count #\Return)) |
|---|
| 30 |
(destructuring-bind (timestamp elapsed client action/code |
|---|
| 31 |
size method uri ident |
|---|
| 32 |
hierarchy/from content) |
|---|
| 33 |
list |
|---|
| 34 |
(declare (ignore timestamp elapsed client |
|---|
| 35 |
size method ident |
|---|
| 36 |
hierarchy/from content)) |
|---|
| 37 |
(let ((action/code (intern action/code))) |
|---|
| 38 |
(pushnew action/code *action/codes*) |
|---|
| 39 |
(incf (action/code-count uri action/code)) |
|---|
| 40 |
(incf (action/code-count uri :total)))))))) |
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
|
|---|
| 44 |
(let (lists) |
|---|
| 45 |
(maphash (lambda (key value) |
|---|
| 46 |
(push (cons key value) lists)) |
|---|
| 47 |
*uri-hash*) |
|---|
| 48 |
(setf lists (sort lists #'> |
|---|
| 49 |
:key (lambda (uri) (cdr (assoc :total (cdr uri)))))) |
|---|
| 50 |
(format t "\"uri\";\"TOTAL\";~{\"~A\"~^;~}~%" *action/codes*) |
|---|
| 51 |
(dolist (list lists) |
|---|
| 52 |
(destructuring-bind (uri . alist) |
|---|
| 53 |
list |
|---|
| 54 |
(format t "\"~A\";" uri) |
|---|
| 55 |
(format t "\"~A\";" (cdr (assoc :total alist))) |
|---|
| 56 |
(format t "~{\"~D\"~^;~}~%" |
|---|
| 57 |
(mapcar (lambda (action/code) |
|---|
| 58 |
(or (cdr (assoc action/code alist)) |
|---|
| 59 |
0)) |
|---|
| 60 |
*action/codes*))))) |
|---|
| 61 |
|
|---|