Skip to content

Instantly share code, notes, and snippets.

@klang
Created November 12, 2015 08:01
Show Gist options
  • Save klang/6370f0af9b73605b20bd to your computer and use it in GitHub Desktop.
Save klang/6370f0af9b73605b20bd to your computer and use it in GitHub Desktop.
Log monitoring and processing
(ns monitor
(:gen-class)
(:import (java.io RandomAccessFile)))
(def sleep-interval 2000)
(defn extract-ip-address [message]
(if (not (nil? message))
(let [pattern "(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}) ([0-9a-f]+\\.[0-9a-f]+\\.[0-9a-f]+) via (\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})"
message-seq (first (re-seq (re-pattern pattern) message))
message-info (zipmap [:everything :to :mac :via] message-seq)] (get-in message-info [:to]))))
(defn analyze-line [line]
(if (not (nil? line))
(let [pattern "(^\\w+ \\d+ \\d\\d:\\d\\d:\\d\\d) [\\w]+ ([\\w]+)\\[\\d+\\]: ([\\w\\W]+)"
log-line-seq (first (re-seq (re-pattern pattern) line))] (zipmap [:everything :time :action :message] log-line-seq))))
(defn filter-ACK [message]
(let [pattern "^Sending ACK to .*"
message-seq (first (re-seq (re-pattern pattern) message))] message-seq))
(defn process-log-entry
"Extract information from the log file line."
[line]
(if-let [data (-> line
analyze-line
:message
filter-ACK
extract-ip-address)]
(do (println (str "queue: " data)))))
(defn read-log
"Loop through the log-file, process each entry, wait at the end. Start over when log is rotated"
[^RandomAccessFile log-file]
(let [line (.readLine log-file)]
(if line
(process-log-entry line)))
(let [pointer (.getFilePointer log-file)
length (.length log-file)]
(cond (= pointer length) (do (Thread/sleep sleep-interval))
(> pointer length) (do (.seek log-file 0))))
(recur log-file))
(defn -main
"Called from the :main entry in the Leiningen file."
[& args]
(println "main run")
(future (read-log (RandomAccessFile. "/var/log/messages" "r"))))
(defproject monitor "0.1.0-SNAPSHOT"
:description "monitor a log file and process specific entries"
:dependencies [[org.clojure/clojure "1.5.1"]]
:main ^:skip-aot monitor.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})
;; initial skeleton from
;; Clojure Recipes
;; By: Julian Gamble
;; Publisher: Addison-Wesley Professional
;; Chapter 24. Detecting Errors with a Log Monitoring Application
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment