Files
event/client.go

104 lines
1.7 KiB
Go
Raw Permalink Normal View History

2023-06-12 20:03:17 -07:00
package event
import (
"context"
"fmt"
"log"
"strings"
"sync"
"time"
"github.com/go-resty/resty/v2"
)
2023-06-12 20:18:19 -07:00
// TODO: Switch to opentelemetry protocol
// TODO: Add protocol-level tests
2023-06-12 20:03:17 -07:00
type Client struct {
targets []*Target
hooks []Hook
mu sync.Mutex
}
type Hook func(context.Context, *Event)
func New() *Client {
return &Client{}
}
func (c *Client) AddTarget(url string, headers map[string]string, writePeriodSeconds float64) *Target {
target := &Target{
client: resty.New().SetBaseURL(url).SetHeaders(headers),
writePeriodSeconds: writePeriodSeconds,
windowSeconds: 100.0,
stop: make(chan bool),
lastEvent: time.Now(),
}
2023-06-12 20:07:04 -07:00
go target.flushLoop(c)
2023-06-12 20:03:17 -07:00
c.mu.Lock()
defer c.mu.Unlock()
c.targets = append(c.targets, target)
return target
}
2023-06-12 20:18:19 -07:00
func (c *Client) AddHook(hook Hook) *Client {
2023-06-12 20:03:17 -07:00
c.mu.Lock()
defer c.mu.Unlock()
c.hooks = append(c.hooks, hook)
2023-06-12 20:18:19 -07:00
return c
2023-06-12 20:03:17 -07:00
}
2023-06-17 14:19:06 -07:00
func (c *Client) Log(ctx context.Context, vals ...any) string {
2023-06-12 20:18:19 -07:00
ev := NewEvent("log", vals...)
c.WriteEvent(ctx, ev)
2023-06-12 20:03:17 -07:00
parts := []string{}
for i := 0; i < len(vals); i += 2 {
2023-06-17 15:19:34 -07:00
parts = append(parts, fmt.Sprintf("%s=%v", vals[i], vals[i+1]))
2023-06-12 20:03:17 -07:00
}
2023-06-17 14:19:06 -07:00
msg := strings.Join(parts, " ")
log.Print(msg)
return msg
}
func (c *Client) Fatal(ctx context.Context, vals ...any) {
msg := c.Log(ctx, vals...)
c.Close()
panic(msg)
2023-06-12 20:03:17 -07:00
}
func (c *Client) Close() {
c.mu.Lock()
defer c.mu.Unlock()
for _, target := range c.targets {
2023-06-17 14:21:32 -07:00
target.close()
2023-06-12 20:03:17 -07:00
}
}
2023-06-12 20:18:19 -07:00
func (c *Client) WriteEvent(ctx context.Context, ev *Event) {
2023-06-12 20:03:17 -07:00
ev.Set("durationMS", time.Since(ev.start).Milliseconds())
c.mu.Lock()
defer c.mu.Unlock()
for _, hook := range c.hooks {
hook(ctx, ev)
}
for _, target := range c.targets {
target.writeEvent(ev)
}
}