diff --git a/x-pack/heartbeat/monitors/browser/synthexec/enrich.go b/x-pack/heartbeat/monitors/browser/synthexec/enrich.go index 57c5fe5a5a2..162bd3f5727 100644 --- a/x-pack/heartbeat/monitors/browser/synthexec/enrich.go +++ b/x-pack/heartbeat/monitors/browser/synthexec/enrich.go @@ -76,22 +76,13 @@ func (je *journeyEnricher) enrich(event *beat.Event, se *SynthEvent, fields StdS je.checkGroup = makeUuid() je.journey = se.Journey je.start = event.Timestamp - case "journey/end": + case "journey/end", "cmd/status": je.end = event.Timestamp } } else { event.Timestamp = time.Now() } - eventext.MergeEventFields(event, common.MapStr{ - "event": common.MapStr{ - "type": se.Type, - }, - "monitor": common.MapStr{ - "check_group": je.checkGroup, - }, - }) - // Id and name differs for inline and suite monitors // - We use the monitor id and name for inline journeys ignoring the // autogenerated `inline`journey id and name. @@ -104,10 +95,14 @@ func (je *journeyEnricher) enrich(event *beat.Event, se *SynthEvent, fields StdS name = fmt.Sprintf("%s - %s", name, je.journey.Name) } eventext.MergeEventFields(event, common.MapStr{ + "event": common.MapStr{ + "type": se.Type, + }, "monitor": common.MapStr{ - "id": id, - "name": name, - "type": fields.Type, + "check_group": je.checkGroup, + "id": id, + "name": name, + "type": fields.Type, }, }) @@ -139,7 +134,6 @@ func (je *journeyEnricher) enrichSynthEvent(event *beat.Event, se *SynthEvent) e // when an `afterAll` hook fails, for example, we don't wan't to include // a summary in the cmd/status event. if !je.journeyComplete { - je.end = event.Timestamp return je.createSummary(event) } case "journey/end": @@ -186,17 +180,27 @@ func (je *journeyEnricher) createSummary(event *beat.Event) error { down = 0 } + // Incase of syntax errors or incorrect runner options, the Synthetics + // runner would exit immediately with exitCode 1 and we do not set the duration + // to inform the journey never ran + if !je.start.IsZero() { + eventext.MergeEventFields(event, common.MapStr{ + "monitor": common.MapStr{ + "duration": common.MapStr{ + "us": int64(je.end.Sub(je.start) / time.Microsecond), + }, + }, + }) + } eventext.MergeEventFields(event, common.MapStr{ "url": je.urlFields, + "event": common.MapStr{ + "type": "heartbeat/summary", + }, "synthetics": common.MapStr{ "type": "heartbeat/summary", "journey": je.journey, }, - "monitor": common.MapStr{ - "duration": common.MapStr{ - "us": int64(je.end.Sub(je.start) / time.Microsecond), - }, - }, "summary": common.MapStr{ "up": up, "down": down, diff --git a/x-pack/heartbeat/monitors/browser/synthexec/enrich_test.go b/x-pack/heartbeat/monitors/browser/synthexec/enrich_test.go index 140ec86bdec..e8a874ec3aa 100644 --- a/x-pack/heartbeat/monitors/browser/synthexec/enrich_test.go +++ b/x-pack/heartbeat/monitors/browser/synthexec/enrich_test.go @@ -145,7 +145,6 @@ func TestJourneyEnricher(t *testing.T) { tests := []struct { name string isInline bool - se []*SynthEvent }{ { name: "suite monitor", @@ -406,3 +405,96 @@ func TestNoSummaryOnAfterHook(t *testing.T) { }) } } + +func TestCreateSummaryEvent(t *testing.T) { + tests := []struct { + name string + je *journeyEnricher + expected common.MapStr + wantErr bool + }{{ + name: "completed without errors", + je: &journeyEnricher{ + journey: &Journey{}, + start: time.Now(), + end: time.Now().Add(10 * time.Microsecond), + journeyComplete: true, + }, + expected: common.MapStr{ + "monitor.duration.us": int64(10), + "summary": common.MapStr{ + "down": 0, + "up": 1, + }, + }, + wantErr: false, + }, { + name: "completed with error", + je: &journeyEnricher{ + journey: &Journey{}, + start: time.Now(), + end: time.Now().Add(10 * time.Microsecond), + journeyComplete: true, + errorCount: 1, + firstError: fmt.Errorf("journey errored"), + }, + expected: common.MapStr{ + "monitor.duration.us": int64(10), + "summary": common.MapStr{ + "down": 1, + "up": 0, + }, + }, + wantErr: true, + }, { + name: "started, but exited without running steps", + je: &journeyEnricher{ + journey: &Journey{}, + start: time.Now(), + end: time.Now().Add(10 * time.Microsecond), + journeyComplete: false, + }, + expected: common.MapStr{ + "monitor.duration.us": int64(10), + "summary": common.MapStr{ + "down": 0, + "up": 1, + }, + }, + wantErr: true, + }, { + name: "syntax error - exited without starting", + je: &journeyEnricher{ + journey: &Journey{}, + end: time.Now().Add(10 * time.Microsecond), + journeyComplete: false, + errorCount: 1, + }, + expected: common.MapStr{ + "summary": common.MapStr{ + "down": 1, + "up": 0, + }, + }, + wantErr: true, + }} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + e := &beat.Event{} + err := tt.je.createSummary(e) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + common.MergeFields(tt.expected, common.MapStr{ + "url": common.MapStr{}, + "event.type": "heartbeat/summary", + "synthetics.type": "heartbeat/summary", + "synthetics.journey": Journey{}, + }, true) + testslike.Test(t, lookslike.Strict(lookslike.MustCompile(tt.expected)), e.Fields) + }) + } +} diff --git a/x-pack/heartbeat/monitors/browser/synthexec/synthtypes.go b/x-pack/heartbeat/monitors/browser/synthexec/synthtypes.go index 6a2bc8515f9..3fe625ef286 100644 --- a/x-pack/heartbeat/monitors/browser/synthexec/synthtypes.go +++ b/x-pack/heartbeat/monitors/browser/synthexec/synthtypes.go @@ -163,5 +163,4 @@ func (j Journey) ToMap() common.MapStr { "name": j.Name, "id": j.Id, } - }