(module log mzscheme
(require (lib "contract.ss")
(all-except (lib "list.ss" "srfi" "1") any)
(lib "string.ss" "srfi" "13")
(lib "time.ss" "srfi" "19")
(lib "cut.ss" "srfi" "26")
(planet "aif.ss" ("schematics" "macro.plt" 1))
(file "parameter.ss")
(file "base.ss"))
(provide (all-defined))
(define-struct log-stream (name) #f)
(define make-log make-log-stream)
(define message-log (make-log 'M))
(define warning-log (make-log 'W))
(define error-log (make-log 'E))
(define-parameter current-log-preamble
(lambda () null)
(lambda (val)
(if (procedure? val)
val
(raise-exn exn:fail:unlib
(format "Expected (symbol -> (list-of string)), received ~a." val))))
with-log-preamble)
(define-parameter current-log-port
current-output-port
(lambda (val)
(if (output-port? val)
val
(raise-exn exn:fail:unlib
(format "Expected output-port, received ~a." val))))
with-log-port)
(define log-message
(lambda args
(log-generic message-log args)))
(define log-warning
(lambda args
(log-generic warning-log args)))
(define log-error
(lambda args
(log-generic error-log args)))
(define/contract log-generic
(-> log-stream? list? any/c)
(lambda (log-stream message-components)
(let* ([time (current-time time-tai)]
[items (cons (log-stream-name log-stream)
(append ((current-log-preamble)) message-components))]
[out (aif log-port parameter? (current-log-port)
(log-port)
log-port)])
(display (string-join (map (cut format "~s" <>) items) ",") out)
(newline out)
time)))
)