I have a bluetooth service written in go, let's call it ble-service. I want to add a characteristic to stream logs from the service over bluetooth.
My plan is to use "github.com/coreos/go-systemd/v22/sdjournal"
to access the local journal from within a gatt notifier, read each log message until there are none left, then wait for more logs to come in.
So far I have:
// +build linux
package service
import (
"fmt"
"regexp"
"time"
"github.com/coreos/go-systemd/v22/sdjournal"
"github.com/paypal/gatt"
)
var (
attrLogServiceUUID = gatt.UUID16(0xD200)
attrLogs = BleAttribute{uuid: gatt.UUID16(0xD201), name: "Ble Service Logs"}
)
var messageRe = regexp.MustCompile(`"message"=>"(.*?)"`)
func nextJournalLog(journal *sdjournal.Journal) (msg string, hasMore bool, err error) {
i, err := journal.Next()
if err != nil {
return "", i == 0, err
}
if i == 0 {
return "", false, err
}
fmt.Println("Cursor ", i)
entry, err := journal.GetEntry()
if err != nil {
return "", true, err
}
fmt.Println("Entry: ", entry)
msgDataValue, err := journal.GetDataValue("MESSAGE")
if err != nil {
return "", true, err
}
fmt.Println("Message: ", msgDataValue)
matches := messageRe.FindStringSubmatch(msgDataValue)
fmt.Println(matches)
if len(matches) > 1 {
return matches[1], true, nil
}
return "", true, nil
}
func NewLogService() (s *gatt.Service) {
s = newService(attrLogServiceUUID)
logsChar := addCharacteristic(s, attrLogs)
logsChar.HandleNotifyFunc(
func(r gatt.Request, n gatt.Notifier) {
defer logBLENotify(r, logsChar, "Logs")()
journal, err := sdjournal.NewJournal()
if err != nil {
fmt.Println("Error creating journal", err)
return
}
defer func() { journal.Close() }()
err = journal.SeekTail()
if err != nil {
fmt.Println("Error seeking journal tail", err)
return
}
cursor, err := journal.PreviousSkip(3)
if err != nil {
fmt.Println("Error seeking journal tail", err)
return
}
fmt.Println("Cursor ", cursor)
for !n.Done() {
msg, hasMore, err := nextJournalLog(journal)
time.Sleep(time.Second)
if err != nil {
fmt.Println(err)
continue
}
if !hasMore {
fmt.Println("Waiting for more logs")
time.Sleep(3 * time.Second)
continue
}
_, err = n.Write([]byte(msg))
if err != nil {
fmt.Println("Failed to write msg", msg)
continue
}
}
})
return
}
When ran as a systems service, I can subscribe to the above log characteristic, but I see no log output. However, If I run this as an executable, I can see the journald logs from the last time I ran it as a systems service.
Is there a way to access the logs of the service as it is running?