上一篇文章裡,我們定了項目基本目錄結構。現在來回顧一下我的思路:
- 建立入口檔案;
- 指定配置、日志目錄;
- 指定資料庫、隊列、緩存元件目錄;
- 建立資料處理的controller目錄;
- 指定公共函數等雜項。
接下來,我們還是按照這個順序填充代碼。
入口檔案
func main() {
config.InitConfig()
logger.InitLogger()
}
暫且忽略一些實作細節,我們需要先初始化配置和日志,先來看看日志,我選用Uber的zap日志庫。來看看日志子產品怎麼寫?
日志
package logger
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
var l *zap.Logger
func InitLogger(logPath, logLevel string) error {
hook := lumberjack.Logger{
Filename: logPath,
MaxSize: 1024,
MaxBackups: 3,
MaxAge: 7,
Compress: true,
}
w := zapcore.AddSync(&hook)
var level zapcore.Level
switch logLevel {
case "debug":
level = zap.DebugLevel
case "info":
level = zap.InfoLevel
case "error":
level = zap.ErrorLevel
default:
level = zap.DebugLevel
}
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
core := zapcore.NewCore(
zapcore.NewConsoleEncoder(encoderConfig),
w,
level,
)
l = zap.New(core)
return nil
}
func GetLogger() *zap.Logger {
return l
}
我們先定義一個包級的全局變量l,類型是*zap.Logger,并建立了InitLogger和GetLogger這兩個函數。因為,zap不支援日志歸檔,是以在InitLogger中定義了一個lumberjack的hook,用來歸檔日志。我們可以看到InitLogger這個方法有兩個入參:logPath和logLevel。一般來講,這些參數應該是放在配置檔案裡的,接下來我們來寫配置。
配置
我們簡單地建立一個config.json檔案來存放配置:
config.json:
{
"log_config": {
"log_path": "{your_path}",
"log_level": "debug"
}
}
然後在config.go中建立相應的結構體,之後定義InitConfig和GetConfig方法,在InitConfig方法中,我讀取了配置檔案的内容,然後解析到結構體中,并處理了錯誤,如果有錯誤資訊的話,我會将錯誤資訊包裹一層,友善以後的錯誤定位。InitConfig有一個入參,就是配置檔案的路徑,這個參數我會從指令行中擷取。
config.go:
package config
import (
"encoding/json"
"github.com/pkg/errors"
"io/ioutil"
)
type LogConfig struct {
LogPath string `json:"log_path"`
LogLevel string `json:"log_level"`
}
type Config struct {
LogConfig LogConfig `json:"log_config"`
}
var conf Config
func InitConfig(configPath string) error {
configFile, err := ioutil.ReadFile(configPath)
if err != nil {
err = errors.Wrap(err, "Read config file failed.")
return err
}
err = json.Unmarshal(configFile, &conf)
if err != nil {
err = errors.Wrap(err, "Unmarshal config file failed.")
return err
}
return nil
}
func GetConfig() Config {
return conf
}
我們當然不止這麼一點配置,我們還有資料庫、緩存等配置沒有添加,但不急,我們先理出一個路線,之後的配置可以依葫蘆畫瓢。
調整入口檔案
好,日志和配置的初始化大緻寫好了,我們回過頭來看一下入口檔案的調整:
package main
import (
"flag"
"fmt"
"github.com/TomatoMr/awesomeframework/config"
"github.com/TomatoMr/awesomeframework/logger"
"os"
)
func main() {
var configPath string
flag.StringVar(&configPath, "config", "", "配置檔案路徑")
flag.Parse()
if configPath == "" {
fmt.Printf("Config Path must be assigned.")
os.Exit(1)
}
var err error
err = config.InitConfig(configPath)
if err != nil {
fmt.Printf("Init config failed. Error is %v", err)
os.Exit(1)
}
logConfig := config.GetConfig().LogConfig
err = logger.InitLogger(logConfig.LogPath, logConfig.LogLevel)
if err != nil {
fmt.Printf("Init logger failed. Error is %v", err)
os.Exit(1)
}
logger.GetLogger().Info("Init success.")
}
我們調整了入口檔案,從指令行裡擷取配置檔案路徑,之後初始化了配置和日志,最後列印初始化結果。
測試一下
首先,編譯一下:
$ go build
接着修改一下你的config.json檔案的log_path,然後在指令行指定一下你的配置檔案路徑:
$ awesomeframework --config={$your_path}/config.json
最後,來看一下運作正不正常,日志檔案的列印如下:
2020-01-19T20:41:57.506+0800 info Init success.
小結
到目前為止,我們初始化了配置和日志,接下去要開始初始化資料庫等元件。可以在https://github.com/TomatoMr/awesomeframework
找到今天的代碼。未完待續……
歡迎關注我的公衆号:onepunchgo。