update
parent
7e89c07951
commit
716f19133d
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"kumoly.io/kumoly/app/auth"
|
||||
"kumoly.io/kumoly/app/history"
|
||||
"kumoly.io/kumoly/app/server"
|
||||
"kumoly.io/kumoly/app/store"
|
||||
"kumoly.io/kumoly/app/system"
|
||||
|
@ -17,7 +18,7 @@ func main() {
|
|||
auth.SetDB(store.DB)
|
||||
|
||||
sys.Inject(auth.Injector(server.API))
|
||||
sys.Append(server, auth.New(server), &task.Service{})
|
||||
sys.Append(server, auth.New(server), &task.Service{}, &history.Service{})
|
||||
sys.Start()
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package history
|
||||
|
||||
import "kumoly.io/kumoly/app/util"
|
||||
|
||||
func Error() *History {
|
||||
h := getBase()
|
||||
h.Type = ERROR
|
||||
if !PROD {
|
||||
h.Trace = util.Stack()
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func Info() *History {
|
||||
h := getBase()
|
||||
h.Type = INFO
|
||||
return h
|
||||
}
|
||||
|
||||
func getBase() *History {
|
||||
mod, file := util.CallerMod(3)
|
||||
h := &History{
|
||||
Module: mod,
|
||||
Caller: file,
|
||||
}
|
||||
return h
|
||||
}
|
|
@ -1,12 +1,18 @@
|
|||
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"
|
||||
|
@ -19,11 +25,22 @@ type History struct {
|
|||
Module string
|
||||
Type string
|
||||
|
||||
Message string
|
||||
Body string
|
||||
Issuer string
|
||||
Caller string
|
||||
Trace string
|
||||
Message string
|
||||
BodyJson string
|
||||
Body interface{} `gorm:"-"`
|
||||
Issuer string
|
||||
Caller string
|
||||
Trace 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
|
||||
|
@ -40,12 +57,15 @@ func Start(r Receiver) {
|
|||
select {
|
||||
case started <- struct{}{}:
|
||||
default:
|
||||
panic(errors.New(500, "history has already started!"))
|
||||
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
|
||||
|
@ -68,8 +88,13 @@ func Send(h *History) {
|
|||
|
||||
type Receiver func(*History)
|
||||
|
||||
var DBReceiver Receiver = func(h *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) {
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
package history
|
||||
|
||||
import "kumoly.io/kumoly/app/system"
|
||||
import (
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/viper"
|
||||
"kumoly.io/kumoly/app/store"
|
||||
"kumoly.io/kumoly/app/system"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
system.BaseService
|
||||
|
@ -8,6 +13,18 @@ type Service struct {
|
|||
|
||||
func (srv Service) GetName() string { return "history.Service" }
|
||||
func (srv Service) IsService() bool { return true }
|
||||
func (srv Service) Init() error {
|
||||
PROD = viper.GetBool("prod")
|
||||
l := log.With().Str("mod", "history").
|
||||
Str("service", "history.Service").
|
||||
Logger()
|
||||
l.Debug().Msg("Migrating database for history.Service ...")
|
||||
if err := store.Migrate(&History{}); err != nil {
|
||||
l.Error().Err(err).Msg("Migrating database")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (srv Service) Main() error {
|
||||
Start(DBReceiver)
|
||||
return nil
|
||||
|
|
|
@ -7,11 +7,39 @@ import (
|
|||
"runtime"
|
||||
)
|
||||
|
||||
func Stack() string {
|
||||
buf := make([]byte, 1024)
|
||||
for {
|
||||
n := runtime.Stack(buf, false)
|
||||
if n < len(buf) {
|
||||
return string(buf[:n])
|
||||
}
|
||||
buf = make([]byte, 2*len(buf))
|
||||
}
|
||||
}
|
||||
|
||||
func CallerFull(depth int) string {
|
||||
_, file, line, _ := runtime.Caller(depth)
|
||||
return fmt.Sprintf("%s:%d", file, line)
|
||||
}
|
||||
|
||||
func CallerMod(depth int) (mod, file string) {
|
||||
_, f, l, _ := runtime.Caller(depth)
|
||||
ptr := 0
|
||||
for i := len(f) - 1; i > 0; i-- {
|
||||
if f[i] == '/' {
|
||||
if ptr == 0 {
|
||||
file = fmt.Sprintf("%v:%v", f[i+1:], l)
|
||||
ptr = i
|
||||
} else {
|
||||
mod = f[i+1 : ptr]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Caller(depth int) string {
|
||||
_, file, line, _ := runtime.Caller(depth)
|
||||
short := file
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStack(t *testing.T) {
|
||||
fmt.Println(Stack())
|
||||
}
|
||||
|
||||
func TestCallerFull(t *testing.T) {
|
||||
fmt.Println(CallerFull(1))
|
||||
}
|
||||
|
||||
func TestCallerMod(t *testing.T) {
|
||||
fmt.Println(CallerMod(1))
|
||||
}
|
||||
|
||||
func TestCaller(t *testing.T) {
|
||||
fmt.Println(Caller(1))
|
||||
}
|
Loading…
Reference in New Issue