Kratos 实践:基础功能封装

Kratos入口文件 cmd//main.go 中的逻辑大致分为:

  • 接收命令参数
  • 创建日志对象 Logger
  • 读取配置文件

接下来我们将这部分通用代码进行封装;代码将放到项目目录的pkg/bootstrap 下

启动参数处理

为了是程序更加灵活通常会将一些参数在程序启动时传入;比如运行环境,配置文件路径等;接下来我们已接收conf(本地 文件配置); env (运行环境如 dev 开发 ;pro 生产);consul (consul 远程配置 地址) 三个参数为例进行封装;代码:

package bootstrap

import "flag"

type CommandFlags struct {
	Conf   string // 文件配置
	Env    string // 运行环境 dev 开发 ;pro 生产
	Consul string // consul 远程配置 地址
}

func NewCommandFlags() *CommandFlags {
	return &CommandFlags{
		Conf:   "",
		Env:    "",
		Consul: "",
	}
}

func (f *CommandFlags) Init() {
	flag.StringVar(&f.Conf, "conf", "../../configs", "config path, eg: -conf bootstrap.yaml")
	flag.StringVar(&f.Env, "env", "dev", "runtime environment, eg: -env dev")
	flag.StringVar(&f.Consul, "consul", "", "config server host, eg: -consul http://127.0.0.1:8500")
}

接收命令行参数用到了flag包;需要注意的是在入库文件调用封装方法后需要执行 flag.Parse()
如:

func init() {
	Flags   = bootstrap.NewCommandFlags()
	Flags.Init()
    flag.Parse()
}

日志处理

Kratos提供了统一的日志处理组件和日志接入抽象;通过实现Logger 对象可以很方便的实现自定义日志处理逻辑;log.DefaultLogger 可以将日志信息打印到控制台;如果将日志输出到文件中可以考虑通过zap包做封装;代码可以参考kratos-example
代码如下:

import (
	"fmt"
	"os"
	"time"

	"github.com/go-kratos/kratos/v2/log"
	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

var _ log.Logger = (*ZapLogger)(nil)

// ZapLogger is a logger impl.
type ZapLogger struct {
	log  *zap.Logger
	Sync func() error
}

// NewZapLogger return a zap logger.
func NewZapLogger(encoder zapcore.EncoderConfig, prefix string, level zap.AtomicLevel, opts ...zap.Option) *ZapLogger {
	rotateLogger, err := rotatelogs.New("./log/"+prefix+"_%Y%m%d.log", rotatelogs.WithMaxAge(time.Hour*24*30))
	if err != nil {
		log.Fatalf("logger.Setup err: %v", err)
	}
	core := zapcore.NewCore(
		zapcore.NewConsoleEncoder(encoder),
		zapcore.NewMultiWriteSyncer(
			zapcore.AddSync(os.Stdout),    //输出到控制台上
			zapcore.AddSync(rotateLogger), //输出到文本中
		), level)
	zapLogger := zap.New(core, opts...)
	return &ZapLogger{log: zapLogger, Sync: zapLogger.Sync}
}

func (l *ZapLogger) Log(level log.Level, keyvals ...interface{}) error {
	if len(keyvals) == 0 || len(keyvals)%2 != 0 {
		l.log.Warn(fmt.Sprint("Keyvalues must appear in pairs: ", keyvals))
		return nil
	}
	var data []zap.Field
	for i := 0; i < len(keyvals); i += 2 {
		data = append(data, zap.Any(fmt.Sprint(keyvals[i]), fmt.Sprint(keyvals[i+1])))
	}
	switch level {
	case log.LevelDebug:
		l.log.Debug("", data...)
	case log.LevelInfo:
		l.log.Info("", data...)
	case log.LevelWarn:
		l.log.Warn("", data...)
	case log.LevelError:
		l.log.Error("", data...)
	}
	return nil
}

其中通过 rotatelogs 进行日志文件的滚动

读取配置文件

Kratos的config组件可以很方便的从各种配置源加载配置;比如从文件中读取:

path := "configs/config.yaml"
c := config.New(
    config.WithSource(
        file.NewSource(path),
    )

因为之前接收参数是分别接收了本地配置文件和consul远程配置参数;对应的将这两种读取配置的方式做一下封装。

// getConfigKey 获取合法的配置名
func getConfigKey(configKey string, useBackslash bool) string {
	if useBackslash {
		return strings.Replace(configKey, `.`, `/`, -1)
	} else {
		return configKey
	}
}

// NewConsulConfigSource 创建一个远程配置源 - Consul
func NewConsulConfigSource(configHost, configKey string) config.Source {
	consulClient, err := api.NewClient(&api.Config{
		Address: configHost,
	})
	if err != nil {
		panic(err)
	}
	consulSource, err := consulKratos.New(consulClient,
		consulKratos.WithPath(getConfigKey(configKey, true)),
	)
	if err != nil {
		panic(err)
	}

	return consulSource
}

// NewFileConfigSource 创建一个本地文件配置源
func NewFileConfigSource(filePath string) config.Source {
	return file.NewSource(filePath)
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Devin_S

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值