当前位置: 首页 > 知识库问答 >
问题:

golang 的 logger 的 Output calldepth 参数作用?

潘志国
2023-08-01

image.png
文档中 calldepth 的解释太简洁了,

其中 calldepth 是用来做什么,在 什么场景下有起作用

共有2个答案

麻宜春
2023-08-01

calldepth,顾名思义就是“调用深度”。

首先你要知道什么是“函数栈”。

假设有这样的函数间关系 A → B → C... 函数 A 调用了函数 B,函数 B 又调用了函数 C,依次类推……那么在函数 C 内部想要知道到底是谁调用的它(也就是 A),那么就得在栈上往上找 2 层。

log 模块的函数栈是 log.Printf → std.Output → runtime.Caller 这样的,所以默认值是 2,就是从 runtime.Caller 往上找 2 层,就能知道 log.Printf 是从哪来的了。

为啥要往上找?因为你这是日志模块,你肯定需要知道最终打 log 的那个最上层的调用方到底是谁(就是谁执行了 log.Printf 这行代码),这样才能再日志里输出出来的文件、行号等堆栈信息。

如果你不是直接用的 log 模块,而是自己又封装了一层,那 calldepth 就得传 3 了。因为还传 2 只能定位到你封装的那层上,定位不到实际打 log 的那层。

依次类推,你每多封装一层,celldepth 就 +1。


至于注释里的 PC,是 Program Counter(程序计数器)的缩写。

这个需要了解一点计算机组成原理的相关知识。你就知道它实际代表 CPU 当前指令地址就可以了。所谓 “恢复 PC” 就是指定位到当前执行的那句代码上。这个前面已经提到过了。

公孙高轩
2023-08-01

在 Golang 的 logger 中,Output 函数的 calldepth 参数用于指示调用栈的深度。这个参数是一个整数,用于指定应该在调用栈中向上追溯多少层来获取调用日志记录函数的位置信息。这样可以在日志中准确地显示日志记录函数的调用位置。

在 Golang 中,可以使用 log 包提供的 logger 来记录日志。其中 Output 函数用于输出日志记录,它的函数签名如下:

go

func (l *Logger) Output(calldepth int, s string) error
在使用 Output 函数时,calldepth 参数通常设置为 2,这是因为 log 包内部的 Print 系列函数会调用 Output 函数进行日志记录,而 Print 系列函数的调用栈深度为 2。所以将 calldepth 设置为 2,可以正确地获取到日志记录函数的位置信息,使得日志中能够准确显示日志记录函数的调用位置。

示例:

go

package main

import (

"log"

)

func main() {

log.SetFlags(log.Lshortfile)log.Println("This is a log message.")

}
在上面的示例中,log.Lshortfile 表示在日志中显示文件名和行号,而不显示完整的调用栈信息。当使用 log.Println 进行日志记录时,log 包会调用 Output 函数记录日志,而此时 calldepth 设置为 2,表示在调用栈中向上追溯 2 层,从而准确获取到 log.Println 的调用位置。因此,日志中会显示类似 "main.go:9: This is a log message." 这样的信息,其中 "main.go:9" 表示日志记录的位置信息。

 类似资料:
  • 问题内容: 我有以下功能: 其中,的类型是具有以下定义的接口: 题: 这是真的,和是 通过按引用 ,并且有它的价值被复制? 我认为: 是通过引用的,因为它是一张地图 是一个结构。因此,我应该传递指针以避免复制数据 问题答案: 接口类型只是一组方法。请注意,接口定义的成员未指定接收方类型是否为指针。这是因为 值类型的方法集是其关联的指针类型的方法集的子集 。满嘴 我的意思是,如果您具有以下条件: 然

  • 问题内容: 我需要帮助使此类型适用于任何类型。 我有一个函数,我需要接受具有属性的其他类型。 我尝试使用接口,但不适用于我的财产情况。这是代码: 我明白了 错误prog.go:39:在Count的参数中无法将人类([人类]类型)用作[]哺乳动物 有关更多详细信息,请参见Go Playground,网址为http://play.golang.org/p/xzWgjkzcmH 问题答案: 使用接口而不

  • 问题内容: 如果我有 我有: 然后,我可以成功执行以下操作: 但是,假设我要在doSomething中添加另一个参数,例如: 如果我这样称呼,Go在编译时会抱怨: 带有: 有没有办法做到这一点,还是我应该放弃并将返回值分配给某些引用,并将msg和这些值传递给? 问题答案: 在规范中对此进行了描述。它要求内部函数返回所有参数的正确类型。没有多余的参数以及返回多个值的函数。 作为一种特殊情况,如果一个

  • 问题内容: 我正在尝试将多重排序查询传递给mgo软件包的“排序”参数(请参阅https://godoc.org/labix.org/v2/mgo#Query.Sort)。 如果参数是动态的(当前保存在切片中),如何将其转换为有效的排序字符串。 一个有效的例子是: 但是,如果将“ -created_when”和“ -title”保留在一个切片中,则尝试使用切片联接,例如: 该查询无法正常工作。 如何

  • 问题内容: 我需要接受命令行参数才能以以下格式运行Go程序: 我正在使用。但是它只接受到‘1-‘。’> A’被跳过。 非常感谢您对解决此问题的任何帮助。 谢谢 问题答案: 您的外壳将IO 重定向解释为IO 重定向。Shell打开该文件作为命令的标准输出,并将参数传递给命令。 引用参数以避免这种情况:

  • 假设我有以下功能: 我希望调用者指定要打印的浮点数,以及小数点后的位数。(由<代码>表示)。%d说明符) 然而,在编译此代码时,我收到两个警告: 和 我的问题是:如何将格式说明符(例如本例中的)注入现有格式说明符?