package matrix import ( "context" "fmt" "log/slog" "os" "sync/atomic" ) type SlogHandler struct { slog.Handler writer slogWriter } func NewSlogHandler(opts *slog.HandlerOptions) *SlogHandler { handler := SlogHandler{} handler.Handler = slog.NewTextHandler(&handler.writer, opts) return &handler } func (sh *SlogHandler) Attach(bot *Bot) { sh.writer.matrix.Store(bot) } type slogWriter struct { matrix atomic.Pointer[Bot] } func (sw *slogWriter) Write(p []byte) (n int, err error) { matrixInstance := sw.matrix.Load() if matrixInstance == nil { // TODO: consider added a queue that we can drain when we get attached // to a Matrix instance. return } // Spawn a goroutine as not to make the code that initiated the log wait on us going over the network. go func() { if err := matrixInstance.sendInAdminRoom(context.TODO(), string(p)); err != nil { // Make sure not to use any logging method here that might feed back // into this function! fmt.Fprintf(os.Stderr, "failed to log message to admin room: %v\n", err) } }() return len(p), nil }