summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2025-10-12 23:27:25 +0300
committerGravatar Uko Kokņevičs2025-10-12 23:27:25 +0300
commit71a7c39292eef91d732c0b98e3939032c5ae338b (patch)
treee6a6152a4f7c4b11c6910db287bfa8299e04393a /src
parentAdd message-entity-type enum (diff)
downloadukkoclot-71a7c39292eef91d732c0b98e3939032c5ae338b.tar.gz
ukkoclot-71a7c39292eef91d732c0b98e3939032c5ae338b.tar.xz
ukkoclot-71a7c39292eef91d732c0b98e3939032c5ae338b.zip
Replace my simple logging implementation with log4cl
Diffstat (limited to 'src')
-rw-r--r--src/bot/impl.lisp11
-rw-r--r--src/config.lisp2
-rw-r--r--src/db.lisp13
-rw-r--r--src/inline-bots.lisp5
-rw-r--r--src/log.lisp85
-rw-r--r--src/main.lisp13
6 files changed, 24 insertions, 105 deletions
diff --git a/src/bot/impl.lisp b/src/bot/impl.lisp
index 85f4496..652e2f7 100644
--- a/src/bot/impl.lisp
+++ b/src/bot/impl.lisp
@@ -1,10 +1,11 @@
1;; SPDX-License-Identifier: EUPL-1.2 1;; SPDX-License-Identifier: EUPL-1.2
2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com> 2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com>
3(defpackage :ukkoclot/bot/impl 3(defpackage :ukkoclot/bot/impl
4 (:use :c2cl :iterate :ukkoclot/config :ukkoclot/log) 4 (:use :c2cl :iterate :ukkoclot/config)
5 (:import-from :anaphora :aand :acond :it) 5 (:import-from :anaphora :aand :acond :it)
6 (:import-from :cl+ssl) 6 (:import-from :cl+ssl)
7 (:import-from :dex) 7 (:import-from :dex)
8 (:import-from :log)
8 (:import-from :ukkoclot/strings :lisp->snake-case) 9 (:import-from :ukkoclot/strings :lisp->snake-case)
9 (:local-nicknames 10 (:local-nicknames
10 (:jzon :com.inuoe.jzon)) 11 (:jzon :com.inuoe.jzon))
@@ -17,7 +18,7 @@
17(defgeneric parse-value (type json) 18(defgeneric parse-value (type json)
18 (:documentation "Parse value of TYPE from the parsed JSON") 19 (:documentation "Parse value of TYPE from the parsed JSON")
19 (:method (type json) 20 (:method (type json)
20 (log-error "I don't know how to parse simple type ~A!" type) 21 (log:error "I don't know how to parse simple type ~A!" type)
21 (error "I don't know how to parse simple type ~A!" type)) 22 (error "I don't know how to parse simple type ~A!" type))
22 (:method ((type (eql 'boolean)) json) 23 (:method ((type (eql 'boolean)) json)
23 (check-type json boolean) 24 (check-type json boolean)
@@ -100,9 +101,9 @@
100 ((gethash "ok" hash) (parse-value type (gethash "result" hash))) 101 ((gethash "ok" hash) (parse-value type (gethash "result" hash)))
101 ((aand (gethash "parameters" hash) 102 ((aand (gethash "parameters" hash)
102 (gethash "retry_after" it)) 103 (gethash "retry_after" it))
103 (log-info "Should sleep for ~A seconds" it) 104 (log:info "Should sleep for ~A seconds" it)
104 (sleep it) 105 (sleep it)
105 (log-info "Good morning!") 106 (log:info "Good morning!")
106 (do-call% bot method uri type args-encoded)) 107 (do-call% bot method uri type args-encoded))
107 (t (error "TG error ~A: ~A ~:A" 108 (t (error "TG error ~A: ~A ~:A"
108 (gethash "error_code" hash) 109 (gethash "error_code" hash)
@@ -112,5 +113,5 @@
112(defun do-call (bot method path type args) 113(defun do-call (bot method path type args)
113 (let ((uri (concatenate 'string (bot-base-uri bot) path)) 114 (let ((uri (concatenate 'string (bot-base-uri bot) path))
114 (args-encoded (fixup-args args))) 115 (args-encoded (fixup-args args)))
115 (log-debug "~A .../~A ~S" method path args-encoded) 116 (log:debug "~A .../~A ~S" method path args-encoded)
116 (do-call% bot method uri type args-encoded))) 117 (do-call% bot method uri type args-encoded)))
diff --git a/src/config.lisp b/src/config.lisp
index 86a0f33..17c5c73 100644
--- a/src/config.lisp
+++ b/src/config.lisp
@@ -1,7 +1,7 @@
1;; SPDX-License-Identifier: EUPL-1.2 1;; SPDX-License-Identifier: EUPL-1.2
2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com> 2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com>
3(defpackage :ukkoclot/config 3(defpackage :ukkoclot/config
4 (:use :c2cl :ukkoclot/hash-tables :ukkoclot/log) 4 (:use :c2cl :ukkoclot/hash-tables)
5 (:export 5 (:export
6 :config-load :config-merge 6 :config-load :config-merge
7 :config-p 7 :config-p
diff --git a/src/db.lisp b/src/db.lisp
index 9b646d2..5d08e6a 100644
--- a/src/db.lisp
+++ b/src/db.lisp
@@ -1,7 +1,8 @@
1;; SPDX-License-Identifier: EUPL-1.2 1;; SPDX-License-Identifier: EUPL-1.2
2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com> 2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com>
3(defpackage :ukkoclot/db 3(defpackage :ukkoclot/db
4 (:use :c2cl :sqlite :ukkoclot/log) 4 (:use :c2cl :sqlite)
5 (:import-from :log)
5 (:export :get-inline-bot-type :set-inline-bot-type :with-db)) 6 (:export :get-inline-bot-type :set-inline-bot-type :with-db))
6(in-package :ukkoclot/db) 7(in-package :ukkoclot/db)
7 8
@@ -39,24 +40,24 @@
39 (unless current-ver 40 (unless current-ver
40 (setf current-ver 0)) 41 (setf current-ver 0))
41 (cond 42 (cond
42 ((= current-ver +target-version+) (log-info "Database is up to date")) 43 ((= current-ver +target-version+) (log:info "Database is up to date"))
43 44
44 ((> current-ver +target-version+) 45 ((> current-ver +target-version+)
45 (log-error "Database has a higher version than supported?") 46 (log:error "Database has a higher version than supported?")
46 (error "Corrupted Database")) 47 (error "Corrupted Database"))
47 48
48 (t 49 (t
49 (log-info "Updating database from version ~A to ~A" current-ver +target-version+) 50 (log:info "Updating database from version ~A to ~A" current-ver +target-version+)
50 (loop while (< current-ver +target-version+) 51 (loop while (< current-ver +target-version+)
51 do (with-transaction db 52 do (with-transaction db
52 (log-info "Updating database step from ~A" current-ver) 53 (log:info "Updating database step from ~A" current-ver)
53 (incf current-ver) 54 (incf current-ver)
54 (upgrade-step db current-ver) 55 (upgrade-step db current-ver)
55 (execute-non-query 56 (execute-non-query
56 db 57 db
57 "INSERT OR REPLACE INTO version(id, version) VALUES (0, ?)" 58 "INSERT OR REPLACE INTO version(id, version) VALUES (0, ?)"
58 current-ver))) 59 current-ver)))
59 (log-info "Database updating complete :)"))))) 60 (log:info "Database updating complete :)")))))
60 61
61(defun upgrade-step (db new-version) 62(defun upgrade-step (db new-version)
62 (case new-version 63 (case new-version
diff --git a/src/inline-bots.lisp b/src/inline-bots.lisp
index 3ed85e9..3c6b7c4 100644
--- a/src/inline-bots.lisp
+++ b/src/inline-bots.lisp
@@ -1,7 +1,8 @@
1;; SPDX-License-Identifier: EUPL-1.2 1;; SPDX-License-Identifier: EUPL-1.2
2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com> 2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com>
3(defpackage :ukkoclot/inline-bots 3(defpackage :ukkoclot/inline-bots
4 (:use :c2cl :ukkoclot/bot :ukkoclot/config :ukkoclot/log :ukkoclot/tg-types) 4 (:use :c2cl :ukkoclot/bot :ukkoclot/config :ukkoclot/tg-types)
5 (:import-from :log)
5 (:local-nicknames (:db :ukkoclot/db)) 6 (:local-nicknames (:db :ukkoclot/db))
6 (:export :blacklist-inline-bot :on-inline-bot :whitelist-inline-bot)) 7 (:export :blacklist-inline-bot :on-inline-bot :whitelist-inline-bot))
7(in-package :ukkoclot/inline-bots) 8(in-package :ukkoclot/inline-bots)
@@ -17,7 +18,7 @@
17 (if (eq ty :whitelisted) 18 (if (eq ty :whitelisted)
18 t 19 t
19 (progn 20 (progn
20 (log-info "Deleting an unallowed inline bot message from ~A ~A" 21 (log:info "Deleting an unallowed inline bot message from ~A ~A"
21 (user-username via) 22 (user-username via)
22 (user-id via)) 23 (user-id via))
23 (try-delete-message bot msg) 24 (try-delete-message bot msg)
diff --git a/src/log.lisp b/src/log.lisp
deleted file mode 100644
index e6e8661..0000000
--- a/src/log.lisp
+++ /dev/null
@@ -1,85 +0,0 @@
1;; SPDX-License-Identifier: EUPL-1.2
2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com>
3(defpackage :ukkoclot/log
4 (:use :c2cl)
5 (:export :*output* :deflevel :log-error :log-warn :log-info :log-debug))
6(in-package :ukkoclot/log)
7
8(defparameter *output* *error-output*)
9
10(defvar *max-name-length* 8)
11(defvar *max-level-length* 4)
12
13(defvar *levels* nil)
14
15(defun get-levels ()
16 (unless *levels*
17 (setf *levels* (make-hash-table :test #'eq)))
18 *levels*)
19
20(defun register-level (level value)
21 (setf (gethash level (get-levels)) value)
22 (let ((l (length (symbol-name level))))
23 (when (> l *max-level-length*)
24 (setf *max-level-length* l))))
25
26(defun level-value (level)
27 (let ((value (gethash level (get-levels))))
28 (if value
29 value
30 (progn
31 (format *output* "UKKOLOG INTERNAL WARN: UNKNOWN LEVEL ~A" level)
32 1000))))
33
34(defun level< (lhs rhs)
35 (< (level-value lhs) (level-value rhs)))
36
37(defstruct (logger (:constructor make-logger%))
38 (name (error "No value given for NAME") :type keyword :read-only t)
39 (min-level :debug :type keyword)) ;TODO: Make this :info and make it configurable
40
41(defun make-logger (name)
42 (let ((l (length (symbol-name name))))
43 (when (> l *max-name-length*)
44 (setf *max-name-length* l)))
45 (make-logger% :name name))
46
47(defvar *package-loggers* nil)
48
49(defun get-package-loggers ()
50 (unless *package-loggers*
51 (setf *package-loggers* (make-hash-table :test #'eq)))
52 *package-loggers*)
53
54(defun get-package-logger (package)
55 (let* ((name (package-name package))
56 (name-sym (intern name :keyword))
57 (loggers (get-package-loggers))
58 (logger (gethash name-sym loggers)))
59 (unless logger
60 (setf logger (make-logger name-sym))
61 (setf (gethash name-sym loggers) logger))
62 logger))
63
64(defun perform-log (package level fmt-str &rest args)
65 (let ((logger (get-package-logger package)))
66 (unless (level< level (logger-min-level logger))
67 (apply #'format *output*
68 (concatenate 'string "~&~v@A: ~v@A: " fmt-str "~%")
69 *max-name-length* (logger-name logger)
70 *max-level-length* level
71 args))))
72
73(defmacro p (level fmt-str &rest args)
74 `(perform-log ,*package* ,level ,fmt-str ,@args))
75
76(defmacro deflevel (name value)
77 `(progn
78 (register-level ,name ,value)
79 (defmacro ,(intern (concatenate 'string "LOG-" (symbol-name name))) (fmt-str &rest args)
80 `(p ,,name ,fmt-str ,@args))))
81
82(deflevel :error 700)
83(deflevel :warn 600)
84(deflevel :info 500)
85(deflevel :debug 400)
diff --git a/src/main.lisp b/src/main.lisp
index f31cd7c..f90bfb3 100644
--- a/src/main.lisp
+++ b/src/main.lisp
@@ -2,8 +2,9 @@
2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com> 2;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com>
3(defpackage :ukkoclot/main 3(defpackage :ukkoclot/main
4 (:nicknames :ukkoclot) 4 (:nicknames :ukkoclot)
5 (:use :c2cl :ukkoclot/bot :ukkoclot/config :ukkoclot/inline-bots :ukkoclot/log :ukkoclot/tg-types) 5 (:use :c2cl :ukkoclot/bot :ukkoclot/config :ukkoclot/inline-bots :ukkoclot/tg-types)
6 (:import-from :anaphora :acond :awhen :it) 6 (:import-from :anaphora :acond :awhen :it)
7 (:import-from :log)
7 (:import-from :ukkoclot/bot :make-bot :bot-power-on :fixup-value) 8 (:import-from :ukkoclot/bot :make-bot :bot-power-on :fixup-value)
8 (:import-from :ukkoclot/db :with-db) 9 (:import-from :ukkoclot/db :with-db)
9 (:import-from :ukkoclot/strings :escape-xml :is-tg-whitespace-str :starts-with :starts-with-ignore-case) 10 (:import-from :ukkoclot/strings :escape-xml :is-tg-whitespace-str :starts-with :starts-with-ignore-case)
@@ -24,12 +25,12 @@
24 (unwind-protect 25 (unwind-protect
25 (let ((config (config-load #P"config.default.lisp"))) 26 (let ((config (config-load #P"config.default.lisp")))
26 (config-merge config #P"config.lisp") 27 (config-merge config #P"config.lisp")
27 (log-info "Starting up ~A" (config-bot-name config)) 28 (log:info "Starting up ~A" (config-bot-name config))
28 (with-db (db (config-db-path config)) 29 (with-db (db (config-db-path config))
29 (let ((bot (make-bot config db))) 30 (let ((bot (make-bot config db)))
30 ;; TODO: Catch fatal errors & report them 31 ;; TODO: Catch fatal errors & report them
31 (wrapped-main bot config)))) 32 (wrapped-main bot config))))
32 (log-info "We're done!"))) 33 (log:info "We're done!")))
33 34
34(defun wrapped-main (bot config) 35(defun wrapped-main (bot config)
35 (when *in-prod* 36 (when *in-prod*
@@ -81,7 +82,7 @@
81 :callback-query-id (callback-query-id cb) 82 :callback-query-id (callback-query-id cb)
82 :text "OK")) 83 :text "OK"))
83 (t 84 (t
84 (log-info "Unrecognised callback query data: ~A" data) 85 (log:info "Unrecognised callback query data: ~A" data)
85 (answer-callback-query bot 86 (answer-callback-query bot
86 :callback-query-id (callback-query-id cb) 87 :callback-query-id (callback-query-id cb)
87 :text "Unallowed callback query, don't press the button again" 88 :text "Unallowed callback query, don't press the button again"
@@ -215,7 +216,7 @@
215 216
216(defun on-text-command (bot msg text cmd) 217(defun on-text-command (bot msg text cmd)
217 (let ((simple-cmd (simplify-cmd bot cmd))) 218 (let ((simple-cmd (simplify-cmd bot cmd)))
218 (log-debug "text-command: ~A AKA ~A" cmd simple-cmd) 219 (log:debug "text-command: ~A AKA ~A" cmd simple-cmd)
219 ;; TODO: Replace this cond with a nicer dispatch. Something like string-case? 220 ;; TODO: Replace this cond with a nicer dispatch. Something like string-case?
220 (acond 221 (acond
221 ((equal simple-cmd "chatid") 222 ((equal simple-cmd "chatid")
@@ -246,7 +247,7 @@ Send time: ..."))
246 ))) 247 )))
247 248
248(defun report-error (bot evt err) 249(defun report-error (bot evt err)
249 (log-error "While handling ~A: ~A" evt err) 250 (log:error "While handling ~A: ~A" evt err)
250 (let ((msg (format nil "<code>~A</code> while handling ~&<pre>~A</pre>" 251 (let ((msg (format nil "<code>~A</code> while handling ~&<pre>~A</pre>"
251 (escape-xml (format nil "~A" err)) 252 (escape-xml (format nil "~A" err))
252 (escape-xml (format nil "~A" evt))))) 253 (escape-xml (format nil "~A" evt)))))