update
parent
7e89c07951
commit
716f19133d
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"kumoly.io/kumoly/app/auth"
|
"kumoly.io/kumoly/app/auth"
|
||||||
|
"kumoly.io/kumoly/app/history"
|
||||||
"kumoly.io/kumoly/app/server"
|
"kumoly.io/kumoly/app/server"
|
||||||
"kumoly.io/kumoly/app/store"
|
"kumoly.io/kumoly/app/store"
|
||||||
"kumoly.io/kumoly/app/system"
|
"kumoly.io/kumoly/app/system"
|
||||||
|
@ -17,7 +18,7 @@ func main() {
|
||||||
auth.SetDB(store.DB)
|
auth.SetDB(store.DB)
|
||||||
|
|
||||||
sys.Inject(auth.Injector(server.API))
|
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()
|
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
|
package history
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"gorm.io/gorm"
|
||||||
"kumoly.io/kumoly/app/errors"
|
"kumoly.io/kumoly/app/errors"
|
||||||
|
"kumoly.io/kumoly/app/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var PROD = false
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ERROR = "ERROR"
|
ERROR = "ERROR"
|
||||||
INFO = "INFO"
|
INFO = "INFO"
|
||||||
|
@ -19,11 +25,22 @@ type History struct {
|
||||||
Module string
|
Module string
|
||||||
Type string
|
Type string
|
||||||
|
|
||||||
Message string
|
Message string
|
||||||
Body string
|
BodyJson string
|
||||||
Issuer string
|
Body interface{} `gorm:"-"`
|
||||||
Caller string
|
Issuer string
|
||||||
Trace 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
|
var Tunnel chan *History
|
||||||
|
@ -40,12 +57,15 @@ func Start(r Receiver) {
|
||||||
select {
|
select {
|
||||||
case started <- struct{}{}:
|
case started <- struct{}{}:
|
||||||
default:
|
default:
|
||||||
panic(errors.New(500, "history has already started!"))
|
panic(errors.New(500, "history reporter has already started!"))
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case h := <-Tunnel:
|
case h := <-Tunnel:
|
||||||
|
if Interceptor != nil {
|
||||||
|
go Interceptor(h)
|
||||||
|
}
|
||||||
r(h)
|
r(h)
|
||||||
case <-quit:
|
case <-quit:
|
||||||
<-started
|
<-started
|
||||||
|
@ -68,8 +88,13 @@ func Send(h *History) {
|
||||||
|
|
||||||
type Receiver func(*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) {
|
var ConsoleReceiver Receiver = func(h *History) {
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
package history
|
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 {
|
type Service struct {
|
||||||
system.BaseService
|
system.BaseService
|
||||||
|
@ -8,6 +13,18 @@ type Service struct {
|
||||||
|
|
||||||
func (srv Service) GetName() string { return "history.Service" }
|
func (srv Service) GetName() string { return "history.Service" }
|
||||||
func (srv Service) IsService() bool { return true }
|
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 {
|
func (srv Service) Main() error {
|
||||||
Start(DBReceiver)
|
Start(DBReceiver)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -7,11 +7,39 @@ import (
|
||||||
"runtime"
|
"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 {
|
func CallerFull(depth int) string {
|
||||||
_, file, line, _ := runtime.Caller(depth)
|
_, file, line, _ := runtime.Caller(depth)
|
||||||
return fmt.Sprintf("%s:%d", file, line)
|
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 {
|
func Caller(depth int) string {
|
||||||
_, file, line, _ := runtime.Caller(depth)
|
_, file, line, _ := runtime.Caller(depth)
|
||||||
short := file
|
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