4 Star 6 Fork 3

王军 / golib

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
cklog.go 4.56 KB
一键复制 编辑 原始数据 按行查看 历史
王军 提交于 2023-11-18 21:22 . 整理文件
/*
* @Author: Wangjun
* @Date: 2023-06-29 08:55:27
* @LastEditTime: 2023-09-21 13:25:45
* @LastEditors: Wangjun
* @Description:
* @FilePath: \golib\cklog\cklog.go
* hnxr
*/
package cklog
import (
"errors"
"os"
"path/filepath"
"strings"
"time"
"gitee.com/haodreams/godriver/clickhouse"
"gitee.com/haodreams/golib/gensql"
"gitee.com/haodreams/golib/logs"
"gitee.com/haodreams/libs/easy"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
type Logs struct {
App string
Ts easy.Time
Level int
TraceID string
Msg string
UsedTime int32 //耗时
}
type CkLog struct {
db *gorm.DB
queue chan *Logs
app string
closed bool
}
const maxRecord = 5000
var defaultLog = new(CkLog)
/**
* @description: 初始化
* @param {...string} dsn
* @return {*}
*/
func Setup(dsn ...string) {
defaultLog.Setup(dsn...)
}
/**
* @description: 关闭写入ck
* @return {*}
*/
func Close() {
defaultLog.Close()
}
/**
* @description: 设置数据库
* @param {*gorm.DB} db
* @return {*}
*/
func SetDB(db *gorm.DB) {
defaultLog.SetDB(db)
}
/**
* @description: 设置DSN
* @param {string} dsn
* @return {*}
*/
func SetDsn(dsn string) (err error) {
return defaultLog.SetDsn(dsn)
}
/**
* @description: 写入日志
* @param {int} level
* @param {string} traceID
* @param {string} msg
* @return {*}
*/
func Log(level int, traceID string, msg string, UsedTime ...int32) {
defaultLog.WriteString(level, traceID, msg, UsedTime...)
}
// dsn=tcp://10.202.10.174:9000?database=hnxr&username=default&password=E35E00DF%23&compress=0
func (m *CkLog) Setup(dsn ...string) {
m.queue = make(chan *Logs, maxRecord)
binaryPath, _ := filepath.Abs(os.Args[0])
name := filepath.Base(binaryPath)
m.app = strings.TrimSuffix(name, filepath.Ext(name))
if len(dsn) > 0 {
m.SetDsn(dsn[0])
}
go m.work()
}
func (m *CkLog) Close() {
m.closed = true
m.queue <- nil
logs.Info("停止写入CK 日志")
}
func (m *CkLog) work() {
ok := true
ls := make([]*Logs, 2000)
idx := 0
for ok {
select {
case l := <-m.queue:
if l == nil {
ok = false
continue
}
ls[idx] = l
idx++
case <-time.After(time.Second * 2):
if idx > 0 {
m.InsertObjects(ls[:idx])
idx = 0
}
}
if idx >= 2000 {
m.InsertObjects(ls[:idx])
idx = 0
}
}
if idx > 0 {
m.InsertObjects(ls[:idx])
}
}
func (m *CkLog) InsertObjects(rows interface{}) (count int, err error) {
if m.db == nil {
err = errors.New("没有有效的数据库对象")
return
}
sql, records, err := gensql.GenSQLData(m.db, rows)
if err != nil {
return
}
if len(records) == 0 {
return
}
count, err = m.Insert(sql, records)
if err != nil { //再试一次
count, err = m.Insert(sql, records)
if err != nil {
logs.Warn("日志写入ck失败,", err.Error())
}
}
return
}
func (m *CkLog) Insert(sql string, rows [][]interface{}) (count int, err error) {
db, err := m.db.DB()
if err != nil {
return
}
tx, err := db.Begin()
if err != nil {
logs.Error(sql, err)
return
}
stmt, err := tx.Prepare(sql)
if err != nil {
tx.Rollback()
logs.Error(err, sql)
return
}
defer stmt.Close()
for i := range rows {
_, err = stmt.Exec(rows[i]...)
if err != nil {
logs.Warn(sql, "exec insert ", err)
continue
}
count++
}
//logs.Infof("%s connect parser to sql:%d used time:%s", msg, len(vals), time.Since(now))
if err := tx.Commit(); err != nil {
logs.Error(err)
}
return
}
func (m *CkLog) SetDB(db *gorm.DB) {
m.db = db
}
func (m *CkLog) SetDsn(dsn string) (err error) {
db, err := gorm.Open(clickhouse.Open(dsn), &gorm.Config{
NamingStrategy: schema.NamingStrategy{
SingularTable: true,
},
})
if err != nil {
return
}
d, err := db.DB()
if err != nil {
return
}
d.SetMaxIdleConns(1)
d.SetMaxOpenConns(5)
d.SetConnMaxLifetime(time.Second * 3600)
d.SetConnMaxIdleTime(time.Second * 900)
m.db = db
return
}
func (m *CkLog) WriteString(level int, traceID string, msg string, UsedTime ...int32) {
logs.Info(level, " Trace ID:", traceID, " Msg:", msg)
if m.db == nil {
return
}
if m.closed {
logs.Warn("ck log is closed")
return
}
l := new(Logs)
l.Level = level
l.TraceID = traceID
l.Msg = msg
if len(UsedTime) > 0 {
l.UsedTime = UsedTime[0]
}
l.Ts = easy.Time(time.Now().Unix())
l.App = m.app
if len(m.queue) >= maxRecord {
logs.Warn("ck log's queue is full")
return
}
m.queue <- l
}
Go
1
https://gitee.com/haodreams/golib.git
git@gitee.com:haodreams/golib.git
haodreams
golib
golib
956c397b13ee

搜索帮助