package history import ( "encoding/json" "fmt" "time" "github.com/rs/zerolog/log" "gorm.io/gorm" "kumoly.io/kumoly/app/errors" "kumoly.io/kumoly/app/store" ) var PROD = false const ( ERROR = "ERROR" INFO = "INFO" ) type History struct { ID uint `gorm:"primaryKey"` CreatedAt time.Time Module string Type string Caller string Trace string Message string Body interface{} `gorm:"-"` Issuer string BodyJson string } func (h *History) BeforeCreate(tx *gorm.DB) (err error) { if h.Body != nil { body, err := json.Marshal(h.Body) if err != nil { h.BodyJson = string(body) } } return } var Tunnel chan *History var quit chan struct{} var started chan struct{} func init() { Tunnel = make(chan *History) quit = make(chan struct{}, 1) started = make(chan struct{}, 1) } func Start(r Receiver) { select { case started <- struct{}{}: default: panic(errors.New(500, "history reporter has already started!")) } go func() { for { select { case h := <-Tunnel: if Interceptor != nil { go Interceptor(h) } r(h) case <-quit: <-started return } } }() } func Stop() { quit <- struct{}{} } func Send(h *History) { if h.Type == "" { h.Type = INFO } Tunnel <- h } type Receiver func(*History) var Interceptor func(*History) = nil var DBReceiver Receiver = func(h *History) { err := store.DB.Create(h).Error if err != nil { log.Error().Str("mod", "history").Err(err).Msg("DBReceiver error") } } var ConsoleReceiver Receiver = func(h *History) { fmt.Printf("%+v\n", h) }