A common pattern I encounter when writing code is that I want to know when control enters a function, what it does while it's there, when it exits, and what it returns. I got tired of writing all this manually, so I created the in-out-logged module. Demonstration below.
#lang racket
(require in-out-logged)
(define-logger foo)
(define (on-complete op . args)
(log-foo-debug "message from inside on-complete")
(apply op args))
> (in/out-logged ("on-complete, default version")
(on-complete + 1 2 3))
; spits out the following logging (formatted as per racket-mode)
[ debug] entering on-complete, default version.
[ debug] foo: message from inside on-complete
[ debug] leaving on-complete, default version.
; in/out messages to a specified logger at specified level, show results and key/value args
> (in/out-logged ("on-complete with arguments and results"
#:to foo-logger
#:at 'info
#:results (result)
"time" (current-seconds)
"thread-id" 17)
(on-complete + 1 2 3))
; spits out the following logging (formatted as per racket-mode)
[ info] foo: entering on-complete with arguments and results.
time 1642026438
thread-id 17
[ debug] foo: message from inside on-complete
[ info] foo: leaving on-complete with arguments and results. results: (values 6)
time 1642026438
thread-id 17
; in/out messages to (current-logger) at 'debug, don't show results, format args by hand
> (in/out-logged ("explicit argument formatting"
#:with "~a, ~a, and ~a."
"foo" "bar" "baz")
(on-complete + 1 2 3))
; spits out the following logging (formatted as per racket-mode)
[ debug] entering explicit argument formatting. foo, bar, and baz.
[ debug] message from inside on-complete
[ debug] leaving explicit argument formatting. foo, bar, and baz.
; no problem with multiple value return
(in/out-logged ("multiple value return" #:to foo-logger #:results (x y z))
(values 1 2 3))
; spits out the following logging (formatted as per racket-mode)
[ debug] foo: entering multiple value return.
[ debug] foo: leaving multiple value return. results: (values 1 2 3)