From 834942782ca864c32c1b8bb90abfb167a7cd2355 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Mon, 9 Sep 2024 15:43:51 +0200 Subject: [PATCH 1/4] Added intakeV2 context.http.request.body field --- input/elasticapm/docs/spec/v2/span.json | 7 +++++++ input/elasticapm/internal/modeldecoder/v2/decoder.go | 9 +++++++-- input/elasticapm/internal/modeldecoder/v2/model.go | 2 ++ .../internal/modeldecoder/v2/model_generated.go | 3 ++- .../elasticapm/internal/modeldecoder/v2/span_test.go | 11 ++++++++++- 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/input/elasticapm/docs/spec/v2/span.json b/input/elasticapm/docs/spec/v2/span.json index e86da9a6..c8f5f7d4 100644 --- a/input/elasticapm/docs/spec/v2/span.json +++ b/input/elasticapm/docs/spec/v2/span.json @@ -188,6 +188,13 @@ "object" ], "properties": { + "body": { + "description": "The http request body as a string", + "type": [ + "null", + "string" + ] + }, "id": { "description": "ID holds the unique identifier for the http request.", "type": [ diff --git a/input/elasticapm/internal/modeldecoder/v2/decoder.go b/input/elasticapm/internal/modeldecoder/v2/decoder.go index b3a3faad..dacc1e14 100644 --- a/input/elasticapm/internal/modeldecoder/v2/decoder.go +++ b/input/elasticapm/internal/modeldecoder/v2/decoder.go @@ -1071,14 +1071,19 @@ func mapToSpanModel(from *span, event *modelpb.APMEvent) { } event.Http.Request.Method = from.Context.HTTP.Method.Val } - if from.Context.HTTP.Request.ID.IsSet() { + if from.Context.HTTP.Request.IsSet() { if event.Http == nil { event.Http = &modelpb.HTTP{} } if event.Http.Request == nil { event.Http.Request = &modelpb.HTTPRequest{} } - event.Http.Request.Id = from.Context.HTTP.Request.ID.Val + if from.Context.HTTP.Request.ID.IsSet() { + event.Http.Request.Id = from.Context.HTTP.Request.ID.Val + } + if from.Context.HTTP.Request.Body.IsSet() { + event.Http.Request.Body = modeldecoderutil.ToValue(from.Context.HTTP.Request.Body.Val) + } } if from.Context.HTTP.Response.IsSet() { if event.Http == nil { diff --git a/input/elasticapm/internal/modeldecoder/v2/model.go b/input/elasticapm/internal/modeldecoder/v2/model.go index 46a9b99e..2ac2c2d9 100644 --- a/input/elasticapm/internal/modeldecoder/v2/model.go +++ b/input/elasticapm/internal/modeldecoder/v2/model.go @@ -845,6 +845,8 @@ type spanContextHTTP struct { type spanContextHTTPRequest struct { // ID holds the unique identifier for the http request. ID nullable.String `json:"id"` + // The http request body as a string + Body nullable.String `json:"body"` } type spanContextHTTPResponse struct { diff --git a/input/elasticapm/internal/modeldecoder/v2/model_generated.go b/input/elasticapm/internal/modeldecoder/v2/model_generated.go index f5b571f7..a1019fd5 100644 --- a/input/elasticapm/internal/modeldecoder/v2/model_generated.go +++ b/input/elasticapm/internal/modeldecoder/v2/model_generated.go @@ -2500,11 +2500,12 @@ func (val *spanContextHTTP) processNestedSource() error { } func (val *spanContextHTTPRequest) IsSet() bool { - return val.ID.IsSet() + return val.ID.IsSet() || val.Body.IsSet() } func (val *spanContextHTTPRequest) Reset() { val.ID.Reset() + val.Body.Reset() } func (val *spanContextHTTPRequest) validate() error { diff --git a/input/elasticapm/internal/modeldecoder/v2/span_test.go b/input/elasticapm/internal/modeldecoder/v2/span_test.go index 57df65d7..064ba208 100644 --- a/input/elasticapm/internal/modeldecoder/v2/span_test.go +++ b/input/elasticapm/internal/modeldecoder/v2/span_test.go @@ -19,6 +19,7 @@ package v2 import ( "encoding/json" + "google.golang.org/protobuf/types/known/structpb" "net/http" "strconv" "strings" @@ -258,7 +259,7 @@ func TestDecodeMapToSpanModel(t *testing.T) { } }) - t.Run("http-request", func(t *testing.T) { + t.Run("http-request-id", func(t *testing.T) { var input span input.Context.HTTP.Request.ID.Set("some-request-id") var out modelpb.APMEvent @@ -266,6 +267,14 @@ func TestDecodeMapToSpanModel(t *testing.T) { assert.Equal(t, "some-request-id", out.Http.Request.Id) }) + t.Run("http-request-body", func(t *testing.T) { + var input span + input.Context.HTTP.Request.Body.Set("some-request-body") + var out modelpb.APMEvent + mapToSpanModel(&input, &out) + assert.Equal(t, structpb.NewStringValue("some-request-body"), out.Http.Request.Body) + }) + t.Run("http-headers", func(t *testing.T) { var input span input.Context.HTTP.Response.Headers.Set(http.Header{"a": []string{"b", "c"}}) From cd1c3a0faf06eccd981f53daafbdac26fec963c7 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Wed, 11 Sep 2024 10:21:13 +0200 Subject: [PATCH 2/4] Added body to existing modeljson test --- model/modeljson/http.pb.json_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/model/modeljson/http.pb.json_test.go b/model/modeljson/http.pb.json_test.go index 91a9e9d8..38acc1a4 100644 --- a/model/modeljson/http.pb.json_test.go +++ b/model/modeljson/http.pb.json_test.go @@ -18,6 +18,7 @@ package modeljson import ( + "google.golang.org/protobuf/types/known/structpb" "testing" modeljson "github.com/elastic/apm-data/model/modeljson/internal" @@ -51,6 +52,7 @@ func TestHTTPToModelJSON(t *testing.T) { Id: "id", Method: "method", Referrer: "referrer", + Body: structpb.NewStringValue("request-body"), }, }, expected: &modeljson.HTTP{ @@ -61,6 +63,9 @@ func TestHTTPToModelJSON(t *testing.T) { ID: "id", Method: "method", Referrer: "referrer", + Body: &modeljson.HTTPRequestBody{ + Original: "request-body", + }, }, }, }, From 2d29b67c28abe801cafff942a17a9fcd5e94ea95 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Wed, 18 Dec 2024 10:46:06 +0100 Subject: [PATCH 3/4] Switch body from string to any value (string or dictionary) --- input/elasticapm/docs/spec/v2/span.json | 6 +----- input/elasticapm/internal/modeldecoder/v2/model.go | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/input/elasticapm/docs/spec/v2/span.json b/input/elasticapm/docs/spec/v2/span.json index c8f5f7d4..14eea1b1 100644 --- a/input/elasticapm/docs/spec/v2/span.json +++ b/input/elasticapm/docs/spec/v2/span.json @@ -189,11 +189,7 @@ ], "properties": { "body": { - "description": "The http request body as a string", - "type": [ - "null", - "string" - ] + "description": "The http request body usually as a string, but may be a dictionary for multipart/form-data content" }, "id": { "description": "ID holds the unique identifier for the http request.", diff --git a/input/elasticapm/internal/modeldecoder/v2/model.go b/input/elasticapm/internal/modeldecoder/v2/model.go index 2ac2c2d9..229fd1c2 100644 --- a/input/elasticapm/internal/modeldecoder/v2/model.go +++ b/input/elasticapm/internal/modeldecoder/v2/model.go @@ -845,8 +845,8 @@ type spanContextHTTP struct { type spanContextHTTPRequest struct { // ID holds the unique identifier for the http request. ID nullable.String `json:"id"` - // The http request body as a string - Body nullable.String `json:"body"` + // The http request body usually as a string, but may be a dictionary for multipart/form-data content + Body nullable.Interface `json:"body"` } type spanContextHTTPResponse struct { From 345410efe4e28ba525b58954e650f2364c2fa672 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Wed, 18 Dec 2024 10:53:20 +0100 Subject: [PATCH 4/4] Switch field order for lint --- input/elasticapm/internal/modeldecoder/v2/model.go | 4 ++-- input/elasticapm/internal/modeldecoder/v2/model_generated.go | 4 ++-- input/elasticapm/internal/modeldecoder/v2/span_test.go | 3 ++- model/modeljson/http.pb.json_test.go | 3 ++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/input/elasticapm/internal/modeldecoder/v2/model.go b/input/elasticapm/internal/modeldecoder/v2/model.go index 229fd1c2..72c162ab 100644 --- a/input/elasticapm/internal/modeldecoder/v2/model.go +++ b/input/elasticapm/internal/modeldecoder/v2/model.go @@ -843,10 +843,10 @@ type spanContextHTTP struct { } type spanContextHTTPRequest struct { - // ID holds the unique identifier for the http request. - ID nullable.String `json:"id"` // The http request body usually as a string, but may be a dictionary for multipart/form-data content Body nullable.Interface `json:"body"` + // ID holds the unique identifier for the http request. + ID nullable.String `json:"id"` } type spanContextHTTPResponse struct { diff --git a/input/elasticapm/internal/modeldecoder/v2/model_generated.go b/input/elasticapm/internal/modeldecoder/v2/model_generated.go index a1019fd5..9d761090 100644 --- a/input/elasticapm/internal/modeldecoder/v2/model_generated.go +++ b/input/elasticapm/internal/modeldecoder/v2/model_generated.go @@ -2500,12 +2500,12 @@ func (val *spanContextHTTP) processNestedSource() error { } func (val *spanContextHTTPRequest) IsSet() bool { - return val.ID.IsSet() || val.Body.IsSet() + return val.Body.IsSet() || val.ID.IsSet() } func (val *spanContextHTTPRequest) Reset() { - val.ID.Reset() val.Body.Reset() + val.ID.Reset() } func (val *spanContextHTTPRequest) validate() error { diff --git a/input/elasticapm/internal/modeldecoder/v2/span_test.go b/input/elasticapm/internal/modeldecoder/v2/span_test.go index 064ba208..b85b72f2 100644 --- a/input/elasticapm/internal/modeldecoder/v2/span_test.go +++ b/input/elasticapm/internal/modeldecoder/v2/span_test.go @@ -19,13 +19,14 @@ package v2 import ( "encoding/json" - "google.golang.org/protobuf/types/known/structpb" "net/http" "strconv" "strings" "testing" "time" + "google.golang.org/protobuf/types/known/structpb" + "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/model/modeljson/http.pb.json_test.go b/model/modeljson/http.pb.json_test.go index 38acc1a4..bca3c9ee 100644 --- a/model/modeljson/http.pb.json_test.go +++ b/model/modeljson/http.pb.json_test.go @@ -18,9 +18,10 @@ package modeljson import ( - "google.golang.org/protobuf/types/known/structpb" "testing" + "google.golang.org/protobuf/types/known/structpb" + modeljson "github.com/elastic/apm-data/model/modeljson/internal" "github.com/elastic/apm-data/model/modelpb" "github.com/google/go-cmp/cmp"