-
Notifications
You must be signed in to change notification settings - Fork 0
/
run.go
80 lines (63 loc) · 1.34 KB
/
run.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package xo
import (
"context"
)
// Context is used by Run to track execution.
type Context struct {
context.Context
// The caller.
Caller Caller
// The span.
Span Span
}
// Rename will set a new name on the span.
func (c *Context) Rename(name string) {
c.Span.Rename(name)
}
// Attach will add the provided event to the span.
func (c *Context) Attach(event string, attributes M) {
c.Span.Attach(event, attributes)
}
// Log will attach a log event to the span.
func (c *Context) Log(format string, args ...interface{}) {
c.Span.Log(format, args...)
}
// Tag will add the provided attribute to the span.
func (c *Context) Tag(key string, value interface{}) {
c.Span.Tag(key, value)
}
// Run will run the provided function and automatically handle tracing, error
// handling and panic recovering.
func Run(ctx context.Context, fn func(ctx *Context) error) error {
// ensure context
if ctx == nil {
ctx = context.Background()
}
// get caller
caller := GetCaller(1, 0)
// trace
ctx, span := Trace(ctx, caller.Short)
defer span.End()
// wrap
xtc := &Context{
Caller: caller,
Context: ctx,
Span: span,
}
// yield
err := Catch(func() error {
return fn(xtc)
})
// check error
if err == nil {
return nil
}
// wrap error
err = &Err{
Err: err,
Caller: xtc.Caller,
}
// record error
span.Record(err)
return err
}