亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

從零封裝Gin框架實(shí)現(xiàn)日志初始化及切割歸檔功能

 更新時(shí)間:2024年01月31日 10:52:08   作者:生活處處有BUG  
這篇文章主要為大家介紹了從零封裝Gin框架實(shí)現(xiàn)日志初始化及切割歸檔功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

本篇來(lái)講一下怎么將日志服務(wù)集成到項(xiàng)目中,它也是框架中必不可少的,平時(shí)代碼調(diào)試,線上 Bug 分析都離不開(kāi)它。這里將使用 zap 作為日志庫(kù),一般來(lái)說(shuō),日志都是需要寫入到文件保存的,這也是 zap 唯一缺少的部分,所以我將結(jié)合 lumberjack 來(lái)使用,實(shí)現(xiàn)日志切割歸檔的功能

安裝

go get -u go.uber.org/zap
go get -u gopkg.in/natefinch/lumberjack.v2

定義日志配置項(xiàng)

新建 config/log.go 文件,定義 zap 和 lumberjack 初始化需要使用的配置項(xiàng),大家可以根據(jù)自己的喜好去定制

package config

type Log struct {
    Level string `mapstructure:"level" json:"level" yaml:"level"`
    RootDir string `mapstructure:"root_dir" json:"root_dir" yaml:"root_dir"`
    Filename string `mapstructure:"filename" json:"filename" yaml:"filename"`
    Format string `mapstructure:"format" json:"format" yaml:"format"`
    ShowLine bool `mapstructure:"show_line" json:"show_line" yaml:"show_line"`
    MaxBackups int `mapstructure:"max_backups" json:"max_backups" yaml:"max_backups"`
    MaxSize int `mapstructure:"max_size" json:"max_size" yaml:"max_size"` // MB
    MaxAge int `mapstructure:"max_age" json:"max_age" yaml:"max_age"` // day
    Compress bool `mapstructure:"compress" json:"compress" yaml:"compress"`
}

config/config.go 添加 Log 成員屬性

package config

type Configuration struct {
    App App `mapstructure:"app" json:"app" yaml:"app"`
    Log Log `mapstructure:"log" json:"log" yaml:"log"`
}

config.yaml 增加對(duì)應(yīng)配置項(xiàng)

log:
  level: info # 日志等級(jí)
  root_dir: ./storage/logs # 日志根目錄
  filename: app.log # 日志文件名稱
  format: # 寫入格式 可選json
  show_line: true # 是否顯示調(diào)用行
  max_backups: 3 # 舊文件的最大個(gè)數(shù)
  max_size: 500 # 日志文件最大大小(MB)
  max_age: 28 # 舊文件的最大保留天數(shù)
  compress: true # 是否壓縮

定義 utils 工具函數(shù)

新建 utils/directory.go 文件,編寫 PathExists 函數(shù),用于判斷路徑是否存在

package utils
import "os"
func PathExists(path string) (bool, error) {
    _, err := os.Stat(path)
    if err == nil {
        return true, nil
    }
    if os.IsNotExist(err) {
        return false, nil
    }
    return false, err
}

初始化 zap

zap 的具體使用說(shuō)明可查看官方文檔

新建 bootstrap/log.go 文件,編寫:

package bootstrap
import (
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
    "gopkg.in/natefinch/lumberjack.v2"
    "jassue-gin/global"
    "jassue-gin/utils"
    "os"
    "time"
)
var (
    level zapcore.Level // zap 日志等級(jí)
    options []zap.Option // zap 配置項(xiàng)
)
func InitializeLog() *zap.Logger {
    // 創(chuàng)建根目錄
    createRootDir()
    // 設(shè)置日志等級(jí)
    setLogLevel()
    if global.App.Config.Log.ShowLine {
        options = append(options, zap.AddCaller())
    }
    // 初始化 zap
    return zap.New(getZapCore(), options...)
}
func createRootDir() {
    if ok, _ := utils.PathExists(global.App.Config.Log.RootDir); !ok {
        _ = os.Mkdir(global.App.Config.Log.RootDir, os.ModePerm)
    }
}
func setLogLevel() {
    switch global.App.Config.Log.Level {
    case "debug":
        level = zap.DebugLevel
        options = append(options, zap.AddStacktrace(level))
    case "info":
        level = zap.InfoLevel
    case "warn":
        level = zap.WarnLevel
    case "error":
        level = zap.ErrorLevel
        options = append(options, zap.AddStacktrace(level))
    case "dpanic":
        level = zap.DPanicLevel
    case "panic":
        level = zap.PanicLevel
    case "fatal":
        level = zap.FatalLevel
    default:
        level = zap.InfoLevel
    }
}
// 擴(kuò)展 Zap
func getZapCore() zapcore.Core {
    var encoder zapcore.Encoder
    // 調(diào)整編碼器默認(rèn)配置
    encoderConfig := zap.NewProductionEncoderConfig()
    encoderConfig.EncodeTime = func(time time.Time, encoder zapcore.PrimitiveArrayEncoder) {
        encoder.AppendString(time.Format("[" + "2006-01-02 15:04:05.000" + "]"))
    }
    encoderConfig.EncodeLevel = func(l zapcore.Level, encoder zapcore.PrimitiveArrayEncoder) {
        encoder.AppendString(global.App.Config.App.Env + "." + l.String())
    }
    // 設(shè)置編碼器
    if global.App.Config.Log.Format == "json" {
        encoder = zapcore.NewJSONEncoder(encoderConfig)
    } else {
        encoder = zapcore.NewConsoleEncoder(encoderConfig)
    }
    return zapcore.NewCore(encoder, getLogWriter(), level)
}
// 使用 lumberjack 作為日志寫入器
func getLogWriter() zapcore.WriteSyncer {
    file := &lumberjack.Logger{
        Filename:   global.App.Config.Log.RootDir + "/" + global.App.Config.Log.Filename,
        MaxSize:    global.App.Config.Log.MaxSize,
        MaxBackups: global.App.Config.Log.MaxBackups,
        MaxAge:     global.App.Config.Log.MaxAge,
        Compress:   global.App.Config.Log.Compress,
    }
    return zapcore.AddSync(file)
}

