You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
2.1 KiB
Go

package printer
import (
"context"
"joybuywork/internal/app"
"joybuywork/internal/consts"
"joybuywork/internal/plugins/hashid"
"joybuywork/internal/repository/dao"
"joybuywork/internal/repository/model"
"joybuywork/internal/utils"
"go-micro.dev/v4/metadata"
"sync/atomic"
"time"
)
type slows struct {
idx atomic.Int32
slowLogs [][]*model.SlowLog
listen *app.Listener
}
var Slow = &slows{
idx: atomic.Int32{},
slowLogs: make([][]*model.SlowLog, 2),
listen: app.NewListener(),
}
func (s *slows) Run() {
Slow.listen.Listen(func() (messages []string) {
i := s.idx.Load()
if len(s.slowLogs[i]) == 0 {
return
}
var logs = s.slowLogs[i]
if i == 0 {
s.idx.Add(1)
} else {
s.idx.Add(-1)
}
s.slowLogs[i] = nil
_ = dao.SlowLog.WithContext(context.Background()).CreateInBatches(logs, 300)
return
}, 5*time.Second)
}
func (s *slows) Stop() {
Slow.listen.Stop()
}
// 把慢日志入库
func init() {
if consts.CollectSlowLog {
Slow.Run()
}
}
type SlowType func() time.Duration
var (
normalSlow = func() time.Duration { return 51 * time.Millisecond } // 50ms
TenNormalSlow = func() time.Duration { return 501 * time.Millisecond } // 500ms
)
type SlowLog struct {
ctx context.Context
slow SlowType
start time.Time
}
// NewSlowLog 实例化一个慢日志
func NewSlowLog(ctx context.Context, opts ...SlowLogOption) *SlowLog {
sl := &SlowLog{
ctx: ctx,
slow: normalSlow,
}
for _, opt := range opts {
opt(sl)
}
return sl
}
// Start 开始
func (s *SlowLog) Start(msg string) {
s.start = time.Now()
Print(s.ctx, msg, nil)
}
// End 结束
func (s *SlowLog) End(msg string, err error, method, req, res string) {
Print(s.ctx, msg, err)
if time.Since(s.start) < s.slow() {
return
}
if consts.CollectSlowLog {
traceId, _ := metadata.Get(s.ctx, consts.TraceIdKey)
Slow.slowLogs[int(Slow.idx.Load())] = append(Slow.slowLogs[int(Slow.idx.Load())], &model.SlowLog{
ID: hashid.IdBigint(),
Method: method,
Req: utils.STernary[string](req, "", "{}"),
Res: utils.STernary[string](res, "", "{}"),
Sec: time.Since(s.start).Milliseconds(),
TraceID: traceId,
})
}
}