专栏名称: 唤之
目录
相关文章推荐
待字闺中  ·  DeepSeek 爆火带来的大变化 ·  6 天前  
程序员小灰  ·  DeepSeek创始人梁文峰牛逼的个人经历 ·  昨天  
码农翻身  ·  Bill Gates 和 Linus ... ·  2 天前  
程序员小灰  ·  深夜王炸,微信搜索:接入 DeepSeek ... ·  4 天前  
51好读  ›  专栏  ›  唤之

如何对 Go 项目代码进行静态依赖分析

唤之  · 掘金  · 程序员  · 2018-04-08 05:46

正文

看源码的一个比较好的思路是:先从宏观上对系统内部模块的调用关系有一个大概的认识。这个过程又分静态分析和动态分析。动态分析很简单,直接对内存数据进行采样即可,比如 Golang 的 pprof。动态分析有一个缺点是依赖于流量,或者说访问数据,不同的访问数据往往会造成不同的调用关系。静态分析的话现在市面上也有很多好用的开源工具,我们今天看一下 Golang 的代码静态依赖分析怎么来做。

Golang 代码的静态分析尤其简单,为什么?Golang 语法方面,我们在调用一个 package 的时候,需要 import。同时,如果我们代码中对一个 package 没有引用而又把包 import 进来,这个时候 Golang 的编译器是会报错的。这两点意味着我们可以通过分析 import 语句块来得到我们包内部的调用关系。

当然尽管上面原理说的比较简单,但是实现起来还是有一些坑。没关系,我帮你们实现了。链接: github.com/legendtkl/g… 。取名 DAG 也是因为包之间的依赖其实就是一个 DAG。

1. 安装

go get -u github.com/legendtkl/godag

我在实现的时候包里面没有引用第三方包,这样也是为了不能翻墙的同学 go get 无障碍。

2. 使用

以 beego 项目为例,分析其内部的包之间的调用关系。

godag --pkg_name=github.com/astaxie/beego --pkg_path=/Users/kltao/code/go/src/github.com/astaxie/beego --depth=1 --dot_file_path=a.dot

godag 支持四个参数:

  • pkg_name: 要分析的 package 名称,必填
  • pkg_path: package 存放在本地的目录,必填
  • depth: 分析的代码深度。举个例子,如果 depth 为 1,我们则会分析包:beego/cache,beego/context;而如果 depth 为 2,则分析这些包:beego/cache/redis,beego/cache/ssdb 等。
  • dot file path: 是我们输出的 dot 文件,下面细说

3. 输出

3.1 dot

godag 会输出一个 .dot 文件。dot 是一种绘图语言,它可以方便你采用图形的方式快速、直观地表达一些想法,比如描述某个问题的解决方案,构思一个程序的流程,澄清一堆貌似散乱无章的事物之间的联系。举个列子,下面列出 dot 文件以及对应的流程图。

digraph graphname {
     a -> b -> c;
     b -> d;
 }

对应流程图。

关于 dot 文件更详细的信息可以参考: DOT(graph description language) 。我们生产的 dot 文件内容如下。

digraph G {
    "beego/utils" -> "beego/session"
    "beego/logs" -> "beego/logs"
    "beego/utils" -> "beego"
}

3.2 可视化

dot 文件的可视化可以使用 graphviz。graphviz 的安装比较简单,比如 Mac 上安装命令如下

brew install graphviz

dot 文件可视化,使用 dot 命令,比如生成 png 图。







请到「今天看啥」查看全文