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}