forked from Mirrors/bubbletea
106 lines
1.3 KiB
Go
106 lines
1.3 KiB
Go
|
package tracer
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"net"
|
||
|
"sync"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type Tracer interface {
|
||
|
Command(c Command)
|
||
|
Message(m Message)
|
||
|
}
|
||
|
|
||
|
type Event struct {
|
||
|
Timestamp time.Time
|
||
|
Message Message
|
||
|
Command Command
|
||
|
}
|
||
|
|
||
|
type Message struct {
|
||
|
Model string
|
||
|
Type string
|
||
|
Msg string
|
||
|
}
|
||
|
|
||
|
type Command struct {
|
||
|
ID int
|
||
|
Started time.Time
|
||
|
Finished time.Time
|
||
|
Type string
|
||
|
Msg string
|
||
|
}
|
||
|
|
||
|
func NewCommand() Command {
|
||
|
mtx.Lock()
|
||
|
defer mtx.Unlock()
|
||
|
id++
|
||
|
|
||
|
return Command{
|
||
|
ID: id,
|
||
|
Started: time.Now(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var (
|
||
|
ch = make(chan Event)
|
||
|
mtx sync.Mutex
|
||
|
id int
|
||
|
)
|
||
|
|
||
|
type RemoteTracer struct {
|
||
|
}
|
||
|
|
||
|
func NewRemoteTracer() (*RemoteTracer, error) {
|
||
|
listen, err := net.Listen("tcp", ":13337")
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
go func() {
|
||
|
for {
|
||
|
conn, err := listen.Accept()
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
go handleTraceConn(conn)
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
t := &RemoteTracer{}
|
||
|
return t, nil
|
||
|
}
|
||
|
|
||
|
func (rt *RemoteTracer) Command(c Command) {
|
||
|
ev := Event{
|
||
|
Timestamp: time.Now(),
|
||
|
Command: c,
|
||
|
}
|
||
|
|
||
|
ch <- ev
|
||
|
}
|
||
|
|
||
|
func (rt *RemoteTracer) Message(m Message) {
|
||
|
ev := Event{
|
||
|
Timestamp: time.Now(),
|
||
|
Message: m,
|
||
|
}
|
||
|
|
||
|
ch <- ev
|
||
|
}
|
||
|
|
||
|
func handleTraceConn(conn net.Conn) {
|
||
|
for ev := range ch {
|
||
|
b, _ := json.Marshal(ev)
|
||
|
_, _ = conn.Write(b)
|
||
|
_, err := conn.Write([]byte("\n"))
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// close conn
|
||
|
_ = conn.Close()
|
||
|
}
|