-
Notifications
You must be signed in to change notification settings - Fork 591
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
35 changed files
with
3,627 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package main | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
alib "go.opentelemetry.io/contrib/instrgen/lib" | ||
) | ||
|
||
var testcases = map[string]string{ | ||
"./test/fib": "./test/expected/fib", | ||
"./test/methods": "./test/expected/methods", | ||
"./test/goroutines": "./test/expected/goroutines", | ||
"./test/recursion": "./test/expected/recursion", | ||
"./test/package": "./test/expected/package", | ||
"./test/selector": "./test/expected/selector", | ||
} | ||
|
||
var failures []string | ||
|
||
func inject(t *testing.T, root string, packagePattern string) { | ||
var rootFunctions []alib.FuncDescriptor | ||
|
||
rootFunctions = append(rootFunctions, alib.FindRootFunctions(root, packagePattern)...) | ||
interfaces := alib.FindInterfaces(root, packagePattern) | ||
funcDecls := alib.FindFuncDecls(root, packagePattern, interfaces) | ||
backwardCallGraph := alib.BuildCallGraph(root, packagePattern, funcDecls, interfaces) | ||
|
||
fmt.Println("\n\tchild parent") | ||
for k, v := range backwardCallGraph { | ||
fmt.Print("\n\t", k) | ||
fmt.Print(" ", v) | ||
} | ||
fmt.Println("") | ||
|
||
analysis := &alib.Analysis{ProjectPath: root, | ||
PackagePattern: packagePattern, | ||
RootFunctions: rootFunctions, | ||
FuncDecls: funcDecls, | ||
Callgraph: backwardCallGraph, | ||
Interfaces: interfaces, | ||
Debug: false} | ||
err := ExecutePasses(analysis) | ||
require.NoError(t, err) | ||
} | ||
|
||
func Test(t *testing.T) { | ||
for k, v := range testcases { | ||
inject(t, k, "./...") | ||
files := alib.SearchFiles(k, ".go.input") | ||
expectedFiles := alib.SearchFiles(v, ".go.expected") | ||
numOfFiles := len(expectedFiles) | ||
numOfComparisons := 0 | ||
for _, file := range files { | ||
for _, expectedFile := range expectedFiles { | ||
fmt.Println(file) | ||
fmt.Println(expectedFile) | ||
if filepath.Base(file) == filepath.Base(expectedFile) { | ||
f1, err1 := os.ReadFile(file) | ||
require.NoError(t, err1) | ||
f2, err2 := os.ReadFile(expectedFile) | ||
require.NoError(t, err2) | ||
if !assert.True(t, bytes.Equal(f1, f2)) { | ||
fmt.Println(k) | ||
failures = append(failures, k) | ||
} | ||
numOfComparisons = numOfComparisons + 1 | ||
} | ||
} | ||
} | ||
if numOfFiles != numOfComparisons { | ||
panic("not all files were compared") | ||
} | ||
Prune(k, "./...") | ||
} | ||
for _, f := range failures { | ||
fmt.Println("FAILURE : ", f) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
module go.opentelemetry.io/contrib/instrgen/driver | ||
|
||
go 1.18 | ||
|
||
replace go.opentelemetry.io/contrib/instrgen => ../ | ||
|
||
require ( | ||
github.com/stretchr/testify v1.8.1 | ||
go.opentelemetry.io/contrib/instrgen v0.0.0-00010101000000-000000000000 | ||
go.opentelemetry.io/otel v1.11.2 | ||
) | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/go-logr/logr v1.2.3 // indirect | ||
github.com/go-logr/stdr v1.2.2 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.11.2 // indirect | ||
go.opentelemetry.io/otel/sdk v1.11.2 // indirect | ||
go.opentelemetry.io/otel/trace v1.11.2 // indirect | ||
golang.org/x/mod v0.7.0 // indirect | ||
golang.org/x/sys v0.3.0 // indirect | ||
golang.org/x/tools v0.4.0 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= | ||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= | ||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= | ||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= | ||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= | ||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= | ||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | ||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= | ||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= | ||
go.opentelemetry.io/otel v1.11.2 h1:YBZcQlsVekzFsFbjygXMOXSs6pialIZxcjfO/mBDmR0= | ||
go.opentelemetry.io/otel v1.11.2/go.mod h1:7p4EUV+AqgdlNV9gL97IgUZiVR3yrFXYo53f9BM3tRI= | ||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.11.2 h1:BhEVgvuE1NWLLuMLvC6sif791F45KFHi5GhOs1KunZU= | ||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.11.2/go.mod h1:bx//lU66dPzNT+Y0hHA12ciKoMOH9iixEwCqC1OeQWQ= | ||
go.opentelemetry.io/otel/sdk v1.11.2 h1:GF4JoaEx7iihdMFu30sOyRx52HDHOkl9xQ8SMqNXUiU= | ||
go.opentelemetry.io/otel/sdk v1.11.2/go.mod h1:wZ1WxImwpq+lVRo4vsmSOxdd+xwoUJ6rqyLc3SyX9aU= | ||
go.opentelemetry.io/otel/trace v1.11.2 h1:Xf7hWSF2Glv0DE3MH7fBHvtpSBsjcBUe5MYAmZM/+y0= | ||
go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA= | ||
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= | ||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | ||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= | ||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= | ||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4= | ||
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"os" | ||
|
||
alib "go.opentelemetry.io/contrib/instrgen/lib" | ||
) | ||
|
||
func usage() { | ||
fmt.Println("\nusage autotel --command [path to go project] [package pattern]") | ||
fmt.Println("\tcommand:") | ||
fmt.Println("\t\tinject (injects open telemetry calls into project code)") | ||
fmt.Println("\t\tinject-dump-ir (injects open telemetry calls into project code and intermediate passes)") | ||
fmt.Println("\t\tprune (prune open telemetry calls") | ||
fmt.Println("\t\tdumpcfg (dumps control flow graph)") | ||
fmt.Println("\t\tgencfg (generates json representation of control flow graph)") | ||
fmt.Println("\t\trootfunctions (dumps root functions)") | ||
} | ||
|
||
// Prune. | ||
func Prune(projectPath string, packagePattern string) { | ||
var rootFunctions []alib.FuncDescriptor | ||
|
||
interfaces := alib.FindInterfaces(projectPath, packagePattern) | ||
rootFunctions = append(rootFunctions, alib.FindRootFunctions(projectPath, packagePattern)...) | ||
funcDecls := alib.FindFuncDecls(projectPath, packagePattern, interfaces) | ||
backwardCallGraph := alib.BuildCallGraph(projectPath, packagePattern, funcDecls, interfaces) | ||
fmt.Println("\n\tchild parent") | ||
for k, v := range backwardCallGraph { | ||
fmt.Print("\n\t", k) | ||
fmt.Print(" ", v) | ||
} | ||
fmt.Println("") | ||
analysis := &alib.Analysis{ | ||
ProjectPath: projectPath, | ||
PackagePattern: packagePattern, | ||
RootFunctions: rootFunctions, | ||
FuncDecls: funcDecls, | ||
Callgraph: backwardCallGraph, | ||
Interfaces: interfaces, | ||
Debug: false} | ||
err := analysis.Execute(&alib.OtelPruner{}, otelPrunerPassSuffix) | ||
if err != nil { | ||
log.Println("Pruning failed") | ||
} else { | ||
fmt.Println("\tpruning done") | ||
} | ||
} | ||
|
||
// Parsing algorithm works as follows. It goes through all function | ||
// decls and infer function bodies to find call to AutotelEntryPoint | ||
// A parent function of this call will become root of instrumentation | ||
// Each function call from this place will be instrumented automatically | ||
|
||
func executeCommand(arglist []string) { | ||
if arglist[1] == "--inject" { | ||
projectPath := arglist[2] | ||
packagePattern := arglist[3] | ||
Prune(projectPath, packagePattern) | ||
var rootFunctions []alib.FuncDescriptor | ||
|
||
interfaces := alib.FindInterfaces(projectPath, packagePattern) | ||
rootFunctions = append(rootFunctions, alib.FindRootFunctions(projectPath, packagePattern)...) | ||
funcDecls := alib.FindFuncDecls(projectPath, packagePattern, interfaces) | ||
backwardCallGraph := alib.BuildCallGraph(projectPath, packagePattern, funcDecls, interfaces) | ||
fmt.Println("\n\tchild parent") | ||
for k, v := range backwardCallGraph { | ||
fmt.Print("\n\t", k) | ||
fmt.Print(" ", v) | ||
} | ||
fmt.Println("") | ||
analysis := &alib.Analysis{ | ||
ProjectPath: projectPath, | ||
PackagePattern: packagePattern, | ||
RootFunctions: rootFunctions, | ||
FuncDecls: funcDecls, | ||
Callgraph: backwardCallGraph, | ||
Interfaces: interfaces, | ||
Debug: false} | ||
err := ExecutePasses(analysis) | ||
if err != nil { | ||
log.Println("Analysis failed") | ||
} else { | ||
fmt.Println("\tinstrumentation done") | ||
} | ||
} | ||
if arglist[1] == "--inject-dump-ir" { | ||
projectPath := arglist[2] | ||
packagePattern := arglist[3] | ||
Prune(projectPath, packagePattern) | ||
var rootFunctions []alib.FuncDescriptor | ||
|
||
interfaces := alib.FindInterfaces(projectPath, packagePattern) | ||
rootFunctions = append(rootFunctions, alib.FindRootFunctions(projectPath, packagePattern)...) | ||
funcDecls := alib.FindFuncDecls(projectPath, packagePattern, interfaces) | ||
backwardCallGraph := alib.BuildCallGraph(projectPath, packagePattern, funcDecls, interfaces) | ||
fmt.Println("\n\tchild parent") | ||
for k, v := range backwardCallGraph { | ||
fmt.Print("\n\t", k) | ||
fmt.Print(" ", v) | ||
} | ||
fmt.Println("") | ||
analysis := &alib.Analysis{ | ||
ProjectPath: projectPath, | ||
PackagePattern: packagePattern, | ||
RootFunctions: rootFunctions, | ||
FuncDecls: funcDecls, | ||
Callgraph: backwardCallGraph, | ||
Interfaces: interfaces, | ||
Debug: true} | ||
err := ExecutePassesDumpIr(analysis) | ||
if err != nil { | ||
log.Println("Analysis failed") | ||
} else { | ||
fmt.Println("\tinstrumentation done") | ||
} | ||
} | ||
if arglist[1] == "--dumpcfg" { | ||
projectPath := arglist[2] | ||
packagePattern := arglist[3] | ||
var funcDecls map[alib.FuncDescriptor]bool | ||
var backwardCallGraph map[alib.FuncDescriptor][]alib.FuncDescriptor | ||
|
||
interfaces := alib.FindInterfaces(projectPath, packagePattern) | ||
funcDecls = alib.FindFuncDecls(projectPath, packagePattern, interfaces) | ||
backwardCallGraph = alib.BuildCallGraph(projectPath, packagePattern, funcDecls, interfaces) | ||
fmt.Println("\n\tchild parent") | ||
for k, v := range backwardCallGraph { | ||
fmt.Print("\n\t", k) | ||
fmt.Print(" ", v) | ||
} | ||
} | ||
if arglist[1] == "--gencfg" { | ||
projectPath := arglist[2] | ||
packagePattern := arglist[3] | ||
var funcDecls map[alib.FuncDescriptor]bool | ||
var backwardCallGraph map[alib.FuncDescriptor][]alib.FuncDescriptor | ||
interfaces := alib.FindInterfaces(projectPath, packagePattern) | ||
funcDecls = alib.FindFuncDecls(projectPath, packagePattern, interfaces) | ||
backwardCallGraph = alib.BuildCallGraph(projectPath, packagePattern, funcDecls, interfaces) | ||
alib.Generatecfg(backwardCallGraph, "callgraph.js") | ||
} | ||
if arglist[1] == "--rootfunctions" { | ||
projectPath := arglist[2] | ||
packagePattern := arglist[3] | ||
var rootFunctions []alib.FuncDescriptor | ||
rootFunctions = append(rootFunctions, alib.FindRootFunctions(projectPath, packagePattern)...) | ||
fmt.Println("rootfunctions:") | ||
for _, fun := range rootFunctions { | ||
fmt.Println("\t" + fun.TypeHash()) | ||
} | ||
} | ||
if arglist[1] == "--prune" { | ||
projectPath := arglist[2] | ||
packagePattern := arglist[3] | ||
Prune(projectPath, packagePattern) | ||
} | ||
} | ||
|
||
func main() { | ||
fmt.Println("autotel compiler") | ||
if len(os.Args) != 4 { | ||
usage() | ||
os.Exit(-1) | ||
} | ||
executeCommand(os.Args) | ||
} |
Oops, something went wrong.