diff --git a/apmpackage/apm/docs/README.md b/apmpackage/apm/docs/README.md index 539d96d86c9..5f5c6dedfe1 100644 --- a/apmpackage/apm/docs/README.md +++ b/apmpackage/apm/docs/README.md @@ -409,7 +409,9 @@ Traces are written to `traces-apm.*` indices. "transaction": { "id": "945254c567a5417e" }, - "url.original": "http://localhost:8000" + "url": { + "original": "http://localhost:8000" + } } ``` diff --git a/beater/test_approved_es_documents/TestPublishIntegrationErrors.approved.json b/beater/test_approved_es_documents/TestPublishIntegrationErrors.approved.json index f113cf4de01..02357c387cb 100644 --- a/beater/test_approved_es_documents/TestPublishIntegrationErrors.approved.json +++ b/beater/test_approved_es_documents/TestPublishIntegrationErrors.approved.json @@ -214,10 +214,6 @@ } } ] - }, - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" } }, "host": { diff --git a/beater/test_approved_es_documents/TestPublishIntegrationEvents.approved.json b/beater/test_approved_es_documents/TestPublishIntegrationEvents.approved.json index 37bbf07c909..f56f3d5872d 100644 --- a/beater/test_approved_es_documents/TestPublishIntegrationEvents.approved.json +++ b/beater/test_approved_es_documents/TestPublishIntegrationEvents.approved.json @@ -447,7 +447,9 @@ "transaction": { "id": "1234567890987654" }, - "url.original": "http://localhost:8000" + "url": { + "original": "http://localhost:8000" + } }, { "@timestamp": "2019-10-21T11:30:44.929Z", diff --git a/beater/test_approved_es_documents/TestPublishIntegrationSpans.approved.json b/beater/test_approved_es_documents/TestPublishIntegrationSpans.approved.json index 2a45b5e24b7..e775ee4acc3 100644 --- a/beater/test_approved_es_documents/TestPublishIntegrationSpans.approved.json +++ b/beater/test_approved_es_documents/TestPublishIntegrationSpans.approved.json @@ -745,7 +745,9 @@ "trace": { "id": "abcdef0123456789abcdef9876543210" }, - "url.original": "http://localhost:8000", + "url": { + "original": "http://localhost:8000" + }, "user": { "domain": "ldap://abc", "email": "s@test.com", diff --git a/beater/test_approved_es_documents/TestPublishIntegrationTransactions.approved.json b/beater/test_approved_es_documents/TestPublishIntegrationTransactions.approved.json index b2123dd2b04..70463ff4615 100644 --- a/beater/test_approved_es_documents/TestPublishIntegrationTransactions.approved.json +++ b/beater/test_approved_es_documents/TestPublishIntegrationTransactions.approved.json @@ -323,10 +323,6 @@ }, "id": "4340a8e0df1906ecbfa9", "name": "GET /api/types", - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" - }, "result": "success", "sampled": true, "span_count": { diff --git a/changelogs/head.asciidoc b/changelogs/head.asciidoc index 0e380441e1b..7e3fcd27b8c 100644 --- a/changelogs/head.asciidoc +++ b/changelogs/head.asciidoc @@ -6,6 +6,7 @@ https://github.com/elastic/apm-server/compare/7.13\...master[View commits] [float] ==== Breaking Changes - `network.connection_type` is now `network.connection.type` {pull}5671[5671] +- `transaction.page` and `error.page` no longer recorded {pull}5872[5872] [float] ==== Bug fixes diff --git a/docs/data/elasticsearch/generated/errors.json b/docs/data/elasticsearch/generated/errors.json index 2a722df6246..f04e00a6ca1 100644 --- a/docs/data/elasticsearch/generated/errors.json +++ b/docs/data/elasticsearch/generated/errors.json @@ -263,10 +263,6 @@ } } ] - }, - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" } }, "event": { diff --git a/docs/data/elasticsearch/generated/spans.json b/docs/data/elasticsearch/generated/spans.json index ab333394f22..bf631776f5f 100644 --- a/docs/data/elasticsearch/generated/spans.json +++ b/docs/data/elasticsearch/generated/spans.json @@ -115,7 +115,9 @@ "transaction": { "id": "945254c567a5417e" }, - "url.original": "http://localhost:8000" + "url": { + "original": "http://localhost:8000" + } }, { "@timestamp": "2017-05-30T18:53:42.281Z", diff --git a/docs/data/elasticsearch/generated/transactions.json b/docs/data/elasticsearch/generated/transactions.json index 842c7c8ca78..87b201ba719 100644 --- a/docs/data/elasticsearch/generated/transactions.json +++ b/docs/data/elasticsearch/generated/transactions.json @@ -467,10 +467,6 @@ } }, "name": "GET /api/types", - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" - }, "result": "success", "sampled": true, "span_count": { diff --git a/model/apmevent.go b/model/apmevent.go index 40ffb9c514c..e4216b95ac8 100644 --- a/model/apmevent.go +++ b/model/apmevent.go @@ -36,6 +36,7 @@ type APMEvent struct { // in standalone mode. DataStream DataStream + Event Event Agent Agent Container Container Kubernetes Kubernetes @@ -47,6 +48,8 @@ type APMEvent struct { Client Client Cloud Cloud Network Network + Session Session + URL URL // Timestamp holds the event timestamp. Timestamp time.Time @@ -67,7 +70,7 @@ func (e *APMEvent) appendBeatEvent(ctx context.Context, out []beat.Event) []beat case e.Transaction != nil: event.Fields = e.Transaction.fields() case e.Span != nil: - event.Fields = e.Span.fields() + event.Fields = e.Span.fields(e) case e.Metricset != nil: event.Fields = e.Metricset.fields() case e.Error != nil: @@ -85,7 +88,7 @@ func (e *APMEvent) appendBeatEvent(ctx context.Context, out []beat.Event) []beat event.Fields["timestamp"] = utility.TimeAsMicros(e.Timestamp) } - // Set fields common to all events. + // Set top-level field sets. fields := (*mapStr)(&event.Fields) event.Timestamp = e.Timestamp e.DataStream.setFields(fields) @@ -108,5 +111,8 @@ func (e *APMEvent) appendBeatEvent(ctx context.Context, out []beat.Event) []beat fields.maybeSetMapStr("cloud", e.Cloud.fields()) fields.maybeSetMapStr("network", e.Network.fields()) fields.maybeSetMapStr("labels", sanitizeLabels(e.Labels)) + fields.maybeSetMapStr("event", e.Event.fields()) + fields.maybeSetMapStr("url", e.URL.fields()) + fields.maybeSetMapStr("session", e.Session.fields()) return append(out, event) } diff --git a/model/apmevent_test.go b/model/apmevent_test.go index ad7628b8139..6cf02197a96 100644 --- a/model/apmevent_test.go +++ b/model/apmevent_test.go @@ -37,6 +37,7 @@ func TestAPMEventFields(t *testing.T) { uid := "12321" mail := "user@email.com" agentName := "elastic-node" + outcome := "success" for _, test := range []struct { input APMEvent @@ -61,6 +62,9 @@ func TestAPMEventFields(t *testing.T) { Client: Client{Domain: "client.domain"}, Process: Process{Pid: pid}, User: User{ID: uid, Email: mail}, + Event: Event{Outcome: outcome}, + Session: Session{ID: "session_id"}, + URL: URL{Original: "url"}, Labels: common.MapStr{"a": "b", "c": 123}, Transaction: &Transaction{}, Timestamp: time.Date(2019, 1, 3, 15, 17, 4, 908.596*1e6, time.FixedZone("+0100", 3600)), @@ -75,16 +79,18 @@ func TestAPMEventFields(t *testing.T) { "name": "myservice", "node": common.MapStr{"name": serviceNodeName}, }, - "user": common.MapStr{"id": "12321", "email": "user@email.com"}, - "client": common.MapStr{"domain": "client.domain"}, - "source": common.MapStr{"domain": "client.domain"}, + "user": common.MapStr{"id": "12321", "email": "user@email.com"}, + "client": common.MapStr{"domain": "client.domain"}, + "source": common.MapStr{"domain": "client.domain"}, + "event": common.MapStr{"outcome": outcome}, + "session": common.MapStr{"id": "session_id"}, + "url": common.MapStr{"original": "url"}, "labels": common.MapStr{ "a": "b", "c": 123, }, // fields related to APMEvent.Transaction - "event": common.MapStr{"outcome": ""}, "processor": common.MapStr{ "name": "transaction", "event": "transaction", diff --git a/model/context.go b/model/context.go index 711e6ff77b5..b61f8185e95 100644 --- a/model/context.go +++ b/model/context.go @@ -21,26 +21,6 @@ import ( "github.com/elastic/beats/v7/libbeat/common" ) -// Page consists of URL and referer -type Page struct { - URL *URL - Referer string -} - -// Fields returns common.MapStr holding transformed data for attribute page. -func (page *Page) Fields() common.MapStr { - if page == nil { - return nil - } - var fields mapStr - if page.URL != nil { - // Remove in 8.0 - fields.set("url", page.URL.Original) - } - fields.maybeSetString("referer", page.Referer) - return common.MapStr(fields) -} - // customFields transforms in, returning a copy with sanitized keys, // suitable for storing as "custom" in transaction and error documents. func customFields(in common.MapStr) common.MapStr { diff --git a/model/error.go b/model/error.go index ea807f51c95..1ef6b47bf0d 100644 --- a/model/error.go +++ b/model/error.go @@ -44,9 +44,7 @@ type Error struct { GroupingKey string Culprit string - Page *Page HTTP *HTTP - URL *URL Custom common.MapStr Exception *Exception @@ -92,7 +90,6 @@ func (e *Error) fields() common.MapStr { if e.HTTP != nil { fields.maybeSetMapStr("http", e.HTTP.transactionTopLevelFields()) } - fields.maybeSetMapStr("url", e.URL.Fields()) if e.Experimental != nil { fields.set("experimental", e.Experimental) } @@ -113,7 +110,6 @@ func (e *Error) fields() common.MapStr { var errorFields mapStr errorFields.maybeSetString("id", e.ID) - errorFields.maybeSetMapStr("page", e.Page.Fields()) exceptionChain := flattenExceptionTree(e.Exception) if exception := e.exceptionFields(exceptionChain); len(exception) > 0 { errorFields.set("exception", exception) diff --git a/model/error_test.go b/model/error_test.go index 7bc21b2bd80..8187576c592 100644 --- a/model/error_test.go +++ b/model/error_test.go @@ -193,38 +193,3 @@ func TestEventFields(t *testing.T) { }) } } - -func TestErrorTransformPage(t *testing.T) { - id := "123" - urlExample := "http://example.com/path" - - tests := []struct { - Error Error - Output common.MapStr - Msg string - }{ - { - Error: Error{ - ID: id, - URL: ParseURL("https://localhost:8200/", "", ""), - Page: &Page{ - URL: ParseURL(urlExample, "", ""), - }, - }, - Output: common.MapStr{ - "domain": "localhost", - "full": "https://localhost:8200/", - "original": "https://localhost:8200/", - "path": "/", - "port": 8200, - "scheme": "https", - }, - Msg: "With Page URL and Request URL", - }, - } - - for idx, test := range tests { - fields := test.Error.fields() - assert.Equal(t, test.Output, fields["url"], fmt.Sprintf("Failed at idx %v; %s", idx, test.Msg)) - } -} diff --git a/model/event.go b/model/event.go new file mode 100644 index 00000000000..15d8fdd5665 --- /dev/null +++ b/model/event.go @@ -0,0 +1,36 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package model + +import ( + "github.com/elastic/beats/v7/libbeat/common" +) + +// Event holds information about an event, in ECS terms. +// +// https://www.elastic.co/guide/en/ecs/current/ecs-event.html +type Event struct { + // Outcome holds the event outcome: "success", "failure", or "unknown". + Outcome string +} + +func (e *Event) fields() common.MapStr { + var fields mapStr + fields.maybeSetString("outcome", e.Outcome) + return common.MapStr(fields) +} diff --git a/model/metricset.go b/model/metricset.go index c0421f1106f..6a44b633605 100644 --- a/model/metricset.go +++ b/model/metricset.go @@ -50,10 +50,6 @@ const ( // Metricset describes a set of metrics and associated metadata. type Metricset struct { - // Event holds information about the event category with which the - // metrics are associated. - Event MetricsetEventCategorization - // Transaction holds information about the transaction group with // which the metrics are associated. Transaction MetricsetTransaction @@ -115,16 +111,6 @@ type MetricsetSample struct { Counts []int64 } -// MetricsetEventCategorization holds ECS Event Categorization fields -// for inclusion in metrics. Typically these fields will have been -// included in the metric aggregation logic. -// -// See https://www.elastic.co/guide/en/ecs/current/ecs-category-field-values-reference.html -type MetricsetEventCategorization struct { - // Outcome holds the event outcome: "success", "failure", or "unknown". - Outcome string -} - // MetricsetTransaction provides enough information to connect a metricset to the related kind of transactions. type MetricsetTransaction struct { // Name holds the transaction name: "GET /foo", etc. @@ -160,7 +146,6 @@ func (me *Metricset) fields() common.MapStr { var fields mapStr fields.set("processor", metricsetProcessorEntry) - fields.maybeSetMapStr(metricsetEventKey, me.Event.fields()) fields.maybeSetMapStr(metricsetTransactionKey, me.Transaction.fields()) fields.maybeSetMapStr(metricsetSpanKey, me.Span.fields()) if me.TimeseriesInstanceID != "" { @@ -184,12 +169,6 @@ func (me *Metricset) fields() common.MapStr { return common.MapStr(fields) } -func (e *MetricsetEventCategorization) fields() common.MapStr { - var fields mapStr - fields.maybeSetString("outcome", e.Outcome) - return common.MapStr(fields) -} - func (t *MetricsetTransaction) fields() common.MapStr { var fields mapStr fields.maybeSetString("type", t.Type) diff --git a/model/metricset_test.go b/model/metricset_test.go index 987954010f4..e72736dc86b 100644 --- a/model/metricset_test.go +++ b/model/metricset_test.go @@ -38,8 +38,6 @@ func TestMetricset(t *testing.T) { spType = "db" spSubtype = "sql" - - eventOutcome = "success" ) tests := []struct { @@ -96,7 +94,6 @@ func TestMetricset(t *testing.T) { }, { Metricset: &Metricset{ - Event: MetricsetEventCategorization{Outcome: eventOutcome}, Transaction: MetricsetTransaction{ Type: trType, Name: trName, @@ -116,7 +113,6 @@ func TestMetricset(t *testing.T) { }, Output: common.MapStr{ "processor": common.MapStr{"event": "metric", "name": "metric"}, - "event": common.MapStr{"outcome": eventOutcome}, "timeseries": common.MapStr{"instance": "foo"}, "transaction": common.MapStr{ "type": trType, diff --git a/model/modeldecoder/rumv3/decoder.go b/model/modeldecoder/rumv3/decoder.go index 5f121b506d4..1b6ab74e44a 100644 --- a/model/modeldecoder/rumv3/decoder.go +++ b/model/modeldecoder/rumv3/decoder.go @@ -220,17 +220,17 @@ func mapToErrorModel(from *errorEvent, event *model.APMEvent) { mapToResponseModel(from.Context.Response, out.HTTP.Response) } if from.Context.Page.IsSet() { - out.Page = &model.Page{} - mapToPageModel(from.Context.Page, out.Page) - out.URL = out.Page.URL - if out.Page.Referer != "" { + if from.Context.Page.URL.IsSet() { + event.URL = model.ParseURL(from.Context.Page.URL.Val, "", "") + } + if from.Context.Page.Referer.IsSet() { if out.HTTP == nil { out.HTTP = &model.HTTP{} } if out.HTTP.Request == nil { out.HTTP.Request = &model.HTTPRequest{} } - out.HTTP.Request.Referrer = out.Page.Referer + out.HTTP.Request.Referrer = from.Context.Page.Referer.Val } } if len(from.Context.Custom) > 0 { @@ -437,15 +437,6 @@ func mapToMetricsetModel(from *metricset, event *model.APMEvent) { } } -func mapToPageModel(from contextPage, out *model.Page) { - if from.URL.IsSet() { - out.URL = model.ParseURL(from.URL.Val, "", "") - } - if from.Referer.IsSet() { - out.Referer = from.Referer.Val - } -} - func mapToResponseModel(from contextResponse, out *model.HTTPResponse) { if from.Headers.IsSet() { out.Headers = modeldecoderutil.HTTPHeadersToMap(from.Headers.Val.Clone()) @@ -579,7 +570,7 @@ func mapToSpanModel(from *span, event *model.APMEvent) { http.Response.StatusCode = from.Context.HTTP.StatusCode.Val } if from.Context.HTTP.URL.IsSet() { - out.URL = from.Context.HTTP.URL.Val + event.URL.Original = from.Context.HTTP.URL.Val } if from.Context.HTTP.Response.IsSet() { http.Response = &response @@ -619,17 +610,17 @@ func mapToSpanModel(from *span, event *model.APMEvent) { out.Name = from.Name.Val } if from.Outcome.IsSet() { - out.Outcome = from.Outcome.Val + event.Event.Outcome = from.Outcome.Val } else { if from.Context.HTTP.StatusCode.IsSet() { statusCode := from.Context.HTTP.StatusCode.Val if statusCode >= http.StatusBadRequest { - out.Outcome = "failure" + event.Event.Outcome = "failure" } else { - out.Outcome = "success" + event.Event.Outcome = "success" } } else { - out.Outcome = "unknown" + event.Event.Outcome = "unknown" } } if from.SampleRate.IsSet() && from.SampleRate.Val > 0 { @@ -734,17 +725,17 @@ func mapToTransactionModel(from *transaction, event *model.APMEvent) { mapToResponseModel(from.Context.Response, out.HTTP.Response) } if from.Context.Page.IsSet() { - out.Page = &model.Page{} - mapToPageModel(from.Context.Page, out.Page) - out.URL = out.Page.URL - if out.Page.Referer != "" { + if from.Context.Page.URL.IsSet() { + event.URL = model.ParseURL(from.Context.Page.URL.Val, "", "") + } + if from.Context.Page.Referer.IsSet() { if out.HTTP == nil { out.HTTP = &model.HTTP{} } if out.HTTP.Request == nil { out.HTTP.Request = &model.HTTPRequest{} } - out.HTTP.Request.Referrer = out.Page.Referer + out.HTTP.Request.Referrer = from.Context.Page.Referer.Val } } } @@ -766,17 +757,17 @@ func mapToTransactionModel(from *transaction, event *model.APMEvent) { out.Name = from.Name.Val } if from.Outcome.IsSet() { - out.Outcome = from.Outcome.Val + event.Event.Outcome = from.Outcome.Val } else { if from.Context.Response.StatusCode.IsSet() { statusCode := from.Context.Response.StatusCode.Val if statusCode >= http.StatusInternalServerError { - out.Outcome = "failure" + event.Event.Outcome = "failure" } else { - out.Outcome = "success" + event.Event.Outcome = "success" } } else { - out.Outcome = "unknown" + event.Event.Outcome = "unknown" } } if from.ParentID.IsSet() { @@ -799,8 +790,8 @@ func mapToTransactionModel(from *transaction, event *model.APMEvent) { out.RepresentativeCount = 1 } if from.Session.ID.IsSet() { - out.Session.ID = from.Session.ID.Val - out.Session.Sequence = from.Session.Sequence.Val + event.Session.ID = from.Session.ID.Val + event.Session.Sequence = from.Session.Sequence.Val } if from.SpanCount.Dropped.IsSet() { dropped := from.SpanCount.Dropped.Val diff --git a/model/modeldecoder/rumv3/error_test.go b/model/modeldecoder/rumv3/error_test.go index 0c6ff01625b..184bf7e93f1 100644 --- a/model/modeldecoder/rumv3/error_test.go +++ b/model/modeldecoder/rumv3/error_test.go @@ -177,10 +177,7 @@ func TestDecodeMapToErrorModel(t *testing.T) { input.Context.Page.URL.Set("https://my.site.test:9201") var out model.APMEvent mapToErrorModel(&input, &out) - assert.Equal(t, "https://my.site.test:9201", out.Error.Page.URL.Full) - assert.Equal(t, "https://my.site.test:9201", out.Error.URL.Full) - assert.Equal(t, 9201, out.Error.Page.URL.Port) - assert.Equal(t, "https", out.Error.Page.URL.Scheme) + assert.Equal(t, "https://my.site.test:9201", out.URL.Full) }) t.Run("page.referer", func(t *testing.T) { @@ -188,7 +185,6 @@ func TestDecodeMapToErrorModel(t *testing.T) { input.Context.Page.Referer.Set("https://my.site.test:9201") var out model.APMEvent mapToErrorModel(&input, &out) - assert.Equal(t, "https://my.site.test:9201", out.Error.Page.Referer) assert.Equal(t, "https://my.site.test:9201", out.Error.HTTP.Request.Referrer) }) diff --git a/model/modeldecoder/rumv3/metadata_test.go b/model/modeldecoder/rumv3/metadata_test.go index 3d57699b210..e3add97c5c9 100644 --- a/model/modeldecoder/rumv3/metadata_test.go +++ b/model/modeldecoder/rumv3/metadata_test.go @@ -59,6 +59,9 @@ func metadataExceptions(keys ...string) func(key string) bool { "Service.Node", "Service.Agent.EphemeralID", "Host", + "Event", + "Session", + "URL", // event-specific fields "Error", diff --git a/model/modeldecoder/rumv3/transaction_test.go b/model/modeldecoder/rumv3/transaction_test.go index 0a5fd728ad7..33b4c9499dd 100644 --- a/model/modeldecoder/rumv3/transaction_test.go +++ b/model/modeldecoder/rumv3/transaction_test.go @@ -295,22 +295,22 @@ func TestDecodeMapToTransactionModel(t *testing.T) { input.Outcome.Set("failure") input.Context.HTTP.StatusCode.Set(http.StatusPermanentRedirect) mapToSpanModel(&input, &out) - assert.Equal(t, "failure", out.Span.Outcome) + assert.Equal(t, "failure", out.Event.Outcome) // derive from span fields - success input.Outcome.Reset() input.Context.HTTP.StatusCode.Set(http.StatusPermanentRedirect) mapToSpanModel(&input, &out) - assert.Equal(t, "success", out.Span.Outcome) + assert.Equal(t, "success", out.Event.Outcome) // derive from span fields - failure input.Outcome.Reset() input.Context.HTTP.StatusCode.Set(http.StatusBadRequest) mapToSpanModel(&input, &out) - assert.Equal(t, "failure", out.Span.Outcome) + assert.Equal(t, "failure", out.Event.Outcome) // derive from span fields - unknown input.Outcome.Reset() input.Context.HTTP.StatusCode.Reset() mapToSpanModel(&input, &out) - assert.Equal(t, "unknown", out.Span.Outcome) + assert.Equal(t, "unknown", out.Event.Outcome) }) t.Run("transaction-outcome", func(t *testing.T) { @@ -321,22 +321,22 @@ func TestDecodeMapToTransactionModel(t *testing.T) { input.Outcome.Set("failure") input.Context.Response.StatusCode.Set(http.StatusBadRequest) mapToTransactionModel(&input, &out) - assert.Equal(t, "failure", out.Transaction.Outcome) + assert.Equal(t, "failure", out.Event.Outcome) // derive from span fields - success input.Outcome.Reset() input.Context.Response.StatusCode.Set(http.StatusBadRequest) mapToTransactionModel(&input, &out) - assert.Equal(t, "success", out.Transaction.Outcome) + assert.Equal(t, "success", out.Event.Outcome) // derive from span fields - failure input.Outcome.Reset() input.Context.Response.StatusCode.Set(http.StatusInternalServerError) mapToTransactionModel(&input, &out) - assert.Equal(t, "failure", out.Transaction.Outcome) + assert.Equal(t, "failure", out.Event.Outcome) // derive from span fields - unknown input.Outcome.Reset() input.Context.Response.StatusCode.Reset() mapToTransactionModel(&input, &out) - assert.Equal(t, "unknown", out.Transaction.Outcome) + assert.Equal(t, "unknown", out.Event.Outcome) }) t.Run("page.URL", func(t *testing.T) { @@ -344,10 +344,7 @@ func TestDecodeMapToTransactionModel(t *testing.T) { input.Context.Page.URL.Set("https://my.site.test:9201") var out model.APMEvent mapToTransactionModel(&input, &out) - assert.Equal(t, "https://my.site.test:9201", out.Transaction.Page.URL.Full) - assert.Equal(t, "https://my.site.test:9201", out.Transaction.URL.Full) - assert.Equal(t, 9201, out.Transaction.Page.URL.Port) - assert.Equal(t, "https", out.Transaction.Page.URL.Scheme) + assert.Equal(t, "https://my.site.test:9201", out.URL.Full) }) t.Run("page.referer", func(t *testing.T) { @@ -355,7 +352,6 @@ func TestDecodeMapToTransactionModel(t *testing.T) { input.Context.Page.Referer.Set("https://my.site.test:9201") var out model.APMEvent mapToTransactionModel(&input, &out) - assert.Equal(t, "https://my.site.test:9201", out.Transaction.Page.Referer) assert.Equal(t, "https://my.site.test:9201", out.Transaction.HTTP.Request.Referrer) }) @@ -375,14 +371,14 @@ func TestDecodeMapToTransactionModel(t *testing.T) { modeldecodertest.SetStructValues(&input, modeldecodertest.DefaultValues()) input.Session.ID.Reset() mapToTransactionModel(&input, &out) - assert.Equal(t, model.TransactionSession{}, out.Transaction.Session) + assert.Equal(t, model.Session{}, out.Session) input.Session.ID.Set("session_id") input.Session.Sequence.Set(123) mapToTransactionModel(&input, &out) - assert.Equal(t, model.TransactionSession{ + assert.Equal(t, model.Session{ ID: "session_id", Sequence: 123, - }, out.Transaction.Session) + }, out.Session) }) } diff --git a/model/modeldecoder/v2/decoder.go b/model/modeldecoder/v2/decoder.go index 9f91d614cbe..17dcded6039 100644 --- a/model/modeldecoder/v2/decoder.go +++ b/model/modeldecoder/v2/decoder.go @@ -275,16 +275,13 @@ func mapToErrorModel(from *errorEvent, config modeldecoder.Config, event *model. mapToResponseModel(from.Context.Response, out.HTTP.Response) } if from.Context.Request.URL.IsSet() { - out.URL = &model.URL{} - mapToRequestURLModel(from.Context.Request.URL, out.URL) + mapToRequestURLModel(from.Context.Request.URL, &event.URL) } if from.Context.Page.IsSet() { - out.Page = &model.Page{} - mapToPageModel(from.Context.Page, out.Page) - if out.URL == nil { - out.URL = out.Page.URL + if from.Context.Page.URL.IsSet() && !from.Context.Request.URL.IsSet() { + event.URL = model.ParseURL(from.Context.Page.URL.Val, "", "") } - if out.Page.Referer != "" { + if from.Context.Page.Referer.IsSet() { if out.HTTP == nil { out.HTTP = &model.HTTP{} } @@ -292,7 +289,7 @@ func mapToErrorModel(from *errorEvent, config modeldecoder.Config, event *model. out.HTTP.Request = &model.HTTPRequest{} } if out.HTTP.Request.Referrer == "" { - out.HTTP.Request.Referrer = out.Page.Referer + out.HTTP.Request.Referrer = from.Context.Page.Referer.Val } } } @@ -592,15 +589,6 @@ func mapToMetricsetModel(from *metricset, config modeldecoder.Config, event *mod } } -func mapToPageModel(from contextPage, out *model.Page) { - if from.URL.IsSet() { - out.URL = model.ParseURL(from.URL.Val, "", "") - } - if from.Referer.IsSet() { - out.Referer = from.Referer.Val - } -} - func mapToRequestModel(from contextRequest, out *model.HTTPRequest) { if from.Method.IsSet() { out.Method = from.Method.Val @@ -861,7 +849,7 @@ func mapToSpanModel(from *span, config modeldecoder.Config, event *model.APMEven http.Response.StatusCode = from.Context.HTTP.StatusCode.Val } if from.Context.HTTP.URL.IsSet() { - out.URL = from.Context.HTTP.URL.Val + event.URL.Original = from.Context.HTTP.URL.Val } out.HTTP = &http } @@ -902,17 +890,17 @@ func mapToSpanModel(from *span, config modeldecoder.Config, event *model.APMEven out.Name = from.Name.Val } if from.Outcome.IsSet() { - out.Outcome = from.Outcome.Val + event.Event.Outcome = from.Outcome.Val } else { if from.Context.HTTP.StatusCode.IsSet() { statusCode := from.Context.HTTP.StatusCode.Val if statusCode >= http.StatusBadRequest { - out.Outcome = "failure" + event.Event.Outcome = "failure" } else { - out.Outcome = "success" + event.Event.Outcome = "success" } } else { - out.Outcome = "unknown" + event.Event.Outcome = "unknown" } } if from.ParentID.IsSet() { @@ -1049,8 +1037,7 @@ func mapToTransactionModel(from *transaction, config modeldecoder.Config, event } } if from.Context.Request.URL.IsSet() { - out.URL = &model.URL{} - mapToRequestURLModel(from.Context.Request.URL, out.URL) + mapToRequestURLModel(from.Context.Request.URL, &event.URL) } if from.Context.Response.IsSet() { if out.HTTP == nil { @@ -1060,12 +1047,10 @@ func mapToTransactionModel(from *transaction, config modeldecoder.Config, event mapToResponseModel(from.Context.Response, out.HTTP.Response) } if from.Context.Page.IsSet() { - out.Page = &model.Page{} - mapToPageModel(from.Context.Page, out.Page) - if out.URL == nil { - out.URL = out.Page.URL + if from.Context.Page.URL.IsSet() && !from.Context.Request.URL.IsSet() { + event.URL = model.ParseURL(from.Context.Page.URL.Val, "", "") } - if out.Page.Referer != "" { + if from.Context.Page.Referer.IsSet() { if out.HTTP == nil { out.HTTP = &model.HTTP{} } @@ -1073,7 +1058,7 @@ func mapToTransactionModel(from *transaction, config modeldecoder.Config, event out.HTTP.Request = &model.HTTPRequest{} } if out.HTTP.Request.Referrer == "" { - out.HTTP.Request.Referrer = out.Page.Referer + out.HTTP.Request.Referrer = from.Context.Page.Referer.Val } } } @@ -1096,17 +1081,17 @@ func mapToTransactionModel(from *transaction, config modeldecoder.Config, event out.Name = from.Name.Val } if from.Outcome.IsSet() { - out.Outcome = from.Outcome.Val + event.Event.Outcome = from.Outcome.Val } else { if from.Context.Response.StatusCode.IsSet() { statusCode := from.Context.Response.StatusCode.Val if statusCode >= http.StatusInternalServerError { - out.Outcome = "failure" + event.Event.Outcome = "failure" } else { - out.Outcome = "success" + event.Event.Outcome = "success" } } else { - out.Outcome = "unknown" + event.Event.Outcome = "unknown" } } if from.ParentID.IsSet() { @@ -1128,8 +1113,8 @@ func mapToTransactionModel(from *transaction, config modeldecoder.Config, event out.RepresentativeCount = 1 } if from.Session.ID.IsSet() { - out.Session.ID = from.Session.ID.Val - out.Session.Sequence = from.Session.Sequence.Val + event.Session.ID = from.Session.ID.Val + event.Session.Sequence = from.Session.Sequence.Val } if from.SpanCount.Dropped.IsSet() { dropped := from.SpanCount.Dropped.Val diff --git a/model/modeldecoder/v2/error_test.go b/model/modeldecoder/v2/error_test.go index b516b55f8f8..c4843b3fcce 100644 --- a/model/modeldecoder/v2/error_test.go +++ b/model/modeldecoder/v2/error_test.go @@ -190,10 +190,7 @@ func TestDecodeMapToErrorModel(t *testing.T) { input.Context.Page.URL.Set("https://my.site.test:9201") var out model.APMEvent mapToErrorModel(&input, modeldecoder.Config{}, &out) - assert.Equal(t, "https://my.site.test:9201", out.Error.Page.URL.Full) - assert.Equal(t, "https://my.site.test:9201", out.Error.URL.Full) - assert.Equal(t, 9201, out.Error.Page.URL.Port) - assert.Equal(t, "https", out.Error.Page.URL.Scheme) + assert.Equal(t, "https://my.site.test:9201", out.URL.Full) }) t.Run("page.referer", func(t *testing.T) { @@ -201,7 +198,6 @@ func TestDecodeMapToErrorModel(t *testing.T) { input.Context.Page.Referer.Set("https://my.site.test:9201") var out model.APMEvent mapToErrorModel(&input, modeldecoder.Config{}, &out) - assert.Equal(t, "https://my.site.test:9201", out.Error.Page.Referer) assert.Equal(t, "https://my.site.test:9201", out.Error.HTTP.Request.Referrer) }) diff --git a/model/modeldecoder/v2/metadata_test.go b/model/modeldecoder/v2/metadata_test.go index 5dd956dce9b..d6acd94e926 100644 --- a/model/modeldecoder/v2/metadata_test.go +++ b/model/modeldecoder/v2/metadata_test.go @@ -67,7 +67,21 @@ func isUnmappedMetadataField(key string) bool { "Host.Type", "UserAgent", "UserAgent.Name", - "UserAgent.Original": + "UserAgent.Original", + "Event", + "Event.Outcome", + "Session.ID", + "Session", + "Session.Sequence", + "URL", + "URL.Original", + "URL.Scheme", + "URL.Full", + "URL.Domain", + "URL.Port", + "URL.Path", + "URL.Query", + "URL.Fragment": return true } return false diff --git a/model/modeldecoder/v2/span_test.go b/model/modeldecoder/v2/span_test.go index ea506eab9fa..a9b59804529 100644 --- a/model/modeldecoder/v2/span_test.go +++ b/model/modeldecoder/v2/span_test.go @@ -161,22 +161,22 @@ func TestDecodeMapToSpanModel(t *testing.T) { input.Outcome.Set("failure") input.Context.HTTP.StatusCode.Set(http.StatusPermanentRedirect) mapToSpanModel(&input, modeldecoder.Config{}, &out) - assert.Equal(t, "failure", out.Span.Outcome) + assert.Equal(t, "failure", out.Event.Outcome) // derive from other fields - success input.Outcome.Reset() input.Context.HTTP.StatusCode.Set(http.StatusPermanentRedirect) mapToSpanModel(&input, modeldecoder.Config{}, &out) - assert.Equal(t, "success", out.Span.Outcome) + assert.Equal(t, "success", out.Event.Outcome) // derive from other fields - failure input.Outcome.Reset() input.Context.HTTP.StatusCode.Set(http.StatusBadRequest) mapToSpanModel(&input, modeldecoder.Config{}, &out) - assert.Equal(t, "failure", out.Span.Outcome) + assert.Equal(t, "failure", out.Event.Outcome) // derive from other fields - unknown input.Outcome.Reset() input.Context.HTTP.StatusCode.Reset() mapToSpanModel(&input, modeldecoder.Config{}, &out) - assert.Equal(t, "unknown", out.Span.Outcome) + assert.Equal(t, "unknown", out.Event.Outcome) }) t.Run("timestamp", func(t *testing.T) { diff --git a/model/modeldecoder/v2/transaction_test.go b/model/modeldecoder/v2/transaction_test.go index cd4f85d2f99..2f84fe3a285 100644 --- a/model/modeldecoder/v2/transaction_test.go +++ b/model/modeldecoder/v2/transaction_test.go @@ -155,9 +155,6 @@ func TestDecodeMapToTransactionModel(t *testing.T) { t.Run("transaction-values", func(t *testing.T) { exceptions := func(key string) bool { // All the below exceptions are tested separately - if strings.HasPrefix(key, "Page.URL") { - return true - } switch key { case "HTTP.Request.Headers", "HTTP.Response.Headers", "Experimental", "RepresentativeCount": return true @@ -220,10 +217,7 @@ func TestDecodeMapToTransactionModel(t *testing.T) { var out model.APMEvent input.Context.Page.URL.Set("https://my.site.test:9201") mapToTransactionModel(&input, modeldecoder.Config{Experimental: false}, &out) - assert.Equal(t, "https://my.site.test:9201", out.Transaction.Page.URL.Full) - assert.Equal(t, "https://my.site.test:9201", out.Transaction.URL.Full) - assert.Equal(t, 9201, out.Transaction.Page.URL.Port) - assert.Equal(t, "https", out.Transaction.Page.URL.Scheme) + assert.Equal(t, "https://my.site.test:9201", out.URL.Full) }) t.Run("page.referer", func(t *testing.T) { @@ -231,7 +225,6 @@ func TestDecodeMapToTransactionModel(t *testing.T) { var out model.APMEvent input.Context.Page.Referer.Set("https://my.site.test:9201") mapToTransactionModel(&input, modeldecoder.Config{Experimental: false}, &out) - assert.Equal(t, "https://my.site.test:9201", out.Transaction.Page.Referer) assert.Equal(t, "https://my.site.test:9201", out.Transaction.HTTP.Request.Referrer) }) @@ -263,22 +256,22 @@ func TestDecodeMapToTransactionModel(t *testing.T) { input.Outcome.Set("failure") input.Context.Response.StatusCode.Set(http.StatusBadRequest) mapToTransactionModel(&input, modeldecoder.Config{}, &out) - assert.Equal(t, "failure", out.Transaction.Outcome) + assert.Equal(t, "failure", out.Event.Outcome) // derive from other fields - success input.Outcome.Reset() input.Context.Response.StatusCode.Set(http.StatusBadRequest) mapToTransactionModel(&input, modeldecoder.Config{}, &out) - assert.Equal(t, "success", out.Transaction.Outcome) + assert.Equal(t, "success", out.Event.Outcome) // derive from other fields - failure input.Outcome.Reset() input.Context.Response.StatusCode.Set(http.StatusInternalServerError) mapToTransactionModel(&input, modeldecoder.Config{}, &out) - assert.Equal(t, "failure", out.Transaction.Outcome) + assert.Equal(t, "failure", out.Event.Outcome) // derive from other fields - unknown input.Outcome.Reset() input.Context.Response.StatusCode.Reset() mapToTransactionModel(&input, modeldecoder.Config{}, &out) - assert.Equal(t, "unknown", out.Transaction.Outcome) + assert.Equal(t, "unknown", out.Event.Outcome) }) t.Run("session", func(t *testing.T) { @@ -287,14 +280,14 @@ func TestDecodeMapToTransactionModel(t *testing.T) { modeldecodertest.SetStructValues(&input, modeldecodertest.DefaultValues()) input.Session.ID.Reset() mapToTransactionModel(&input, modeldecoder.Config{}, &out) - assert.Equal(t, model.TransactionSession{}, out.Transaction.Session) + assert.Equal(t, model.Session{}, out.Session) input.Session.ID.Set("session_id") input.Session.Sequence.Set(123) mapToTransactionModel(&input, modeldecoder.Config{}, &out) - assert.Equal(t, model.TransactionSession{ + assert.Equal(t, model.Session{ ID: "session_id", Sequence: 123, - }, out.Transaction.Session) + }, out.Session) }) } diff --git a/model/modelprocessor/datastream.go b/model/modelprocessor/datastream.go index 8f61476aba5..96af159c376 100644 --- a/model/modelprocessor/datastream.go +++ b/model/modelprocessor/datastream.go @@ -66,7 +66,6 @@ func (s *SetDataStream) setDataStream(event *model.APMEvent) { } func isApplicationMetricset(ms *model.Metricset) bool { - return ms.Event == (model.MetricsetEventCategorization{}) && - ms.Transaction == (model.MetricsetTransaction{}) && + return ms.Transaction == (model.MetricsetTransaction{}) && ms.Span == (model.MetricsetSpan{}) } diff --git a/model/session.go b/model/session.go new file mode 100644 index 00000000000..e148a97c4d5 --- /dev/null +++ b/model/session.go @@ -0,0 +1,43 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package model + +import "github.com/elastic/beats/v7/libbeat/common" + +// Session holds information about a group of related transactions, such as +// a sequence of web interactions. +type Session struct { + // ID holds a session ID for grouping a set of related transactions. + ID string + + // Sequence holds an optional sequence number for a transaction + // within a session. Sequence is ignored if it is zero or if + // ID is empty. + Sequence int +} + +func (s *Session) fields() common.MapStr { + if s.ID == "" { + return nil + } + out := common.MapStr{"id": s.ID} + if s.Sequence > 0 { + out["sequence"] = s.Sequence + } + return out +} diff --git a/model/span.go b/model/span.go index c2ab0380c1f..ddd0ecd0a16 100644 --- a/model/span.go +++ b/model/span.go @@ -45,7 +45,6 @@ type Span struct { Message *Message Name string - Outcome string Start *float64 Duration float64 Stacktrace Stacktrace @@ -57,7 +56,6 @@ type Span struct { DB *DB HTTP *HTTP - URL string Destination *Destination DestinationService *DestinationService Composite *Composite @@ -155,7 +153,7 @@ func (c *Composite) fields() common.MapStr { return common.MapStr(fields) } -func (e *Span) fields() common.MapStr { +func (e *Span) fields(apmEvent *APMEvent) common.MapStr { spanTransformations.Inc() if frames := len(e.Stacktrace); frames > 0 { spanStacktraceCounter.Inc() @@ -186,9 +184,6 @@ func (e *Span) fields() common.MapStr { if e.HTTP != nil { fields.maybeSetMapStr("http", e.HTTP.spanTopLevelFields()) } - fields.maybeSetString("url.original", e.URL) - - common.MapStr(fields).Put("event.outcome", e.Outcome) var span mapStr span.set("name", e.Name) @@ -204,7 +199,7 @@ func (e *Span) fields() common.MapStr { if e.HTTP != nil { span.maybeSetMapStr("http", e.HTTP.spanFields()) - span.maybeSetString("http.url.original", e.URL) + span.maybeSetString("http.url.original", apmEvent.URL.Original) } span.maybeSetMapStr("db", e.DB.fields()) span.maybeSetMapStr("message", e.Message.Fields()) diff --git a/model/span_test.go b/model/span_test.go index 132ea3cdbee..62fff83eb27 100644 --- a/model/span_test.go +++ b/model/span_test.go @@ -57,22 +57,10 @@ func TestSpanTransform(t *testing.T) { "name": "", "type": "", }, - "event": common.MapStr{"outcome": ""}, "timestamp": common.MapStr{"us": timestampUs}, - }, - }, - { - Msg: "Span with outcome", - Span: Span{Outcome: "success"}, - Output: common.MapStr{ - "processor": common.MapStr{"event": "span", "name": "transaction"}, - "span": common.MapStr{ - "duration": common.MapStr{"us": 0}, - "name": "", - "type": "", + "url": common.MapStr{ + "original": url, }, - "timestamp": common.MapStr{"us": timestampUs}, - "event": common.MapStr{"outcome": "success"}, }, }, { @@ -86,7 +74,6 @@ func TestSpanTransform(t *testing.T) { Subtype: subtype, Action: action, Start: &start, - Outcome: "unknown", RepresentativeCount: 5, Duration: 1.20, Stacktrace: Stacktrace{{AbsPath: path}}, @@ -94,7 +81,6 @@ func TestSpanTransform(t *testing.T) { Request: &HTTPRequest{Method: method}, Response: &HTTPResponse{StatusCode: statusCode}, }, - URL: url, DB: &DB{ Instance: instance, Statement: statement, @@ -155,18 +141,23 @@ func TestSpanTransform(t *testing.T) { "trace": common.MapStr{"id": traceID}, "parent": common.MapStr{"id": parentID}, "destination": common.MapStr{"address": address, "port": port}, - "event": common.MapStr{"outcome": "unknown"}, "http": common.MapStr{ "response": common.MapStr{"status_code": statusCode}, "request": common.MapStr{"method": "get"}, }, - "url.original": url, + "url": common.MapStr{ + "original": url, + }, }, }, } for _, test := range tests { - event := APMEvent{Span: &test.Span, Timestamp: timestamp} + event := APMEvent{ + Span: &test.Span, + Timestamp: timestamp, + URL: URL{Original: url}, + } output := event.appendBeatEvent(context.Background(), nil) require.Len(t, output, 1) assert.Equal(t, test.Output, output[0].Fields, test.Msg) diff --git a/model/transaction.go b/model/transaction.go index 0609ca43490..c62d77ad1cb 100644 --- a/model/transaction.go +++ b/model/transaction.go @@ -44,18 +44,14 @@ type Transaction struct { Type string Name string Result string - Outcome string Duration float64 Marks TransactionMarks Message *Message Sampled bool SpanCount SpanCount - Page *Page HTTP *HTTP - URL *URL Custom common.MapStr UserExperience *UserExperience - Session TransactionSession Experimental interface{} @@ -66,16 +62,6 @@ type Transaction struct { RepresentativeCount float64 } -type TransactionSession struct { - // ID holds a session ID for grouping a set of related transactions. - ID string - - // Sequence holds an optional sequence number for a transaction - // within a session. Sequence is ignored if it is zero or if - // ID is empty. - Sequence int -} - type SpanCount struct { Dropped *int Started *int @@ -96,12 +82,9 @@ func (e *Transaction) fields() common.MapStr { if e.HTTP != nil { fields.maybeSetMapStr("http", e.HTTP.transactionTopLevelFields()) } - fields.maybeSetMapStr("url", e.URL.Fields()) - fields.maybeSetMapStr("session", e.Session.fields()) if e.Experimental != nil { fields.set("experimental", e.Experimental) } - common.MapStr(fields).Put("event.outcome", e.Outcome) var transaction mapStr transaction.set("id", e.ID) @@ -110,7 +93,6 @@ func (e *Transaction) fields() common.MapStr { transaction.maybeSetString("name", e.Name) transaction.maybeSetString("result", e.Result) transaction.maybeSetMapStr("marks", e.Marks.fields()) - transaction.maybeSetMapStr("page", e.Page.Fields()) transaction.maybeSetMapStr("custom", customFields(e.Custom)) transaction.maybeSetMapStr("message", e.Message.Fields()) transaction.maybeSetMapStr("experience", e.UserExperience.Fields()) @@ -155,14 +137,3 @@ func (m TransactionMark) fields() common.MapStr { } return out } - -func (s *TransactionSession) fields() common.MapStr { - if s.ID == "" { - return nil - } - out := common.MapStr{"id": s.ID} - if s.Sequence > 0 { - out["sequence"] = s.Sequence - } - return out -} diff --git a/model/transaction_test.go b/model/transaction_test.go index 459d2808c12..da966bc64db 100644 --- a/model/transaction_test.go +++ b/model/transaction_test.go @@ -125,12 +125,6 @@ func TestTransactionTransform(t *testing.T) { } } -func TestTransactionTransformOutcome(t *testing.T) { - tx := Transaction{Outcome: "success"} - fields := tx.fields() - assert.Equal(t, common.MapStr{"outcome": "success"}, fields["event"]) -} - func TestEventsTransformWithMetadata(t *testing.T) { hostname := "a.b.c" architecture := "darwin" @@ -156,10 +150,9 @@ func TestEventsTransformWithMetadata(t *testing.T) { User: User{ID: id, Name: name}, UserAgent: UserAgent{Original: userAgent}, Client: Client{IP: net.ParseIP(ip)}, + URL: URL{Original: url}, Transaction: &Transaction{ - Page: &Page{URL: &URL{Original: url}, Referer: referer}, HTTP: &HTTP{Request: &request, Response: &response}, - URL: &URL{Original: url}, Custom: common.MapStr{"foo.bar": "baz"}, Message: &Message{QueueName: "routeUser"}, Sampled: true, @@ -197,18 +190,18 @@ func TestEventsTransformWithMetadata(t *testing.T) { "id": "", "type": "", "sampled": true, - "page": common.MapStr{"url": url, "referer": referer}, "custom": common.MapStr{ "foo_bar": "baz", }, "message": common.MapStr{"queue": common.MapStr{"name": "routeUser"}}, }, - "event": common.MapStr{"outcome": ""}, - "url": common.MapStr{"original": url}, "http": common.MapStr{ "request": common.MapStr{"method": "post", "referrer": referer}, "response": common.MapStr{"finished": false, "headers": common.MapStr{"content-type": []string{"text/html"}}}, }, + "url": common.MapStr{ + "original": url, + }, }, event.Fields) } @@ -226,43 +219,6 @@ func TestTransformTransactionHTTP(t *testing.T) { }, fields["http"]) } -func TestTransactionTransformPage(t *testing.T) { - id := "123" - urlExample := "http://example.com/path" - - tests := []struct { - Transaction Transaction - Output common.MapStr - Msg string - }{ - { - Transaction: Transaction{ - ID: id, - Type: "tx", - Duration: 65.98, - URL: ParseURL("https://localhost:8200/", "", ""), - Page: &Page{ - URL: ParseURL(urlExample, "", ""), - }, - }, - Output: common.MapStr{ - "domain": "localhost", - "full": "https://localhost:8200/", - "original": "https://localhost:8200/", - "path": "/", - "port": 8200, - "scheme": "https", - }, - Msg: "With Page URL and Request URL", - }, - } - - for idx, test := range tests { - fields := test.Transaction.fields() - assert.Equal(t, test.Output, fields["url"], fmt.Sprintf("Failed at idx %v; %s", idx, test.Msg)) - } -} - func TestTransactionTransformMarks(t *testing.T) { tests := []struct { Transaction Transaction @@ -292,49 +248,3 @@ func TestTransactionTransformMarks(t *testing.T) { assert.Equal(t, test.Output, marks, fmt.Sprintf("Failed at idx %v; %s", idx, test.Msg)) } } - -func TestTransactionSession(t *testing.T) { - tests := []struct { - Transaction Transaction - Output common.MapStr - }{{ - Transaction: Transaction{ - Session: TransactionSession{ - ID: "session_id", - }, - }, - Output: common.MapStr{ - "id": "session_id", - }, - }, { - Transaction: Transaction{ - Session: TransactionSession{ - ID: "session_id", - Sequence: 123, - }, - }, - Output: common.MapStr{ - "id": "session_id", - "sequence": 123, - }, - }, { - Transaction: Transaction{ - Session: TransactionSession{ - // Sequence is ignored if ID is empty. - Sequence: 123, - }, - }, - Output: nil, - }} - - for _, test := range tests { - fields := test.Transaction.fields() - session, err := fields.GetValue("session") - if test.Output == nil { - assert.Equal(t, common.ErrKeyNotFound, err) - } else { - require.NoError(t, err) - assert.Equal(t, test.Output, session) - } - } -} diff --git a/model/url.go b/model/url.go index 51a642215ec..4ec4c1f8c08 100644 --- a/model/url.go +++ b/model/url.go @@ -36,11 +36,11 @@ type URL struct { Fragment string } -func ParseURL(original, defaultHostname, defaultScheme string) *URL { +func ParseURL(original, defaultHostname, defaultScheme string) URL { original = truncate(original) url, err := url.Parse(original) if err != nil { - return &URL{Original: original} + return URL{Original: original} } if url.Scheme == "" { url.Scheme = defaultScheme @@ -51,7 +51,7 @@ func ParseURL(original, defaultHostname, defaultScheme string) *URL { if url.Host == "" { url.Host = defaultHostname } - out := &URL{ + out := URL{ Original: original, Scheme: url.Scheme, Full: truncate(url.String()), @@ -80,11 +80,8 @@ func truncate(s string) string { return s } -// Fields returns common.MapStr holding transformed data for attribute url. -func (url *URL) Fields() common.MapStr { - if url == nil { - return nil - } +// fields returns common.MapStr holding transformed data for attribute url. +func (url *URL) fields() common.MapStr { var fields mapStr fields.maybeSetString("full", url.Full) fields.maybeSetString("fragment", url.Fragment) diff --git a/processor/otel/metadata_test.go b/processor/otel/metadata_test.go index 260adddfffe..0fcf584a0d3 100644 --- a/processor/otel/metadata_test.go +++ b/processor/otel/metadata_test.go @@ -234,6 +234,7 @@ func transformResourceMetadata(t *testing.T, resourceAttrs map[string]pdata.Attr otelSpan.SetSpanID(pdata.NewSpanID([8]byte{2})) events := transformTraces(t, traces) events[0].Transaction = nil + events[0].Event.Outcome = "" events[0].Timestamp = time.Time{} return events[0] } diff --git a/processor/otel/test_approved/span_jaeger_http.approved.json b/processor/otel/test_approved/span_jaeger_http.approved.json index f0a6f7b8ff6..d7944dfa5bc 100644 --- a/processor/otel/test_approved/span_jaeger_http.approved.json +++ b/processor/otel/test_approved/span_jaeger_http.approved.json @@ -73,7 +73,9 @@ "trace": { "id": "00000000000000000000000046467830" }, - "url.original": "http://foo.bar.com?a=12" + "url": { + "original": "http://foo.bar.com?a=12" + } }, { "@timestamp": "2019-12-16T12:46:58.000Z", @@ -112,6 +114,9 @@ }, "trace": { "id": "00000000000000000000000046467830" + }, + "url": { + "original": "http://foo.bar.com?a=12" } }, { @@ -146,6 +151,9 @@ }, "trace": { "id": "00000000000000000000000046467830" + }, + "url": { + "original": "http://foo.bar.com?a=12" } }, { @@ -182,6 +190,9 @@ }, "trace": { "id": "00000000000000000000000046467830" + }, + "url": { + "original": "http://foo.bar.com?a=12" } }, { @@ -218,6 +229,9 @@ }, "trace": { "id": "00000000000000000000000046467830" + }, + "url": { + "original": "http://foo.bar.com?a=12" } }, { @@ -254,6 +268,9 @@ }, "trace": { "id": "00000000000000000000000046467830" + }, + "url": { + "original": "http://foo.bar.com?a=12" } }, { @@ -288,6 +305,9 @@ }, "trace": { "id": "00000000000000000000000046467830" + }, + "url": { + "original": "http://foo.bar.com?a=12" } } ] diff --git a/processor/otel/test_approved/span_jaeger_http_status_code.approved.json b/processor/otel/test_approved/span_jaeger_http_status_code.approved.json index 85b41ea0bbf..0c4efe5ab9d 100644 --- a/processor/otel/test_approved/span_jaeger_http_status_code.approved.json +++ b/processor/otel/test_approved/span_jaeger_http_status_code.approved.json @@ -66,7 +66,9 @@ "trace": { "id": "00000000000000000000000046467830" }, - "url.original": "http://foo.bar.com?a=12" + "url": { + "original": "http://foo.bar.com?a=12" + } } ] } diff --git a/processor/otel/test_approved/span_jaeger_https_default_port.approved.json b/processor/otel/test_approved/span_jaeger_https_default_port.approved.json index fb59e555a3a..cba479e9272 100644 --- a/processor/otel/test_approved/span_jaeger_https_default_port.approved.json +++ b/processor/otel/test_approved/span_jaeger_https_default_port.approved.json @@ -52,7 +52,9 @@ "trace": { "id": "00000000000000000000000046467830" }, - "url.original": "https://foo.bar.com:443?a=12" + "url": { + "original": "https://foo.bar.com:443?a=12" + } } ] } diff --git a/processor/otel/traces.go b/processor/otel/traces.go index c1bf17eef77..0d59bf9d7a8 100644 --- a/processor/otel/traces.go +++ b/processor/otel/traces.go @@ -209,6 +209,7 @@ func (c *Consumer) convertSpan( event := baseEvent event.Labels = initEventLabels(event.Labels) event.Timestamp = startTime.Add(timeDelta) + event.Event.Outcome = spanStatusOutcome(otelSpan.Status()) if root || otelSpan.Kind() == pdata.SpanKindServer || otelSpan.Kind() == pdata.SpanKindConsumer { event.Transaction = &model.Transaction{ ID: spanID, @@ -217,7 +218,6 @@ func (c *Consumer) convertSpan( Duration: durationMillis, Name: name, Sampled: true, - Outcome: spanStatusOutcome(otelSpan.Status()), } translateTransaction(otelSpan, otelLibrary, &event) } else { @@ -227,7 +227,6 @@ func (c *Consumer) convertSpan( TraceID: traceID, Duration: durationMillis, Name: name, - Outcome: spanStatusOutcome(otelSpan.Status()), } translateSpan(otelSpan, &event) } @@ -238,6 +237,7 @@ func (c *Consumer) convertSpan( events := otelSpan.Events() event.Labels = baseEvent.Labels // only copy common labels to span events + event.Event.Outcome = "" // don't set event.outcome for span events for i := 0; i < events.Len(); i++ { convertSpanEvent(logger, events.At(i), event, timeDelta, out) } @@ -438,8 +438,8 @@ func translateTransaction( // Set outcome nad result from status code. if statusCode := httpResponse.StatusCode; statusCode > 0 { - if event.Transaction.Outcome == outcomeUnknown { - event.Transaction.Outcome = serverHTTPStatusCodeOutcome(statusCode) + if event.Event.Outcome == outcomeUnknown { + event.Event.Outcome = serverHTTPStatusCodeOutcome(statusCode) } if event.Transaction.Result == "" { event.Transaction.Result = httpStatusCodeResult(statusCode) @@ -460,7 +460,7 @@ func translateTransaction( httpHost = net.JoinHostPort(httpHost, strconv.Itoa(netHostPort)) } } - event.Transaction.URL = model.ParseURL(httpURL, httpHost, httpScheme) + event.URL = model.ParseURL(httpURL, httpHost, httpScheme) // Set the remote address from net.peer.* if event.Transaction.HTTP.Request != nil && netPeerIP != "" { @@ -747,15 +747,15 @@ func translateSpan(span pdata.Span, event *model.APMEvent) { switch { case isHTTPSpan: if httpResponse.StatusCode > 0 { - if event.Span.Outcome == outcomeUnknown { - event.Span.Outcome = clientHTTPStatusCodeOutcome(httpResponse.StatusCode) + if event.Event.Outcome == outcomeUnknown { + event.Event.Outcome = clientHTTPStatusCodeOutcome(httpResponse.StatusCode) } } event.Span.Type = "external" subtype := "http" event.Span.Subtype = subtype event.Span.HTTP = &http - event.Span.URL = httpURL + event.URL.Original = httpURL case isDBSpan: event.Span.Type = "db" if db.Type != "" { @@ -950,8 +950,6 @@ func addTransactionCtxToErr(transaction *model.Transaction, err *model.Error) { err.TraceID = transaction.TraceID err.ParentID = transaction.ID err.HTTP = transaction.HTTP - err.URL = transaction.URL - err.Page = transaction.Page err.Custom = transaction.Custom err.TransactionSampled = &transaction.Sampled err.TransactionType = transaction.Type diff --git a/processor/otel/traces_test.go b/processor/otel/traces_test.go index b496ebabb10..5e53d02e7ef 100644 --- a/processor/otel/traces_test.go +++ b/processor/otel/traces_test.go @@ -89,9 +89,9 @@ func TestOutcome(t *testing.T) { batch := transformTraces(t, traces) require.Len(t, batch, 2) - assert.Equal(t, expectedOutcome, batch[0].Transaction.Outcome) + assert.Equal(t, expectedOutcome, batch[0].Event.Outcome) assert.Equal(t, expectedResult, batch[0].Transaction.Result) - assert.Equal(t, expectedOutcome, batch[1].Span.Outcome) + assert.Equal(t, expectedOutcome, batch[1].Event.Outcome) } test(t, "unknown", "", pdata.StatusCodeUnset) @@ -117,14 +117,14 @@ func TestRepresentativeCount(t *testing.T) { } func TestHTTPTransactionURL(t *testing.T) { - test := func(t *testing.T, expected *model.URL, attrs map[string]pdata.AttributeValue) { + test := func(t *testing.T, expected model.URL, attrs map[string]pdata.AttributeValue) { t.Helper() event := transformTransactionWithAttributes(t, attrs) - assert.Equal(t, expected, event.Transaction.URL) + assert.Equal(t, expected, event.URL) } t.Run("scheme_host_target", func(t *testing.T) { - test(t, &model.URL{ + test(t, model.URL{ Scheme: "https", Original: "/foo?bar", Full: "https://testing.invalid:80/foo?bar", @@ -139,7 +139,7 @@ func TestHTTPTransactionURL(t *testing.T) { }) }) t.Run("scheme_servername_nethostport_target", func(t *testing.T) { - test(t, &model.URL{ + test(t, model.URL{ Scheme: "https", Original: "/foo?bar", Full: "https://testing.invalid:80/foo?bar", @@ -155,7 +155,7 @@ func TestHTTPTransactionURL(t *testing.T) { }) }) t.Run("scheme_nethostname_nethostport_target", func(t *testing.T) { - test(t, &model.URL{ + test(t, model.URL{ Scheme: "https", Original: "/foo?bar", Full: "https://testing.invalid:80/foo?bar", @@ -171,7 +171,7 @@ func TestHTTPTransactionURL(t *testing.T) { }) }) t.Run("http.url", func(t *testing.T) { - test(t, &model.URL{ + test(t, model.URL{ Scheme: "https", Original: "https://testing.invalid:80/foo?bar", Full: "https://testing.invalid:80/foo?bar", @@ -184,7 +184,7 @@ func TestHTTPTransactionURL(t *testing.T) { }) }) t.Run("host_no_port", func(t *testing.T) { - test(t, &model.URL{ + test(t, model.URL{ Scheme: "https", Original: "/foo", Full: "https://testing.invalid/foo", @@ -197,7 +197,7 @@ func TestHTTPTransactionURL(t *testing.T) { }) }) t.Run("ipv6_host_no_port", func(t *testing.T) { - test(t, &model.URL{ + test(t, model.URL{ Scheme: "https", Original: "/foo", Full: "https://[::1]/foo", @@ -211,7 +211,7 @@ func TestHTTPTransactionURL(t *testing.T) { }) t.Run("default_scheme", func(t *testing.T) { // scheme is set to "http" if it can't be deduced from attributes. - test(t, &model.URL{ + test(t, model.URL{ Scheme: "http", Original: "/foo", Full: "http://testing.invalid/foo", @@ -228,7 +228,7 @@ func TestHTTPSpanURL(t *testing.T) { test := func(t *testing.T, expected string, attrs map[string]pdata.AttributeValue) { t.Helper() event := transformSpanWithAttributes(t, attrs) - assert.Equal(t, expected, event.Span.URL) + assert.Equal(t, model.URL{Original: expected}, event.URL) } t.Run("host.url", func(t *testing.T) { diff --git a/processor/stream/test_approved_es_documents/testIntakeIntegrationErrors.approved.json b/processor/stream/test_approved_es_documents/testIntakeIntegrationErrors.approved.json index c76e671f090..6985ffd00c1 100644 --- a/processor/stream/test_approved_es_documents/testIntakeIntegrationErrors.approved.json +++ b/processor/stream/test_approved_es_documents/testIntakeIntegrationErrors.approved.json @@ -210,10 +210,6 @@ } } ] - }, - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" } }, "host": { diff --git a/processor/stream/test_approved_es_documents/testIntakeIntegrationEvents.approved.json b/processor/stream/test_approved_es_documents/testIntakeIntegrationEvents.approved.json index a3b8a94b031..25794f41acb 100644 --- a/processor/stream/test_approved_es_documents/testIntakeIntegrationEvents.approved.json +++ b/processor/stream/test_approved_es_documents/testIntakeIntegrationEvents.approved.json @@ -424,7 +424,9 @@ "transaction": { "id": "1234567890987654" }, - "url.original": "http://localhost:8000" + "url": { + "original": "http://localhost:8000" + } }, { "@timestamp": "2019-10-21T11:30:44.929Z", diff --git a/processor/stream/test_approved_es_documents/testIntakeIntegrationRumErrors.approved.json b/processor/stream/test_approved_es_documents/testIntakeIntegrationRumErrors.approved.json index 03da29eda9e..56206933246 100644 --- a/processor/stream/test_approved_es_documents/testIntakeIntegrationRumErrors.approved.json +++ b/processor/stream/test_approved_es_documents/testIntakeIntegrationRumErrors.approved.json @@ -85,10 +85,6 @@ } } ] - }, - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" } }, "http": { diff --git a/processor/stream/test_approved_es_documents/testIntakeIntegrationRumTransactions.approved.json b/processor/stream/test_approved_es_documents/testIntakeIntegrationRumTransactions.approved.json index 0a87e38411e..a8b26e0ba48 100644 --- a/processor/stream/test_approved_es_documents/testIntakeIntegrationRumTransactions.approved.json +++ b/processor/stream/test_approved_es_documents/testIntakeIntegrationRumTransactions.approved.json @@ -49,10 +49,6 @@ "tbt": 3.4 }, "id": "611f4fa950f04631", - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" - }, "sampled": true, "span_count": { "started": 1 @@ -142,7 +138,9 @@ "transaction": { "id": "611f4fa950f04631" }, - "url.original": "http://localhost:8000/test/e2e/general-usecase/span", + "url": { + "original": "http://localhost:8000/test/e2e/general-usecase/span" + }, "user_agent": { "original": "rum-2.0" } diff --git a/processor/stream/test_approved_es_documents/testIntakeIntegrationSpans.approved.json b/processor/stream/test_approved_es_documents/testIntakeIntegrationSpans.approved.json index 52760954679..3368e3cb59d 100644 --- a/processor/stream/test_approved_es_documents/testIntakeIntegrationSpans.approved.json +++ b/processor/stream/test_approved_es_documents/testIntakeIntegrationSpans.approved.json @@ -670,7 +670,9 @@ "trace": { "id": "abcdef0123456789abcdef9876543210" }, - "url.original": "http://localhost:8000", + "url": { + "original": "http://localhost:8000" + }, "user": { "domain": "ldap://abc", "email": "s@test.com", diff --git a/processor/stream/test_approved_es_documents/testIntakeIntegrationTransactions.approved.json b/processor/stream/test_approved_es_documents/testIntakeIntegrationTransactions.approved.json index 01eba0048fe..3a0ecb0a29e 100644 --- a/processor/stream/test_approved_es_documents/testIntakeIntegrationTransactions.approved.json +++ b/processor/stream/test_approved_es_documents/testIntakeIntegrationTransactions.approved.json @@ -297,10 +297,6 @@ }, "id": "4340a8e0df1906ecbfa9", "name": "GET /api/types", - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" - }, "result": "success", "sampled": true, "span_count": { diff --git a/processor/stream/test_approved_es_documents/testIntakeRUMV3Errors.approved.json b/processor/stream/test_approved_es_documents/testIntakeRUMV3Errors.approved.json index 7ec0ef5bba9..3140bd1984d 100644 --- a/processor/stream/test_approved_es_documents/testIntakeRUMV3Errors.approved.json +++ b/processor/stream/test_approved_es_documents/testIntakeRUMV3Errors.approved.json @@ -42,11 +42,7 @@ "type": "Error" } ], - "id": "3661352868c17c78b773d2f1beae6d41", - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" - } + "id": "3661352868c17c78b773d2f1beae6d41" }, "http": { "request": { diff --git a/processor/stream/test_approved_es_documents/testIntakeRUMV3Events.approved.json b/processor/stream/test_approved_es_documents/testIntakeRUMV3Events.approved.json index db6d4df432a..a91e91a5d3f 100644 --- a/processor/stream/test_approved_es_documents/testIntakeRUMV3Events.approved.json +++ b/processor/stream/test_approved_es_documents/testIntakeRUMV3Events.approved.json @@ -123,10 +123,6 @@ } }, "name": "general-usecase-initial-p-load", - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" - }, "sampled": true, "span_count": { "dropped": 1, @@ -549,7 +545,9 @@ "transaction": { "id": "ec2e280be8345240" }, - "url.original": "http://localhost:8000/test/e2e/general-usecase/app.e2e-bundle.min.js?token=REDACTED", + "url": { + "original": "http://localhost:8000/test/e2e/general-usecase/app.e2e-bundle.min.js?token=REDACTED" + }, "user": { "email": "user@email.com", "id": "123", @@ -724,7 +722,9 @@ "transaction": { "id": "ec2e280be8345240" }, - "url.original": "http://localhost:8000/test/e2e/common/data.json?test=hamid", + "url": { + "original": "http://localhost:8000/test/e2e/common/data.json?test=hamid" + }, "user": { "email": "user@email.com", "id": "123", @@ -826,7 +826,9 @@ "transaction": { "id": "ec2e280be8345240" }, - "url.original": "http://localhost:8003/data", + "url": { + "original": "http://localhost:8003/data" + }, "user": { "email": "user@email.com", "id": "123", @@ -929,7 +931,9 @@ "transaction": { "id": "ec2e280be8345240" }, - "url.original": "http://localhost:8003/fetch", + "url": { + "original": "http://localhost:8003/fetch" + }, "user": { "email": "user@email.com", "id": "123", diff --git a/systemtest/approvals/TestNoMatchingSourcemap.approved.json b/systemtest/approvals/TestNoMatchingSourcemap.approved.json index b5d8fc013ec..3fc1d6db555 100644 --- a/systemtest/approvals/TestNoMatchingSourcemap.approved.json +++ b/systemtest/approvals/TestNoMatchingSourcemap.approved.json @@ -77,7 +77,9 @@ "transaction": { "id": "611f4fa950f04631" }, - "url.original": "http://localhost:8000/test/e2e/general-usecase/span" + "url": { + "original": "http://localhost:8000/test/e2e/general-usecase/span" + } } ] } diff --git a/systemtest/approvals/TestRUMErrorSourcemapping.approved.json b/systemtest/approvals/TestRUMErrorSourcemapping.approved.json index 4effabf07a1..841df9f446f 100644 --- a/systemtest/approvals/TestRUMErrorSourcemapping.approved.json +++ b/systemtest/approvals/TestRUMErrorSourcemapping.approved.json @@ -249,10 +249,6 @@ } } ] - }, - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" } }, "event": { diff --git a/systemtest/approvals/TestRUMSpanSourcemapping.approved.json b/systemtest/approvals/TestRUMSpanSourcemapping.approved.json index 64c603ff346..ab95d079e5b 100644 --- a/systemtest/approvals/TestRUMSpanSourcemapping.approved.json +++ b/systemtest/approvals/TestRUMSpanSourcemapping.approved.json @@ -128,7 +128,9 @@ "transaction": { "id": "611f4fa950f04631" }, - "url.original": "http://localhost:8000/test/e2e/general-usecase/span" + "url": { + "original": "http://localhost:8000/test/e2e/general-usecase/span" + } } ] } diff --git a/systemtest/approvals/TestSourcemapUploadInvalidElasticsearchConfig.approved.json b/systemtest/approvals/TestSourcemapUploadInvalidElasticsearchConfig.approved.json index 59b399291cb..305389a8c89 100644 --- a/systemtest/approvals/TestSourcemapUploadInvalidElasticsearchConfig.approved.json +++ b/systemtest/approvals/TestSourcemapUploadInvalidElasticsearchConfig.approved.json @@ -256,10 +256,6 @@ } } ] - }, - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" } }, "event": { diff --git a/systemtest/approvals/TestTransactionAggregation.approved.json b/systemtest/approvals/TestTransactionAggregation.approved.json index 599d6da22b4..95684a51231 100644 --- a/systemtest/approvals/TestTransactionAggregation.approved.json +++ b/systemtest/approvals/TestTransactionAggregation.approved.json @@ -37,7 +37,7 @@ } }, "timeseries": { - "instance": "systemtest:abc:29d4be3fbd7f200f" + "instance": "systemtest:abc:d8f2bb8faa13bba6" }, "transaction": { "name": "abc", @@ -90,7 +90,7 @@ } }, "timeseries": { - "instance": "systemtest:def:41b636ee77bc8c1c" + "instance": "systemtest:def:8445550d2ba82fde" }, "transaction": { "name": "def", diff --git a/systemtest/approvals/TestTransactionAggregationShutdown.approved.json b/systemtest/approvals/TestTransactionAggregationShutdown.approved.json index 6804f9c5a50..c729be9e333 100644 --- a/systemtest/approvals/TestTransactionAggregationShutdown.approved.json +++ b/systemtest/approvals/TestTransactionAggregationShutdown.approved.json @@ -37,7 +37,7 @@ } }, "timeseries": { - "instance": "systemtest:name:56ef3b5d147616b4" + "instance": "systemtest:name:28a46e05f123d23f" }, "transaction": { "name": "name", diff --git a/tests/system/error.approved.json b/tests/system/error.approved.json index 2a722df6246..f04e00a6ca1 100644 --- a/tests/system/error.approved.json +++ b/tests/system/error.approved.json @@ -263,10 +263,6 @@ } } ] - }, - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" } }, "event": { diff --git a/tests/system/spans.approved.json b/tests/system/spans.approved.json index ab333394f22..bf631776f5f 100644 --- a/tests/system/spans.approved.json +++ b/tests/system/spans.approved.json @@ -115,7 +115,9 @@ "transaction": { "id": "945254c567a5417e" }, - "url.original": "http://localhost:8000" + "url": { + "original": "http://localhost:8000" + } }, { "@timestamp": "2017-05-30T18:53:42.281Z", diff --git a/tests/system/transaction.approved.json b/tests/system/transaction.approved.json index 842c7c8ca78..87b201ba719 100644 --- a/tests/system/transaction.approved.json +++ b/tests/system/transaction.approved.json @@ -467,10 +467,6 @@ } }, "name": "GET /api/types", - "page": { - "referer": "http://localhost:8000/test/e2e/", - "url": "http://localhost:8000/test/e2e/general-usecase/" - }, "result": "success", "sampled": true, "span_count": { diff --git a/x-pack/apm-server/aggregation/spanmetrics/aggregator.go b/x-pack/apm-server/aggregation/spanmetrics/aggregator.go index 6f70926c461..efa99516e4f 100644 --- a/x-pack/apm-server/aggregation/spanmetrics/aggregator.go +++ b/x-pack/apm-server/aggregation/spanmetrics/aggregator.go @@ -202,7 +202,7 @@ func (a *Aggregator) processSpan(event *model.APMEvent) model.APMEvent { serviceEnvironment: event.Service.Environment, serviceName: event.Service.Name, agentName: event.Agent.Name, - outcome: event.Span.Outcome, + outcome: event.Event.Outcome, resource: event.Span.DestinationService.Resource, } duration := time.Duration(event.Span.Duration * float64(time.Millisecond)) @@ -264,11 +264,11 @@ func makeMetricset(timestamp time.Time, key aggregationKey, metrics spanMetrics, Name: key.serviceName, Environment: key.serviceEnvironment, }, + Event: model.Event{ + Outcome: key.outcome, + }, Metricset: &model.Metricset{ Name: metricsetName, - Event: model.MetricsetEventCategorization{ - Outcome: key.outcome, - }, Span: model.MetricsetSpan{ DestinationService: model.DestinationService{Resource: key.resource}, }, diff --git a/x-pack/apm-server/aggregation/spanmetrics/aggregator_test.go b/x-pack/apm-server/aggregation/spanmetrics/aggregator_test.go index fc39c617f68..2f4582b1819 100644 --- a/x-pack/apm-server/aggregation/spanmetrics/aggregator_test.go +++ b/x-pack/apm-server/aggregation/spanmetrics/aggregator_test.go @@ -117,11 +117,9 @@ func TestAggregatorRun(t *testing.T) { assert.ElementsMatch(t, []model.APMEvent{{ Agent: model.Agent{Name: "java"}, Service: model.Service{Name: "service-A"}, + Event: model.Event{Outcome: "success"}, Metricset: &model.Metricset{ Name: "service_destination", - Event: model.MetricsetEventCategorization{ - Outcome: "success", - }, Span: model.MetricsetSpan{ DestinationService: model.DestinationService{Resource: destinationX}, }, @@ -134,11 +132,9 @@ func TestAggregatorRun(t *testing.T) { }, { Agent: model.Agent{Name: "java"}, Service: model.Service{Name: "service-A"}, + Event: model.Event{Outcome: "failure"}, Metricset: &model.Metricset{ Name: "service_destination", - Event: model.MetricsetEventCategorization{ - Outcome: "failure", - }, Span: model.MetricsetSpan{ DestinationService: model.DestinationService{Resource: destinationZ}, }, @@ -151,11 +147,9 @@ func TestAggregatorRun(t *testing.T) { }, { Agent: model.Agent{Name: "java"}, Service: model.Service{Name: "service-A"}, + Event: model.Event{Outcome: "success"}, Metricset: &model.Metricset{ Name: "service_destination", - Event: model.MetricsetEventCategorization{ - Outcome: "success", - }, Span: model.MetricsetSpan{ DestinationService: model.DestinationService{Resource: destinationZ}, }, @@ -168,11 +162,9 @@ func TestAggregatorRun(t *testing.T) { }, { Agent: model.Agent{Name: "python"}, Service: model.Service{Name: "service-B"}, + Event: model.Event{Outcome: "success"}, Metricset: &model.Metricset{ Name: "service_destination", - Event: model.MetricsetEventCategorization{ - Outcome: "success", - }, Span: model.MetricsetSpan{ DestinationService: model.DestinationService{Resource: destinationZ}, }, @@ -225,11 +217,9 @@ func TestAggregatorOverflow(t *testing.T) { assert.Equal(t, model.APMEvent{ Agent: model.Agent{Name: "agent"}, Service: model.Service{Name: "service"}, + Event: model.Event{Outcome: "success"}, Metricset: &model.Metricset{ Name: "service_destination", - Event: model.MetricsetEventCategorization{ - Outcome: "success", - }, Span: model.MetricsetSpan{ DestinationService: model.DestinationService{Resource: "destination3"}, }, @@ -251,11 +241,11 @@ func makeSpan( event := model.APMEvent{ Agent: model.Agent{Name: agentName}, Service: model.Service{Name: serviceName}, + Event: model.Event{Outcome: outcome}, Span: &model.Span{ Name: serviceName + ":" + destinationServiceResource, Duration: duration.Seconds() * 1000, RepresentativeCount: count, - Outcome: outcome, }, } if destinationServiceResource != "" { diff --git a/x-pack/apm-server/aggregation/txmetrics/aggregator.go b/x-pack/apm-server/aggregation/txmetrics/aggregator.go index 319613fdc2b..4b48adfdb8f 100644 --- a/x-pack/apm-server/aggregation/txmetrics/aggregator.go +++ b/x-pack/apm-server/aggregation/txmetrics/aggregator.go @@ -339,11 +339,11 @@ func (a *Aggregator) updateTransactionMetrics(key transactionAggregationKey, has func (a *Aggregator) makeTransactionAggregationKey(event model.APMEvent) transactionAggregationKey { return transactionAggregationKey{ - traceRoot: event.Transaction.ParentID == "", - transactionName: event.Transaction.Name, - transactionOutcome: event.Transaction.Outcome, - transactionResult: event.Transaction.Result, - transactionType: event.Transaction.Type, + traceRoot: event.Transaction.ParentID == "", + transactionName: event.Transaction.Name, + transactionResult: event.Transaction.Result, + transactionType: event.Transaction.Type, + eventOutcome: event.Event.Outcome, agentName: event.Agent.Name, serviceEnvironment: event.Service.Environment, @@ -381,11 +381,11 @@ func makeMetricset( Host: model.Host{ Hostname: key.hostname, }, + Event: model.Event{ + Outcome: key.eventOutcome, + }, Metricset: &model.Metricset{ Name: metricsetName, - Event: model.MetricsetEventCategorization{ - Outcome: key.transactionOutcome, - }, Transaction: model.MetricsetTransaction{ Name: key.transactionName, Type: key.transactionType, @@ -434,9 +434,9 @@ type transactionAggregationKey struct { serviceName string serviceVersion string transactionName string - transactionOutcome string transactionResult string transactionType string + eventOutcome string } func (k *transactionAggregationKey) hash() uint64 { @@ -452,9 +452,9 @@ func (k *transactionAggregationKey) hash() uint64 { h.WriteString(k.serviceName) h.WriteString(k.serviceVersion) h.WriteString(k.transactionName) - h.WriteString(k.transactionOutcome) h.WriteString(k.transactionResult) h.WriteString(k.transactionType) + h.WriteString(k.eventOutcome) return h.Sum64() } diff --git a/x-pack/apm-server/aggregation/txmetrics/aggregator_test.go b/x-pack/apm-server/aggregation/txmetrics/aggregator_test.go index dc712ac472f..486cd8d1a4e 100644 --- a/x-pack/apm-server/aggregation/txmetrics/aggregator_test.go +++ b/x-pack/apm-server/aggregation/txmetrics/aggregator_test.go @@ -396,9 +396,9 @@ func TestAggregationFields(t *testing.T) { input := model.APMEvent{Transaction: &model.Transaction{RepresentativeCount: 1}} inputFields := []*string{ &input.Transaction.Name, - &input.Transaction.Outcome, &input.Transaction.Result, &input.Transaction.Type, + &input.Event.Outcome, &input.Agent.Name, &input.Service.Environment, &input.Service.Name, @@ -411,12 +411,9 @@ func TestAggregationFields(t *testing.T) { addExpectedCount := func(expectedCount int64) { expectedEvent := input expectedEvent.Transaction = nil + expectedEvent.Event.Outcome = input.Event.Outcome expectedEvent.Metricset = &model.Metricset{ Name: "transaction", - //Metadata: input.Metadata, - Event: model.MetricsetEventCategorization{ - Outcome: input.Transaction.Outcome, - }, Transaction: model.MetricsetTransaction{ Name: input.Transaction.Name, Type: input.Transaction.Type, diff --git a/x-pack/apm-server/sampling/groups.go b/x-pack/apm-server/sampling/groups.go index 0bf8734d11a..bc9d23c3cf0 100644 --- a/x-pack/apm-server/sampling/groups.go +++ b/x-pack/apm-server/sampling/groups.go @@ -50,7 +50,7 @@ func (g *policyGroup) match(transactionEvent *model.APMEvent) bool { if g.policy.ServiceEnvironment != "" && g.policy.ServiceEnvironment != transactionEvent.Service.Environment { return false } - if g.policy.TraceOutcome != "" && g.policy.TraceOutcome != transactionEvent.Transaction.Outcome { + if g.policy.TraceOutcome != "" && g.policy.TraceOutcome != transactionEvent.Event.Outcome { return false } if g.policy.TraceName != "" && g.policy.TraceName != transactionEvent.Transaction.Name { diff --git a/x-pack/apm-server/sampling/groups_test.go b/x-pack/apm-server/sampling/groups_test.go index 90c03fd7e28..7b29c41253e 100644 --- a/x-pack/apm-server/sampling/groups_test.go +++ b/x-pack/apm-server/sampling/groups_test.go @@ -22,9 +22,11 @@ func TestTraceGroupsPolicies(t *testing.T) { Name: serviceName, Environment: serviceEnvironment, }, + Event: model.Event{ + Outcome: traceOutcome, + }, Transaction: &model.Transaction{ Name: traceName, - Outcome: traceOutcome, TraceID: uuid.Must(uuid.NewV4()).String(), ID: uuid.Must(uuid.NewV4()).String(), },