What is Verbose?

Verbose is a logging framework for Common Lisp that aims to provide a good default setup as well as an extensible back-end to suit all your logging needs.

How To

Load Verbose with ASDF or Quicklisp.

(ql:quickload :verbose)

By default, a new logging thread is already started and set up with a REPL-Faucet on the INFO level, that simply prints log messages from the INFO level and above to the standard output:

(v:info :TEST "Hello world!")
LOG: 2014-04-01 13:32:49 [INFO ] <TEST>: Hello world!

Each logging statement expects a category and a format string. Optionally you can pass in format arguments:

(v:info :TEST "2+2=~f" (+ 2 2))
LOG: 2014-04-01 13:33:20 [INFO ] <TEST>: 2+2=4.0

You can change the logging level of the REPL-Faucet easily. The available levels by default are :FATAL :SEVERE :ERROR :WARN :INFO :DEBUG :TRACE.

(setf (v:repl-level) :DEBUG)

Using the category-tree-filter you can limit what kinds of categories are shown:

(v:info :foo "Foo")

(v:info "Foo")
LOG: 2014-04-01 13:51:03 [INFO ] <FOO.BAR.STUFF>: Foo

To extend Verbose you can use Piping constructs. The *global-controller* in itself is a pipeline and can be used as such.

Log message passing through the pipeline happens in a separate thread. If you create new pipe segments for your logging pipeline that need to access some form of shared variable, you can use shared-instance, which is SETFable. One shared-instance that is most likely of interest to everyone is saved under the symbol *standard-output*. Setting this anew is useful if you start a new REPL session and need to redirect logging to it. The *standard-output* and *error-output* shared-instances are handled specially and their values are bound to their respective special variables during message passing.

(setf (v:shared-instance '*standard-output*) *standard-output*)

If you want to log to a file, you can either create your own custom file faucet, or use a preset one like the rotating-log-faucet:

(v:add-pipe (make-instance 'v:rotating-log-faucet :file #p"~/verbose.log" :interval (v:make-cron-interval "* * * * *")))

Which creates a faucet that logs to a file with "verbose.log" suffix in your home directory, rotating every minute as per the CRON interval. In case you want to filter the message to a certain level or category instead, you can precede it by a filter:

(v:add-pipe (make-instance 'piping:predicate-filter :predicate #'(lambda (message) (message-visible message :WARN)))
              (make-instance 'v:rotating-log-faucet :file #p"~/verbose.log" :interval (v:make-cron-interval "* * * * *")))

Using the piping constructs you can create complex logging systems or even change the pipeline on the fly. When you do, be aware that since the message passing happens in a separate thread, you need to acquire access to the pipeline first before modifying it:

(v:with-controller-lock ()
    (piping:pipeline v:*global-controller*))

See the documentation of Piping for more information.

Other Guff

Verbose is licensed under the Artistic License 2.0 and ©2014 TymoonNET/NexT, Nicolas Hafner.
This library can be obtained via git on For questions, patches or suggestions, please contact me via email or write a github issue.

Verbose Package Index