这是我参与「第五届青训营」伴学笔记创作活动的第27
Viper
概述
viper是go一个强大的流行的配置解决方案的库。viper是spf13的另外一个重量级库。有大量项目都使用该库,比如hugo, docker等。 它基本上可以处理所有类型的配置需求和格式, viper支持功能:
- 设置
默认配置 - 支持各种配置文件,如
JSON,TOML, YAML, HCL, envfile和Java属性配置文件 - 支持监听
文件变化以及重新读取配置 - 支持从环境变量读取配置
- 支持从
远程配置系统(etcd或Consul)读取配置,并能监听远程配置修改 - 支持从命令行标志Flag读取配置,比如搭配cobra使用
- 支持读取缓冲区数据
安装: go get github.com/spf13/viper
使用
获取viper实例
viper包默认提供了一个全局的Viper实例
func GetViper() *Viper
func New() *Viper
func NewWithOptions(opts ...Option) *Viper
func Sub(key string) *Viper
viper.GetViper()获取的为全局的Viper实例对象New和NewWithOptions提供了创建实例的方法Sub为读取子配置项提供了一个新的实例Viper
默认配置
viper.SetDefault("ContentDir", "content")
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
读配置
配置文件app.yml
app:
name: viper-test
mode: dev
db:
mysql:
url: "root:root@tcp(127.0.0.1:3306)/stock?charset=utf8mb4&parseTime=True&loc=Local"
redis:
host: 127.0.0.1
port: 6067
db: 0
passwd: 123456
初始化viper
func InitConfig() (*viper.Viper, error) {
v := viper.New() v.AddConfigPath(".")// 添加配置文件搜索路径,点号为当前目录
v.AddConfigPath("./configs") // 添加多个搜索目录
v.SetConfigType("yaml")// 如果配置文件没有后缀,可以不用配置
v.SetConfigName("app.yml") // 文件名,没有后缀
// v.SetConfigFile("configs/app.yml") // 读取配置文件
if err := v.ReadInConfig(); err == nil {
log.Printf("use config file -> %s\n", v.ConfigFileUsed())
} else {
return nil,err
} return v, nil
}
监听配置变化
func (v *Viper) WatchConfig()
func (v *Viper) WatchRemoteConfig() error
func (v *Viper) WatchRemoteConfigOnChannel() error
logrus
概述
GitHub访问地址:github.com/sirupsen/lo…
golang中,流行的日志框架包括logrus、zap、zerolog、seelog等。logrus是目前Github上star数量最多的日志库
特性:
- 完全兼容golang标准库日志模块:logrus拥有六种日志级别:
debug、info、warn、error、fatal和panic,这是golang标准库日志模块的API的超集。如果您的项目使用标准库日志模块,完全可以以最低的代价迁移到logrus上。 可扩展的Hook机制:允许使用者通过hook的方式将日志分发到任意地方,如本地文件系统、标准输出、logstash、elasticsearch或者mq等,或者通过hook定义日志内容和格式等。可选的日志输出格式:logrus内置了两种日志格式,JSONFormatter和TextFormatter,如果这两个格式不满足需求,可以自己动手实现接口Formatter,来定义自己的日志格式。Field机制:logrus鼓励通过Field机制进行精细化的、结构化的日志记录,而不是通过冗长的消息来记录日志。- logrus是一个
可插拔的、结构化的日志框架
缺点:
- 没有提供
行号和文件名的支持 - 输出到本地文件系统没有提供日志分割功能
- 官方没有提供输出到ELK等日志处理中心的功能
使用
logrus.Debug("Useful debugging information.")
logrus.Info("Something noteworthy happened!")
logrus.Warn("You should probably take a look at this.")
logrus.Error("Something failed but I'm not quitting.")
logrus.Fatal("Bye.") //log之后会调用os.Exit(1)
logrus.Panic("I'm bailing.") //log之后会panic()
另外还有一个+f的版本,用起来和Printf一样,区别在于是否识别格式化输出
logrus.Fatal("%s ", v.Get("args.name")) //FATA[0000] %sxiaoming
logrus.Fatalf("%s ", v.Get("args.name")) //FATA[0000] xiaoming
Kitex
namespace go hello
struct ReqBody {
1: string name
2: i32 type
3: string email
}
struct Request {
1: string data
2: string message
3: ReqBody reqBody
}
struct Msg {
1: i64 status
2: i64 code
3: string msg
}
struct Response {
1: Msg msg
2: string data
}
service HelloService {
Response echo(1: Request req)
Response testHello4Get(1: Request req)
Response testHello4Post(1: Request req)
}
生成代码
kitex -module "hz-kitex-examples" -thrift frugal_tag -service helloserver idl/hello.thrift
-
-module module_name:"hz-kitex-examples"- 该参数用于指定生成代码所属的 Go 模块,会影响生成代码里的 import path。
- 如果当前目录是在当前的目录,那么可以不指定该参数;会使用GOPATH/src 开始的相对路径作为 import path 前缀。例如,在 $GOPATH/src/example.com/hello/world 下执行 kitex,那么 kitex_gen/example_package/example_package.go 在其他代码代码里的 import path 会是 example.com/hello/world/kitex_gen/example_package。
- 如果当前目录不在 $GOPATH/src 下,那么必须指定该参数。
- 如果指定了 -module 参数,那么 kitex 会从当前目录开始往上层搜索 go.mod 文件
- 如果不存在 go.mod 文件,那么 kitex 会调用 go mod init 生成 go.mod;
- 如果存在 go.mod 文件,那么 kitex 会检查 -module 的参数和 go.mod 里的模块名字是否一致,如果不一致则会报错退出;
- 最后,go.mod 的位置及其模块名字会决定生成代码里的 import path
-
-service service_name:helloserver- 使用该选项时,kitex 会生成构建一个服务的脚手架代码,参数 service_name 给出启动时服务自身的名字,通常其值取决于使用 Kitex 框架时搭配的服务注册和服务发现功能
-use path - 在生成服务端代码(使用了 -service)时,可以用 -use 选项来让 kitex 不生成 kitex_gen 目录,而使用该选项给出的 import path。
- 使用该选项时,kitex 会生成构建一个服务的脚手架代码,参数 service_name 给出启动时服务自身的名字,通常其值取决于使用 Kitex 框架时搭配的服务注册和服务发现功能
-
-combine-service- 对于 thrift IDL,kitex 在生成服务端代码脚手架时,只会针对最后一个 service 生成相关的定义。如果你的 IDL 里定义了多个 service 定义并且希望在一个服务里同时提供这些 service 定义的能力时,可以使用 -combine-service 选项。
- 该选项会生成一个合并了目标 IDL 文件中所有 service 方法的 CombineService,并将其用作 main 包里使用的 service 定义。注意这个模式下,被合并的 service 之间不能有冲突的方法名。
-
-protobuf value- 传递给 protoc 的参数。会拼接在 -go_out 的参数后面。可用的值参考 protoc 的帮助文档。
-
-thrift value- 传递给 thriftgo 的参数。会拼接在 -g go: 的参数后面。可用的值参考 thriftgo 的帮助文档。kitex 默认传递了 naming_style=golint,ignore_initialisms,gen_setter,gen_deep_equal,可以被覆盖。