dmesg/main.go

72 lines
1.5 KiB
Go
Raw Normal View History

2025-02-01 13:01:07 -08:00
// 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)
}
}