## quick start
不是很严格的情况下使用`SugaredLogger`
```
logger, _ := zap.NewProduction()
defer logger.Sync() // flushes buffer, if any
sugar := logger.Sugar()
sugar.Infow("failed to fetch URL",
// Structured context as loosely typed key-value pairs.
"url", url,
"attempt", 3,
"backoff", time.Second,
)
sugar.Infof("Failed to fetch URL: %s", url)
```
需要类型安全时 使用`Logger`
```
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("failed to fetch URL",
// Structured context as strongly typed Field values.
zap.String("url", url),
zap.Int("attempt", 3),
zap.Duration("backoff", time.Second),
)
```
## 项目使用
```
package main
import (
"go.uber.org/zap"
"encoding/json"
)
func main() {
rawJSON := []byte(`{
"level": "debug",
"encoding": "json",
"outputPaths": ["stdout", "./demo.log"],
"errorOutputPaths": ["stderr"],
"initialFields": {"foo": "bar"},
"encoderConfig": {
"messageKey": "message",
"levelKey": "level",
"levelEncoder": "lowercase"
}
}`)
var cfg zap.Config
if err := json.Unmarshal(rawJSON, &cfg); err != nil {
panic(err)
}
logger, err := cfg.Build()
if err != nil {
panic(err)
}
defer logger.Sync()
logger.Info("logger construction succeeded")
}
```
## 在其他文件使用该logger
其他文件需要setlogger方法
```
package demo
import (
"go.uber.org/zap")
var logger *zap.Logger
func SetLogger(l *zap.Logger) {
logger = l
logger.Named("history")
}
func LogInOtherFile() {
logger.Info("log in demo", zap.String("user", "cc"))
}
```
在logger初始化后调用setlogger
```
package main
import (
"go.uber.org/zap"
"encoding/json"
"demo/demo"
)
func main() {
rawJSON := []byte(`{
"level": "debug",
"encoding": "json",
"outputPaths": ["stdout", "./demo.log"],
"errorOutputPaths": ["stderr"],
"initialFields": {},
"encoderConfig": {
"messageKey": "message",
"levelKey": "level",
"levelEncoder": "lowercase"
}
}`)
var cfg zap.Config
if err := json.Unmarshal(rawJSON, &cfg); err != nil {
panic(err)
}
logger, err := cfg.Build()
if err != nil {
panic(err)
}
defer logger.Sync()
logger.Info("logger construction succeeded")
demo.SetLogger(logger)
demo.LogInOtherFile()
}
```
## 更方便的调用
牺牲性能为代价,增强可用性:
```
//Sugar wraps the Logger to provide a more ergonomic, but slightly slower,
//API. Sugaring a Logger is quite inexpensive, so it's reasonable for a
//single application to use both Loggers and SugaredLoggers, converting
//between them on the boundaries of performance-sensitive code.
s := logger.Sugar()
s.Info("Use config file: ", ".demo.log")
s.Info("Config: ", cfg)
```
## 结合cobra来使用
logger初始化放在cobra的initConfig中:
```
func initConfig() {
.....
.....
.....
// init logger
initLogger()
}
```
defer 放在cobra的Execute中:
```
func Execute() {
if logger != nil {
defer logger.Sync()
}
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
```
## NewDevelopment和NewProduction区别
zap.NewDevelopment() 包含代码中文件信息
```
2018-01-18T15:40:05.991+0800 INFO tool/zaplog.go:83 to sugar failed to fetch URLurlhttp://example.comattempt3backoff1s
2018-01-18T15:40:05.991+0800 INFO tool/zaplog.go:88 to sugar failed to fetch URL {"url": "http://example.com", "attempt": 3, "backoff": "1s"}
2018-01-18T15:40:05.991+0800 INFO tool/zaplog.go:94 to desugar failed to fetch URL {"url": "http://example.com", "attempt": 3, "backoff": "1s"}
```
zap.NewProduction() 去除了文件信息
```
{"level":"info","ts":1516261205.991458,"caller":"tool/zaplog.go:109","msg":"to sugar failed to fetch URLurlhttp://example.comattempt3backoff1s"}
{"level":"info","ts":1516261205.9914737,"caller":"tool/zaplog.go:114","msg":"to sugar failed to fetch URL","url":"http://example.com","attempt":3,"backoff":1}
```
- 命令行库cobra
- 用户路径检测go-homedir
- 配置解决方案viper(cobra配置用)
- 高效结构化日志库zap
- RPC框架grpc
- mongdb操作mgo
- ORM库xorm
- GRPCrest接口grpcgateway
- 使用gogoproto时grpcgateway的protobuf和json转换方法
- sync.Map
- zmq
- gogoproto
- go类型转换和类型断言
- go select用法详解以及定时器
- go并发资源竞争
- 官方命令行库flag
- 配置文件解析器 robig/config
- interface {} 接口
- goroutine && channel
- go 命名
- 类型switch
- 数据
- 初始化
- 指针方法 && 值方法
- 内嵌
- mqtt go实现
- grpc middleware