trpc.group/trpc-go/trpc-go@v1.0.3/log/README.zh_CN.md (about) 1 [English](README.md) | 中文 2 3 # log 4 5 ## 概述 6 7 下面是一个使用 `log` 包的最简单的程序: 8 9 ```go 10 // The code below is located in example/main.go 11 package main 12 13 import "trpc.group/trpc-go/trpc-go/log" 14 15 func main() { 16 log.Info("hello, world") 17 } 18 ``` 19 20 截至撰写本文时,它打印: 21 22 ``` 23 2023-09-07 11:46:40.905 INFO example/main.go:6 hello, world 24 ``` 25 26 `Info` 函数使用 `log` 包中默认的 Logger 打印出一条日志级别为 Info 的消息。 27 根据输出消息的重要性和紧急性, log 包除了支持上述的 Info 级别的日志外,还有提供其他五种日志级别(Trace、Debug、Warn、Error 和 Fatal)。 28 该日志除了包含消息-"hello, world"和日志级别-"INFO"外,还包含打印时间-"2023-09-07 11:46:40.905",调用栈-"example/main.go:6"。 29 30 你也可以使用 `Infof` 输出相同的日志级别的日志, `Infof` 更为灵活,允许你以想要的格式打印消息。 31 32 ```go 33 log.Infof("hello, %s", "world") 34 ``` 35 36 除此之外,你可以传递一系列键值对给 `With` 函数从默认的 Logger 中创建出新的 Logger。 37 新的 Logger 在打印日志时,会把键值对输出到消息的后面。 38 39 ```go 40 logger := log.With(log.Field{Key:"user", Value: os.Getenv("USER")}) 41 logger.Info("hello, world") 42 ``` 43 44 现在的输出如下所示: 45 46 ``` 47 2023-09-07 15:05:21.168 INFO example/main.go:12 hello, world {"user": "goodliu"} 48 ``` 49 50 正如之前提到的,`Info` 函数使用默认的 Logger,你可以显式地获取这个 Logger,并调用它的方法: 51 52 ```go 53 dl := log.GetDefaultLogger() 54 l := dl.With(log.Field{Key: "user", Value: os.Getenv("USER")}) 55 l.Info("hello, world") 56 ``` 57 58 ## 主要类型 59 60 `log` 包包含两种主要类型: 61 62 - `Logger` 是前端,提供类似于 `Info`和 `Infof` 的输出方法,你可以使用这些方法产生日志。 63 - `Writer` 是后端,处理 `Logger` 产生的日志,将日志写入到各种日志服务系统中,如控制台、本地文件和远端。 64 65 `log` 包支持设置多个互相独立的 `Logger`,每个 `Logger` 又支持设置多个互相独立的 `Writer`。 66 如图所示,在这个示例图中包含三个 `Logger`, “Default Logger”,“Other Logger-1“ 和 ”Other Logger-2“,其中的 ”Default Logger“ 是 log 包中内置默认的 `Logger`。 67 ”Default Logger“ 包含三个不同的 `Writer`, "Console Writer",“File Writer” 和 “Remote Writer”,其中的 "Console Writer" 是 ”Default Logger“ 默认的 `Writer`。 68 `Logger` 和 `Writer` 都被设计为定制化开发的插件,关于如何开发它们,可以参考[这里](/docs/developer_guide/develop_plugins/log.zh_CN.md) 。 69 70 71 ```ascii 72 +------------------+ 73 | +--------------+ | 74 | |Console Writer| | 75 | +--------------+ | 76 | +-----------+ | 77 +----------------+ | | File Witer| | 78 +-------------> Default Logger +--------> +-----------+ | 79 | +----------------+ | +-------------+ | 80 | | |Remote Writer| | 81 | | +-------------+ | 82 | +------------------+ 83 | +-------------+ 84 | | +--------+ | 85 | | |Writer-A| | 86 +----+----+ +----------------+ | +--------+ | 87 | Loggers +--------> Other Logger-1 +-------->| +--------+ | 88 +----+----+ +----------------+ | |Writer-B| | 89 | | +--------+ | 90 | +-------------+ 91 | +----------------+ +---------+ 92 +-------------> Other Logger-2 +----------> Writer-C| 93 +----------------+ +---------+ 94 ``` 95 96 下面将先介绍如何在配置文件中配置 `Logger` 和 `Writer` ,然后再以自下而上地方式分别介绍 `Writer` 和 `Logger`。 97 98 ## 配置 `Logger` 和 `Writer` 99 100 因为 `Logger` 和 `Writer` 都是采用插件的方式来实现的,所以相关配置都需要放到“plugins”字段下面。 101 102 ```yaml 103 plugins: 104 log: 105 default: 106 - writer: console 107 ... 108 - writer: file 109 ... 110 - writer: remote 111 ... 112 logger1: 113 - writer: writer-a 114 ... 115 - writer: writer-b 116 ... 117 logger2: 118 - writer: writer-c 119 ... 120 ``` 121 122 上面配置了三个名字为 “default”,“logger1”,和 “logger2” 的 `Logger`。 123 其中的 “default” 是系统默认的 `Logger`,它配置了名字为 “console”,“file” 和 “remote” 的 `Writer`。 124 在不做任何日志配置时,日志默认写入到 ”console“,日志级别为 Debug,打印方式为文本格式,其对应的配置文件为: 125 126 ```yaml 127 plugins: 128 log: 129 default: 130 - writer: console 131 level: debug 132 formatter: console 133 ``` 134 135 对于 `Writer` 的配置参数,设计如下: 136 137 | 配置项 | 配置项 | 类型 | 默认值 | 配置解释 | 138 | ----------------------- | ---------------- | :----: | :----: |-----------------------------------------------------------------------| 139 | writer | writer | string | | 必填 日志 Writer 插件的名字,框架默认支持“file,console” | 140 | writer | writer_config | 对象 | nil | 当日志 Writer 为“file”时才需要设置 | 141 | writer | formatter | string | “” | 日志打印格式,支持“console”和“json”,为空时默认设置为“console” | 142 | writer | formatter_config | 对象 | nil | 日志输出时 zapcore Encoder 配置,为空时为参考 formatter_config 的默认值 | 143 | writer | remote_config | 对象 | nil | 远程日志格式 配置格式你随便定 由第三方组件自己注册,具体配置参考各日志插件文档 | 144 | writer | level | string | | 必填 日志级别大于等于设置级别时,输出到 writer 后端 取值范围:trace,debug,info,warn,error,fatal | 145 | writer | caller_skip | int | 2 | 用于控制 log 函数嵌套深度,不填或者输入 0 时,默认为 2 | 146 | writer.formatter_config | time_fmt | string | "" | 日志输出时间格式,空默认为"2006-01-02 15:04:05.000" | 147 | writer.formatter_config | time_key | string | "" | 日志输出时间在以 Json 输出时的 key 的名称,默认为"T", 用 "none" 来禁用这一字段 | 148 | writer.formatter_config | level_key | string | "" | 日志级别在以 Json 输出时的 key 的名称,默认为"L", 用 "none" 来禁用这一字段 | 149 | writer.formatter_config | name_key | string | "" | 日志名称在以 Json 输出时的 key 的名称,默认为"N", 用 "none" 来禁用这一字段 | 150 | writer.formatter_config | caller_key | string | "" | 日志输出调用者在以 Json 输出时的 key 的名称,默认为"C", 用 "none" 来禁用这一字段 | 151 | writer.formatter_config | message_key | string | "" | 日志输出消息体在以 Json 输出时的 key 的名称,默认为"M", 用 "none" 来禁用这一字段 | 152 | writer.formatter_config | stacktrace_key | string | "" | 日志输出堆栈在以 Json 输出时的 key 的名称,默认为"S", 用 "none" 来禁用这一字段 | 153 | writer.writer_config | log_path | string | | 必填 日志路径名,例如:/usr/local/trpc/log/ | 154 | writer.writer_config | filename | string | | 必填 日志文件名,例如:trpc.log | 155 | writer.writer_config | write_mode | int | 0 | 日志写入模式,1-同步,2-异步,3-极速 (异步丢弃), 不配置默认极速模式,即异步丢弃 | 156 | writer.writer_config | roll_type | string | "" | 文件滚动类型,"size"按大小分割文件,"time"按时间分割文件,为空时默认按大小分割 | 157 | writer.writer_config | max_age | int | 0 | 日志最大保留时间,为 0 表示不清理旧文件 | 158 | writer.writer_config | max_backups | int | 0 | 日志最大文件数,为 0 表示不删除多余文件 | 159 | writer.writer_config | compress | bool | false | 日志文件是否压缩,默认不压缩 | 160 | writer.writer_config | max_size | string | "" | 按大小分割时才有效,日志文件最大大小(单位 MB),为 0 表示不按大小滚动 | 161 | writer.writer_config | time_unit | string | "" | 按时间分割时才有效,按时间分割文件的时间单位,支持 year/month/day/hour/minute, 默认值为 day | 162 163 ## 多 Writer 164 165 多 Writer 可以提供如下功能: 166 167 - 支持日志同时上报到多个输出后端,比如同时打印到 console 和本地日志文件 168 - 支持每个输出后端单独设置日志级别,比如 debug 级别以上日志打 console,warn 级别以上日志保存到日志文件 169 - 支持每个输出后端单独设置日志格式(console,json 等),日志字段名称 170 - 支持“file”类型后端滚动日志功能,包括按文件大小或者时间来分割日志文件 171 172 这里需要强调的是:**日志的打印设置是以 Writer 粒度来配置的**。 173 你需要为每个输出端做配置,比如:Debug 级别以上日志打 console,Warn 级别以上日志保存到日志文件,那就必须要分别配置 console 和 file 这两个 Writer。 174 175 系统默认支持 **"console"** 和 **"file"** 两种 Writer。 176 177 ### 将日志写入到控制台 178 179 当 writer 设置为 ”console“ 时,日志会被写入到控制台。 180 配置参考示例如下: 181 182 ```yaml 183 plugins: 184 log: # 所有日志配置 185 default: # 默认日志配置,log.Debug("xxx") 186 - writer: console # 控制台标准输出 默认 187 level: debug # 标准输出日志的级别 188 formatter: json # 标准输出日志的格式 189 formatter_config: 190 time_fmt: 2006-01-02 15:04:05 # 日志时间格式。"2006-01-02 15:04:05"为常规时间格式,"seconds"为秒级时间戳,"milliseconds"为毫秒时间戳,"nanoseconds"为纳秒时间戳 191 time_key: Time # 日志时间字段名称,不填默认"T",填 "none" 可禁用此字段 192 level_key: Level # 日志级别字段名称,不填默认"L",填 "none" 可禁用此字段 193 name_key: Name # 日志名称字段名称,不填默认"N",填 "none" 可禁用此字段 194 caller_key: Caller # 日志调用方字段名称,不填默认"C",填 "none" 可禁用此字段 195 message_key: Message # 日志消息体字段名称,不填默认"M",填 "none" 可禁用此字段 196 stacktrace_key: StackTrace # 日志堆栈字段名称,不填默认"S",填 "none" 可禁用此字段 197 ``` 198 199 ### 将日志写入到本地 200 201 当 writer 设置为“file”时,日志会被写入到本地日志文件。 202 203 日志按时间进行文件滚动存放的配置示例如下: 204 205 ```yaml 206 plugins: 207 log: # 所有日志配置 208 default: # 默认日志配置,log.Debug("xxx") 209 - writer: file # 本地文件日志 210 level: info # 本地文件滚动日志的级别 211 formatter: json # 标准输出日志的格式 212 formatter_config: 213 time_fmt: 2006-01-02 15:04:05 # 日志时间格式。"2006-01-02 15:04:05"为常规时间格式,"seconds"为秒级时间戳,"milliseconds"为毫秒时间戳,"nanoseconds"为纳秒时间戳 214 time_key: Time # 日志时间字段名称,不填默认"T",填 "none" 可禁用此字段 215 level_key: Level # 日志级别字段名称,不填默认"L",填 "none" 可禁用此字段 216 name_key: Name # 日志名称字段名称,不填默认"N",填 "none" 可禁用此字段 217 caller_key: Caller # 日志调用方字段名称,不填默认"C",填 "none" 可禁用此字段 218 message_key: Message # 日志消息体字段名称,不填默认"M",填 "none" 可禁用此字段 219 stacktrace_key: StackTrace # 日志堆栈字段名称,不填默认"S",填 "none" 可禁用此字段 220 writer_config: 221 log_path: /tmp/log/ 222 filename: trpc_size.log # 本地文件滚动日志存放的路径 223 write_mode: 2 # 日志写入模式,1-同步,2-异步,3-极速 (异步丢弃), 不配置默认异步模式 224 roll_type: time # 文件滚动类型,time 为按时间滚动 225 max_age: 7 # 最大日志保留天数 226 max_backups: 10 # 最大日志文件数 227 time_unit: day # 滚动时间间隔,支持:minute/hour/day/month/year 228 ``` 229 230 日志按文件大小进行文件滚动存放的配置示例如下: 231 232 ```yaml 233 plugins: 234 log: # 所有日志配置 235 default: # 默认日志配置,log.Debug("xxx") 236 - writer: file # 本地文件日志 237 level: info # 本地文件滚动日志的级别 238 formatter: json # 标准输出日志的格式 239 formatter_config: 240 time_fmt: 2006-01-02 15:04:05 # 日志时间格式。"2006-01-02 15:04:05"为常规时间格式,"seconds"为秒级时间戳,"milliseconds"为毫秒时间戳,"nanoseconds"为纳秒时间戳 241 time_key: Time # 日志时间字段名称,不填默认"T",填 "none" 可禁用此字段 242 level_key: Level # 日志级别字段名称,不填默认"L",填 "none" 可禁用此字段 243 name_key: Name # 日志名称字段名称,不填默认"N",填 "none" 可禁用此字段 244 caller_key: Caller # 日志调用方字段名称,不填默认"C",填 "none" 可禁用此字段 245 message_key: Message # 日志消息体字段名称,不填默认"M",填 "none" 可禁用此字段 246 stacktrace_key: StackTrace # 日志堆栈字段名称,不填默认"S",填 "none" 可禁用此字段 247 writer_config: 248 log_path: /tmp/log/ 249 filename: trpc_size.log # 本地文件滚动日志存放的路径 250 write_mode: 2 # 日志写入模式,1-同步,2-异步,3-极速 (异步丢弃), 不配置默认异步模式 251 roll_type: size # 文件滚动类型,size 为按大小滚动 252 max_age: 7 # 最大日志保留天数 253 max_backups: 10 # 最大日志文件数 254 compress: false # 日志文件是否压缩 255 max_size: 10 # 本地文件滚动日志的大小 单位 MB 256 ``` 257 258 ### 将日志写入到远端 259 260 将日志写入到远端需要设置“remote_config”字段。 261 默认 `Logger` 配置两个远端 `Writer` 的配置示例如下: 262 263 ```yaml 264 plugins: 265 log: #日志配置 支持多个日志 可通过 log.Get("xxx").Debug 打日志 266 default: # 默认日志的配置,每个日志可支持多个 Writer 267 - writer: remote-writer1 # 名字为 remote-writer1 的 remote writer 268 level: debug # 远程日志的级别 269 remote_config: # 远程日志配置,你自定义的结构,每一种远程日志都有自己独立的配置 270 # 相关配置 271 - writer: remote-writer2 # 名字为 remote-writer2 的 remote writer 272 level: info # 远程日志的级别 273 remote_config: # 远程日志配置,你自定义的结构,每一种远程日志都有自己独立的配置 274 # 相关配置 275 ``` 276 277 ## 多 Logger 278 279 `log` 包支持同时多个 logger,每个 logger 可以设置不同的日志级别,打印格式,和 writers。 280 你可以为不同的应用场景设置不同的 logger,例如: 281 282 - 不同的应用模块使用不同的日志文件存储 283 - 不同的事件,基于事件的关注度不同,采用不同的日志级别收集日志 284 285 多 logger 功能大大增加了日志使用的灵活性。 286 287 ### 配置 Logger 288 289 在配置文件中配置你的 logger,比如配置名为 “custom” 的 logger: 290 291 ```yaml 292 plugins: 293 log: # 所有日志配置 294 default: # 默认日志配置,log.Debug("xxx") 295 - writer: console # 控制台标准输出 默认 296 level: debug # 标准输出日志的级别 297 custom: # 你自定义的 Logger 配置,名字随便定,每个服务可以有多个 Logger,可使用 log.Get("custom").Debug("xxx") 打日志 298 - writer: file # 你自定义的core配置,名字随便定 299 caller_skip: 1 # 用于定位日志的调用处 300 level: debug # 你自定义core输出的级别 301 writer_config: # 本地文件输出具体配置 302 filename: ../log/trpc1.log # 本地文件滚动日志存放的路径 303 ``` 304 305 配置文件中对于 `caller_skip` 的疑问见「关于 `caller_skip` 的说明」这一节。 306 307 ### 注册 Logger 插件 308 309 在 `main` 函数入口注册日志插件: 310 311 ```go 312 import ( 313 "trpc.group/trpc-go/trpc-go/log" 314 "trpc.group/trpc-go/trpc-go/plugin" 315 ) 316 func main() { 317 // 注意:plugin.Register 要在 trpc.NewServer 之前执行 318 plugin.Register("custom", log.DefaultLogFactory) 319 s := trpc.NewServer() 320 } 321 ``` 322 323 ### 获取 Logger 324 325 `log` 包提供了以下两种方式供你获取 `Logger`: 326 327 #### 方法一:直接指定 Logger 328 329 ```go 330 // 使用名称为“custom”的 Logger 331 // 注意:log.Get 得在 trpc.NewServer 之后执行,因为插件的加载是在 trpc.NewServer 中进行的 332 log.Get("custom").Debug("message") 333 ``` 334 335 #### 方法二:为 Context 指定 Logger,使用 Context 类型日志接口 336 337 ```go 338 // 设置 ctx 的 Logger 为 custom 339 trpc.Message(ctx).WithLogger(log.Get("custom")) 340 // 使用“Context”类型的日志接口 341 log.DebugContext(ctx, "custom log msg") 342 ``` 343 344 ### 日志级别 345 346 根据输出消息的重要性和紧急性, log 包提供六种日志打印级别,并按由低到高的顺序进行了如下划分: 347 348 1. Trace:这是最低的级别,通常用于记录程序的所有运行信息,包括一些细节信息和调试信息。 349 这个级别的日志通常只在开发和调试阶段使用,因为它可能会生成大量的日志数据。 350 2. Debug:这个级别主要用于调试过程中,提供程序运行的详细信息,帮助你找出问题的原因。 351 3. Info: 这个级别用于记录程序的常规操作,比如用户登录、系统状态更新等。 352 这些信息对于了解系统的运行状态和性能很有帮助。 353 4. Warn:警告级别表示可能的问题,这些问题不会立即影响程序的功能,但可能会在未来引发错误。 354 这个级别的日志可以帮助你提前发现和预防问题。 355 5. Error:错误级别表示严重的问题,这些问题可能会阻止程序执行某些功能。 356 这个级别的日志需要立即关注和处理。 357 6. Fatal:致命错误级别表示非常严重的错误,这些错误可能会导致程序崩溃。 358 这是最高的日志级别,表示需要立即处理的严重问题。 359 360 正确地使用日志级别可以帮助你更好地理解和调试你的应用程序。 361 362 ### 日志打印接口 363 364 `log` 包提供了3组日志打印接口: 365 366 - 默认 Logger 的日志函数:使用最频繁的一种方式。直接使用默认 `Logger` 进行日志打印,方便简单。 367 - 基于 Context Logger 的日志函数:为特定场景提供指定 `Logger`,并保存在 Context 里,后续使用当前 Context `Logger` 进行日志打印。 368 这种方式特别适合 RPC 调用模式:当服务收到 RPC 请求时,为 ctx 设置 `Logger`,并附加此次请求相关的 field 信息,此 RPC 调用的后续日志上报都会带上之前设定的 field 信息。 369 - 指定的 Logger 的日志函数:可以用于用户自行选择 `Logger`,并调用 `Logger` 的接口函数实现日志打印。 370 371 #### 默认 Logger 的日志函数 372 373 默认 Logger 的名称固定为“default”,默认打印级别为 debug,打印 console,打印格式为文本格式。配置可以通过在框架文件中 plugins.log 中修改。 374 使用默认 Logger 打印日志的函数如下,函数风格与“fmt.Print()”和"fmt.Printf()"保持一致。 375 376 ```go 377 // 对默认 Logger 提供“fmt.Print()”风格的函数接口 378 func Trace(args ...interface{}) 379 func Debug(args ...interface{}) 380 func Info(args ...interface{}) 381 func Warn(args ...interface{}) 382 func Error(args ...interface{}) 383 func Fatal(args ...interface{}) 384 385 // 对默认 Logger 提供“fmt.Printf()”风格的函数接口 386 // 格式化打印遵循 fmt.Printf() 标准 387 func Tracef(format string, args ...interface{}) 388 func Debugf(format string, args ...interface{}) 389 func Infof(format string, args ...interface{}) 390 func Warnf(format string, args ...interface{}) 391 func Errorf(format string, args ...interface{}) 392 func Fatalf(format string, args ...interface{}) 393 ``` 394 395 同时系统也提供了默认 Logger 的管理函数,包括获取,设置默认 Logger,设置 Logger 的打印级别。 396 397 ```go 398 // 通过名称获取 Logger 399 func Get(name string) Logger 400 // 设置指定 Logger 为默认 Logger 401 func SetLogger(logger Logger) 402 // 设置默认 Logger 下指定 writer 的日志级别,output 为 writer 数组下标 "0" "1" "2" 403 func SetLevel(output string, level Level) 404 // 获取默认 Logger 下指定 writer 的日志级别,output 为 writer 数组下标 "0" "1" "2" 405 func GetLevel(output string) Level 406 ``` 407 408 #### 基于 Context Logger 的日志函数 409 410 基于 Context Logger 的日志函数,每个 Context Logger 必须独占一个 Logger,确保 Context Logger 的配置不被串改。 411 `log` 提供了 `With` 和 `WithContext` 来继承父 Logger 配置,并生成新的 Logger。 412 413 ```go 414 // With adds user defined fields to Logger. Field support multiple values. 415 func With(fields ...Field) Logger 416 // WithContext adds user defined fields to the Logger of context. 417 // Fields support multiple values. 418 func WithContext(ctx context.Context, fields ...Field) Logger 419 ``` 420 421 然后通过下面函数为 context 设置 Logger: 422 423 ```go 424 logger := ... 425 trpc.Message(ctx).WithLogger(logger) 426 ``` 427 428 context 级别的日志打印函数和默认 Logger 打印日志的函数类似: 429 430 ```go 431 // 对 Context Logger 提供“fmt.Print()”风格的函数 432 func TraceContext(args ...interface{}) 433 func DebugContext(args ...interface{}) 434 func InfoContext(args ...interface{}) 435 func WarnContext(args ...interface{}) 436 func ErrorContext(args ...interface{}) 437 func FatalContext(args ...interface{}) 438 439 // 对 Context Logger 提供“fmt.Printf()”风格的函数 440 // 格式化打印遵循 fmt.Printf() 标准 441 func TraceContextf(format string, args ...interface{}) 442 func DebugContextf(format string, args ...interface{}) 443 func InfoContextf(format string, args ...interface{}) 444 func WarnContextf(format string, args ...interface{}) 445 func ErrorContextf(format string, args ...interface{}) 446 func FatalContextf(format string, args ...interface{}) 447 ``` 448 449 #### 指定的 Logger 的日志函数 450 451 同时,`log` 也提供了函数供用户自行选择 Logger。 452 对于每一个 Logger 都实现了 Logger Interface。 453 接口定义为: 454 455 ```go 456 type Logger interface { 457 // 接口提供“fmt.Print()”风格的函数 458 Trace(args ...interface{}) 459 Debug(args ...interface{}) 460 Info(args ...interface{}) 461 Warn(args ...interface{}) 462 Error(args ...interface{}) 463 Fatal(args ...interface{}) 464 465 // 接口提供“fmt.Printf()”风格的函数 466 Tracef(format string, args ...interface{}) 467 Debugf(format string, args ...interface{}) 468 Infof(format string, args ...interface{}) 469 Warnf(format string, args ...interface{}) 470 Errorf(format string, args ...interface{}) 471 Fatalf(format string, args ...interface{}) 472 473 // SetLevel 设置输出端日志级别 474 SetLevel(output string, level Level) 475 // GetLevel 获取输出端日志级别 476 GetLevel(output string) Level 477 478 // WithFields 设置一些你自定义数据到每条 log 里:比如 uid,imei 等 fields 必须 kv 成对出现 479 WithFields(fields ...string) Logger 480 } 481 ``` 482 483 用户可以直接使用上面接口函数进行日志打印,例如 484 485 ```go 486 log.Get("custom").Debug("message") 487 log.Get("custom").Debugf("hello %s", "world") 488 ``` 489 490 ## 框架日志 491 492 1. 框架以尽量不打日志为原则,将错误一直往上抛交给用户自己处理 493 2. 底层严重问题才会打印 trace 日志,需要设置环境变量才会开启:export TRPC_LOG_TRACE=1 494 495 ### `trace` 级别日志的开启 496 497 要开启日志的 `trace` 级别,首先要保证配置上的日志级别设置为 `debug` 或 `trace`,然后通过环境变量来开启 `trace`: 498 499 - 通过环境变量设置 500 501 在执行服务二进制的脚本中添加 502 503 ```shell 504 export TRPC_LOG_TRACE=1 505 ./server -conf path/to/trpc_go.yaml 506 ``` 507 508 - 通过代码进行设置 509 510 添加以下代码即可: 511 512 ```go 513 import "trpc.group/trpc-go/trpc-go/log" 514 515 func init() { 516 log.EnableTrace() 517 } 518 ``` 519 520 推荐使用环境变量的方式,更灵活一点。 521 522 ## 关于 `caller_skip` 的说明 523 524 使用 `Logger` 的方式不同,`caller_skip` 的设置也有所不同: 525 526 ### 用法1: 使用 Default Logger 527 528 ```go 529 log.Debug("default logger") // 使用默认的 logger 530 ``` 531 532 此时该 Logger 使用的配置为 `default`: 533 534 ```yaml 535 default: # 默认日志配置,log.Debug("xxx") 536 - writer: console # 控制台标准输出 默认 537 level: debug # 标准输出日志的级别 538 - writer: file # 本地文件日志 539 level: debug # 本地文件滚动日志的级别 540 formatter: json # 标准输出日志的格式 541 writer_config: # 本地文件输出具体配置 542 filename: ../log/trpc_time.log # 本地文件滚动日志存放的路径 543 write_mode: 2 # 日志写入模式,1-同步,2-异步,3-极速 (异步丢弃), 不配置默认异步模式 544 roll_type: time # 文件滚动类型,time 为按时间滚动 545 max_age: 7 # 最大日志保留天数 546 max_backups: 10 # 最大日志文件数 547 compress: false # 日志文件是否压缩 548 max_size: 10 # 本地文件滚动日志的大小 单位 MB 549 time_unit: day # 滚动时间间隔,支持:minute/hour/day/month/year 550 ``` 551 552 此时不需要关注或者去设置 `caller_skip` 的值,该值默认为 2,意思是在 `zap.Logger.Debug` 上套了两层(`trpc.log.Debug -> trpc.log.zapLog.Debug -> zap.Logger.Debug`) 553 554 ### 用法2: 将自定义的 Logger 放到 context 555 556 ```go 557 trpc.Message(ctx).WithLogger(log.Get("custom")) 558 log.DebugContext(ctx, "custom log msg") 559 ``` 560 561 此时也不需要关注或者去设置 `caller_skip` 的值,该值默认为 2,意思是在 `zap.Logger.Debug` 上套了两层(`trpc.log.DebugContext -> trpc.log.zapLog.Debug -> zap.Logger.Debug`) 562 563 配置例子如下: 564 565 ```yaml 566 custom: # 你的 Logger 配置,名字随便定,每个服务可以有多个 Logger,可使用 log.Get("custom").Debug("xxx") 打日志 567 - writer: file # 你的 core 配置,名字随便定 568 level: debug # 你的 core 输出的级别 569 writer_config: # 本地文件输出具体配置 570 filename: ../log/trpc1.log # 本地文件滚动日志存放的路径 571 ``` 572 573 ### 用法3: 不在 context 中使用自定义的 Logger 574 575 ```go 576 log.Get("custom").Debug("message") 577 ``` 578 579 此时需要将 `custom` Logger 的 `caller_skip` 值设置为 1,因为 `log.Get("custom")` 直接返回的是 `trpc.log.zapLog`,调用 `trpc.log.zapLog.Debug` 只在 `zap.Logger.Debug` 上套了一层(`trpc.log.zapLog.Debug -> zap.Logger.Debug`) 580 581 配置例子如下: 582 583 ```yaml 584 custom: # 你自定义的 Logger 配置,名字随便定,每个服务可以有多个 Logger,可使用 log.Get("custom").Debug("xxx") 打日志 585 - writer: file # 你自定义的 core 配置,名字随便定 586 caller_skip: 1 # 用于定位日志的调用处 587 level: debug # 你自定义 core 输出的级别 588 writer_config: # 本地文件输出具体配置 589 filename: ../log/trpc1.log # 本地文件滚动日志存放的路径 590 ``` 591 592 要注意 `caller_skip` 放置的位置(不要放在 `writer_config` 里面),并且对于多个 `writer` 都有 `caller_skip` 时,该 Logger 的 `caller_skip` 的值以最后一个为准,比如: 593 594 ```yaml 595 custom: # 你自定义的 Logger 配置,名字随便定,每个服务可以有多个 Logger,可使用 log.Get("custom").Debug("xxx") 打日志 596 - writer: file # 你自定义的 core 配置,名字随便定 597 caller_skip: 1 # 用于定位日志的调用处 598 level: debug # 你自定义的 core 输出的级别 599 writer_config: # 本地文件输出具体配置 600 filename: ../log/trpc1.log # 本地文件滚动日志存放的路径 601 - writer: file # 本地文件日志 602 caller_skip: 2 # 用于定位日志的调用处 603 level: debug # 本地文件滚动日志的级别 604 writer_config: # 本地文件输出具体配置 605 filename: ../log/trpc2.log # 本地文件滚动日志存放的路径 606 ``` 607 608 最终 `custom` 这个 Logger 的 `caller_skip` 值会被设置为 2。 609 610 **注意:** 上述用法 2 和用法 3 是冲突的,只能同时用其中的一种。