diff --git a/packetbeat/_meta/kibana/default/dashboard/Packetbeat-tls.json b/packetbeat/_meta/kibana/default/dashboard/Packetbeat-tls.json index ecf4bc59a250..5f27a5aca342 100644 --- a/packetbeat/_meta/kibana/default/dashboard/Packetbeat-tls.json +++ b/packetbeat/_meta/kibana/default/dashboard/Packetbeat-tls.json @@ -13,7 +13,7 @@ }, "id": "Navigation", "type": "visualization", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 10 }, { @@ -24,14 +24,14 @@ }, "savedSearchId": "ffc3c0b0-d2d7-11e7-9914-4982455b3063", "title": "TLS Sessions", - "uiStateJSON": "{\"vis\":{\"colors\":{\"false\":\"#E24D42\",\"true\":\"#7EB26D\"}}}", + "uiStateJSON": "{\"vis\":{\"colors\":{\"false\":\"#E24D42\",\"true\":\"#7EB26D\"},\"legendOpen\":false}}", "version": 1, "visState": "{\"title\":\"TLS Sessions\",\"type\":\"histogram\",\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"labels\":{\"show\":true,\"truncate\":100},\"position\":\"bottom\",\"scale\":{\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{},\"type\":\"category\"}],\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"},\"valueAxis\":\"ValueAxis-1\"},\"legendPosition\":\"right\",\"seriesParams\":[{\"data\":{\"id\":\"1\",\"label\":\"Count\"},\"drawLinesBetweenPoints\":true,\"mode\":\"stacked\",\"show\":\"true\",\"showCircles\":true,\"type\":\"histogram\",\"valueAxis\":\"ValueAxis-1\"}],\"times\":[],\"type\":\"histogram\",\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"labels\":{\"filter\":false,\"rotate\":0,\"show\":true,\"truncate\":100},\"name\":\"LeftAxis-1\",\"position\":\"left\",\"scale\":{\"mode\":\"normal\",\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{\"text\":\"Count\"},\"type\":\"value\"}]},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{},\"customLabel\":\"Sessions per minute\"}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"tls.handshake_completed\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\",\"json\":\"\",\"customLabel\":\"Handshake completed\"}}]}" }, "id": "059fe5e0-d2dd-11e7-9914-4982455b3063", "type": "visualization", - "updated_at": "2017-11-29T00:29:13.363Z", - "version": 1 + "updated_at": "2017-11-30T00:11:22.296Z", + "version": 2 }, { "attributes": { @@ -46,7 +46,7 @@ }, "id": "c14377a0-d353-11e7-9914-4982455b3063", "type": "visualization", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -62,7 +62,7 @@ }, "id": "061de380-d361-11e7-9914-4982455b3063", "type": "visualization", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -79,7 +79,7 @@ }, "id": "a28d09d0-d361-11e7-9914-4982455b3063", "type": "visualization", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -96,7 +96,7 @@ }, "id": "0af0b790-d37d-11e7-9914-4982455b3063", "type": "visualization", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -113,7 +113,7 @@ }, "id": "ae6e33c0-d37d-11e7-9914-4982455b3063", "type": "visualization", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -130,7 +130,7 @@ }, "id": "2c467370-d392-11e7-8fa0-232aa9259081", "type": "visualization", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -147,7 +147,7 @@ }, "id": "0958a910-d396-11e7-8fa0-232aa9259081", "type": "visualization", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -164,7 +164,7 @@ }, "id": "86743f90-d396-11e7-8fa0-232aa9259081", "type": "visualization", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -181,7 +181,7 @@ }, "id": "463d2bf0-d3a8-11e7-9081-ab2af08e9961", "type": "visualization", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -198,9 +198,26 @@ }, "id": "ad2a8b50-d49d-11e7-996f-bd7c1ca4591b", "type": "visualization", - "updated_at": "2017-11-29T00:38:53.829Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"$state\":{\"store\":\"appState\"},\"meta\":{\"alias\":null,\"disabled\":false,\"index\":\"packetbeat-*\",\"key\":\"responsetime\",\"negate\":false,\"params\":{\"gte\":0,\"lt\":1000},\"type\":\"range\",\"value\":\"0 to 1,000\"},\"range\":{\"responsetime\":{\"gte\":0,\"lt\":1000}}}],\"query\":{\"language\":\"lucene\",\"query\":\"\"}}" + }, + "savedSearchId": "8e2af860-d520-11e7-9fff-7b1ebf397ba9", + "title": "TLS handshake latency", + "uiStateJSON": "{\"vis\":{\"legendOpen\":false}}", + "version": 1, + "visState": "{\"title\":\"TLS handshake latency\",\"type\":\"area\",\"params\":{\"type\":\"area\",\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100,\"filter\":true},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Count\"}}],\"seriesParams\":[{\"show\":\"true\",\"type\":\"area\",\"mode\":\"stacked\",\"data\":{\"label\":\"Count\",\"id\":\"1\"},\"drawLinesBetweenPoints\":true,\"showCircles\":true,\"interpolate\":\"linear\",\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"responsetime\",\"interval\":2,\"extended_bounds\":{},\"customLabel\":\"Handshake latency (milliseconds)\"}}]}" + }, + "id": "d2e15950-d560-11e7-9fff-7b1ebf397ba9", + "type": "visualization", + "updated_at": "2017-11-30T00:10:49.715Z", + "version": 2 + }, { "attributes": { "columns": [ @@ -220,7 +237,7 @@ }, "id": "ffc3c0b0-d2d7-11e7-9914-4982455b3063", "type": "search", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -242,7 +259,7 @@ }, "id": "94908e80-d2d8-11e7-9914-4982455b3063", "type": "search", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -264,7 +281,7 @@ }, "id": "bf3d23b0-d37c-11e7-9914-4982455b3063", "type": "search", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -286,7 +303,7 @@ }, "id": "8f0ff590-d37d-11e7-9914-4982455b3063", "type": "search", - "updated_at": "2017-11-29T00:29:13.363Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, { @@ -308,9 +325,31 @@ }, "id": "6b1b1360-d49d-11e7-996f-bd7c1ca4591b", "type": "search", - "updated_at": "2017-11-29T00:37:02.998Z", + "updated_at": "2017-11-29T15:31:44.592Z", "version": 1 }, + { + "attributes": { + "columns": [ + "_source" + ], + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"packetbeat-*\",\"highlightAll\":true,\"version\":true,\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"filter\":[{\"$state\":{\"store\":\"appState\"},\"exists\":{\"field\":\"tls.handshake_completed\"},\"meta\":{\"alias\":null,\"disabled\":false,\"index\":\"packetbeat-*\",\"key\":\"tls.handshake_completed\",\"negate\":false,\"type\":\"exists\",\"value\":\"exists\"}},{\"$state\":{\"store\":\"appState\"},\"exists\":{\"field\":\"responsetime\"},\"meta\":{\"alias\":null,\"disabled\":false,\"index\":\"packetbeat-*\",\"key\":\"responsetime\",\"negate\":false,\"type\":\"exists\",\"value\":\"exists\"}}]}" + }, + "sort": [ + "@timestamp", + "desc" + ], + "title": "TLS handshake latency", + "version": 1 + }, + "id": "8e2af860-d520-11e7-9fff-7b1ebf397ba9", + "type": "search", + "updated_at": "2017-11-29T16:33:23.311Z", + "version": 2 + }, { "attributes": { "description": "TLS Sessions", @@ -319,17 +358,17 @@ "searchSourceJSON": "{\"filter\":[],\"query\":{\"language\":\"lucene\",\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"default_field\":\"*\",\"query\":\"*\"}}},\"highlightAll\":true,\"version\":true}" }, "optionsJSON": "{\"darkTheme\":false,\"useMargins\":false}", - "panelsJSON": "[{\"gridData\":{\"h\":4,\"i\":\"4\",\"w\":3,\"x\":0,\"y\":0},\"id\":\"Navigation\",\"panelIndex\":\"4\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"gridData\":{\"h\":4,\"i\":\"8\",\"w\":9,\"x\":3,\"y\":0},\"id\":\"059fe5e0-d2dd-11e7-9914-4982455b3063\",\"panelIndex\":\"8\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"gridData\":{\"h\":3,\"i\":\"9\",\"w\":3,\"x\":3,\"y\":7},\"id\":\"c14377a0-d353-11e7-9914-4982455b3063\",\"panelIndex\":\"9\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"gridData\":{\"h\":3,\"i\":\"10\",\"w\":2,\"x\":0,\"y\":4},\"id\":\"061de380-d361-11e7-9914-4982455b3063\",\"panelIndex\":\"10\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"gridData\":{\"h\":3,\"i\":\"11\",\"w\":10,\"x\":2,\"y\":4},\"id\":\"a28d09d0-d361-11e7-9914-4982455b3063\",\"panelIndex\":\"11\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"gridData\":{\"h\":3,\"i\":\"12\",\"w\":3,\"x\":6,\"y\":7},\"id\":\"0af0b790-d37d-11e7-9914-4982455b3063\",\"panelIndex\":\"12\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"gridData\":{\"h\":3,\"i\":\"13\",\"w\":3,\"x\":9,\"y\":7},\"id\":\"ae6e33c0-d37d-11e7-9914-4982455b3063\",\"panelIndex\":\"13\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"gridData\":{\"h\":3,\"i\":\"14\",\"w\":3,\"x\":0,\"y\":7},\"id\":\"2c467370-d392-11e7-8fa0-232aa9259081\",\"panelIndex\":\"14\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"gridData\":{\"h\":3,\"i\":\"15\",\"w\":6,\"x\":0,\"y\":10},\"id\":\"0958a910-d396-11e7-8fa0-232aa9259081\",\"panelIndex\":\"15\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"gridData\":{\"h\":3,\"i\":\"16\",\"w\":6,\"x\":0,\"y\":13},\"id\":\"86743f90-d396-11e7-8fa0-232aa9259081\",\"panelIndex\":\"16\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"gridData\":{\"h\":3,\"i\":\"17\",\"w\":6,\"x\":6,\"y\":10},\"id\":\"463d2bf0-d3a8-11e7-9081-ab2af08e9961\",\"panelIndex\":\"17\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"gridData\":{\"w\":6,\"h\":3,\"x\":6,\"y\":13,\"i\":\"18\"},\"version\":\"7.0.0-alpha1-SNAPSHOT\",\"panelIndex\":\"18\",\"type\":\"visualization\",\"id\":\"ad2a8b50-d49d-11e7-996f-bd7c1ca4591b\"}]", + "panelsJSON": "[{\"panelIndex\":\"4\",\"gridData\":{\"x\":0,\"y\":0,\"w\":3,\"h\":4,\"i\":\"4\"},\"id\":\"Navigation\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"panelIndex\":\"8\",\"gridData\":{\"x\":3,\"y\":0,\"w\":9,\"h\":4,\"i\":\"8\"},\"id\":\"059fe5e0-d2dd-11e7-9914-4982455b3063\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"panelIndex\":\"9\",\"gridData\":{\"x\":3,\"y\":7,\"w\":3,\"h\":3,\"i\":\"9\"},\"id\":\"c14377a0-d353-11e7-9914-4982455b3063\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"panelIndex\":\"10\",\"gridData\":{\"x\":0,\"y\":4,\"w\":3,\"h\":3,\"i\":\"10\"},\"id\":\"061de380-d361-11e7-9914-4982455b3063\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"panelIndex\":\"11\",\"gridData\":{\"x\":0,\"y\":10,\"w\":12,\"h\":3,\"i\":\"11\"},\"id\":\"a28d09d0-d361-11e7-9914-4982455b3063\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"panelIndex\":\"12\",\"gridData\":{\"x\":6,\"y\":7,\"w\":3,\"h\":3,\"i\":\"12\"},\"id\":\"0af0b790-d37d-11e7-9914-4982455b3063\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"panelIndex\":\"13\",\"gridData\":{\"x\":9,\"y\":7,\"w\":3,\"h\":3,\"i\":\"13\"},\"id\":\"ae6e33c0-d37d-11e7-9914-4982455b3063\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"panelIndex\":\"14\",\"gridData\":{\"x\":0,\"y\":7,\"w\":3,\"h\":3,\"i\":\"14\"},\"id\":\"2c467370-d392-11e7-8fa0-232aa9259081\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"panelIndex\":\"15\",\"gridData\":{\"x\":0,\"y\":13,\"w\":6,\"h\":3,\"i\":\"15\"},\"id\":\"0958a910-d396-11e7-8fa0-232aa9259081\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"panelIndex\":\"16\",\"gridData\":{\"x\":0,\"y\":16,\"w\":6,\"h\":3,\"i\":\"16\"},\"id\":\"86743f90-d396-11e7-8fa0-232aa9259081\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"panelIndex\":\"17\",\"gridData\":{\"x\":6,\"y\":13,\"w\":6,\"h\":3,\"i\":\"17\"},\"id\":\"463d2bf0-d3a8-11e7-9081-ab2af08e9961\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"panelIndex\":\"18\",\"gridData\":{\"x\":6,\"y\":16,\"w\":6,\"h\":3,\"i\":\"18\"},\"id\":\"ad2a8b50-d49d-11e7-996f-bd7c1ca4591b\",\"type\":\"visualization\",\"version\":\"7.0.0-alpha1-SNAPSHOT\"},{\"panelIndex\":\"19\",\"gridData\":{\"x\":3,\"y\":4,\"w\":9,\"h\":3,\"i\":\"19\"},\"version\":\"7.0.0-alpha1-SNAPSHOT\",\"type\":\"visualization\",\"id\":\"d2e15950-d560-11e7-9fff-7b1ebf397ba9\"}]", "timeRestore": false, "title": "[Packetbeat] TLS Sessions", - "uiStateJSON": "{\"P-15\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-16\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-17\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}},\"P-7\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-18\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}", + "uiStateJSON": "{\"P-15\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-16\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-17\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-18\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}},\"P-7\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}", "version": 1 }, "id": "tls-sessions", "type": "dashboard", - "updated_at": "2017-11-29T00:39:28.426Z", + "updated_at": "2017-11-30T00:16:42.402Z", "version": 2 } ], "version": "7.0.0-alpha1-SNAPSHOT" -} +} \ No newline at end of file diff --git a/packetbeat/docs/images/tls-dashboard.png b/packetbeat/docs/images/tls-dashboard.png index a0715e839ce1..d3a518075a2e 100644 Binary files a/packetbeat/docs/images/tls-dashboard.png and b/packetbeat/docs/images/tls-dashboard.png differ diff --git a/packetbeat/protos/tls/tls.go b/packetbeat/protos/tls/tls.go index 8c66256a8606..2a20d0b5bd58 100644 --- a/packetbeat/protos/tls/tls.go +++ b/packetbeat/protos/tls/tls.go @@ -26,6 +26,7 @@ type tlsConnectionData struct { handshakeCompleted int8 eventSent bool + startTime, endTime time.Time } // TLS protocol plugin @@ -103,6 +104,9 @@ func (plugin *tlsPlugin) Parse( defer logp.Recover("ParseTLS exception") conn := ensureTLSConnection(private) + if private == nil { + conn.startTime = pkt.Ts + } conn = plugin.doParse(conn, pkt, tcptuple, dir) if conn == nil { return nil @@ -171,6 +175,7 @@ func (plugin *tlsPlugin) doParse( case resultEncrypted: conn.handshakeCompleted |= 1 << dir if conn.handshakeCompleted == 3 { + conn.endTime = pkt.Ts plugin.sendEvent(conn) } } @@ -343,6 +348,12 @@ func (plugin *tlsPlugin) createEvent(conn *tlsConnectionData) beat.Event { } } + // set "responsetime" if handshake completed + responseTime := int32(conn.endTime.Sub(conn.startTime) / time.Millisecond) + if responseTime >= 0 { + fields["responsetime"] = responseTime + } + timestamp := time.Now() return beat.Event{ Timestamp: timestamp, diff --git a/packetbeat/protos/tls/tls_test.go b/packetbeat/protos/tls/tls_test.go index a892357f8c41..d47071d28073 100644 --- a/packetbeat/protos/tls/tls_test.go +++ b/packetbeat/protos/tls/tls_test.go @@ -150,6 +150,9 @@ func TestClientHello(t *testing.T) { assert.Len(t, results.events, 1) event := results.events[0] + // Remove responsetime (but fail if not present) so that the test + // does not depend on execution speed + assert.NoError(t, event.Fields.Delete("responsetime")) b, err := json.Marshal(event.Fields) assert.Nil(t, err) assert.Equal(t, expectedClientHello, string(b)) @@ -218,6 +221,9 @@ func TestFragmentedHandshake(t *testing.T) { assert.Len(t, results.events, 1) event := results.events[0] + // Remove responsetime (but fail if not present) so that the test + // does not depend on execution speed + assert.NoError(t, event.Delete("responsetime")) b, err := json.Marshal(event.Fields) assert.Nil(t, err) assert.Equal(t, expectedClientHello, string(b))