前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手把手,带你从零封装Gin框架(三):日志初始化

手把手,带你从零封装Gin框架(三):日志初始化

作者头像
用户10002156
发布2024-01-10 11:05:49
9580
发布2024-01-10 11:05:49
举报
文章被收录于专栏:生活处处有BUG

前言

本篇来讲一下怎么将日志服务集成到项目中,它也是框架中必不可少的,平时代码调试,线上 Bug 分析都离不开它。这里将使用 zap 作为日志库,一般来说,日志都是需要写入到文件保存的,这也是 zap 唯一缺少的部分,所以我将结合 lumberjack 来使用,实现日志切割归档的功能

安装

代码语言:javascript
复制
go get -u go.uber.org/zap

go get -u gopkg.in/natefinch/lumberjack.v2

定义日志配置项

新建 config/log.go 文件,定义 zaplumberjack 初始化需要使用的配置项,大家可以根据自己的喜好去定制

代码语言:javascript
复制
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 成员属性

代码语言:javascript
复制
package config

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

config.yaml 增加对应配置项

代码语言:javascript
复制
log:
  level: info # 日志等级
  root_dir: ./storage/logs # 日志根目录
  filename: app.log # 日志文件名称
  format: # 写入格式 可选json
  show_line: true # 是否显示调用行
  max_backups: 3 # 旧文件的最大个数
  max_size: 500 # 日志文件最大大小(MB)
  max_age: 28 # 旧文件的最大保留天数
  compress: true # 是否压缩

定义 utils 工具函数

新建 utils/directory.go 文件,编写 PathExists 函数,用于判断路径是否存在

代码语言:javascript
复制
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 的具体使用说明可查看官方文档

新建 bootstrap/log.go 文件,编写:

代码语言:javascript
复制
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 日志等级
    options []zap.Option // zap 配置项
)

func InitializeLog() *zap.Logger {
    // 创建根目录
    createRootDir()

    // 设置日志等级
    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
    }
}

// 扩展 Zap
func getZapCore() zapcore.Core {
    var encoder zapcore.Encoder

    // 调整编码器默认配置
    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())
    }

    // 设置编码器
    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 成员属性

代码语言:javascript
复制
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)

测试

main.go 中调用日志初始化函数,并尝试写入日志

代码语言:javascript
复制
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()

    // 测试路由
    r.GET("/ping", func(c *gin.Context) {
        c.String(http.StatusOK, "log test")
    })

    // 启动服务器
    r.Run(":" + global.App.Config.App.Port)
}

启动 main.go ,生成 storage/logs/app.log 文件,表示日志初始化成功,文件内容显示如下:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生活处处有BUG 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 安装
  • 定义日志配置项
  • 定义 utils 工具函数
  • 初始化 zap
  • 定义全局变量 Log
  • 测试
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档