blob: e6e8661fe31a03d1f186a50c4bf648a8acfd0cae (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
;; SPDX-License-Identifier: EUPL-1.2
;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs <perkontevs@gmail.com>
(defpackage :ukkoclot/log
(:use :c2cl)
(:export :*output* :deflevel :log-error :log-warn :log-info :log-debug))
(in-package :ukkoclot/log)
(defparameter *output* *error-output*)
(defvar *max-name-length* 8)
(defvar *max-level-length* 4)
(defvar *levels* nil)
(defun get-levels ()
(unless *levels*
(setf *levels* (make-hash-table :test #'eq)))
*levels*)
(defun register-level (level value)
(setf (gethash level (get-levels)) value)
(let ((l (length (symbol-name level))))
(when (> l *max-level-length*)
(setf *max-level-length* l))))
(defun level-value (level)
(let ((value (gethash level (get-levels))))
(if value
value
(progn
(format *output* "UKKOLOG INTERNAL WARN: UNKNOWN LEVEL ~A" level)
1000))))
(defun level< (lhs rhs)
(< (level-value lhs) (level-value rhs)))
(defstruct (logger (:constructor make-logger%))
(name (error "No value given for NAME") :type keyword :read-only t)
(min-level :debug :type keyword)) ;TODO: Make this :info and make it configurable
(defun make-logger (name)
(let ((l (length (symbol-name name))))
(when (> l *max-name-length*)
(setf *max-name-length* l)))
(make-logger% :name name))
(defvar *package-loggers* nil)
(defun get-package-loggers ()
(unless *package-loggers*
(setf *package-loggers* (make-hash-table :test #'eq)))
*package-loggers*)
(defun get-package-logger (package)
(let* ((name (package-name package))
(name-sym (intern name :keyword))
(loggers (get-package-loggers))
(logger (gethash name-sym loggers)))
(unless logger
(setf logger (make-logger name-sym))
(setf (gethash name-sym loggers) logger))
logger))
(defun perform-log (package level fmt-str &rest args)
(let ((logger (get-package-logger package)))
(unless (level< level (logger-min-level logger))
(apply #'format *output*
(concatenate 'string "~&~v@A: ~v@A: " fmt-str "~%")
*max-name-length* (logger-name logger)
*max-level-length* level
args))))
(defmacro p (level fmt-str &rest args)
`(perform-log ,*package* ,level ,fmt-str ,@args))
(defmacro deflevel (name value)
`(progn
(register-level ,name ,value)
(defmacro ,(intern (concatenate 'string "LOG-" (symbol-name name))) (fmt-str &rest args)
`(p ,,name ,fmt-str ,@args))))
(deflevel :error 700)
(deflevel :warn 600)
(deflevel :info 500)
(deflevel :debug 400)
|