Skip to content

Commit 2236188

Browse files
committed
slog: log-file-truename, and an example
log-file-truename is useful to avoid user code having to second-guess what slog is doing.
1 parent a5111ed commit 2236188

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

README.md

+29-2
Original file line numberDiff line numberDiff line change
@@ -2055,6 +2055,15 @@ nil
20552055

20562056
If you call `slog-to` with a filename destination*outside* the dynamic extent of `logging` or `closing-opened-log-files` then you perhaps want to call `(close-open-log-files :reset t)` every once in a while as well (the `reset` argument doesn't really matter, but it cleans up the map).
20572057

2058+
**`log-file-truename`** is a little utility function: it will return the `truename` of a filename designator, making sure any needed directories are created and creating & opening the file if need be. It's useful just so user code does not need to duplicate what `slog` does, and particularly if you're calling `slog-to` explicitly in situations like:
2059+
2060+
```lisp
2061+
(let ((logname (log-file-truename "my-log.log")))
2062+
... perhaps change directory etc ...
2063+
(slog-to logname ...)
2064+
...)
2065+
```
2066+
20582067
Finally note that all this mechanism is only about filename destinations: if you log to stream destinations you need to manage the streams as you normally would. The purpose of it is so you can simply not have to worry about the streams but just specify what log file(s) you want written.
20592068

20602069
### Checking the log file map is sane
@@ -2122,10 +2131,28 @@ There are some sanity tests for this code which are run on loading `slog`, becau
21222131

21232132
You can use `get-precision-universal-time` to write your own formatters, using `log-entry-internal-time` to get the time the entry was created.
21242133

2134+
### An example: rotating log files
2135+
```lisp
2136+
(defun rotate-log-files (&key (all nil))
2137+
;; Obviously this would want to be more careful in real life
2138+
(flet ((rotate-one (file)
2139+
(let ((rotated (make-pathname :type "old"
2140+
:defaults file)))
2141+
(when (probe-file rotated)
2142+
(delete-file rotated))
2143+
(when (probe-file file)
2144+
(rename-file file rotated)))))
2145+
(multiple-value-bind (newly-closed already-closed) (close-open-log-files :all all)
2146+
(dolist (a already-closed)
2147+
(rotate-one a))
2148+
(dolist (n newly-closed)
2149+
(rotate-one n)))))
2150+
```
2151+
21252152
### Notes
2126-
A previous version `slog` handled files rather differently: it tried to delay creating or opening them as long as possible, and thus needed to be able to find an absolute pathname for a file which it had not opened or created, requiring it to have a notion of the current directory which was better than `*default-pathname-defaults*`. This is now all gone: the current version simply treats pathnames as they are.
2153+
A previous version of `slog` handled files rather differently: it tried to delay creating or opening them as long as possible, and thus needed to be able to find an absolute pathname for a file which it had not opened or created, requiring it to have a notion of the current directory which was better than `*default-pathname-defaults*`. This is now all gone: the current version simply treats pathnames as they are.
21272154

2128-
Condition objects are meant to be immutable (from the [CLHS](http://www.lispworks.com/documentation/HyperSpec/Body/m_defi_5.htm "define-condition"):
2155+
Condition objects are meant to be immutable: from the [CLHS](http://www.lispworks.com/documentation/HyperSpec/Body/m_defi_5.htm "define-condition")
21292156

21302157
> The consequences are unspecified if an attempt is made to assign the slots by using `setf`.
21312158

slog.lisp

+8-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#:simple-log-entry
2727
#:slog
2828
#:closing-opened-log-files
29+
#:log-file-truename
2930
#:current-log-files
3031
#:log-files-sane-p
3132
#:close-open-log-files
@@ -168,6 +169,12 @@
168169
(open-log-file-pathname (log-file-pathname lf)))))
169170
lf)
170171

172+
(defun log-file-truename (filespec)
173+
;; This lets user code get back the truename of a log file, wrapping
174+
;; creating the file, and directories etc, so you don't need to
175+
;; replicate a bunch of the guts of slog.
176+
(log-file-pathname (ensure-log-file filespec)))
177+
171178
(defun close-open-log-files-up-to (up-to &key (abort nil) (test nil))
172179
;; Close any open log files up to a specified tail. With test
173180
;; return only those whose pathnames pass the test. Returns the
@@ -224,7 +231,7 @@
224231
;; Normally just close the current open log files. if TEST is given
225232
;; close only those whose pathnames pass the test. With reset reset
226233
;; the current list (only to the last saved state). You can't give
227-
;; both test and reset this would leak filehandles.
234+
;; both test and reset as this would leak filehandles.
228235
(when (and test reset)
229236
(error "can't give both test and reset"))
230237
(let ((clft (if all nil *slfs*)))

0 commit comments

Comments
 (0)