writer.go

 1package logging
 2
 3import (
 4	"bytes"
 5	"fmt"
 6	"time"
 7
 8	"github.com/go-logfmt/logfmt"
 9	"github.com/kujtimiihoxha/termai/internal/pubsub"
10)
11
12type writer struct {
13	messages []LogMessage
14	*pubsub.Broker[LogMessage]
15}
16
17func (w *writer) Write(p []byte) (int, error) {
18	d := logfmt.NewDecoder(bytes.NewReader(p))
19	for d.ScanRecord() {
20		msg := LogMessage{
21			ID: fmt.Sprintf("%d", time.Now().UnixNano()),
22		}
23		for d.ScanKeyval() {
24			switch string(d.Key()) {
25			case "time":
26				parsed, err := time.Parse(time.RFC3339, string(d.Value()))
27				if err != nil {
28					return 0, fmt.Errorf("parsing time: %w", err)
29				}
30				msg.Time = parsed
31			case "level":
32				msg.Level = string(d.Value())
33			case "msg":
34				msg.Message = string(d.Value())
35			default:
36				if string(d.Key()) == persistKeyArg {
37					msg.Persist = true
38				} else if string(d.Key()) == PersistTimeArg {
39					parsed, err := time.ParseDuration(string(d.Value()))
40					if err != nil {
41						continue
42					}
43					msg.PersistTime = parsed
44				} else {
45					msg.Attributes = append(msg.Attributes, Attr{
46						Key:   string(d.Key()),
47						Value: string(d.Value()),
48					})
49				}
50			}
51		}
52		w.messages = append(w.messages, msg)
53		w.Publish(pubsub.CreatedEvent, msg)
54	}
55	if d.Err() != nil {
56		return 0, d.Err()
57	}
58	return len(p), nil
59}