-
Notifications
You must be signed in to change notification settings - Fork 9
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
1 parent
21f69bb
commit 1206d25
Showing
9 changed files
with
175 additions
and
19 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,85 @@ | ||
package profiler | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
"strings" | ||
"unicode" | ||
|
||
"github.com/luthersystems/elps/lisp" | ||
"github.com/luthersystems/elps/lisp/lisplib/libhelp" | ||
) | ||
|
||
// FunLabeler provides an alternative name for a function label in the trace. | ||
type FunLabeler func(runtime *lisp.Runtime, fun *lisp.LVal) string | ||
|
||
// WithELPSDocLabeler labels spans using elps doc magic strings. | ||
func WithELPSDocLabeler() Option { | ||
return WithFunLabeler(elpsDocFunLabeler) | ||
} | ||
|
||
// WithFunLabeler sets the labeler for tracing spans. | ||
func WithFunLabeler(funLabeler FunLabeler) Option { | ||
return func(p *profiler) { | ||
p.funLabeler = funLabeler | ||
} | ||
} | ||
|
||
// defaultFunName constructs a pretty canonical name using the function name. | ||
func defaultFunName(runtime *lisp.Runtime, fun *lisp.LVal) string { | ||
if fun.Type != lisp.LFun { | ||
return "" | ||
} | ||
funData := fun.FunData() | ||
if funData == nil { | ||
return "" | ||
} | ||
return fmt.Sprintf("%s:%s", funData.Package, getFunNameFromFID(runtime, funData.FID)) | ||
} | ||
|
||
// ELPSDocLabel is a magic string used to extract function labels. | ||
const ELPSDocLabel = `@trace{([^}]+)}` | ||
|
||
var elpsDocLabelRegExp = regexp.MustCompile(ELPSDocLabel) | ||
|
||
var sanitizeRegExp = regexp.MustCompile(`[\W_]+`) | ||
|
||
func sanitizeLabel(userLabel string) string { | ||
userLabel = strings.TrimSpace(userLabel) | ||
if userLabel == "" { | ||
return "" | ||
} | ||
|
||
userLabel = sanitizeRegExp.ReplaceAllString(userLabel, "_") | ||
// Ensure the label doesn't start with a digit or special character | ||
if len(userLabel) > 0 && !unicode.IsLetter(rune(userLabel[0])) { | ||
userLabel = "label_" + userLabel | ||
} | ||
|
||
// Eliminate duplicate underscores | ||
parts := strings.Split(userLabel, "_") | ||
var nonEmptyParts []string | ||
for _, part := range parts { | ||
if part != "" { | ||
nonEmptyParts = append(nonEmptyParts, part) | ||
} | ||
} | ||
return strings.Join(nonEmptyParts, "_") | ||
} | ||
|
||
func elpsDocFunLabeler(runtime *lisp.Runtime, fun *lisp.LVal) string { | ||
docStr := libhelp.FunDocstring(fun) | ||
if docStr == "" { | ||
return "" | ||
} | ||
matches := elpsDocLabelRegExp.FindAllStringSubmatch(docStr, -1) | ||
label := "" | ||
for _, match := range matches { | ||
if len(match) > 1 { | ||
label = match[1] | ||
break | ||
} | ||
} | ||
|
||
return sanitizeLabel(label) | ||
} |
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,68 @@ | ||
package profiler | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestSanitizeLabel(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
label string | ||
expected string | ||
}{ | ||
{ | ||
name: "normal case", | ||
label: "NormalLabel", | ||
expected: "NormalLabel", | ||
}, | ||
{ | ||
name: "contains spaces", | ||
label: "Label With Spaces", | ||
expected: "Label_With_Spaces", | ||
}, | ||
{ | ||
name: "contains special characters", | ||
label: "Label@#$%^&", | ||
expected: "Label", | ||
}, | ||
{ | ||
name: "starts with a digit", | ||
label: "123Label", | ||
expected: "label_123Label", | ||
}, | ||
{ | ||
name: "empty string", | ||
label: "", | ||
expected: "", | ||
}, | ||
{ | ||
name: "starts with a digit", | ||
label: "123Label", | ||
expected: "label_123Label", | ||
}, | ||
{ | ||
name: "starts with an underscore", | ||
label: "_Label", | ||
expected: "label_Label", | ||
}, | ||
{ | ||
name: "starts with a special character", | ||
label: "@Label", | ||
expected: "label_Label", | ||
}, | ||
{ | ||
name: "starts with a space", | ||
label: " Label", | ||
expected: "Label", | ||
}, | ||
} | ||
|
||
for _, tc := range tests { | ||
t.Run(tc.name, func(t *testing.T) { | ||
actual := sanitizeLabel(tc.label) | ||
assert.Equal(t, tc.expected, actual, "sanitizeLabel(%s)", tc.label) | ||
}) | ||
} | ||
} |
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
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
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 |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
(debug-print x)) | ||
|
||
(defun add-it (x y) | ||
"@trace" | ||
"@trace{ Add-It }" | ||
(+ x y)) | ||
|
||
(defun recurse-it (x) | ||
|