首頁 > 軟體

golang xorm 自定義紀錄檔記錄器之使用zap實現紀錄檔輸出、切割紀錄檔(最新)

2022-10-28 14:03:04

1.準備並下載好需要的包

  • xorm.io/xorm  
  • xorm.io/core
  • go.uber.org/zap
  • gopkg.in/natefinch/lumberjack.v2  用於切割zap
  • github.com/lib/pq  本文使用postgresql資料庫

2. 連線postgresql資料庫

// 建立pg資料庫連線
func newDb() (*xorm.Engine, error) {
	source := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
		"127.0.0.1", 5432, "postgres", "root", "postgres")
 
	engine, err := xorm.NewEngine("postgres", source)
	if err != nil {
		return nil, err
	}
 
	// 連線池中最大連線數
	engine.SetMaxOpenConns(100)
	// 連線池中最大空閒連線數
	engine.SetMaxIdleConns(10)
	// 單個連線最大存活時間(單位:秒)
	engine.SetConnMaxLifetime(10)
	engine.ShowSQL(true)
 
	// 輸出紀錄檔 終點部分使用自定義紀錄檔記錄器
	engine.SetLogger(&customXormLogger{
		level:   xormlog.LOG_INFO,
		showSQL: true,
	})
 
	return engine, nil
}

3. zap紀錄檔工具

// zap
func getZapLog() *zap.Logger {
	loggerName := "db" // 紀錄檔檔名稱
 
	if logger, has := loggerMap[loggerName]; has {
		return logger
	} else {
		loggerMu.Lock()
 
		output := zapcore.AddSync(&lumberjack.Logger{
			Filename:   "./log",
			MaxSize:    100, // 紀錄檔檔案最大容量(單位:MB),超過容量,檔案會自動分割
			MaxBackups: 1,   // 保留的紀錄檔天數(單位:天)
			MaxAge:     10,  // 保留的紀錄檔檔案個數,檔案數量超過該值,最舊的檔案會被刪除
		})
 
		// 如果需要可以輸出當控制檯
		//output = zapcore.NewMultiWriteSyncer(output, os.Stdout)
		level := zapcore.DebugLevel
		_ = level.Set("info") // 設定紀錄檔級別  debug info warn error fatal (紀錄檔級別從大到小)
 
		core := zapcore.NewCore(
			zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), // 設定紀錄檔輸出格式 這塊可以自定義
			output,
			zap.NewAtomicLevelAt(level),
		)
		newLogger := zap.New(core, zap.AddStacktrace(zapcore.ErrorLevel))
 
		loggerMap[loggerName] = newLogger
		loggerMu.Unlock()
		return newLogger
	}
}

4.實現xorm 自定義紀錄檔記錄器

// 重點:實現xormLogger介面 自定義記錄器
type customXormLogger struct {
	level   xormlog.LogLevel
	showSQL bool
}
 
var _ xormlog.Logger = &customXormLogger{}
 
func (c *customXormLogger) Debug(v ...interface{}) {
	if c.level <= xormlog.LOG_DEBUG {
		fmt.Println(v...)
	}
	return
}
 
func (c *customXormLogger) Debugf(format string, v ...interface{}) {
	if c.level <= xormlog.LOG_DEBUG {
		getZapLog().Debug(fmt.Sprint(v...))
	}
	return
}
 
func (c *customXormLogger) Error(v ...interface{}) {
	if c.level <= xormlog.LOG_ERR {
		fmt.Println(v...)
	}
	return
}
 
func (c *customXormLogger) Errorf(format string, v ...interface{}) {
	if c.level <= xormlog.LOG_ERR {
		getZapLog().Error(fmt.Sprint(v...))
	}
	return
}
 
func (c *customXormLogger) Info(v ...interface{}) {
	if c.level <= xormlog.LOG_INFO {
		fmt.Println(v...)
	}
	return
}
 
func (c *customXormLogger) Infof(format string, v ...interface{}) {
	if c.level <= xormlog.LOG_INFO {
		getZapLog().Info(fmt.Sprint(v...))
	}
	return
}
 
func (c *customXormLogger) Warn(v ...interface{}) {
	if c.level <= xormlog.LOG_WARNING {
		fmt.Println(v...)
	}
	return
}
 
func (c *customXormLogger) Warnf(format string, v ...interface{}) {
	if c.level <= xormlog.LOG_WARNING {
		getZapLog().Warn(fmt.Sprint(v...))
	}
	return
}
 
func (c *customXormLogger) Level() xormlog.LogLevel {
	return c.level
}
 
func (c *customXormLogger) SetLevel(l xormlog.LogLevel) {
	c.level = l
	return
}
 
func (c *customXormLogger) ShowSQL(show ...bool) {
	if len(show) == 0 {
		c.showSQL = true
		return
	}
	c.showSQL = show[0]
}
 
func (c *customXormLogger) IsShowSQL() bool {
	return c.showSQL
}

5.使用

// 測試
	pgDb, err := newDb()
	fmt.Println(err)
 
	queryInterface, _ := pgDb.SQL("select * from test").QueryInterface()
 
	fmt.Println(queryInterface)

完整程式碼

package main
 
