in tools/go-agent/instrument/plugins/instrument.go [344:454]
func (i *Instrument) copyOperatorsFS(context *rewrite.Context, baseDir, packageName string) ([]string, error) {
result := make([]string, 0)
var debugBaseDir string
for _, dir := range rewrite.OperatorDirs {
entries, err := core.FS.ReadDir(dir)
if err != nil {
return nil, err
}
files := make([]*rewrite.FileInfo, 0)
if i.compileOpts.DebugDir != "" {
debugBaseDir = filepath.Join(i.compileOpts.DebugDir, "plugins", "core", dir)
}
for _, entry := range entries {
if strings.HasSuffix(entry.Name(), "_test.go") || strings.HasSuffix(entry.Name(), "_test_base.go") {
continue
}
file, err1 := fs.ReadFile(core.FS, filepath.Join(dir, entry.Name()))
if err1 != nil {
return nil, err1
}
var rewriteFile *rewrite.FileInfo
if debugBaseDir != "" {
rewriteFile = rewrite.NewFileWithDebug(dir, entry.Name(), string(file), debugBaseDir)
} else {
rewriteFile = rewrite.NewFile(dir, entry.Name(), string(file))
}
files = append(files, rewriteFile)
}
rewrited, err := context.MultipleFilesWithWritten("skywalking_agent_core_", baseDir, filepath.Base(dir), files)
if err != nil {
return nil, err
}
result = append(result, rewrited...)
}
// write extra file for link the operator function
tmpFiles, err := tools.WriteMultipleFile(baseDir, map[string]string{
"skywalking_agent_core_linker.go": tools.ExecuteTemplate(`package {{.PackageName}}
import (
_ "unsafe"
)
//go:linkname {{.OperatorGetLinkMethod}} {{.OperatorGetLinkMethod}}
var {{.OperatorGetLinkMethod}} func() interface{}
//go:linkname {{.OperatorAppendInitNotifyLinkMethod}} {{.OperatorAppendInitNotifyLinkMethod}}
var {{.OperatorAppendInitNotifyLinkMethod}} func(func())
//go:linkname {{.MetricsRegisterAppenderLinkMethod}} {{.MetricsRegisterAppenderLinkMethod}}
var {{.MetricsRegisterAppenderLinkMethod}} func(interface{})
//go:linkname {{.MetricsHookAppenderLinkMethod}} {{.MetricsHookAppenderLinkMethod}}
var {{.MetricsHookAppenderLinkMethod}} func(func())
func init() {
if {{.OperatorGetLinkMethod}} != nil {
{{.OperatorGetRealMethod}} = func() {{.OperatorTypeName}} {
tmpOp := {{.OperatorGetLinkMethod}}()
if tmpOp == nil {
return nil
}
if opVal, ok := tmpOp.({{.OperatorTypeName}}); ok {
return opVal
}
return nil
}
}
if {{.OperatorAppendInitNotifyLinkMethod}} != nil {
{{.OperatorAppendInitNotifyRealMethod}} = {{.OperatorAppendInitNotifyLinkMethod}}
}
if {{.MetricsRegisterAppenderLinkMethod}} != nil {
{{.MetricsRegisterAppenderRealMethod}} = {{.MetricsRegisterAppenderLinkMethod}}
}
if {{.MetricsHookAppenderLinkMethod}} != nil {
{{.MetricsHookAppenderRealMethod}} = {{.MetricsHookAppenderLinkMethod}}
}
}
`, struct {
PackageName string
OperatorGetLinkMethod string
OperatorGetRealMethod string
OperatorTypeName string
OperatorAppendInitNotifyLinkMethod string
OperatorAppendInitNotifyRealMethod string
MetricsRegisterAppenderLinkMethod string
MetricsRegisterAppenderRealMethod string
MetricsHookAppenderLinkMethod string
MetricsHookAppenderRealMethod string
}{
PackageName: packageName,
OperatorGetLinkMethod: consts.GlobalTracerGetMethodName,
OperatorGetRealMethod: rewrite.GlobalOperatorRealGetMethodName,
OperatorTypeName: rewrite.GlobalOperatorTypeName,
OperatorAppendInitNotifyLinkMethod: consts.GlobalTracerInitAppendNotifyMethodName,
OperatorAppendInitNotifyRealMethod: rewrite.GlobalOperatorRealAppendTracerInitNotify,
MetricsRegisterAppenderLinkMethod: consts.MetricsRegisterAppendMethodName,
MetricsRegisterAppenderRealMethod: rewrite.MetricsRegisterAppender,
MetricsHookAppenderLinkMethod: consts.MetricsHookAppendMethodName,
MetricsHookAppenderRealMethod: rewrite.MetricsCollectAppender,
}),
})
if err != nil {
return nil, err
}
result = append(result, tmpFiles...)
return result, nil
}