--- /dev/null
+#!/usr/bin/newlisp
+
+;; This script performs per-IP access analysis of the nginx access
+;; log. This is translated into a display format of:
+;; total-count hit-count IP path
+
+(signal 2 (fn (x) (exit 0)))
+
+(setf DISPLAY-TOTALS (and (find "--tot" (main-args)) true))
+
+; "Object" holding data for an IP
+; (self 1) = IP
+; (self 2) = total-count
+; (self 3) = a-list of (path hit-count)
+(context 'ROW)
+(define (ROW:ROW IP) (list (context) IP 0 (list)))
+
+(define (add-path PATH)
+ (unless (assoc PATH (self 3)) (push (list PATH 0) (self 3)))
+ (inc (lookup PATH (self 3)))
+ (inc (self 2)))
+
+(define (display)
+ (if MAIN:DISPLAY-TOTALS (list (list (self 2) (length (self 3)) (self 1)))
+ (sort (map (fn (P) (list (self 2) (P 1) (self 1) (P 0))) (self 3)))))
+
+(context MAIN)
+
+; Table of rows, keyed by IP
+(define IPS:IPS nil)
+
+(while (setf LINE (read-line))
+ (when (regex "^([^ ]+)[^\"]*[^ ]+ ([^ ]+)" LINE 0)
+ (let ((IP $1) (PATH $2))
+ (unless (IPS IP) (IPS IP (ROW IP)))
+ (:add-path (IPS IP) PATH))))
+
+(map println
+ (sort (flat (map (fn (R) (:display R)) (map last (IPS))) 1) >))
+(exit 0)
+
+
+
\ No newline at end of file