app/history/history.go

124 lines
2.1 KiB
Go
Raw Normal View History

2021-12-16 06:25:57 +00:00
package history
import (
2021-12-16 13:43:56 +00:00
"encoding/json"
2021-12-16 06:25:57 +00:00
"fmt"
2021-12-17 07:52:32 +00:00
"sync"
2021-12-16 06:25:57 +00:00
"time"
2021-12-16 11:44:07 +00:00
2021-12-16 13:43:56 +00:00
"github.com/rs/zerolog/log"
"gorm.io/gorm"
2021-12-16 11:44:07 +00:00
"kumoly.io/kumoly/app/errors"
2021-12-16 13:43:56 +00:00
"kumoly.io/kumoly/app/store"
2021-12-16 06:25:57 +00:00
)
2021-12-16 13:43:56 +00:00
var PROD = false
2021-12-16 06:25:57 +00:00
const (
ERROR = "ERROR"
INFO = "INFO"
)
type History struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
2021-12-16 15:58:02 +00:00
Module string
Type string
Caller string
Trace string
2021-12-17 07:52:32 +00:00
BodyJson string
2021-12-16 06:25:57 +00:00
2021-12-16 18:03:07 +00:00
Name string
2021-12-16 15:58:02 +00:00
Message string
Body interface{} `gorm:"-"`
Issuer string
2021-12-17 07:52:32 +00:00
// Group to identify auth, empty for admin
Group string
// Scope for users to narrow down view point
Scope string
2021-12-16 13:43:56 +00:00
}
func (h *History) BeforeCreate(tx *gorm.DB) (err error) {
if h.Body != nil {
2021-12-18 09:30:05 +00:00
if body, err := json.Marshal(h.Body); err != nil {
log.Error().Str("mod", "history").Err(err).Msg("history create error")
} else {
2021-12-16 13:43:56 +00:00
h.BodyJson = string(body)
}
}
return
2021-12-16 06:25:57 +00:00
}
var Tunnel chan *History
var quit chan struct{}
2021-12-16 11:44:07 +00:00
var started chan struct{}
2021-12-17 07:52:32 +00:00
var wg sync.WaitGroup
2021-12-16 06:25:57 +00:00
func init() {
Tunnel = make(chan *History)
2021-12-16 10:11:34 +00:00
quit = make(chan struct{}, 1)
2021-12-16 11:44:07 +00:00
started = make(chan struct{}, 1)
2021-12-16 06:25:57 +00:00
}
func Start(r Receiver) {
2021-12-17 07:52:32 +00:00
if len(started) == 1 {
2021-12-16 13:43:56 +00:00
panic(errors.New(500, "history reporter has already started!"))
2021-12-16 11:44:07 +00:00
}
2021-12-17 07:52:32 +00:00
started <- struct{}{}
2021-12-16 06:25:57 +00:00
go func() {
2021-12-16 10:11:34 +00:00
for {
select {
case h := <-Tunnel:
2021-12-17 07:52:32 +00:00
wg.Add(1)
2021-12-16 13:43:56 +00:00
if Interceptor != nil {
2021-12-17 07:52:32 +00:00
Interceptor(h)
2021-12-16 13:43:56 +00:00
}
2021-12-16 10:11:34 +00:00
r(h)
2021-12-17 07:52:32 +00:00
wg.Done()
2021-12-16 10:11:34 +00:00
case <-quit:
2021-12-16 11:44:07 +00:00
<-started
2021-12-16 10:11:34 +00:00
return
}
2021-12-16 06:25:57 +00:00
}
}()
}
func Stop() {
2021-12-18 13:32:46 +00:00
if len(started) == 0 {
return
}
2021-12-16 06:25:57 +00:00
quit <- struct{}{}
2021-12-18 09:30:05 +00:00
log.Debug().Str("mod", "history").Msg("stop received")
2021-12-17 07:52:32 +00:00
wg.Wait()
2021-12-18 09:30:05 +00:00
log.Debug().Str("mod", "history").Msg("stoped")
2021-12-16 06:25:57 +00:00
}
2021-12-16 10:11:34 +00:00
func Send(h *History) {
2021-12-17 07:52:32 +00:00
if len(started) == 0 {
log.Warn().Str("mod", "history").
Interface("history", h).
Msg("history reporter has not started, report will be discarded")
}
2021-12-16 11:11:46 +00:00
if h.Type == "" {
h.Type = INFO
}
2021-12-16 10:11:34 +00:00
Tunnel <- h
}
2021-12-16 06:25:57 +00:00
type Receiver func(*History)
2021-12-16 13:43:56 +00:00
var Interceptor func(*History) = nil
2021-12-16 06:25:57 +00:00
2021-12-16 13:43:56 +00:00
var DBReceiver Receiver = func(h *History) {
err := store.DB.Create(h).Error
if err != nil {
2021-12-17 07:52:32 +00:00
log.Error().Str("mod", "history").
Interface("history", h).
Err(err).Msg("DBReceiver error")
2021-12-16 13:43:56 +00:00
}
2021-12-16 06:25:57 +00:00
}
var ConsoleReceiver Receiver = func(h *History) {
fmt.Printf("%+v\n", h)
}