Description
When working with beats and elastic-agent integrations, there are occasions in which the ingest pipelines might be slower than intended, looking at benchmarking stats it has pointed us towards the date processor
being the culprit.
With integrations that potentially have tens or hundreds of processors, a single date processor will still take up almost more time than almost the rest combined, no matter the complexity.
Just to give a small example to reproduce it on a brand new deployed ESS cluster, with 3 nodes, 8GB of ram and version 7.13.1:
First I create a new ingest pipeline, that has most of the available processors today:
PUT _ingest/pipeline/benchmarking
{
"description": "Benchmarking Pipeline",
"processors": [
{
"date": {
"description": "Converts timestamp to @timestamp with single format",
"field": "timestamp",
"target_field": "@timestamp",
"formats": [
"dd/MM/yyyy HH:mm:ss"
],
"timezone": "Europe/Amsterdam"
}
},
{
"append": {
"field": "append",
"value": [
"test1",
"test2",
"test3"
]
}
},
{
"convert": {
"field": "integer",
"type": "integer"
}
},
{
"dissect": {
"field": "message",
"pattern": "%{dissect}"
}
},
{
"fingerprint": {
"fields": [
"message"
],
"target_field": "fingerprint"
}
},
{
"grok": {
"field": "message",
"patterns": [
"%{GREEDYDATA:grok}"
]
}
},
{
"gsub": {
"field": "gsub",
"pattern": " ",
"replacement": ""
}
},
{
"join": {
"field": "join",
"separator": "-"
}
},
{
"json": {
"field": "jsontest",
"target_field": "json"
}
},
{
"kv": {
"field": "kv",
"field_split": " ",
"value_split": "="
}
},
{
"lowercase": {
"field": "lowercase"
}
},
{
"remove": {
"field": "remove"
}
},
{
"rename": {
"field": "rename",
"target_field": "renames"
}
},
{
"script": {
"description": "Extract 'tags' from 'env' field",
"lang": "painless",
"source": """
String[] test = ctx.testscript.splitOnToken('@');
ctx.testscriptoutput = test;
"""
}
},
{
"set": {
"description": "Set static value",
"field": "set",
"value": "setvalue"
}
},
{
"set": {
"description": "Set copy from field",
"field": "setcopy",
"copy_from": "set"
}
},
{
"split": {
"field": "split",
"separator": ","
}
},
{
"trim": {
"field": "trim"
}
},
{
"uppercase": {
"field": "uppercase"
}
},
{
"urldecode": {
"field": "urldecode"
}
},
{
"uri_parts": {
"field": "testurl",
"target_field": "url",
"keep_original": true,
"remove_if_successful": true
}
},
{
"user_agent" : {
"field" : "agent"
}
}
]
}
After this, I start ingesting some test documents, I tested with 80 documents only, because I already started to see the results I wanted to prove:
POST my-index-000001/_doc/?pipeline=benchmarking
{
"agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
"timestamp": "24/02/1989 10:20:20",
"append": ["value"],
"integer": "2",
"jsontest": """{"name": "test"}""",
"message": "sometestmessage",
"gsub": "test message",
"join": ["two", "messages"],
"kv": "name=john age=20",
"lowercase": "UPpPerCCase",
"uppercase": "lowercase",
"remove": "removeme",
"rename": "renameme",
"testscript": "test@elastic.co",
"split": "value1,value2",
"trim": " trimme ",
"urldecode": "https://www.elastic.co/test",
"testurl": "https://www.elastic.co/test"
}
After ingesting about 80 documents, this is the output of the node stats API for ingest metrics:
GET /_nodes/stats?metric=ingest&filter_path=nodes.*.ingest.pipelines
"benchmarking" : {
"count" : 80,
"time_in_millis" : 76,
"current" : 0,
"failed" : 0,
"processors" : [
{
"date" : {
"type" : "date",
"stats" : {
"count" : 80,
"time_in_millis" : 26,
"current" : 0,
"failed" : 0
}
}
},
{
"append" : {
"type" : "append",
"stats" : {
"count" : 80,
"time_in_millis" : 1,
"current" : 0,
"failed" : 0
}
}
},
{
"convert" : {
"type" : "convert",
"stats" : {
"count" : 80,
"time_in_millis" : 0,
"current" : 0,
"failed" : 0
}
}
},
{
"dissect" : {
"type" : "dissect",
"stats" : {
"count" : 80,
"time_in_millis" : 2,
"current" : 0,
"failed" : 0
}
}
},
{
"fingerprint" : {
"type" : "fingerprint",
"stats" : {
"count" : 80,
"time_in_millis" : 2,
"current" : 0,
"failed" : 0
}
}
},
{
"grok" : {
"type" : "grok",
"stats" : {
"count" : 80,
"time_in_millis" : 5,
"current" : 0,
"failed" : 0
}
}
},
{
"gsub" : {
"type" : "gsub",
"stats" : {
"count" : 80,
"time_in_millis" : 1,
"current" : 0,
"failed" : 0
}
}
},
{
"join" : {
"type" : "join",
"stats" : {
"count" : 80,
"time_in_millis" : 1,
"current" : 0,
"failed" : 0
}
}
},
{
"json" : {
"type" : "json",
"stats" : {
"count" : 80,
"time_in_millis" : 2,
"current" : 0,
"failed" : 0
}
}
},
{
"kv" : {
"type" : "kv",
"stats" : {
"count" : 80,
"time_in_millis" : 1,
"current" : 0,
"failed" : 0
}
}
},
{
"lowercase" : {
"type" : "lowercase",
"stats" : {
"count" : 80,
"time_in_millis" : 0,
"current" : 0,
"failed" : 0
}
}
},
{
"remove" : {
"type" : "remove",
"stats" : {
"count" : 80,
"time_in_millis" : 1,
"current" : 0,
"failed" : 0
}
}
},
{
"rename" : {
"type" : "rename",
"stats" : {
"count" : 80,
"time_in_millis" : 1,
"current" : 0,
"failed" : 0
}
}
},
{
"script" : {
"type" : "script",
"stats" : {
"count" : 80,
"time_in_millis" : 7,
"current" : 0,
"failed" : 0
}
}
},
{
"set" : {
"type" : "set",
"stats" : {
"count" : 80,
"time_in_millis" : 0,
"current" : 0,
"failed" : 0
}
}
},
{
"set" : {
"type" : "set",
"stats" : {
"count" : 80,
"time_in_millis" : 0,
"current" : 0,
"failed" : 0
}
}
},
{
"split" : {
"type" : "split",
"stats" : {
"count" : 80,
"time_in_millis" : 0,
"current" : 0,
"failed" : 0
}
}
},
{
"trim" : {
"type" : "trim",
"stats" : {
"count" : 80,
"time_in_millis" : 0,
"current" : 0,
"failed" : 0
}
}
},
{
"uppercase" : {
"type" : "uppercase",
"stats" : {
"count" : 80,
"time_in_millis" : 0,
"current" : 0,
"failed" : 0
}
}
},
{
"urldecode" : {
"type" : "urldecode",
"stats" : {
"count" : 80,
"time_in_millis" : 0,
"current" : 0,
"failed" : 0
}
}
},
{
"uri_parts" : {
"type" : "uri_parts",
"stats" : {
"count" : 80,
"time_in_millis" : 2,
"current" : 0,
"failed" : 0
}
}
},
{
"user_agent" : {
"type" : "user_agent",
"stats" : {
"count" : 80,
"time_in_millis" : 11,
"current" : 0,
"failed" : 0
}
}
}
]
},
As you can see, the amount of difference already is quite significant, while most processors spent less than 1 millisecond going through 80 documents, the date processor, with a single date format is already up in 26ms, and this value will just keep on getting further and further, and would only increase with ingest rates being much higher than in my test scenario.