import (
	"fmt"
	_ "github.com/lib/pq"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
	"sync"
	"xorm.io/xorm"
	xormlog "xorm.io/xorm/log"
)
 
var (
	loggerMap = map[string]*zap.Logger{}
	loggerMu  = &sync.Mutex{}
)
 
// 建立pg資料庫連線
func newDb() (*xorm.Engine, error) {
	source := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
		"127.0.0.1", 5432, "postgres", "root", "postgres")
 
	engine, err := xorm.NewEngine("postgres", source)
	if err != nil {
		return nil, err
	}
 
	// 連線池中最大連線數
	engine.SetMaxOpenConns(100)
	// 連線池中最大空閒連線數
	engine.SetMaxIdleConns(10)
	// 單個連線最大存活時間(單位:秒)
	engine.SetConnMaxLifetime(10)
	engine.ShowSQL(true)
 
	// 輸出紀錄檔 終點部分使用自定義紀錄檔記錄器
	engine.SetLogger(&customXormLogger{
		level:   xormlog.LOG_INFO,
		showSQL: true,
	})
 
	return engine, nil
}
 
// zap
func getZapLog() *zap.Logger {
	loggerName := "db" // 紀錄檔檔名稱
 
	if logger, has := loggerMap[loggerName]; has {
		return logger
	} else {
		loggerMu.Lock()
 
		output := zapcore.AddSync(&lumberjack.Logger{
			Filename:   "./log",
			MaxSize:    100, // 紀錄檔檔案最大容量(單位:MB),超過容量,檔案會自動分割
			MaxBackups: 1,   // 保留的紀錄檔天數(單位:天)
			MaxAge:     10,  // 保留的紀錄檔檔案個數,檔案數量超過該值,最舊的檔案會被刪除
		})
 
		// 如果需要可以輸出當控制檯
		//output = zapcore.NewMultiWriteSyncer(output, os.Stdout)
		level := zapcore.DebugLevel
		_ = level.Set("info") // 設定紀錄檔級別  debug info warn error fatal (紀錄檔級別從大到小)
 
		core := zapcore.NewCore(
			zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), // 設定紀錄檔輸出格式 這塊可以自定義
			output,
			zap.NewAtomicLevelAt(level),
		)
		newLogger := zap.New(core, zap.AddStacktrace(zapcore.ErrorLevel))
 
		loggerMap[loggerName] = newLogger
		loggerMu.Unlock()
		return newLogger
	}
}
 
// 重點:實現xormLogger介面 自定義記錄器
type customXormLogger struct {
	level   xormlog.LogLevel
	showSQL bool
}
 
var _ xormlog.Logger = &customXormLogger{}
 
func (c *customXormLogger) Debug(v ...interface{}) {
	if c.level <= xormlog.LOG_DEBUG {
		fmt.Println(v...)
	}
	return
}
 
func (c *customXormLogger) Debugf(format string, v ...interface{}) {
	if c.level <= xormlog.LOG_DEBUG {
		getZapLog().Debug(fmt.Sprint(v...))
	}
	return
}
 
func (c *customXormLogger) Error(v ...interface{}) {
	if c.level <= xormlog.LOG_ERR {
		fmt.Println(v...)
	}
	return
}
 
func (c *customXormLogger) Errorf(format string, v ...interface{}) {
	if c.level <= xormlog.LOG_ERR {
		getZapLog().Error(fmt.Sprint(v...))
	}
	return
}
 
func (c *customXormLogger) Info(v ...interface{}) {
	if c.level <= xormlog.LOG_INFO {
		fmt.Println(v...)
	}
	return
}
 
func (c *customXormLogger) Infof(format string, v ...interface{}) {
	if c.level <= xormlog.LOG_INFO {
		getZapLog().Info(fmt.Sprint(v...))
	}
	return
}
 
func (c *customXormLogger) Warn(v ...interface{}) {
	if c.level <= xormlog.LOG_WARNING {
		fmt.Println(v...)
	}
	return
}
 
func (c *customXormLogger) Warnf(format string, v ...interface{}) {
	if c.level <= xormlog.LOG_WARNING {
		getZapLog().Warn(fmt.Sprint(v...))
	}
	return
}
 
func (c *customXormLogger) Level() xormlog.LogLevel {
	return c.level
}
 
func (c *customXormLogger) SetLevel(l xormlog.LogLevel) {
	c.level = l
	return
}
 
func (c *customXormLogger) ShowSQL(show ...bool) {
	if len(show) == 0 {
		c.showSQL = true
		return
	}
	c.showSQL = show[0]
}
 
func (c *customXormLogger) IsShowSQL() bool {
	return c.showSQL
}
 
func main() {
	// 測試
	pgDb, err := newDb()
	fmt.Println(err)
 
	queryInterface, _ := pgDb.SQL("select * from test").QueryInterface()
 
	fmt.Println(queryInterface)
}

參考檔案

Golang XORM搭配OpenTracing+Jaeger鏈路監控讓SQL執行一覽無遺(附原始碼)

到此這篇關於golang xorm 自定義紀錄檔記錄器,使用zap實現紀錄檔輸出、切割紀錄檔的文章就介紹到這了,更多相關golang  zap紀錄檔內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com