详解Go语言中配置文件使用与日志配置

2022-06-01 11:02:31
目录
项目结构调整配置文件使用日志配置小结

接着上一篇的文章构建的项目:Go语学习笔记 - 环境安装、接口测试

只是简单的把GET和POST接口的使用测试了一下。

我还是想按照正常的项目结构调整一下,这篇笔记主要是三个部分:调整项目目录结构、增加配置文件使用、增加日志配置,很常规而且也是每个项目都需要用到的。

项目地址:github地址 

项目结构调整

说先对项目目录结构调整一下,按照我自己的开发习惯,增加了几个目录。

项目结构如下图:

解释一下目录结构

    app/constants:主要放置一些常量app/controllers:控制层,熟悉java的不多说。app/errors:异常定义目录app/pojo:结构体定义文件,主要是接口请求的结构体和接口返回的结构体,或者自定义的结构体。app/router:路由文件app/services:服务实现逻辑目录app/utils:工具文件目录config/log:日志配置文件目录,后面会讲到怎么使用。config/toml:配置文件使用,后面会讲到怎么使用。main.go作为程序的主入口。

    配置文件使用

    在我们项目结构中,经常会使用到配置文件。配置文件里面会记录像mysql用户名、端口、redis配置信息等等内容。下面先配置一下toml_config.go,来对config.toml配置文件读取。

    下面是toml_config.go的内容

    package toml
     
    import (
        "fmt"
        "github.com/spf13/viper"
    )
     
    type TomlConfig struct {
        AppName string
        Log     LogConfig
    }
     
    // 日志保存地址
    type LogConfig struct {
        Path  string
        Level string
    }
     
    var c TomlConfig
     
    func init() {
        // 设置文件名
        viper.SetConfigName("config")
        // 设置文件类型
        viper.SetConfigType("toml")
        // 设置文件路径,可以多个viper会根据设置顺序依次查找
        viper.AddConfigPath(".")
        viper.AutomaticEnv()
        err := viper.ReadInConfig()
        if err != nil {
            panic(fmt.Errorf("fatal error config file: %s", err))
        }
     
        viper.Unmarshal(&c)
    }
    func GetConfig() TomlConfig {
        return c
    }
    

    需要安装几个库,命令如下:

    go get github.com/natefinch/lumberjack
    go get go.uber.org/zap/zapcore
    

    注意,在go文件中,init方法在加载该文件所在包的时候会默认执行。

    我们看一下配置的内容,主要是日志级别和存放地址。

    验证的话,等下面日志配置好了一起看一下。

    日志配置

    下面继续配置一下日志,也可以看到配置文件里面配置的日志级别和存放地址都是日志的配置项。

    主要在config/log下的logger.go文件,配置了日志相关内容。

    logger.go的内容如下

    package log
     
    import (
        "os"
     
        "github.com/natefinch/lumberjack"
        "go.uber.org/zap"
        "go.uber.org/zap/zapcore"
    )
     
    type Field = zap.Field
     
    var (
        Logger  *zap.Logger
        String  = zap.String
        Any     = zap.Any
        Int     = zap.Int
        Float32 = zap.Float32
    )
     
    // logpath 日志文件路径
    // loglevel 日志级别
    func InitLogger(logpath string, loglevel string) {
        // 日志分割
        hook := lumberjack.Logger{
            Filename:   logpath, // 日志文件路径,默认 os.TempDir()
            MaxSize:    100,     // 每个日志文件保存100M,默认 100M
            MaxBackups: 30,      // 保留30个备份,默认不限
            MaxAge:     7,       // 保留7天,默认不限
     
            Compress: true, // 是否压缩,默认不压缩
        }
        write := zapcore.AddSync(&hook)
        // 设置日志级别
        // debug 可以打印出 info debug warn
        // info  级别可以打印 warn info
        // warn  只能打印 warn
        // debug->info->warn->error
        var level zapcore.Level
        switch loglevel {
        case "debug":
            level = zap.DebugLevel
        case "info":
            level = zap.InfoLevel
        case "error":
            level = zap.ErrorLevel
        case "warn":
            level = zap.WarnLevel
        default:
            level = zap.InfoLevel
        }
        encoderConfig := zapcore.EncoderConfig{
            TimeKey:        "time",
            LevelKey:       "level",
            NameKey:        "logger",
            CallerKey:      "linenum",
            MessageKey:     "msg",
            StacktraceKey:  "stacktrace",
            LineEnding:     zapcore.DefaultLineEnding,
            EncodeLevel:    zapcore.LowercaseLevelEncoder,  // 小写编码器
            EncodeTime:     zapcore.ISO8601TimeEncoder,     // ISO8601 UTC 时间格式
            EncodeDuration: zapcore.SecondsDurationEncoder, //
            EncodeCaller:   zapcore.FullCallerEncoder,      // 全路径编码器
            EncodeName:     zapcore.FullNameEncoder,
        }
        // 设置日志级别
        atomicLevel := zap.NewAtomicLevel()
        atomicLevel.SetLevel(level)
     
        var writes = []zapcore.WriteSyncer{write}
        // 如果是开发环境,同时在控制台上也输出
        if level == zap.DebugLevel {
            writes = append(writes, zapcore.AddSync(os.Stdout))
        }
        core := zapcore.NewCore(
            zapcore.NewConsoleEncoder(encoderConfig),
            // zapcore.NewJSONEncoder(encoderConfig),
            zapcore.NewMultiWriteSyncer(writes...), // 打印到控制台和文件
            // write,
            level,
        )
        // 开启开发模式,堆栈跟踪
        caller := zap.AddCaller()
        // 开启文件及行号
        development := zap.Development()
        // 设置初始化字段,如:添加一个服务器名称
        filed := zap.Fields(zap.String("application", "test-gin"))
        // 构造日志
        Logger = zap.New(core, caller, development, filed)
        Logger.Info("Logger init success")
    }
    

    需要安装依赖包,命令如下

    go get github.com/spf13/viper
    

    在main.go文件增加logger的初始化加载,看看配置文件和日志是否都生效了。

    main.go增加下面的代码

    看一下执行的日志

    2022-05-31T21:27:54.964+0800    info   D:/goProject/learn-gin/config/log/logger.go:90 Logger init success    {"application": "test-gin"}
    2022-05-31T21:27:54.964+0800   info   D:/goProject/learn-gin/main.go:31  hahahah    {"application": "test-gin"}
    2022-05-31T21:27:54.964+0800   info   D:/goProject/learn-gin/main.go:32  config {"application": "test-gin", "config": {"AppName":"learn-gin","Log":{"Path":"logs/learn.log","Level":"debug"}}}

    可以看到配置文件内容的打印,还有日志的打印效果,OK,舒服了。

    小结

    这有几个点要注意下:

    1、init()和main()方法是golang默认的两个方法,不需要我们调用,程序执行会自动寻找项目中的这俩方法。如果引入了一个包,会优先执行引入包的init方法,再执行自己包内的init方法。

    2、如果go项目构建是报错:missing>

    执行一下命令:

    go build -mod=mod

    到此这篇关于详解Go语言中配置文件使用与日志配置的文章就介绍到这了,更多相关Go语言日志配置内容请搜索易采站长站以前的文章或继续浏览下面的相关文章希望大家以后多多支持易采站长站!