Logging in Lisp

Our first program will print the classic “hello world” message using Lisp. Here’s the full source code:

(defun main ()
  (format t "hello world~%"))

(main)

To run the program, save the code in a file (e.g., hello-world.lisp) and use a Lisp interpreter or compiler. For example, if you’re using SBCL (Steel Bank Common Lisp):

$ sbcl --script hello-world.lisp
hello world

In Lisp, we don’t typically build standalone binaries like in some other languages. Instead, we usually run our code within a Lisp environment. However, some Lisp implementations allow creating executable images. For example, with SBCL:

$ sbcl --load hello-world.lisp --eval '(sb-ext:save-lisp-and-die "hello-world" :executable t :toplevel #'main)'
$ ls
hello-world    hello-world.lisp

We can then execute the built image directly:

$ ./hello-world
hello world

Now that we can run basic Lisp programs, let’s explore more about the language.

Lisp has powerful features for logging and debugging. Let’s look at some examples:

(defpackage :logging-example
  (:use :cl))

(in-package :logging-example)

;; Using the built-in format function for simple logging
(defun log-message (message)
  (format t "~A: ~A~%" (local-time:now) message))

(log-message "Standard logging")

;; Creating a custom logger with a prefix
(defun create-logger (prefix)
  (lambda (message)
    (format t "~A ~A: ~A~%" prefix (local-time:now) message)))

(defparameter *my-logger* (create-logger "MyLog"))
(funcall *my-logger* "Custom logger message")

;; Using a third-party logging library (e.g., log4cl)
;; Note: You would need to install log4cl first
(ql:quickload :log4cl)
(log:config :info)

(log:info "Structured log message")
(log:info "Log with data" :key "value" :number 42)

;; Redirecting log output to a file
(with-open-file (log-file "app.log" :direction :output :if-exists :append :if-does-not-exist :create)
  (let ((log4cl:*log-output* log-file))
    (log:info "This message goes to the file")))

;; Reading from the log file
(with-open-file (in "app.log")
  (format t "Log file contents:~%~A" (read-line in)))

In this example, we demonstrate various logging techniques in Lisp:

  1. We use the built-in format function for simple logging.
  2. We create a custom logger with a prefix.
  3. We show how to use a third-party logging library (log4cl) for more advanced, structured logging.
  4. We demonstrate how to redirect log output to a file.
  5. Finally, we show how to read from the log file.

Note that Lisp’s powerful macro system and dynamic nature allow for very flexible and extensible logging solutions. The exact implementation might vary depending on the specific Lisp implementation and libraries you’re using.