本篇博客我们添加配置,及log处理:
市面上有很多处理解析配置文件的库,可以解析yaml、json、toml等等,本篇我们先采用标准库encoding/json
包来解析 JSON 格式的配置文件。
同样上也有很多处理log的包,比如logrus、zap、zerolog、seelog等等,本篇我们先采用标准库的log 来处理日志
1、在项目根目录下添加 common目录(该目录放一些公共模块),在common目录 添加 utils 目录
(该目录放一些公共的方法),在utils 目录添加config.go 代码如下
package utils
import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
)
type App struct {
Port string `json:"port"`//服务端口
}
type Logging struct {
Path string `json:"path"` //日志路径
Prefix string `json:"prefix"` //日志前缀
Flag int `json:"flag"` //日志格式
}
func InitConfig(path string, config interface{}) {
if len(path) == 0 {
panic(errors.New("configuration path is not provided"))
}
configPath, err := filepath.Abs(path)
if err != nil {
panic(err)
}
file, err := os.Open(configPath)
if err != nil {
fmt.Println("配置文件打开失败:", err)
return
}
defer file.Close()
decoder := json.NewDecoder(file)
err = decoder.Decode(&config)
if err != nil {
fmt.Println("配置文件解析失败:", err)
return
}
}
2、在common目录添加 logger 目录,在logger 目录添加log.go 代码如下
package logger
import (
"errors"
"ginWeb/common/utils"
l "log"
"os"
)
var log *l.Logger
func InitLog(conf utils.Logging) {
// 将日志输出到文件
if len(conf.Path) == 0 {
panic(errors.New("configuration path is not provided"))
}
file, err := os.OpenFile(conf.Path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
log = l.New(file, conf.Prefix, conf.Flag)
}
func Error(desc string) {
log.Println(desc)
}
log 模块对外暴露了Error() 方法,其他模块可以Error()处理日志
3、在项目根目录添加config 目录,在config目录添加 config.go 代码如下
package config
import c "ginWeb/common/utils"
var Settings *Config = &Config{}
type Config struct {
c.App `json:"app"`
c.Logging `json:"log"`
}
在config目录添加 配置文件conf.json 代码如下
{ "app": { "port": "8090" }, "log": { "path": "test_log.txt", "prefix": "ginWeb_test_log", "flag": 1 } }
4.修改handler/app.go 完整代码如下
package handler
import (
"flag"
"fmt"
"ginWeb/common/logger"
"ginWeb/common/utils"
"ginWeb/config"
"os"
)
type App struct {
Uaa UaaHandler
}
func NewApp() *App {
setupItem()
return &App{Uaa: newUaaHandler()}
}
func setupItem() {
configPath := flag.String("config_path", "./config/conf.json", "config file")
flag.Parse()
if configPath == nil {
os.Exit(1)
}
fmt.Println(*configPath)
utils.InitConfig(*configPath, config.Settings)
logger.InitLog(config.Settings.Logging)
return
}
此处 setupItem() 处理项目中配置加载项及一些初始化的模块
5、测试 log输出,修改 handler/uaa.go 完整代码如下
package handler
import (
"ginWeb/common/logger"
"golang.org/x/net/context"
)
type UaaHandler interface {
Login(ctx context.Context, req *LoginReq, rsp *LoginRsp) error
}
type uaa struct {
}
func newUaaHandler() UaaHandler {
return &uaa{}
}
type LoginReq struct{}
type LoginRsp struct {
Id string `json:"id"`
Name string `json:"name"`
}
func (u *uaa) Login(ctx context.Context, req *LoginReq, rsp *LoginRsp) error {
logger.Error("===========login==========start")
rsp.Id, rsp.Name = "1", "小明"
logger.Error("===========login==========end")
return nil
}
6、修改main.go,将启动端口改为 配置文件定义的端口,完整代码如下
package main
import (
"fmt"
"ginWeb/config"
"ginWeb/handler"
router2 "ginWeb/router"
"log"
"net/http"
)
func main() {
router := router2.InitRoutes(handler.NewApp())
srv := &http.Server{
Addr: fmt.Sprintf(":%s", config.Settings.App.Port),
Handler: router,
}
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}
7、然后运行 go run main.go ,
服务起来后 然后执行 curl -XPOST http://127.0.0.1:8090/gin-web/v1/uaa/login
会出现 {"id":"1","name":"小明"}%
项目根目录下 会出现 test_log.txt 文件 ,打开文件 会有 如下日志
ginWeb_test_log2024/02/28 ===========login==========start ginWeb_test_log2024/02/28 ===========login==========end