Writer接口是最底层的IO写入接口,如果业务需要自定义日志内容打印,建议使用Handler特性,参考章节:日志组件-Handler

自定义Writer接口

glog模块实现了标准输出以及文件输出的日志内容打印。当然,开发者也可以通过自定义io.Writer接口实现自定义的日志内容输出。io.Writer是标准库提供的内容输出接口,其定义如下:

  1. type Writer interface {
  2. Write(p []byte) (n int, err error)
  3. }

我们可以通过SetWriter方法或者链式方法To来实现自定义Writer输出,开发者可以在该Writer中实现定义的操作,也可以在其中整合其他的模块功能。

此外,glog.Logger对象已经实现了io.Writer接口,因此开发者可以非常方便地将glog整合使用到其他的模块中。

示例1,实现日志HOOK

在该示例中,我们实现了一个自定义的Writer对象MyWriter,在该对象实现的Writer接口中我们对日志内容进行判断,如果出现了PANI或者FATA错误,那么表示是非常严重的错误,该接口将会第一时间通过HTTP接口告知Monitor监控服务。随后再将日志内容通过glog模块按照配置写入到文件和标准输出。

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/gogf/gf/v2/frame/g"
  6. "github.com/gogf/gf/v2/net/ghttp"
  7. "github.com/gogf/gf/v2/os/glog"
  8. "github.com/gogf/gf/v2/text/gregex"
  9. )
  10. type MyWriter struct {
  11. logger *glog.Logger
  12. }
  13. func (w *MyWriter) Write(p []byte) (n int, err error) {
  14. var (
  15. s = string(p)
  16. ctx = context.Background()
  17. )
  18. if gregex.IsMatchString(`PANI|FATA`, s) {
  19. fmt.Println("SERIOUS ISSUE OCCURRED!! I'd better tell monitor in first time!")
  20. g.Client().PostContent(ctx, "http://monitor.mydomain.com", s)
  21. }
  22. return w.logger.Write(p)
  23. }
  24. func main() {
  25. var ctx = context.Background()
  26. glog.SetWriter(&MyWriter{
  27. logger: glog.New(),
  28. })
  29. glog.Fatal(ctx, "FATAL ERROR")
  30. }

执行后,输出结果为:

  1. SERIOUS ISSUE OCCURRED!! I'd better tell monitor in first time!
  2. 2019-05-23 20:14:49.374 [FATA] FATAL ERROR
  3. Stack:
  4. 1. /Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/v2/geg/os/glog/glog_writer_hook.go:27

示例2,整合graylog

假如我们需要输出日志到文件及标准输出,并且同时也需要输出日志到Graylog,很明显这个也是需要自定义Writer才能实现。当然同理,我们也可以自定义输出到其他的日志收集组件或者数据库中。

Graylog 是与 ELK 可以相提并论的一款集中式日志管理方案,支持数据收集、检索、可视化 Dashboard

示例代码:

  1. package main
  2. import (
  3. "context"
  4. "github.com/gogf/gf/v2/os/glog"
  5. "github.com/robertkowalski/graylog-golang"
  6. )
  7. type MyGrayLogWriter struct {
  8. gelf *gelf.Gelf
  9. logger *glog.Logger
  10. }
  11. func (w *MyGrayLogWriter) Write(p []byte) (n int, err error) {
  12. w.gelf.Send(p)
  13. return w.logger.Write(p)
  14. }
  15. func main() {
  16. var ctx = context.Background()
  17. glog.SetWriter(&MyGrayLogWriter{
  18. logger : glog.New(),
  19. gelf : gelf.New(gelf.Config{
  20. GraylogPort : 80,
  21. GraylogHostname : "graylog-host.com",
  22. Connection : "wan",
  23. MaxChunkSizeWan : 42,
  24. MaxChunkSizeLan : 1337,
  25. }),
  26. })
  27. glog.Println(ctx, "test log")
  28. }