Ver Fonte

docs: add docs for logx (#1960)

Kevin Wan há 2 anos atrás
pai
commit
30958a91f7
2 ficheiros alterados com 396 adições e 0 exclusões
  1. 198 0
      core/logx/readme-cn.md
  2. 198 0
      core/logx/readme.md

+ 198 - 0
core/logx/readme-cn.md

@@ -0,0 +1,198 @@
+<IMG align="right" width="150px" src="https://raw.githubusercontent.com/zeromicro/zero-doc/main/doc/images/go-zero.png">
+
+# logx
+
+[English](readme.md) | 简体中文
+
+## logx 配置
+
+```go
+type LogConf struct {
+	ServiceName         string `json:",optional"`
+	Mode                string `json:",default=console,options=[console,file,volume]"`
+	Encoding            string `json:",default=json,options=[json,plain]"`
+	TimeFormat          string `json:",optional"`
+	Path                string `json:",default=logs"`
+	Level               string `json:",default=info,options=[info,error,severe]"`
+	Compress            bool   `json:",optional"`
+	KeepDays            int    `json:",optional"`
+	StackCooldownMillis int    `json:",default=100"`
+}
+```
+
+- `ServiceName`:设置服务名称,可选。在 `volume` 模式下,该名称用于生成日志文件。在 `rest/zrpc` 服务中,名称将被自动设置为 `rest`或`zrpc` 的名称。
+- `Mode`:输出日志的模式,默认是 `console`
+  - `console` 模式将日志写到 `stdout/stderr`
+  - `file` 模式将日志写到 `Path` 指定目录的文件中
+  - `volume` 模式在 docker 中使用,将日志写入挂载的卷中
+- `Encoding`: 指示如何对日志进行编码,默认是 `json`
+  - `json`模式以 json 格式写日志
+  - `plain`模式用纯文本写日志,并带有终端颜色显示
+- `TimeFormat`:自定义时间格式,可选。默认是 `2006-01-02T15:04:05.000Z07:00`
+- `Path`:设置日志路径,默认为 `logs`
+- `Level`: 用于过滤日志的日志级别。默认为 `info`
+  - `info`,所有日志都被写入
+  - `error`, `info` 的日志被丢弃
+  - `severe`, `info` 和 `error` 日志被丢弃,只有 `severe` 日志被写入
+- `Compress`: 是否压缩日志文件,只在 `file` 模式下工作
+- `KeepDays`:日志文件被保留多少天,在给定的天数之后,过期的文件将被自动删除。对 `console` 模式没有影响
+- `StackCooldownMillis`:多少毫秒后再次写入堆栈跟踪。用来避免堆栈跟踪日志过多
+
+## 打印日志方法
+
+```go
+type Logger interface {
+	// Error logs a message at error level.
+	Error(...interface{})
+	// Errorf logs a message at error level.
+	Errorf(string, ...interface{})
+	// Errorv logs a message at error level.
+	Errorv(interface{})
+	// Errorw logs a message at error level.
+	Errorw(string, ...LogField)
+	// Info logs a message at info level.
+	Info(...interface{})
+	// Infof logs a message at info level.
+	Infof(string, ...interface{})
+	// Infov logs a message at info level.
+	Infov(interface{})
+	// Infow logs a message at info level.
+	Infow(string, ...LogField)
+	// Slow logs a message at slow level.
+	Slow(...interface{})
+	// Slowf logs a message at slow level.
+	Slowf(string, ...interface{})
+	// Slowv logs a message at slow level.
+	Slowv(interface{})
+	// Sloww logs a message at slow level.
+	Sloww(string, ...LogField)
+	// WithContext returns a new logger with the given context.
+	WithContext(context.Context) Logger
+	// WithDuration returns a new logger with the given duration.
+	WithDuration(time.Duration) Logger
+}
+```
+
+- `Error`, `Info`, `Slow`: 将任何类型的信息写进日志,使用 `fmt.Sprint(...)` 来转换为 `string`
+- `Errorf`, `Infof`, `Slowf`: 将指定格式的信息写入日志
+- `Errorv`, `Infov`, `Slowv`: 将任何类型的信息写入日志,用 `json marshal` 编码
+- `Errorw`, `Infow`, `Sloww`: 写日志,并带上给定的 `key:value` 字段
+- `WithContext`:将给定的 ctx 注入日志信息,例如用于记录 `trace-id`和`span-id`
+- `WithDuration`: 将指定的时间写入日志信息中,字段名为 `duration`
+
+## 与第三方日志库集成
+
+- zap
+  - 实现:[https://github.com/zeromicro/zero-contrib/blob/main/logx/zapx/zap.go](https://github.com/zeromicro/zero-contrib/blob/main/logx/zapx/zap.go)
+  - 使用示例:[https://github.com/zeromicro/zero-examples/blob/main/logx/zaplog/main.go](https://github.com/zeromicro/zero-examples/blob/main/logx/zaplog/main.go)
+- logrus
+  - 实现:[https://github.com/zeromicro/zero-contrib/blob/main/logx/logrusx/logrus.go](https://github.com/zeromicro/zero-contrib/blob/main/logx/logrusx/logrus.go)
+  - 使用示例:[https://github.com/zeromicro/zero-examples/blob/main/logx/logrus/main.go](https://github.com/zeromicro/zero-examples/blob/main/logx/logrus/main.go)
+
+对于其它的日志库,请参考上面示例实现,并欢迎提交 `PR` 到 [https://github.com/zeromicro/zero-contrib](https://github.com/zeromicro/zero-contrib)
+
+## 将日志写到指定的存储
+
+`logx`定义了两个接口,方便自定义 `logx`,将日志写入任何存储。
+
+- `logx.NewWriter(w io.Writer)`
+- `logx.SetWriter(write logx.Writer)`
+
+例如,如果我们想把日志写进kafka,而不是控制台或文件,我们可以像下面这样做。
+
+```go
+type KafkaWriter struct {
+	Pusher *kq.Pusher
+}
+
+func NewKafkaWriter(pusher *kq.Pusher) *KafkaWriter {
+	return &KafkaWriter{
+		Pusher: pusher,
+	}
+}
+
+func (w *KafkaWriter) Write(p []byte) (n int, err error) {
+	// writing log with newlines, trim them.
+	if err := w.Pusher.Push(strings.TrimSpace(string(p))); err != nil {
+		return 0, err
+	}
+
+	return len(p), nil
+}
+
+func main() {
+  func main() {
+	pusher := kq.NewPusher([]string{"localhost:9092"}, "go-zero")
+	defer pusher.Close()
+
+	writer := logx.NewWriter(NewKafkaWriter(pusher))
+	logx.SetWriter(writer)
+  
+  // more code
+}
+```
+
+完整代码:[https://github.com/zeromicro/zero-examples/blob/main/logx/tokafka/main.go](https://github.com/zeromicro/zero-examples/blob/main/logx/tokafka/main.go)
+
+## 过滤敏感字段
+
+如果我们需要防止  `password` 字段被记录下来,我们可以像下面这样实现。
+
+```go
+type (
+	Message struct {
+		Name     string
+		Password string
+		Message  string
+	}
+
+	SensitiveLogger struct {
+		logx.Writer
+	}
+)
+
+func NewSensitiveLogger(writer logx.Writer) *SensitiveLogger {
+	return &SensitiveLogger{
+		Writer: writer,
+	}
+}
+
+func (l *SensitiveLogger) Info(msg interface{}, fields ...logx.LogField) {
+	if m, ok := msg.(Message); ok {
+		l.Writer.Info(Message{
+			Name:     m.Name,
+			Password: "******",
+			Message:  m.Message,
+		}, fields...)
+	} else {
+		l.Writer.Info(msg, fields...)
+	}
+}
+
+func main() {
+  // setup logx to make sure originalWriter not nil,
+  // the injected writer is only for filtering, like a middleware.
+
+	originalWriter := logx.Reset()
+	writer := NewSensitiveLogger(originalWriter)
+	logx.SetWriter(writer)
+
+	logx.Infov(Message{
+		Name:     "foo",
+		Password: "shouldNotAppear",
+		Message:  "bar",
+	})
+  
+  // more code
+}
+```
+
+完整代码:[https://github.com/zeromicro/zero-examples/blob/main/logx/filterfields/main.go](https://github.com/zeromicro/zero-examples/blob/main/logx/filterfields/main.go)
+
+## 更多示例
+
+[https://github.com/zeromicro/zero-examples/tree/main/logx](https://github.com/zeromicro/zero-examples/tree/main/logx)
+
+## Give a Star! ⭐
+
+如果你正在使用或者觉得这个项目对你有帮助,请 **star** 支持,感谢!

+ 198 - 0
core/logx/readme.md

@@ -0,0 +1,198 @@
+<img align="right" width="150px" src="https://raw.githubusercontent.com/zeromicro/zero-doc/main/doc/images/go-zero.png">
+
+# logx
+
+English | [简体中文](readme-cn.md)
+
+## logx configurations
+
+```go
+type LogConf struct {
+	ServiceName         string `json:",optional"`
+	Mode                string `json:",default=console,options=[console,file,volume]"`
+	Encoding            string `json:",default=json,options=[json,plain]"`
+	TimeFormat          string `json:",optional"`
+	Path                string `json:",default=logs"`
+	Level               string `json:",default=info,options=[info,error,severe]"`
+	Compress            bool   `json:",optional"`
+	KeepDays            int    `json:",optional"`
+	StackCooldownMillis int    `json:",default=100"`
+}
+```
+
+- `ServiceName`: set the service name, optional. on `volume` mode, the name is used to generate the log files. Within `rest/zrpc` services, the name will be set to the name of `rest` or `zrpc` automatically.
+- `Mode`: the mode to output the logs, default is `console`.
+  -  `console` mode writes the logs to `stdout/stderr`.
+  - `file` mode writes the logs to the files specified by `Path`.
+  - `volume` mode is used in docker, to write logs into mounted volumes.
+- `Encoding`: indicates how to encode the logs, default is `json`.
+  - `json` mode writes the logs in json format.
+  - `plain` mode writes the logs with plain text, with terminal color enabled.
+- `TimeFormat`: customize the time format, optional. Default is `2006-01-02T15:04:05.000Z07:00`.
+- `Path`: set the log path, default to `logs`.
+- `Level`: the logging level to filter logs. Default is `info`.
+  - `info`, all logs are written.
+  - `error`, `info` logs are suppressed.
+  - `severe`, `info` and `error` logs are suppressed, only `severe` logs are written.
+- `Compress`: whether or not to compress log files, only works with `file` mode.
+- `KeepDays`: how many days that the log files are kept, after the given days, the outdated files will be deleted automatically. It has no effect on `console` mode.
+- `StackCooldownMillis`: how many milliseconds to rewrite stacktrace again. It’s used to avoid stacktrace flooding.
+
+## Logging methods
+
+```go
+type Logger interface {
+	// Error logs a message at error level.
+	Error(...interface{})
+	// Errorf logs a message at error level.
+	Errorf(string, ...interface{})
+	// Errorv logs a message at error level.
+	Errorv(interface{})
+	// Errorw logs a message at error level.
+	Errorw(string, ...LogField)
+	// Info logs a message at info level.
+	Info(...interface{})
+	// Infof logs a message at info level.
+	Infof(string, ...interface{})
+	// Infov logs a message at info level.
+	Infov(interface{})
+	// Infow logs a message at info level.
+	Infow(string, ...LogField)
+	// Slow logs a message at slow level.
+	Slow(...interface{})
+	// Slowf logs a message at slow level.
+	Slowf(string, ...interface{})
+	// Slowv logs a message at slow level.
+	Slowv(interface{})
+	// Sloww logs a message at slow level.
+	Sloww(string, ...LogField)
+	// WithContext returns a new logger with the given context.
+	WithContext(context.Context) Logger
+	// WithDuration returns a new logger with the given duration.
+	WithDuration(time.Duration) Logger
+}
+```
+
+- `Error`, `Info`, `Slow`: write any kind of messages into logs, with like `fmt.Sprint(…)`.
+- `Errorf`, `Infof`, `Slowf`: write messages with given format into logs.
+- `Errorv`, `Infov`, `Slowv`: write any kind of messages into logs, with json marshalling to encode them.
+- `Errorw`, `Infow`, `Sloww`: write the string message with given `key:value` fields.
+- `WithContext`: inject the given ctx into the log messages, typically used to log `trace-id` and `span-id`.
+- `WithDuration`: write elapsed duration into the log messages, with key `duration`.
+
+## Integrating with third-party logging libs
+
+- zap
+  - implementation: [https://github.com/zeromicro/zero-contrib/blob/main/logx/zapx/zap.go](https://github.com/zeromicro/zero-contrib/blob/main/logx/zapx/zap.go)
+  - usage example: [https://github.com/zeromicro/zero-examples/blob/main/logx/zaplog/main.go](https://github.com/zeromicro/zero-examples/blob/main/logx/zaplog/main.go)
+- logrus
+  - implementation: [https://github.com/zeromicro/zero-contrib/blob/main/logx/logrusx/logrus.go](https://github.com/zeromicro/zero-contrib/blob/main/logx/logrusx/logrus.go)
+  - usage example: [https://github.com/zeromicro/zero-examples/blob/main/logx/logrus/main.go](https://github.com/zeromicro/zero-examples/blob/main/logx/logrus/main.go)
+
+For more libs, please implement and PR to [https://github.com/zeromicro/zero-contrib](https://github.com/zeromicro/zero-contrib)
+
+## Write the logs to specific stores
+
+`logx` defined two interfaces to let you customize `logx` to write logs into any stores.
+
+- `logx.NewWriter(w io.Writer)`
+- `logx.SetWriter(writer logx.Writer)`
+
+For example, if we want to write the logs into kafka instead of console or files, we can do it like below:
+
+```go
+type KafkaWriter struct {
+	Pusher *kq.Pusher
+}
+
+func NewKafkaWriter(pusher *kq.Pusher) *KafkaWriter {
+	return &KafkaWriter{
+		Pusher: pusher,
+	}
+}
+
+func (w *KafkaWriter) Write(p []byte) (n int, err error) {
+	// writing log with newlines, trim them.
+	if err := w.Pusher.Push(strings.TrimSpace(string(p))); err != nil {
+		return 0, err
+	}
+
+	return len(p), nil
+}
+
+func main() {
+  func main() {
+	pusher := kq.NewPusher([]string{"localhost:9092"}, "go-zero")
+	defer pusher.Close()
+
+	writer := logx.NewWriter(NewKafkaWriter(pusher))
+	logx.SetWriter(writer)
+  
+  // more code
+}
+```
+
+Complete code: [https://github.com/zeromicro/zero-examples/blob/main/logx/tokafka/main.go](https://github.com/zeromicro/zero-examples/blob/main/logx/tokafka/main.go)
+
+## Filtering sensitive fields
+
+If we need to prevent the `password` fields from logging, we can do it like below:
+
+```go
+type (
+	Message struct {
+		Name     string
+		Password string
+		Message  string
+	}
+
+	SensitiveLogger struct {
+		logx.Writer
+	}
+)
+
+func NewSensitiveLogger(writer logx.Writer) *SensitiveLogger {
+	return &SensitiveLogger{
+		Writer: writer,
+	}
+}
+
+func (l *SensitiveLogger) Info(msg interface{}, fields ...logx.LogField) {
+	if m, ok := msg.(Message); ok {
+		l.Writer.Info(Message{
+			Name:     m.Name,
+			Password: "******",
+			Message:  m.Message,
+		}, fields...)
+	} else {
+		l.Writer.Info(msg, fields...)
+	}
+}
+
+func main() {
+  // setup logx to make sure originalWriter not nil,
+  // the injected writer is only for filtering, like a middleware.
+
+	originalWriter := logx.Reset()
+	writer := NewSensitiveLogger(originalWriter)
+	logx.SetWriter(writer)
+
+	logx.Infov(Message{
+		Name:     "foo",
+		Password: "shouldNotAppear",
+		Message:  "bar",
+	})
+  
+  // more code
+}
+```
+
+Complete code: [https://github.com/zeromicro/zero-examples/blob/main/logx/filterfields/main.go](https://github.com/zeromicro/zero-examples/blob/main/logx/filterfields/main.go)
+
+## More examples
+
+[https://github.com/zeromicro/zero-examples/tree/main/logx](https://github.com/zeromicro/zero-examples/tree/main/logx)
+
+## Give a Star! ⭐
+
+If you like or are using this project to learn or start your solution, please give it a star. Thanks!