-
Notifications
You must be signed in to change notification settings - Fork 0
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
30050ab
commit 165b098
Showing
6 changed files
with
378 additions
and
199 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package stacktrace | ||
|
||
import ( | ||
"fmt" | ||
"log/slog" | ||
) | ||
|
||
func ErrToSlogAttr(err error, opts ...TracesOpt) slog.Attr { | ||
if err == nil { | ||
return slog.Attr{} | ||
} | ||
|
||
st, ok := Unwrap(err) | ||
if !ok { | ||
return slog.String("error", err.Error()) | ||
} | ||
|
||
if st == nil { | ||
return slog.String("error", "nil stacktrace") | ||
} | ||
|
||
tracebacks := st.GetTraces(opts...) | ||
|
||
tracebackAttrs := make([]slog.Attr, 0, len(tracebacks)) | ||
for traceIndex := range tracebacks { | ||
traceback := tracebacks[traceIndex] | ||
stackAttrs := make([]slog.Attr, 0, len(traceback.Stack)) | ||
for stackIndex := range traceback.Stack { | ||
stack := traceback.Stack[stackIndex] | ||
key := fmt.Sprintf("%d", stackIndex) | ||
stackAttr := slog.Group( | ||
key, | ||
slog.String("type", string(stack.Type)), | ||
slog.String("severity", string(stack.Severity)), | ||
slog.String("position", stack.LinePos), | ||
slog.String("message", stack.Message), | ||
) | ||
stackAttrs = append(stackAttrs, stackAttr) | ||
} | ||
tracebackAttr := slog.Group(fmt.Sprintf("%d", traceIndex), "stack", stackAttrs) | ||
tracebackAttrs = append(tracebackAttrs, tracebackAttr) | ||
} | ||
|
||
return slog.Group("tracebacks", "traces", tracebackAttrs) | ||
} |
This file was deleted.
Oops, something went wrong.
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,96 @@ | ||
package stacktrace | ||
|
||
type TracesOpt interface { | ||
Apply(o *TracesOptions) | ||
} | ||
|
||
type TracesOptions struct { | ||
// EnsureDuplicates ensures that duplicates are not printed | ||
EnsureDuplicates bool | ||
dupLocs map[string]struct{} | ||
} | ||
|
||
func NewTracesOptions() *TracesOptions { | ||
opts := &TracesOptions{ | ||
EnsureDuplicates: false, | ||
dupLocs: make(map[string]struct{}), | ||
} | ||
return opts | ||
} | ||
|
||
type ensureDuplicatesOpt struct{} | ||
|
||
func (ensureDuplicatesOpt) Apply(o *TracesOptions) { | ||
o.EnsureDuplicates = true | ||
} | ||
|
||
func WithEnsureDuplicates() TracesOpt { | ||
return &ensureDuplicatesOpt{} | ||
} | ||
|
||
type Stack struct { | ||
LinePos string | ||
Severity Severity | ||
Message string | ||
Type Type | ||
} | ||
|
||
func NewStack() *Stack { | ||
return &Stack{} | ||
} | ||
|
||
type Trace struct { | ||
Stack []Stack | ||
} | ||
|
||
func NewTrace() *Trace { | ||
return &Trace{Stack: make([]Stack, 0)} | ||
} | ||
|
||
func (st *StackTrace) getTraces(opts *TracesOptions) []Trace { | ||
traces := make([]Trace, 0) | ||
|
||
tracesWithList := func() []Trace { | ||
for _, elem := range st.List { | ||
elemTraces := elem.getTraces(opts) | ||
traces = append(traces, elemTraces...) | ||
} | ||
return traces | ||
} | ||
|
||
trace := NewTrace() | ||
stack := NewStack() | ||
stack.LinePos = st.GetLocWithPos() | ||
stack.Severity = st.Severity | ||
stack.Message = st.FullMessageWithInfo() | ||
stack.Type = st.Type | ||
|
||
if _, ok := opts.dupLocs[stack.LinePos]; ok { | ||
return tracesWithList() | ||
} | ||
|
||
trace.Stack = append(trace.Stack, *stack) | ||
if st.Wrapped != nil { | ||
wrappedTraces := st.Wrapped.getTraces(opts) | ||
if len(wrappedTraces) == 0 { | ||
return tracesWithList() | ||
} | ||
for i := range wrappedTraces { | ||
trace.Stack = append(trace.Stack, wrappedTraces[i].Stack...) | ||
} | ||
} else if opts.EnsureDuplicates { | ||
opts.dupLocs[stack.LinePos] = struct{}{} | ||
} | ||
|
||
traces = append(traces, *trace) | ||
|
||
return tracesWithList() | ||
} | ||
|
||
func (st *StackTrace) GetTraces(opts ...TracesOpt) []Trace { | ||
o := NewTracesOptions() | ||
for _, opt := range opts { | ||
opt.Apply(o) | ||
} | ||
return st.getTraces(o) | ||
} |
Oops, something went wrong.