src/model/log.lisp
(in-package :murja.model.log)
(defun get-logs ()
"Shells out to `journalctl -xeu Murja.service` and returns whatever it happens to output.
If lisp-fixup:*dev?* happens to be truthy, this instead cats a log-file from `(asdf:system-relative-pathname :aggressive-murja \"resources/testlog\")`"
(str:split (format nil "~%")
(let ((fstr (make-array '(0) :element-type 'character
:fill-pointer 0 :adjustable t)))
(with-output-to-string (s fstr)
(if lisp-fixup:*dev?*
(sb-ext:run-program "/bin/cat" (list (format nil "~a" (asdf:system-relative-pathname :aggressive-murja "resources/testlog"))) :output s)
(sb-ext:run-program "/usr/bin/journalctl" (list "-xeu" "Murja.service") :output s))
fstr))))
(defun get-groups ()
(coerce
(postmodern:query "SELECT name, alarmy FROM blog.log_group" :array-hash)
'list))
(defun count-reads (groups logs)
"Takes in whatever groups there are in the database, current logs and returns counts of each group in a hashmap"
(reduce (lambda (acc group-regex)
(let ((count (->>
logs
(remove-if-not (partial #'cl-ppcre:scan group-regex))
length)))
(setf (gethash group-regex acc)
count)
acc))
(->>
groups
(mapcar (partial #'gethash "name")))
:initial-value (make-hash-table)))
(defqueries "log-fns")
(defun db-counts (user-id)
(let ((counts (coerce (get-log-group-counts* user-id) 'list)))
(reduce (lambda (acc hash-table)
(setf (gethash (gethash "name" hash-table) acc)
(gethash "read_count" hash-table))
acc)
counts
:initial-value (make-hash-table :test 'equal))))
(defun get-alarmy-groups (user-id read-counts groups)
(let ((db-counts (db-counts user-id)))
(->>
groups
(remove-if-not (partial #'gethash "alarmy"))
(remove-if (lambda (group)
(let ((name (gethash "name" group)))
(= (or (gethash name db-counts) 0)
(gethash name read-counts)))))
(mapcar (partial #'gethash "name")))))
;; (defroute get-logs-groups ("/api/logs/groups" :method :get
;; :decorators (@transaction
;; @json
;; @authenticated
;; (@can? "update-settings"))) ()
;; (let ((user-id (gethash "id" *user*)))
;; (assert user-id)
;; (let* ((groups (get-groups))
;; (read-counts (count-reads groups (get-logs)))
;; (alarmy-groups (get-alarmy-groups user-id read-counts groups)))
;; (dolist (group groups)
;; (let ((name (gethash "name" group)))
;; (if (member name alarmy-groups)
;; (setf (gethash "sound-alarm" group) t)
;; (setf (gethash "sound-alarm" group) nil))))
;; (dolist (k (alexandria:hash-table-alist read-counts))
;; (destructuring-bind (group . count) k
;; (log:info "Updating ~a to ~d~%" group count)
;; (upsert-readcount* count user-id group)))
;; (stringify (or groups #())))))