运维八一 运维八一
首页
运维杂记
编程浅尝
周积跬步
专栏
生活
关于
收藏
  • 分类
  • 标签
  • 归档
Source (opens new window)

运维八一

运维,运维!
首页
运维杂记
编程浅尝
周积跬步
专栏
生活
关于
收藏
  • 分类
  • 标签
  • 归档
Source (opens new window)
  • Go

    • 前言

    • Go基础知识

    • Go基本语法

    • 实战项目:简单web服务

    • 基本数据类型

    • 内置运算符

    • 分支和循环

    • 函数 function

    • 结构体 struct

    • 方法 method

    • 实战项目:跟踪函数调用链

      • v0_1 使用 defer 跟踪函数的执行过程
      • v0_2 自动获取所跟踪函数的函数名
        • v0.2 自动获取所跟踪函数的函数名
      • v0_3 增加 Goroutine 标识
      • v0_4 让输出的跟踪信息更具层次感
      • v0_5 利用代码生成自动注入 Trace 函数
      • 总结
    • 接口 interface

    • 并发 concurrency

    • 指针

    • 实战项目:实现轻量级线程池

    • 实战项目:实现TCP服务器

    • go常用包

    • Gin框架

    • go随记

  • Python

  • Shell

  • Java

  • Vue

  • 前端

  • 编程浅尝
  • Go
  • 实战项目:跟踪函数调用链
lyndon
2022-06-07
目录

v0_2 自动获取所跟踪函数的函数名

# v0.2 自动获取所跟踪函数的函数名

要解决“调用 Trace 时需要手动显式传入要跟踪的函数名”的问题,也就是要让 Trace 函数能够自动获取到它跟踪函数的函数名信息。

带来的好处:

在手动显式传入的情况下:

defer Trace("foo")()
1

一旦实现了自动获取函数名,所有支持函数调用链跟踪的函数都只需使用下面调用形式的 Trace 函数就可以了:

defer Trace()()
1

这种一致的 Trace 函数调用方式也为后续的自动向代码中注入 Trace 函数奠定了基础。

**解决方案:**实现 Trace 函数对它跟踪函数名的自动获取,需要借助 Go 标准库 runtime 包的帮助。

// trace1/trace.go

func Trace() func() {
    pc, _, _, ok := runtime.Caller(1)
    if !ok {
        panic("not found caller")
    }

    fn := runtime.FuncForPC(pc)
    name := fn.Name()
    
    println("enter:", name)
    return func() { println("exit:", name) }

}

func foo() {
    defer Trace()()
    bar()
}

func bar() {
    defer Trace()()
}

func main() {
    defer Trace()()
    foo()
}

/*
enter: main.main
enter: main.foo
enter: main.bar
exit: main.bar
exit: main.foo
exit: main.main
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

通过 runtime.Caller 函数获得当前 Goroutine 的函数调用栈上的信息,runtime.Caller 的参数标识的是要获取的是哪一个栈帧的信息。当参数为 0 时,返回的是 Caller 函数的调用者的函数信息,在这里就是 Trace 函数。但我们需要的是 Trace 函数的调用者的信息,于是我们传入 1。

Caller 函数有四个返回值:

  • 第一个返回值代表的是程序计数(pc);
  • 第二个和第三个参数代表对应函数所在的源文件名以及所在行数,这里暂时不需要;
  • 最后一个参数代表是否能成功获取这些信息,如果获取失败,抛出 panic。

通过 runtime.FuncForPC 函数和程序计数器(PC)得到被跟踪函数的函数名称。

上次更新: 2022/10/06, 00:04:41
v0_1 使用 defer 跟踪函数的执行过程
v0_3 增加 Goroutine 标识

← v0_1 使用 defer 跟踪函数的执行过程 v0_3 增加 Goroutine 标识→

最近更新
01
ctr和crictl显示镜像不一致
03-13
02
alpine镜像集成常用数据库客户端
03-13
03
create-cluster
02-26
更多文章>
Theme by Vdoing | Copyright © 2015-2024 op81.com
苏ICP备18041258号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式