go-zero 微服务框架如何将日志输出到文件

在 go-zero 中,默认日志是输出到 控制台 的,项目运行起来后,往往都是输出到日志,今天看看 go-zero 框架的 API 功能的日志配置。

目前网上关于 go-zero 的配置相对少,找了一圈,没找到更多的资料或者案例,而且官方给的 doc 又是一笔带过,不多说,下面看看吧。

我们直接给出对应的配置:userapi.yaml

Name: userapi-api
Host: 0.0.0.0
Port: 8888

Auth:
  AccessSecret: 84a8a776-e447-4870-83ea-a17e8d28c76d
  AccessExpire: 3600

# 需要以 Log 作为 section
Log:
  Mode: file
  Level: debug
  Path: ./logs
  Rotation: daily

然后运行项目即可看到在项目中出现对应的不同 log:

image.png

为什么需要这样配置呢,追代码吧。

先看看项目启动的代码部分:
userapi.go

package main

import (
	"flag"
	"fmt"
	"userapiv1/internal/config"
	"userapiv1/internal/handler"
	"userapiv1/internal/svc"

	"github.com/zeromicro/go-zero/core/conf"
	"github.com/zeromicro/go-zero/rest"
)

var configFile = flag.String("f", "etc/userapi-api.yaml", "the config file")

func main() {
	flag.Parse()

	var c config.Config
	conf.MustLoad(*configFile, &c)

	server := rest.MustNewServer(c.RestConf)
	defer server.Stop()

	ctx := svc.NewServiceContext(c)
	handler.RegisterHandlers(server, ctx)

	// go-zero version >= v1.7.0
	//logx.AddWriter(logx.NewWriter(os.Stdout))  // 添加控制台输出

	fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
	server.Start()
}

go-zero/rest/server.go

func MustNewServer(c RestConf, opts ...RunOption) *Server {
	server, err := NewServer(c, opts...) // here
	if err != nil {
		log.Fatal(err)
	}

	return server
}

// NewServer returns a server with given config of c and options defined in opts.
// Be aware that later RunOption might overwrite previous one that write the same option.
func NewServer(c RestConf, opts ...RunOption) (*Server, error) {
	if err := c.SetUp(); err != nil { // here
		return nil, err
	}

	server := &Server{
		ngin:   newEngine(c),
		router: router.NewRouter(),
	}

	opts = append([]RunOption{WithNotFoundHandler(nil)}, opts...)
	for _, opt := range opts {
		opt(server)
	}

	return server, nil
}

go-zero/core/service/serviceconf.go

func (sc ServiceConf) SetUp() error {
	if len(sc.Log.ServiceName) == 0 {
		sc.Log.ServiceName = sc.Name
	}
	if err := logx.SetUp(sc.Log); err != nil { // here
		return err
	}

	sc.initMode()
	prometheus.StartAgent(sc.Prometheus)

	if len(sc.Telemetry.Name) == 0 {
		sc.Telemetry.Name = sc.Name
	}
	trace.StartAgent(sc.Telemetry)
	proc.AddShutdownListener(func() {
		trace.StopAgent()
	})

	if len(sc.MetricsUrl) > 0 {
		stat.SetReportWriter(stat.NewRemoteWriter(sc.MetricsUrl))
	}
	devserver.StartAgent(sc.DevServer)

	return nil
}

可以看到这里完成日志的配置,接下来看看具体的结构体:
同文件下:

// A ServiceConf is a service config.
type ServiceConf struct {
	Name       string
	Log        logx.LogConf
	Mode       string `json:",default=pro,options=dev|test|rt|pre|pro"`
	MetricsUrl string `json:",optional"`
	// Deprecated: please use DevServer
	Prometheus prometheus.Config `json:",optional"`
	Telemetry  trace.Config      `json:",optional"`
	DevServer  devserver.Config  `json:",optional"`
}

go-zero/core/logx/config.go

// A LogConf is a logging config.
type LogConf struct {
	// ServiceName represents the service name.
	ServiceName string `json:",optional"`
	// Mode represents the logging mode, default is `console`.
	// console: log to console.
	// file: log to file.
	// volume: used in k8s, prepend the hostname to the log file name.
	Mode string `json:",default=console,options=[console,file,volume]"`
	// Encoding represents the encoding type, default is `json`.
	// json: json encoding.
	// plain: plain text encoding, typically used in development.
	Encoding string `json:",default=json,options=[json,plain]"`
	// TimeFormat represents the time format, default is `2006-01-02T15:04:05.000Z07:00`.
	TimeFormat string `json:",optional"`
	// Path represents the log file path, default is `logs`.
	Path string `json:",default=logs"`
	// Level represents the log level, default is `info`.
	Level string `json:",default=info,options=[debug,info,error,severe]"`
	// MaxContentLength represents the max content bytes, default is no limit.
	MaxContentLength uint32 `json:",optional"`
	// Compress represents whether to compress the log file, default is `false`.
	Compress bool `json:",optional"`
	// Stdout represents whether to log statistics, default is `true`.
	Stat bool `json:",default=true"`
	// KeepDays represents how many days the log files will be kept. Default to keep all files.
	// Only take effect when Mode is `file` or `volume`, both work when Rotation is `daily` or `size`.
	KeepDays int `json:",optional"`
	// StackCooldownMillis represents the cooldown time for stack logging, default is 100ms.
	StackCooldownMillis int `json:",default=100"`
	// MaxBackups represents how many backup log files will be kept. 0 means all files will be kept forever.
	// Only take effect when RotationRuleType is `size`.
	// Even thougth `MaxBackups` sets 0, log files will still be removed
	// if the `KeepDays` limitation is reached.
	MaxBackups int `json:",default=0"`
	// MaxSize represents how much space the writing log file takes up. 0 means no limit. The unit is `MB`.
	// Only take effect when RotationRuleType is `size`
	MaxSize int `json:",default=0"`
	// RotationRuleType represents the type of log rotation rule. Default is `daily`.
	// daily: daily rotation.
	// size: size limited rotation.
	Rotation string `json:",default=daily,options=[daily,size]"`
}

所以兜一圈,你就会发现在 yaml 配置文件中应该以 Log 打头的 section,具体的字段的话,参考 logx.LogConf 字段进行配置。

另外有一点需要说明的是,我用的 go-zero 版本是 v1.5.0,如果需要在 控制台 也输出日志的话,需要在项目启动位置加入以下代码:

func main() {
	flag.Parse()

	var c config.Config
	conf.MustLoad(*configFile, &c)

	server := rest.MustNewServer(c.RestConf)
	defer server.Stop()

	ctx := svc.NewServiceContext(c)
	handler.RegisterHandlers(server, ctx)

	// go-zero version >= v1.7.0
	//logx.AddWriter(logx.NewWriter(os.Stdout))  // 添加控制台输出

	fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
	server.Start()
}

有个坑,就是对应的 go-zero 需要版本升级。

以上就是 go-zero 的日志配置,码字不易,希望对大家有用。

posted on 2024-07-30 12:32  进击的davis  阅读(9)  评论(0编辑  收藏  举报

导航