summaryrefslogtreecommitdiff
path: root/src/log.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'src/log.lisp')
-rw-r--r--src/log.lisp85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/log.lisp b/src/log.lisp
new file mode 100644
index 0000000..e6e8661
--- /dev/null
+++ b/src/log.lisp
@@ -0,0 +1,85 @@
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)