Skip to content

Commit a15642f

Browse files
authored
QoL (#13)
* Use the defer in the example * Add magic comment in defer * Add utility function to detect named return value * Add caller information to metrics * Register metrics globally only on nil argument
1 parent 6cf9fb1 commit a15642f

File tree

9 files changed

+428
-105
lines changed

9 files changed

+428
-105
lines changed

Diff for: .gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# Local build of autometrics generator
2-
autometrics
2+
/autometrics

Diff for: cmd/autometrics/main.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import (
99

1010
func main() {
1111
fileName := os.Getenv("GOFILE")
12+
moduleName := os.Getenv("GOPACKAGE")
1213
promGenerator := doc.NewPrometheusDoc()
13-
if err := doc.TransformFile(fileName, promGenerator); err != nil {
14+
15+
if err := doc.TransformFile(fileName, moduleName, promGenerator); err != nil {
1416
log.Fatalf("error transforming %s: %s", fileName, err)
1517
}
1618
}

Diff for: examples/web/.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Local build of autometrics-dev/autometrics-go/cmd/autometrics
2-
autometrics
2+
/autometrics
33

44
# Local build of the example server
5-
web-server
5+
/web-server

Diff for: examples/web/cmd/main.go

+4-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"time"
1010

1111
"github.com/autometrics-dev/autometrics-go/pkg/autometrics"
12-
"github.com/prometheus/client_golang/prometheus"
1312
"github.com/prometheus/client_golang/prometheus/promhttp"
1413
)
1514

@@ -20,14 +19,11 @@ import (
2019
func main() {
2120
rand.Seed(time.Now().UnixNano())
2221

23-
reg := prometheus.NewRegistry()
24-
autometrics.Init(reg)
22+
autometrics.Init(nil)
2523

2624
http.HandleFunc("/", errorable(indexHandler))
2725
http.HandleFunc("/random-error", errorable(randomErrorHandler))
28-
29-
// Expose /metrics HTTP endpoint using the created custom registry.
30-
http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg}))
26+
http.Handle("/metrics", promhttp.Handler())
3127

3228
log.Println("binding on http://localhost:62086")
3329
log.Fatal(http.ListenAndServe(":62086", nil))
@@ -59,6 +55,7 @@ func main() {
5955
//
6056
//autometrics:doc
6157
func indexHandler(w http.ResponseWriter, _ *http.Request) (err error) {
58+
defer autometrics.Instrument(autometrics.PreInstrument(), &err) //autometrics:defer-statement
6259
_, err = fmt.Fprintf(w, "Hello, World!\n")
6360
return
6461
}
@@ -91,6 +88,7 @@ var handlerError = errors.New("failed to handle request")
9188
//
9289
//autometrics:doc
9390
func randomErrorHandler(w http.ResponseWriter, _ *http.Request) (err error) {
91+
defer autometrics.Instrument(autometrics.PreInstrument(), &err) //autometrics:defer-statement
9492
isErr := rand.Intn(2) == 0
9593

9694
if isErr {

Diff for: internal/doc/generate.go

+36-8
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ import (
1010
)
1111

1212
type AutometricsLinkCommentGenerator interface {
13-
GenerateAutometricsComment(funcName string) []string
13+
GenerateAutometricsComment(funcName, moduleName string) []string
1414
}
1515

1616
// TransformFile takes a file path and generates the documentation
1717
// for the `//autometrics:doc` functions.
1818
//
19-
// It also replaces the file in place
20-
func TransformFile(path string, generator AutometricsLinkCommentGenerator) error {
19+
// It also replaces the file in place.
20+
func TransformFile(path, moduleName string, generator AutometricsLinkCommentGenerator) error {
2121
cwd, err := os.Getwd()
2222
if err != nil {
2323
return fmt.Errorf("error getting a working directory: %w", err)
@@ -27,6 +27,7 @@ func TransformFile(path string, generator AutometricsLinkCommentGenerator) error
2727
if err != nil {
2828
return fmt.Errorf("error reading file information from %s: %w", path, err)
2929
}
30+
3031
permissions := info.Mode()
3132

3233
sourceBytes, err := os.ReadFile(path)
@@ -40,7 +41,8 @@ func TransformFile(path string, generator AutometricsLinkCommentGenerator) error
4041
}
4142

4243
sourceCode := string(sourceBytes)
43-
transformedSource, err := GenerateDocumentation(sourceCode, generator)
44+
45+
transformedSource, err := GenerateDocumentation(sourceCode, moduleName, generator)
4446
if err != nil {
4547
return fmt.Errorf("error generating documentation: %w", err)
4648
}
@@ -57,7 +59,7 @@ func TransformFile(path string, generator AutometricsLinkCommentGenerator) error
5759
// the documentation for the `//autometrics:doc` functions.
5860
//
5961
// It returns the new source code with augmented documentation.
60-
func GenerateDocumentation(sourceCode string, generator AutometricsLinkCommentGenerator) (string, error) {
62+
func GenerateDocumentation(sourceCode, moduleName string, generator AutometricsLinkCommentGenerator) (string, error) {
6163
fileTree, err := decorator.Parse(sourceCode)
6264
if err != nil {
6365
return "", fmt.Errorf("error parsing source code: %w", err)
@@ -83,7 +85,7 @@ func GenerateDocumentation(sourceCode string, generator AutometricsLinkCommentGe
8385
// Insert new autometrics comment
8486
listIndex := hasAutometricsDocDirective(docComments)
8587
if listIndex >= 0 {
86-
autometricsComment := generateAutometricsComment(x.Name.Name, generator)
88+
autometricsComment := generateAutometricsComment(x.Name.Name, moduleName, generator)
8789
x.Decorations().Start.Replace(insertComments(docComments, listIndex, autometricsComment)...)
8890
}
8991
}
@@ -131,17 +133,18 @@ func autometricsDocEndDirective(commentGroup []string) int {
131133
return -1
132134
}
133135

134-
func generateAutometricsComment(funcName string, generator AutometricsLinkCommentGenerator) []string {
136+
func generateAutometricsComment(funcName, moduleName string, generator AutometricsLinkCommentGenerator) []string {
135137
var ret []string
136138
ret = append(ret, "//")
137139
ret = append(ret, "// autometrics:doc-start DO NOT EDIT")
138140
ret = append(ret, "//")
139141
ret = append(ret, "// # Autometrics")
140142
ret = append(ret, "//")
141-
ret = append(ret, generator.GenerateAutometricsComment(funcName)...)
143+
ret = append(ret, generator.GenerateAutometricsComment(funcName, moduleName)...)
142144
ret = append(ret, "//")
143145
ret = append(ret, "// autometrics:doc-end DO NOT EDIT")
144146
ret = append(ret, "//")
147+
145148
return ret
146149
}
147150

@@ -161,3 +164,28 @@ func insertComments(inputArray []string, index int, values []string) []string {
161164

162165
return inputArray
163166
}
167+
168+
// errorReturnValueName returns the name of the error return value if it exists.
169+
func errorReturnValueName(funcNode *dst.FuncDecl) (string, error) {
170+
returnValues := funcNode.Type.Results
171+
if returnValues == nil || returnValues.List == nil {
172+
return "", nil
173+
}
174+
175+
for _, field := range returnValues.List {
176+
fieldType := field.Type
177+
if spec, ok := fieldType.(*dst.Ident); ok {
178+
if spec.Name == "error" {
179+
// Assuming that the `error` type has 0 or 1 name before it.
180+
if field.Names == nil {
181+
return "", nil
182+
} else if len(field.Names) > 1 {
183+
return "", fmt.Errorf("expecting a single named `error` return value, got %d instead.", len(field.Names))
184+
}
185+
return field.Names[0].Name, nil
186+
}
187+
}
188+
}
189+
190+
return "", nil
191+
}

0 commit comments

Comments
 (0)