日志组件-Writer接口 - 图1提示

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. }