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 Time: time.Now(),
23 }
24 for d.ScanKeyval() {
25 switch string(d.Key()) {
26 case "time":
27 parsed, err := time.Parse(time.RFC3339, string(d.Value()))
28 if err != nil {
29 return 0, fmt.Errorf("parsing time: %w", err)
30 }
31 msg.Time = parsed
32 case "level":
33 msg.Level = string(d.Value())
34 case "msg":
35 msg.Message = string(d.Value())
36 default:
37 if string(d.Key()) == persistKeyArg {
38 msg.Persist = true
39 } else if string(d.Key()) == PersistTimeArg {
40 parsed, err := time.ParseDuration(string(d.Value()))
41 if err != nil {
42 continue
43 }
44 msg.PersistTime = parsed
45 } else {
46 msg.Attributes = append(msg.Attributes, Attr{
47 Key: string(d.Key()),
48 Value: string(d.Value()),
49 })
50 }
51 }
52 }
53 w.messages = append(w.messages, msg)
54 w.Publish(pubsub.CreatedEvent, msg)
55 }
56 if d.Err() != nil {
57 return 0, d.Err()
58 }
59 return len(p), nil
60}