定義全局變量 Log

在 global/app.go 中,添加 Log 成員屬性

package global
import (
    "github.com/spf13/viper"
    "go.uber.org/zap"
    "jassue-gin/config"
)
type Application struct {
    ConfigViper *viper.Viper
    Config config.Configuration
    Log *zap.Logger
}
var App = new(Application)

測(cè)試

在 main.go 中調(diào)用日志初始化函數(shù),并嘗試寫入日志

package main
import (
    "github.com/gin-gonic/gin"
    "jassue-gin/bootstrap"
    "jassue-gin/global"
    "net/http"
)
func main() {
    // 初始化配置
    bootstrap.InitializeConfig()
    // 初始化日志
    global.App.Log = bootstrap.InitializeLog()
    global.App.Log.Info("log init success!")
    r := gin.Default()
    // 測(cè)試路由
    r.GET("/ping", func(c *gin.Context) {
        c.String(http.StatusOK, "log test")
    })
    // 啟動(dòng)服務(wù)器
    r.Run(":" + global.App.Config.App.Port)
}

啟動(dòng) main.go ,生成 storage/logs/app.log 文件,表示日志初始化成功,文件內(nèi)容顯示如下:

以上就是從零封裝Gin框架實(shí)現(xiàn)日志初始化及切割歸檔功能的詳細(xì)內(nèi)容,更多關(guān)于Gin日志切割歸檔的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go編程中常見(jiàn)錯(cuò)誤和不良實(shí)踐解析

    Go編程中常見(jiàn)錯(cuò)誤和不良實(shí)踐解析

    這篇文章主要為大家介紹了Go編程中常見(jiàn)錯(cuò)誤和不良實(shí)踐解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • golang通過(guò)反射手動(dòng)實(shí)現(xiàn)json序列化的方法

    golang通過(guò)反射手動(dòng)實(shí)現(xiàn)json序列化的方法

    在 Go 語(yǔ)言中,JSON 序列化和反序列化通常通過(guò)標(biāo)準(zhǔn)庫(kù) encoding/json 來(lái)實(shí)現(xiàn),本文給大家介紹golang  通過(guò)反射手動(dòng)實(shí)現(xiàn)json序列化的方法,感興趣的朋友一起看看吧
    2024-12-12
  • golang redis中Pipeline通道的使用詳解

    golang redis中Pipeline通道的使用詳解

    本文主要介紹了golang redis中Pipeline通道的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 詳解Golang中的Mutex并發(fā)原語(yǔ)

    詳解Golang中的Mutex并發(fā)原語(yǔ)

    Mutex?是?Go?語(yǔ)言中互斥鎖的實(shí)現(xiàn),它是一種同步機(jī)制,用于控制多個(gè)?goroutine?之間的并發(fā)訪問(wèn)。本文將著重介紹?Go?的?Mutex?并發(fā)原語(yǔ),希望對(duì)大家有所幫助
    2023-03-03
  • Go語(yǔ)言字符串及strings和strconv包使用實(shí)例

    Go語(yǔ)言字符串及strings和strconv包使用實(shí)例

    字符串是工作中最常用的,值得我們專門的練習(xí)一下,下面這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言字符串及strings和strconv包使用的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-06-06
  • Golang?Time包與日期函數(shù)的用法詳解

    Golang?Time包與日期函數(shù)的用法詳解

    在golang中,time包提供了時(shí)間的顯示和測(cè)量用的函數(shù),下面小編就來(lái)和大家詳細(xì)聊聊Golang中Time包與日期函數(shù)的具體用法,快跟隨小編一起學(xué)習(xí)一下吧
    2023-07-07
  • golang elasticsearch Client的使用詳解

    golang elasticsearch Client的使用詳解

    這篇文章主要介紹了golang elasticsearch Client的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-05-05
  • Golang實(shí)現(xiàn)請(qǐng)求限流的幾種辦法(小結(jié))

    Golang實(shí)現(xiàn)請(qǐng)求限流的幾種辦法(小結(jié))

    這篇文章主要介紹了Golang實(shí)現(xiàn)請(qǐng)求限流的幾種辦法(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • golang控制結(jié)構(gòu)select機(jī)制及使用示例詳解

    golang控制結(jié)構(gòu)select機(jī)制及使用示例詳解

    這篇文章主要介紹了golang控制結(jié)構(gòu)select機(jī)制及使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • go語(yǔ)言中基本數(shù)據(jù)類型及應(yīng)用快速了解

    go語(yǔ)言中基本數(shù)據(jù)類型及應(yīng)用快速了解

    這篇文章主要為大家介紹了go語(yǔ)言中基本數(shù)據(jù)類型應(yīng)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07

最新評(píng)論