go-kit/log
GitHub: go-kit/log
Go 语言微服务工具集 go-kit 中的结构化日志库,提供最小化接口和键值对格式,帮助开发者以低成本实现结构化日志记录。
Stars: 194 | Forks: 19
# package log
[](https://pkg.go.dev/github.com/go-kit/log)
[](https://goreportcard.com/report/go-kit/log)
[](https://github.com/go-kit/log/actions/workflows/test.yml)
[](https://coveralls.io/github/go-kit/log?branch=main)
`package log` 为服务中的结构化日志提供了一个最小化的接口。
它可以被封装以实现编码约定、强制类型安全、提供分级
日志等功能。它既可以用于典型的应用日志事件,
也可以用于日志结构化的数据流。
## 结构化日志
基本上,结构化日志承认了日志即 _数据_ 的事实,并理应获得某种程度的模式严谨性。为我们的日志使用更严格的、面向键/值的消息格式(包含上下文和语义信息),可以让我们更容易地深入了解所构建系统的操作活动。因此,`package log` 坚信,结构化日志能够以极小的代价换取巨大的收益。
从非结构化日志迁移到结构化日志,可能比你想象的要容易得多。
```
// Unstructured
log.Printf("HTTP server listening on %s", addr)
// Structured
logger.Log("transport", "HTTP", "addr", addr, "msg", "listening")
```
## 用法
### 典型的应用日志
```
w := log.NewSyncWriter(os.Stderr)
logger := log.NewLogfmtLogger(w)
logger.Log("question", "what is the meaning of life?", "answer", 42)
// Output:
// question="what is the meaning of life?" answer=42
```
### 上下文 Logger
```
func main() {
var logger log.Logger
logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
logger = log.With(logger, "instance_id", 123)
logger.Log("msg", "starting")
NewWorker(log.With(logger, "component", "worker")).Run()
NewSlacker(log.With(logger, "component", "slacker")).Run()
}
// Output:
// instance_id=123 msg=starting
// instance_id=123 component=worker msg=running
// instance_id=123 component=slacker msg=running
```
### 与 stdlib logger 交互
将 stdlib logger 重定向到 Go kit logger。
```
import (
"os"
stdlog "log"
kitlog "github.com/go-kit/log"
)
func main() {
logger := kitlog.NewJSONLogger(kitlog.NewSyncWriter(os.Stdout))
stdlog.SetOutput(kitlog.NewStdlibAdapter(logger))
stdlog.Print("I sure like pie")
}
// Output:
// {"msg":"I sure like pie","ts":"2016/01/01 12:34:56"}
```
或者,如果出于遗留原因,你需要通过 stdlib log package 路由所有的日志,你可以将 Go kit logger 重定向到 stdlib logger。
```
logger := kitlog.NewLogfmtLogger(kitlog.StdlibWriter{})
logger.Log("legacy", true, "msg", "at least it's something")
// Output:
// 2016/01/01 12:34:56 legacy=true msg="at least it's something"
```
### 时间戳和调用者
```
var logger log.Logger
logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
logger.Log("msg", "hello")
// Output:
// ts=2016-01-01T12:34:56Z caller=main.go:15 msg=hello
```
## 级别
日志级别通过 [level package](https://godoc.org/github.com/go-kit/log/level) 支持。
## 支持的输出格式
- [Logfmt](https://brandur.org/logfmt)([另请参阅](https://blog.codeship.com/logfmt-a-log-format-thats-easy-to-read-and-write))
- JSON
## 增强
`package log` 的核心是单方法的 Logger 接口。
```
type Logger interface {
Log(keyvals ...interface{}) error
}
```
该接口及其支持代码是经过多次迭代和评估的结果。有关 Logger 接口演变的更多详细信息,请参阅 [The Hunt for a Logger Interface](http://go-talks.appspot.com/github.com/ChrisHines/talks/structured-logging/structured-logging.slide#1),这是 [Chris Hines](https://github.com/ChrisHines) 的一场演讲。
此外,请参阅
[#63](https://github.com/go-kit/kit/issues/63)、
[#76](https://github.com/go-kit/kit/pull/76)、
[#131](https://github.com/go-kit/kit/issues/131)、
[#157](https://github.com/go-kit/kit/pull/157)、
[#164](https://github.com/go-kit/kit/issues/164) 和
[#252](https://github.com/go-kit/kit/pull/252)
以回顾关于 package log 和 Logger 接口的历史讨论。
我们当然欢迎附加价值的 package 和建议,
比如对 [分级 logger](https://godoc.org/github.com/go-kit/log/level) 的改进。优秀的提案应该
- 能够与 [上下文 logger](https://godoc.org/github.com/go-kit/log#With) 组合使用,
- 不会破坏任何已封装的上下文 logger 中 [log.Caller](https://godoc.org/github.com/go-kit/log#Caller) 的行为,并且
- 对只接受未加修饰的 log.Logger 的 package 保持友好。
## 基准测试与比较
有一些 Go 日志基准测试和比较包含了 Go kit 的 package log。
- [imkira/go-loggers-bench](https://github.com/imkira/go-loggers-bench) 包含了 kit/log
- [uber-common/zap](https://github.com/uber-common/zap),一个零分配的日志库,包含了与 kit/log 的比较
标签:ETW劫持, EVTX分析, Go, Ruby工具, SOC Prime, 开发工具, 日志审计, 日志库, 日志记录, 结构化日志