An open API service indexing awesome lists of open source software.

https://github.com/hymkor/sxlog-go

A slog.Handler for S-Expression Output
https://github.com/hymkor/sxlog-go

go golang lisp s-expression slog

Last synced: 11 months ago
JSON representation

A slog.Handler for S-Expression Output

Awesome Lists containing this project

README

          

sxlog - A `slog.Handler` for S-Expression Output
===============================================

`sxlog` is a custom [Go slog](https://pkg.go.dev/log/slog) handler that formats log entries as **Lisp-style S-expressions**.

### Example

Here is a minimal example that logs a message using `sxlog`:

[example.go](./example.go)

```example.go
package main

import (
"log/slog"
"os"

"github.com/hymkor/sxlog-go"
)

func main() {
logger := slog.New(sxlog.New(os.Stderr))
slog.SetDefault(logger)

slog.Info("hello", "count", 3)
}
```

### Output

```go run example.go|
("2025-07-24 00:06:58" INFO "hello" ("count" 3))
```

### Notes

* The log entry is formatted as an S-expression:
`(timestamp level message (key value) ...)`
* The output is suitable for consumption by Lisp-based tools or for structured, human-readable logging.

### Read sxlog-go's log with CommonLisp

[decode-sbcl.lsp](./decode-sbcl.lsp)

```decode-sbcl.lsp
(let* ((sxpr (read *standard-input* nil nil))
(stamp (car sxpr))
(level (elt sxpr 1))
(message (elt sxpr 2))
(attr (cdddr sxpr))
(countv (cadr (assoc "count" attr :test #'equalp)))
)
(format t "ALL=~S~%" sxpr)
(format t "TIME=~S~%" stamp)
(format t "LEVEL=~S~%" level)
(format t "MESSAGE=~S~%" message)
(format t "COUNT=~S~%" countv)
)

```

`go run example.go 2>&1 | sbcl --script decode-sbcl.lsp `

```
ALL=("2025-07-24 00:13:45" INFO "hello" ("count" 3))
TIME="2025-07-24 00:13:45"
LEVEL=INFO
MESSAGE="hello"
COUNT=3
```

### Read sxlog-go's log with Go

[example-decode.go](./example-decode.go)

```example-decode.go
package main

import (
"bufio"
"fmt"
"os"

"github.com/hymkor/sxencode-go"
)

func main() {
decoder := sxencode.NewDecoder(bufio.NewReader(os.Stdin))

type logSx struct {
Time string `sxpr:",noname"`
Level string `sxpr:",noname"`
Message string `sxpr:",noname"`
Count int `sxpr:"count"`
}

var v logSx

err := decoder.Decode(&v)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
return
}
fmt.Println("Time:", v.Time)
fmt.Println("Level:", v.Level)
fmt.Println("Message:", v.Message)
fmt.Println("Count:", v.Count)
}
```