Skip to content

Latest commit

 

History

History
96 lines (61 loc) · 3.61 KB

README_CN.md

File metadata and controls

96 lines (61 loc) · 3.61 KB

go-inject

Quick start

go install github.com/kakj-go/go-inject/tools/generate-inject@latest
go install github.com/kakj-go/go-inject/tools/toolexec-inject@latest

generate-inject

toolexec-inject

Instructions

创建 inject 方法

  1. 首先创建一个 inject 目录用于存放注入的代码
  2. 然后根据需要创建对应的.go文件
  3. 文件开头需要加入注释 //inject:github.com/gin-gonic/gin/routergroup.go 注释的内容就是你要拦截的文件.
//inject:github.com/gin-gonic/gin/routergroup.go
package gin

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

// 这时候如果是方法由于对象的结构体不在当前包中,所以我们可以定义一个同名的结构体,参数和返回值同理
type IRoutes interface {
}

// 代码里面你就可以将对应的文件的函数或者方法粘贴过来并清空方法体
func (group *RouterGroup) POST(relativePath string, handlers ...gin.HandlerFunc) IRoutes {
	fmt.Println("before POST")
	defer fmt.Println("after POST")

	return nil
}

注意代码的最后一行 return 是不会注入到三方库中

由于是代码注入的模式,如果在代码中间写 if return 之类的代码会改变原代码的逻辑。这里就可以动态修改三方库的逻辑而不用动源码

对于有些函数或者方法返回值只有结构体而没有名称的,你可以根据返回值的位置加上对应的 __injectResult0 这种名称,具体可以参考 修改返回值

对于结构体和参数返回值是可以直接用三方库的,前提是三方库吧其暴露出来即可。

由于注入的模式是拷贝函数或者方法的 body. 所以在里面使用全局变量是不太行的,但是使用公共包是可行的,因为 import 的包也会注入到三方库中

返回值或者结构体如果想访问其私有参数,可以在文件中定义自定义结构体,使用自己的结构体就可以访问了。具体参考 定义结构体

创建 generate 声明

在 main 方法文件目录下新建 generate.go. 然后 import 中就可以导入三方的注入代码或者自己开发的注入代码。在 package 加入 //go:generate generate-inject -path ../ 这行注释。

其中 path 是项目目录相对于 go generate 工作目录

//go:generate generate-inject -path ../
package main

import (
	_ "gin_generate_inject/inject/gin"
	_ "github.com/kakj-go/go-inject-trace-contrib/skywalking/github.com/gin-gonic/gin"
)

使用 generate-inject 注入代码

cd 到对应的 generate.go 目录,执行 go generate。然后就可以愉快的玩耍了

使用 toolexec-inject 注入代码

cd 到对应的 main 方法目录, 执行 go build -a -toolexec="toolexec-inject -path ../"

其中 path 是项目目录相对于 go build 工作目录

generate-inject 说明

generate-inject 核心是基于 go generate 的机制动态修改 vendor 代码来实现代码注入的。所以对于 golang src 库是无法注入的。其注入的代码可以在 vendor 对应的文件中看到

toolexec-inject 说明

toolexec-inject 核心是在代码构建的时候加上 -a -toolexec="" 来动态修改编译时候的临时文件来实现的,golang src 库是可以注入的

toolexec: 劫持 Golang 编译

致谢

go-build-hijacking

skywalking-go