新聞中心
Zap(https://github.com/uber-go/zap)是一個(gè)功能非常豐富、易于使用的 Golang日志庫(kù)。記錄日志時(shí),一般會(huì)選擇輸出到控制臺(tái)(stdout和stderr)或者輸出到文件或者同時(shí)輸出到兩者。zap 庫(kù)也提供了對(duì)應(yīng)的選項(xiàng)。

指定日志輸出目標(biāo)
zap 配置項(xiàng)中(zap.Config), 使用 OutputPaths 和 ErrorOutputPaths 可以指定日志輸出目標(biāo),首先看下這個(gè)配置項(xiàng)的定義和說(shuō)明:
// OutputPaths is a list of URLs or file paths to write logging output to.
// See Open for details.
OutputPaths []string `json:"outputPaths" yaml:"outputPaths"`
// ErrorOutputPaths is a list of URLs to write internal logger errors to.
// The default is standard error.
//
// Note that this setting only affects internal errors; for sample code that
// sends error-level logs to a different location from info- and debug-level
// logs, see the package-level AdvancedConfiguration example.
ErrorOutputPaths []string `json:"errorOutputPaths" yaml:"errorOutputPaths"`
OutputPaths:是一個(gè)字符串類型的切片,可以指定URL、文件路徑或者 stdout,默認(rèn)是stdout。
ErrorOutputPaths:也是一個(gè)字符串類型的切片,和 OutputPaths 類似,默認(rèn)是stderr。
看個(gè)例子
package main
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func main() {
cfg := zap.NewProductionConfig()
cfg.OutputPaths = []string{"stdout"}
cfg.ErrorOutputPaths = []string{"stderr"}
cfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
logger, err := cfg.Build()
if err != nil {
panic("init logger error")
}
sugar := Logger.Sugar()
sugar.Info("這是一條測(cè)試日志")
}
這個(gè)例子是將日志輸出到控制臺(tái),如果想也把日志輸出到文件一份,修改下第 10 和 11 行,代碼如下:
cfg.OutputPaths = []string{"stdout", "./test.log"}
cfg.ErrorOutputPaths = []string{"stderr", "./test.log"}
如果只想輸出到文件,代碼如下:
cfg.OutputPaths = []string{"./test.log"}
cfg.ErrorOutputPaths = []string{"./test.log"}
自定義日志輸出方式
可以使用 zap.RegisterSink 函數(shù)來(lái)注冊(cè)自定義的的輸出方式,該函數(shù)第二個(gè)參數(shù)為一個(gè)自定義的工廠函數(shù), 接收一個(gè) *url.URL 類型的指針, 返回一個(gè) Sink 類型和一個(gè) error,所以需要實(shí)現(xiàn) Sink 接口??匆粋€(gè)具體的示例,自定義了一個(gè)通過(guò) http 協(xié)議輸出到指定接口的輸出方式:
package main
import (
"bytes"
"errors"
"fmt"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"net/http"
"net/url"
)
type Http struct {
Remote *url.URL
}
func (h Http) Sync() error {
return nil
}
func (h Http) Close() error {
return nil
}
func (h Http) Write(p []byte) (n int, err error) {
req, err := http.NewRequest("POST", h.Remote.String(), bytes.NewBuffer(p))
if err != nil {
return 0, nil
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return 0, nil
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return -1, errors.New("request failed")
}
return len(p), nil
}
// 實(shí)現(xiàn)工廠函數(shù)
func httpSink(url *url.URL) (sink zap.Sink, err error) {
h := Http{Remote: url}
return h, nil
}
func main() {
// 注冊(cè)自定義方法
if err := zap.RegisterSink("Http", httpSink); err != nil {
fmt.Println(err)
return
}
cfg := zap.NewProductionConfig()
cfg.OutputPaths = []string{"stdout", "http://127.0.0.1/log"}
cfg.ErrorOutputPaths = []string{"stderr", "http://127.0.0.1/log"}
cfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
logger, err := cfg.Build()
if err != nil {
panic(err)
}
logger.Sugar().Info("這是一條測(cè)試日志")
}
然后啟動(dòng)一個(gè)服務(wù)端,代碼如下:
package main
import (
"bytes"
"io/ioutil"
"log"
"net/http"
)
func main() {
http.HandleFunc("/log", func(w http.ResponseWriter, r *http.Request) {
body, _ := ioutil.ReadAll(r.Body)
log.Println("日志內(nèi)容內(nèi)容: ", bytes.NewBuffer(body).String())
})
log.Fatal(http.ListenAndServe(":80", nil))
}
然后運(yùn)行打印日志的代碼,可以看到服務(wù)端接收到了日志。
文章名稱:Golang日志庫(kù)Zap如何自定義輸出目標(biāo)?
當(dāng)前地址:http://www.dlmjj.cn/article/djgscgc.html
其他資訊
- 20個(gè)G是不是就是20個(gè)GB?20g防御服務(wù)器是什么
- 服務(wù)器如何托管的?(網(wǎng)絡(luò)服務(wù)器租賃怎么選擇托管機(jī)房)
- 深入解析數(shù)據(jù)庫(kù)與數(shù)據(jù)倉(cāng)庫(kù)間的區(qū)別與聯(lián)系(數(shù)據(jù)庫(kù)數(shù)據(jù)倉(cāng)庫(kù)的區(qū)別)
- 網(wǎng)線網(wǎng)絡(luò)一直不好,一直都是幾K幾十K的網(wǎng)速,視頻打不開(kāi),怎么回事?(網(wǎng)站打開(kāi)慢有時(shí)候甚至打不開(kāi)主機(jī)是不是有問(wèn)題啊)
- 怎么查ip是否公網(wǎng)


咨詢
建站咨詢
