commit 9d9780ecc8d6cf2fa5240ac8f12cf45fcae913ff Author: Timmy Welch Date: Sat Feb 1 13:01:07 2025 -0800 Initial commit diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..804ff56 --- /dev/null +++ b/go.mod @@ -0,0 +1,14 @@ +module dmesg + +go 1.22.5 + +require ( + github.com/alexjch/go-dmesg v0.0.1 // indirect + github.com/gokrazy/gokrazy v0.0.0-20250128195218-b3656e138176 // indirect + github.com/gokrazy/internal v0.0.0-20240629150625-a0f1dee26ef5 // indirect + github.com/google/renameio/v2 v2.0.0 // indirect + github.com/kenshaw/evdev v0.1.0 // indirect + github.com/mdlayher/watchdog v0.0.0-20201005150459-8bdc4f41966b // indirect + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/sys v0.20.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..31f5e49 --- /dev/null +++ b/go.sum @@ -0,0 +1,17 @@ +github.com/alexjch/go-dmesg v0.0.1 h1:9OCcZIsb9c/+P5gl+w8DpKXYi7I6aaINlQgkEiz9OCw= +github.com/alexjch/go-dmesg v0.0.1/go.mod h1:wSeufifwO3dOS31bBz+ovoEahUflK1kQo8uB+pvPOcg= +github.com/gokrazy/gokrazy v0.0.0-20250128195218-b3656e138176 h1:zRHdeXtfNyir8WOKPYW/C4GH1l7Y/41iGYWzBoDOw8I= +github.com/gokrazy/gokrazy v0.0.0-20250128195218-b3656e138176/go.mod h1:1yOdp952OIkgR9lBNUzV+mBSIcvPV0RCaCmBq9WKTJw= +github.com/gokrazy/internal v0.0.0-20240629150625-a0f1dee26ef5 h1:XDklMxV0pE5jWiNaoo5TzvWfqdoiRRScmr4ZtDzE4Uw= +github.com/gokrazy/internal v0.0.0-20240629150625-a0f1dee26ef5/go.mod h1:t3ZirVhcs9bH+fPAJuGh51rzT7sVCZ9yfXvszf0ZjF0= +github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= +github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= +github.com/kenshaw/evdev v0.1.0 h1:wmtceEOFfilChgdNT+c/djPJ2JineVsQ0N14kGzFRUo= +github.com/kenshaw/evdev v0.1.0/go.mod h1:B/fErKCihUyEobz0mjn2qQbHgyJKFQAxkXSvkeeA/Wo= +github.com/mdlayher/watchdog v0.0.0-20201005150459-8bdc4f41966b h1:7tUBfsEEBWfFeHOB7CUfoOamak+Gx/BlirfXyPk1WjI= +github.com/mdlayher/watchdog v0.0.0-20201005150459-8bdc4f41966b/go.mod h1:bmoJUS6qOA3uKFvF3KVuhf7mU1KQirzQMeHXtPyKEqg= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +golang.org/x/sys v0.0.0-20201005065044-765f4ea38db3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/main.go b/main.go new file mode 100644 index 0000000..ffe7ce2 --- /dev/null +++ b/main.go @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT +package main + +import ( + "bufio" + "fmt" + "os" + "os/signal" + "syscall" + + "github.com/alexjch/go-dmesg/pkg/dmesg" + "github.com/gokrazy/gokrazy" +) + +// Primitives are: +// - scanner, a bufio.Scanner that reads from /dev/kmsg +// - decoder, a dmesg.Decoder that wraps a scanner and decodes log records +// {decoder{scanner}}} +var LEVELS = map[uint8]string{ + 0: "Emergency", + 1: "Alert", + 2: "Critical", + 3: "Error", + 4: "Warning", + 5: "Notice", + 6: "Info", + 7: "Debug", +} + +func NewScanner() (*dmesg.Scanner, error) { + // Open /dev/kmsg for reading in a non-blocking manner + f, err := os.OpenFile("/dev/kmsg", syscall.O_RDONLY|syscall.O_NONBLOCK, 0) + if err != nil { + return nil, fmt.Errorf("Failed to open kernel log: %w", err) + } + f.Seek(0, 3) + // Wrap an os.File in a bufio.Scanner + scanner := bufio.NewScanner(f) + return &dmesg.Scanner{ + Scanner: *scanner, + ReadCloser: f, + }, nil +} +func main() { + gokrazy.WaitForClock() + // Handle Ctrl-C + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt) + // Create a scanner + scan, err := NewScanner() + if err != nil { + panic(err) + } + defer scan.Close() + // Create a decoder + dec, err := dmesg.NewDecoder(scan) + if err != nil { + panic(err) + } + // Stop the decoder when Ctrl-C is pressed + go func() { + <-c + dec.Stop() + }() + // Follow the decoder until Ctrl-C is pressed + if err := dec.Follow(func(r *dmesg.Record) { + fmt.Printf("%9s: %v: %s\n", LEVELS[r.Priority], r.Timestamp, r.Message) + }); err != nil { + panic(err) + } +}