Skip to content

Commit

Permalink
capture code stacktrace (#184)
Browse files Browse the repository at this point in the history
* simple fix for #22

* add otel_stacktrace

* generate code for otel stacktrace

* copy otel stacktrace to internal model

* only relevant for spans not transactions

* add test

* go with a sub-object for span.code.stacktrace

* switch bach to a nested structure

* update generated code

* create nested object when reading pb

* fix rum tests

* fix otel tests

* fix intake v2 tests

* move to top-level field

* fix test and write to json doc

* add missing bits

* use untruncated value for code stacktrace

* remove code from span

---------

Co-authored-by: Silvia Mitter <silvia.mitter@elastic.co>
  • Loading branch information
SylvainJuge and simitt authored Jan 11, 2024
1 parent 4f1a8bc commit 1bb8a93
Show file tree
Hide file tree
Showing 16 changed files with 669 additions and 145 deletions.
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ protolint:
gomodtidy:
go mod tidy -v

generate:
generate_code:
go generate ./...

generate: generate_code update-licenses

fieldalignment:
go run golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@v0.4.0 -test=false $(shell go list ./... | grep -v modeldecoder/generator | grep -v test | grep -v model/modelpb)

Expand Down
2 changes: 2 additions & 0 deletions input/elasticapm/internal/modeldecoder/v2/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ func isUnmappedMetadataField(key string) bool {
"client.ip",
"client.port",
"cloud.origin",
"code",
"code.stacktrace",
"container.runtime",
"container.image_name",
"container.image_tag",
Expand Down
8 changes: 8 additions & 0 deletions input/otlp/traces.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const (
attributeUrlFull = "url.full"
attributeUserAgentOriginal = "user_agent.original"
attributeDbElasticsearchClusterName = "db.elasticsearch.cluster.name"
attributeStackTrace = "code.stacktrace" // semconv 1.24 or later
)

// ConsumeTracesResult contains the number of rejected spans and error message for partial success response.
Expand Down Expand Up @@ -754,6 +755,13 @@ func TranslateSpan(spanKind ptrace.SpanKind, attributes pcommon.Map, event *mode
httpURL = stringval
isHTTP = true

case attributeStackTrace:
if event.Code == nil {
event.Code = modelpb.CodeFromVTPool()
}
// stacktrace is expected to be large thus un-truncated value is needed
event.Code.Stacktrace = v.Str()

// miscellaneous
case "span.kind": // filter out
case semconv.AttributePeerService:
Expand Down
9 changes: 9 additions & 0 deletions input/otlp/traces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,15 @@ func TestGRPCTransactionFromNodejsSDK(t *testing.T) {
})
}

func TestSpanCodeStacktrace(t *testing.T) {
t.Run("code stacktrace", func(t *testing.T) {
event := transformSpanWithAttributes(t, map[string]interface{}{
"code.stacktrace": "stacktrace value",
})
assert.Equal(t, "stacktrace value", event.Code.Stacktrace)
})
}

func testJaegerLogs() []jaegermodel.Log {
return []jaegermodel.Log{{
// errors that can be converted to elastic errors
Expand Down
6 changes: 6 additions & 0 deletions model/modeljson/apmevent.pb.json.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,5 +248,11 @@ func MarshalAPMEvent(e *modelpb.APMEvent, w *fastjson.Writer) error {
}
}

if e.Code != nil {
doc.Code = &modeljson.Code{
Stacktrace: e.Code.Stacktrace,
}
}

return doc.MarshalFastJSON(w)
}
3 changes: 3 additions & 0 deletions model/modeljson/apmevent.pb.json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,5 +487,8 @@ func fullEvent(t testing.TB) *modelpb.APMEvent {
Duration: uint64(3 * time.Second),
Severity: 4,
},
Code: &modelpb.Code{
Stacktrace: "stacktrace",
},
}
}
1 change: 1 addition & 0 deletions model/modeljson/internal/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type Document struct {
Session *Session `json:"session,omitempty"`
Process *Process `json:"process,omitempty"`
Event *Event `json:"event,omitempty"`
Code *Code `json:"code,omitempty"`

Timestamp Time `json:"@timestamp"`
DataStream *DataStream `json:"data_stream,omitempty"`
Expand Down
16 changes: 16 additions & 0 deletions model/modeljson/internal/marshal_fastjson.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions model/modeljson/internal/span.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ type Span struct {
RepresentativeCount float64 `json:"representative_count,omitempty"`
}

type Code struct {
Stacktrace string `json:"stacktrace,omitempty"`
}

type SpanDestination struct {
Service SpanDestinationService `json:"service"`
}
Expand Down
1 change: 1 addition & 0 deletions model/modeljson/span.pb.json.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func SpanModelJSON(e *modelpb.Span, out *modeljson.Span) {
}
}
}

if n := len(e.Links); n > 0 {
out.Links = make([]modeljson.SpanLink, n)
for i, link := range e.Links {
Expand Down
303 changes: 159 additions & 144 deletions model/modelpb/apmevent.pb.go

Large diffs are not rendered by default.

54 changes: 54 additions & 0 deletions model/modelpb/apmevent_vtproto.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

162 changes: 162 additions & 0 deletions model/modelpb/code.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 1bb8a93

Please sign in to comment.