Skip to content

Commit 3a9129a

Browse files
committed
Merge branch 'refs/heads/main' into add-langchain
2 parents 9bf6906 + a0c2018 commit 3a9129a

13 files changed

+371
-136
lines changed

README.md

+19-3
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,14 @@ Also there are several [**documents**](./docs) that you may find useful for eith
8181
| database/sql | https://pkg.go.dev/database/sql | - | - |
8282
| echo | https://github.com/labstack/echo | v4.0.0 | v4.12.0 |
8383
| elasticsearch | https://github.com/elastic/go-elasticsearch | v8.4.0 | v8.15.0 |
84-
| fasthttp | https://github.com/valyala/fasthttp | v1.45.0 | v1.57.0 |
84+
| fasthttp | https://github.com/valyala/fasthttp | v1.45.0 | v1.59.0 |
8585
| fiber | https://github.com/gofiber/fiber | v2.43.0 | v2.52.5 |
8686
| gin | https://github.com/gin-gonic/gin | v1.7.0 | v1.10.0 |
8787
| gorestful | https://github.com/emicklei/go-restful | v3.7.0 | v3.12.1 |
8888
| go-redis | https://github.com/redis/go-redis | v9.0.5 | v9.5.1 |
8989
| go-redis v8 | https://github.com/redis/go-redis | v8.11.0 | v8.11.5 |
9090
| gorm | https://github.com/go-gorm/gorm | v1.22.0 | v1.25.9 |
91-
| grpc | https://google.golang.org/grpc | v1.44.0 | v1.68.2 |
91+
| grpc | https://google.golang.org/grpc | v1.44.0 | v1.71.0 |
9292
| hertz | https://github.com/cloudwego/hertz | v0.8.0 | v0.9.2 |
9393
| kitex | https://github.com/cloudwego/kitex | v0.5.1 | v0.11.3 |
9494
| kratos | https://github.com/go-kratos/kratos | v2.6.3 | v2.8.2 |
@@ -126,4 +126,20 @@ to engage with us.
126126
These are only part of the companies using this project, for reference only. If you are using this project, please [add your company here](https://github.com/alibaba/opentelemetry-go-auto-instrumentation/issues/225) to tell us your scenario to make this project better.
127127

128128
- <img src="./docs/alibaba.png" width="80">
129-
- <img src="./docs/aliyun.png" width="100">
129+
- <img src="./docs/aliyun.png" width="100">
130+
131+
### Contributors
132+
133+
<a href="https://github.com/alibaba/opentelemetry-go-auto-instrumentation/graphs/contributors">
134+
<img alt="contributors" src="https://contrib.rocks/image?repo=alibaba/opentelemetry-go-auto-instrumentation"/>
135+
</a>
136+
137+
# Star History
138+
139+
[![Star History](https://api.star-history.com/svg?repos=alibaba/opentelemetry-go-auto-instrumentation&type=Date)](https://star-history.com/#alibaba/opentelemetry-go-auto-instrumentation&Date)
140+
141+
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
142+
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
143+
↑ 返回顶部 ↑
144+
</a>
145+
</p>

test/errors_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ func TestRunErrors(t *testing.T) {
4848
}
4949
re = regexp.MustCompile(".*OtelOnEnterTrampoline_p1.*")
5050
matches = re.FindAllString(text, -1)
51-
if len(matches) != 3 {
52-
t.Fatalf("expecting 3 matches")
51+
if len(matches) != 4 {
52+
t.Fatalf("expecting 4 matches")
5353
}
5454
re = regexp.MustCompile(".*OtelOnExitTrampoline_p2.*")
5555
matches = re.FindAllString(text, -1)
56-
if len(matches) != 3 {
57-
t.Fatalf("expecting 3 matches")
56+
if len(matches) != 4 {
57+
t.Fatalf("expecting 4 matches")
5858
}
5959
}

test/errorstest/auxiliary/helper.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ func TestSkip() *int {
2121
func TestSkip2() int {
2222
return 1024
2323
}
24-
func p1() {}
25-
func p2() {}
24+
func p1() { /*Test*/ }
25+
func p2() { // Test
26+
}
27+
2628
func p3(arg1 int, arg2 bool, arg3 float64) (int, bool, float64) {
2729
return arg1, arg2, arg3
2830
}

test/helloworld_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func TestRunHelloworld(t *testing.T) {
5151
ExpectContains(t, stderr, "BYD")
5252

5353
text := ReadInstrumentLog(t, filepath.Join("fmt", "print.go"))
54-
re := regexp.MustCompile(".*OtelOnEnterTrampoline.*OtelOnExitTrampoline.*")
54+
re := regexp.MustCompile("//line <generated>:1")
5555
matches := re.FindAllString(text, -1)
5656
if len(matches) < 1 {
5757
t.Fatalf("expecting at least one match")

tool/instrument/inst_func.go

+62-68
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package instrument
1616

1717
import (
1818
"fmt"
19+
"go/parser"
1920
"path/filepath"
2021
"regexp"
2122
"sort"
@@ -28,15 +29,7 @@ import (
2829
)
2930

3031
const (
31-
TrampolineJumpIfDesc = "/* TRAMPOLINE_JUMP_IF */"
32-
TrampolineJumpIfDescRegexp = "/\\* TRAMPOLINE_JUMP_IF \\*/"
33-
TrampolineNoNewlinePlaceholder = "/* NO_NEWWLINE_PLACEHOLDER */"
34-
TrampolineNoNewlinePlaceholderRegexp = "/\\* NO_NEWWLINE_PLACEHOLDER \\*/\n"
35-
TrampolineSemicolonPlaceholder = "/* SEMICOLON_PLACEHOLDER */"
36-
TrampolineSemicolonPlaceholderRegexp = "/\\* SEMICOLON_PLACEHOLDER \\*/\n"
37-
)
38-
39-
const (
32+
TJumpLabel = "/* TRAMPOLINE_JUMP_IF */"
4033
OtelAPIFile = "otel_api.go"
4134
OtelTrampolineFile = "otel_trampoline.go"
4235
)
@@ -54,10 +47,15 @@ func (rp *RuleProcessor) copyOtelApi(pkgName string) error {
5447

5548
func (rp *RuleProcessor) loadAst(filePath string) (*dst.File, error) {
5649
file := rp.tryRelocated(filePath)
57-
return util.ParseAstFromFile(file)
50+
rp.parser = util.NewAstParser()
51+
var err error
52+
rp.target, err = rp.parser.ParseFile(file, parser.ParseComments)
53+
return rp.target, err
5854
}
5955

6056
func (rp *RuleProcessor) restoreAst(filePath string, root *dst.File) (string, error) {
57+
rp.parser = nil
58+
rp.target = nil
6159
filePath = rp.tryRelocated(filePath)
6260
name := filepath.Base(filePath)
6361
newFile, err := util.WriteAstToFile(root, filepath.Join(rp.workDir, name))
@@ -87,7 +85,7 @@ func (rp *RuleProcessor) makeName(r *resource.InstFuncRule, onEnter bool) string
8785
func findJumpPoint(jumpIf *dst.IfStmt) *dst.BlockStmt {
8886
// Multiple func rules may apply to the same function, we need to find the
8987
// appropriate jump point to insert trampoline jump.
90-
if len(jumpIf.Decs.If) == 1 && jumpIf.Decs.If[0] == TrampolineJumpIfDesc {
88+
if len(jumpIf.Decs.If) == 1 && jumpIf.Decs.If[0] == TJumpLabel {
9189
// Insert trampoline jump within the else block
9290
elseBlock := jumpIf.Else.(*dst.BlockStmt)
9391
if len(elseBlock.List) > 1 {
@@ -181,32 +179,9 @@ func (rp *RuleProcessor) insertTJump(t *resource.InstFuncRule,
181179
ifStmt: tjump,
182180
rule: t,
183181
})
184-
185-
// @@ Unfortunately, dst framework does not support fine-grained space control
186-
// i.e. there is no way to generate all above AST into one line code, we have
187-
// to manually format it. There we insert OtelNewlineTrampolineHolder anchor
188-
// so that we aware of where we should remove trailing newline.
189-
// if .... { /* NO_NEWWLINE_PLACEHOLDER */
190-
// ... /* NO_NEWWLINE_PLACEHOLDER */
191-
// } else { /* NO_NEWWLINE_PLACEHOLDER */
192-
// ... /* SEMICOLON_PLACEHOLDER */
193-
// } /* NO_NEWWLINE_PLACEHOLDER */
194-
// NEW_LINE
195-
{ // then block
196-
callExpr := tjump.Body.List[0]
197-
callExpr.Decorations().Start.Append(TrampolineNoNewlinePlaceholder)
198-
callExpr.Decorations().End.Append(TrampolineSemicolonPlaceholder)
199-
retStmt := tjump.Body.List[1]
200-
retStmt.Decorations().End.Append(TrampolineNoNewlinePlaceholder)
201-
}
202-
{ // else block
203-
deferStmt := tjump.Else.(*dst.BlockStmt).List[0]
204-
deferStmt.Decorations().Start.Append(TrampolineNoNewlinePlaceholder)
205-
deferStmt.Decorations().End.Append(TrampolineSemicolonPlaceholder)
206-
tjump.Else.Decorations().End.Append(TrampolineNoNewlinePlaceholder)
207-
tjump.Decs.If.Append(TrampolineJumpIfDesc) // Anchor label
208-
}
209-
182+
// Add label for trampoline-jump-if. Note that the label will be cleared
183+
// during optimization pass, to make it pretty in the generated code
184+
tjump.Decs.If.Append(TJumpLabel)
210185
// Find if there is already a trampoline-jump-if, insert new tjump if so,
211186
// otherwise prepend to block body
212187
found := false
@@ -222,10 +197,35 @@ func (rp *RuleProcessor) insertTJump(t *resource.InstFuncRule,
222197
}
223198
}
224199
if !found {
225-
// Outmost trampoline-jump-if may follow by user code right after else
226-
// block, replacing the trailing newline mandatorily breaks the code,
227-
// we need to insert extra new line to make replacement possible
228-
tjump.Decorations().After = dst.EmptyLine
200+
// Tag the trampoline-jump-if with a special line directive so that
201+
// debugger can show the correct line number
202+
tjump.Decs.Before = dst.NewLine
203+
tjump.Decs.Start.Append("//line <generated>:1")
204+
pos := rp.parser.FindPosition(funcDecl.Body)
205+
if len(funcDecl.Body.List) > 0 {
206+
// It does happens because we may insert raw code snippets at the
207+
// function entry. These dynamically generated nodes do not have
208+
// corresponding node positions. We need to keep looking downward
209+
// until we find a node that contains position information, and then
210+
// annotate it with a line directive.
211+
for i := 0; i < len(funcDecl.Body.List); i++ {
212+
stmt := funcDecl.Body.List[i]
213+
pos = rp.parser.FindPosition(stmt)
214+
if !pos.IsValid() {
215+
continue
216+
}
217+
tag := fmt.Sprintf("//line %s", pos.String())
218+
stmt.Decorations().Before = dst.NewLine
219+
stmt.Decorations().Start.Append(tag)
220+
}
221+
} else {
222+
pos = rp.parser.FindPosition(funcDecl.Body)
223+
tag := fmt.Sprintf("//line %s", pos.String())
224+
empty := util.EmptyStmt()
225+
empty.Decs.Before = dst.NewLine
226+
empty.Decs.Start.Append(tag)
227+
funcDecl.Body.List = append(funcDecl.Body.List, empty)
228+
}
229229
funcDecl.Body.List = append([]dst.Stmt{tjump}, funcDecl.Body.List...)
230230
}
231231

@@ -237,38 +237,21 @@ func (rp *RuleProcessor) insertTJump(t *resource.InstFuncRule,
237237
return nil
238238
}
239239

240-
func (rp *RuleProcessor) inliningTJump(filePath string) error {
241-
text, err := util.ReadFile(filePath)
242-
if err != nil {
243-
return err
244-
}
245-
// Remove trailing newline
246-
re := regexp.MustCompile(TrampolineNoNewlinePlaceholderRegexp)
247-
text = re.ReplaceAllString(text, " ")
248-
// Replace with semicolon
249-
re = regexp.MustCompile(TrampolineSemicolonPlaceholderRegexp)
250-
text = re.ReplaceAllString(text, ";")
251-
// Remove trampoline jump if ideitifiers
252-
re = regexp.MustCompile(TrampolineJumpIfDescRegexp)
253-
text = re.ReplaceAllString(text, "")
254-
// All done, persist to file
255-
_, err = util.WriteFile(filePath, text)
256-
return err
257-
}
258-
259240
func (rp *RuleProcessor) insertRaw(r *resource.InstFuncRule, decl *dst.FuncDecl) error {
260241
util.Assert(r.OnEnter != "" || r.OnExit != "", "sanity check")
261242
if r.OnEnter != "" {
262243
// Prepend raw code snippet to function body for onEnter
263-
onEnterSnippet, err := util.ParseAstFromSnippet(r.OnEnter)
244+
p := util.NewAstParser()
245+
onEnterSnippet, err := p.ParseSnippet(r.OnEnter)
264246
if err != nil {
265247
return err
266248
}
267249
decl.Body.List = append(onEnterSnippet, decl.Body.List...)
268250
}
269251
if r.OnExit != "" {
270252
// Use defer func(){ raw_code_snippet }() for onExit
271-
onExitSnippet, err := util.ParseAstFromSnippet(
253+
p := util.NewAstParser()
254+
onExitSnippet, err := p.ParseSnippet(
272255
fmt.Sprintf("defer func(){ %s }()", r.OnExit),
273256
)
274257
if err != nil {
@@ -301,8 +284,8 @@ func sortFuncRules(fnRules []*resource.InstFuncRule) []*resource.InstFuncRule {
301284

302285
func (rp *RuleProcessor) writeTrampoline(pkgName string) error {
303286
// Prepare trampoline code header
304-
code := "package " + pkgName
305-
trampoline, err := util.ParseAstFromSource(code)
287+
p := util.NewAstParser()
288+
trampoline, err := p.ParseSource("package " + pkgName)
306289
if err != nil {
307290
return err
308291
}
@@ -319,6 +302,18 @@ func (rp *RuleProcessor) writeTrampoline(pkgName string) error {
319302
return nil
320303
}
321304

305+
func (rp *RuleProcessor) enableLineDirective(filePath string) error {
306+
text, err := util.ReadFile(filePath)
307+
if err != nil {
308+
return err
309+
}
310+
re := regexp.MustCompile(".*//line ")
311+
text = re.ReplaceAllString(text, "//line ")
312+
// All done, persist to file
313+
_, err = util.WriteFile(filePath, text)
314+
return err
315+
}
316+
322317
func (rp *RuleProcessor) applyFuncRules(bundle *resource.RuleBundle) (err error) {
323318
// Nothing to do if no func rules
324319
if len(bundle.File2FuncRules) == 0 {
@@ -338,7 +333,6 @@ func (rp *RuleProcessor) applyFuncRules(bundle *resource.RuleBundle) (err error)
338333
if err != nil {
339334
return err
340335
}
341-
rp.target = astRoot
342336
rp.trampolineJumps = make([]*TJump, 0)
343337
for fnName, rules := range fn2rules {
344338
for _, decl := range astRoot.Decls {
@@ -378,9 +372,9 @@ func (rp *RuleProcessor) applyFuncRules(bundle *resource.RuleBundle) (err error)
378372
if err != nil {
379373
return err
380374
}
381-
// Wait, all above code snippets should be inlined to new line to
382-
// avoid potential misbehaviors during debugging
383-
err = rp.inliningTJump(filePath)
375+
// Line directive must be placed at the beginning of the line, otherwise
376+
// it will be ignored by the compiler
377+
err = rp.enableLineDirective(filePath)
384378
if err != nil {
385379
return err
386380
}

tool/instrument/instrument.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ import (
3737
type RuleProcessor struct {
3838
packageName string
3939
workDir string
40-
target *dst.File // The target file to be instrumented
40+
target *dst.File // The target file to be instrumented
41+
parser *util.AstParser // The parser for the target file
4142
compileArgs []string
4243
rule2Suffix map[*resource.InstFuncRule]string
4344
rawFunc *dst.FuncDecl

0 commit comments

Comments
 (0)