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

运维八一

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

    • 前言

    • Go基础知识

    • Go基本语法

    • 实战项目:简单web服务

    • 基本数据类型

    • 内置运算符

    • 分支和循环

    • 函数 function

    • 结构体 struct

    • 方法 method

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

      • v0_1 使用 defer 跟踪函数的执行过程
        • v0.1 使用 defer 跟踪函数的执行过程
      • 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_1 使用 defer 跟踪函数的执行过程

# v0.1 使用 defer 跟踪函数的执行过程

// trace.go
package main

func Trace(name string) func() {
    println("enter:", name)
    return func() {
        println("exit:", name)
    }
}

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

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

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

/*
enter: main
enter: foo
enter: bar
exit: bar
exit: foo
exit: 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

这个 Go 程序的函数调用的全过程一目了然:程序按main -> foo -> bar的函数调用次序执行,代码在函数的入口与出口处分别输出了跟踪日志。

在这段实现中,在每个函数的入口处都使用 defer 设置了一个 deferred 函数。根据 defer 的运作机制,Go 会在 defer 设置 deferred 函数时对 defer 后面的表达式进行求值。

以 foo 函数中的defer Trace("foo")()这行代码为例:Go 会对 defer 后面的表达式Trace("foo")()进行求值。由于这个表达式包含一个函数调用Trace("foo"),所以这个函数会被执行。上面的 Trace 函数只接受一个参数,˙这个参数代表函数名,Trace 会首先打印进入某函数的日志,比如:“enter: foo”。然后返回一个闭包函数,这个闭包函数一旦被执行,就会输出离开某函数的日志。在 foo 函数中,这个由 Trace 函数返回的闭包函数就被设置为了 deferred 函数,于是当 foo 函数返回后,这个闭包函数就会被执行,输出“exit: foo”的日志。

离期望的“跟踪函数调用链”的实现还有一些不足之处:

  • 调用 Trace 时需手动显式传入要跟踪的函数名;
  • 如果是并发应用,不同 Goroutine 中函数链跟踪混在一起无法分辨;
  • 输出的跟踪结果缺少层次感,调用关系不易识别;
  • 对要跟踪的函数,需手动调用 Trace 函数。
上次更新: 2022/10/06, 00:04:41
用类型嵌入模拟实现“继承”
v0_2 自动获取所跟踪函数的函数名

← 用类型嵌入模拟实现“继承” v0_2 自动获取所跟踪函数的函数名→

最近更新
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
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式