OTTL Converter Functions in Edge Delta

Learn about OTTL Converter Functions.

OTTL Converter Functions

Converters provide utility functions for transforming telemetry data. They do not alter the original as they are not editors. Therefore converters are typically embedded within editors such as set.

For example, in Edge Delta you need to decode the log body from byte array and save it in another field or a cache before you can use it. See Working with the body and Working with a cache for more information.

Decode

The Decode converter decodes an encoded field.

Syntax: Decode(value, encoding)

  • value: the bracket notation location of the encoded field
  • encoding: the encoding type from the IANA encoding index

Input

[
	{
		"_type": "log",
		"body": "Deployment issue",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "c2ltcGxlLWhvc3Q=",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733442011940
	}
]

Statement

set(resource["decoded_host.name"], Decode(resource["host.name"], "base64"))

Output

[
	{
		"_type": "log",
		"body": "Deployment issue",
		"resource": {
			"decoded_host.name": "simple-host",
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "c2ltcGxlLWhvc3Q=",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733442074816
	}
]

The base64 encoded string c2ltcGxlLWhvc3Q= was decoded to simple-host and stored in the decoded_host.name field.

Concat

The Concat converter concatenates multiple fields with a specified delimiter.

Syntax: Concat(values, delimiter)

  • values: array of fields to concatenate
  • delimiter: a string separator between concatenated values

Input

[
	{
		"_type": "log",
		"body": "12:34 [INFO] hello info - i am an info log - username:foobar, password=fancycat",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "ED_TEST",
			"k8s.namespace": "my-namespace",
			"k8s.pod.name": "my-pod",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733443632205
	}
]

Statement

set(resource["pod_full_name"], Concat([resource["k8s.pod.name"], resource["k8s.namespace"]], "."))

Output

[
	{
		"_type": "log",
		"body": "12:34 [INFO] hello info - i am an info log - username:foobar, password=fancycat",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "ED_TEST",
			"k8s.namespace": "my-namespace",
			"k8s.pod.name": "my-pod",
			"pod_full_name": "my-pod.my-namespace",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733443608806
	}
]

The pod name and namespace were concatenated with a . to create a unique pod_full_name.

ConvertCase

The ConvertCase converter changes the case of a string field.

Syntax: ConvertCase(value, caseType)

  • value: the bracket notation location of the string field
  • caseType: the desired case format (“lower”, “upper”, “snake”, “camel”)

Input

[
	{
		"_type": "log",
		"attributes": {
			"method": "post"
		},
		"body": "172.28.34.214 - - [06/Dec/2024:03:39:40 +0000] \"POST /admin/users HTTP/1.1\" 204 0 \"-\" \"lambda.amazonaws.com\"",
		"resource": {...},
		"timestamp": 1733456539663
	}
]

Statement

set(attributes["method"], ConvertCase(attributes["method"], "upper"))

Output

[
	{
		"_type": "log",
		"attributes": {
			"method": "POST"
		},
		"body": "172.28.34.214 - - [06/Dec/2024:03:39:40 +0000] \"POST /admin/users HTTP/1.1\" 204 0 \"-\" \"lambda.amazonaws.com\"",
		"resource": {...},
		"timestamp": 1733456574823
	}
]

The method attribute was converted to uppercase.

ConvertAttributesToElementsXML

The ConvertAttributesToElementsXML converter changes attributes of XML elements to nested child elements.

Syntax: ConvertAttributesToElementsXML(xml_string)

  • xml_string: the bracket notation location of the XML string field

Consider this log:

<log timestamp="1730511053177" level="info"/>

As it is ingested it is escaped into JSON and saved as a byte array. See Understand Escaping Characters and Working with the body. Suppose the log is decoded and saved in an attribute named decoded.

Input

[
	{
		"_type": "log",
		"attributes": {
			"decoded": "<log timestamp=\"1730511053177\" level=\"info\"/>"
		},
		"body": "<log timestamp=\"1730511053177\" level=\"info\"/>",
		"resource": {...},
		"timestamp": 1733457562038
	}
]

Statement

set(attributes["elements"], ConvertAttributesToElementsXML(attributes["decoded"]))

Output

[
	{
		"_type": "log",
		"attributes": {
			"decoded": "<log timestamp=\"1730511053177\" level=\"info\"/>",
			"elements": "<log><timestamp>1730511053177</timestamp><level>info</level></log>"
		},
		"body": "<log timestamp=\"1730511053177\" level=\"info\"/>",
		"resource": {...},
		"timestamp": 1733457578941
	}
]

In the new elements attribute, the timestamp and level are converted into child elements within the log element.

ConvertTextToElementsXML

The ConvertTextToElementsXML converter wraps text content in an XML element with a dedicated tag.

Syntax: ConvertTextToElementsXML(xml_string, tag_name)

  • xml_string: the bracket notation location of the XML string field
  • tag_name (optional): the new tag name for wrapping the text

Consider the following log:

<system><event type="startup" severity="info"> System initializing...<message>Check configuration settings.</message></event>System initialized.</system>

As it is ingested it is escaped into JSON and saved as a byte array. See Understand Escaping Characters and Working with the body. Suppose the log is decoded and saved in an attribute named decoded.

Input

[
	{
		"_type": "log",
		"attributes": {
			"decoded": "<system><event type=\"startup\" severity=\"info\"> System initializing...<message>Check configuration settings.</message></event>System initialized.</system>"
		},
		"body": "<system><event type=\"startup\" severity=\"info\"> System initializing...<message>Check configuration settings.</message></event>System initialized.</system>",
		"resource": {...},
		"timestamp": 1733458494510
	}
]

Statement

set(attributes["elements"], ConvertTextToElementsXML(attributes["decoded"]))

Output

[
	{
		"_type": "log",
		"attributes": {
			"decoded": "<system><event type=\"startup\" severity=\"info\"> System initializing...<message>Check configuration settings.</message></event>System initialized.</system>",
			"elements": "<system><event type=\"startup\" severity=\"info\"><value>System initializing...</value><message>Check configuration settings.</message></event><value>System initialized.</value></system>"
		},
		"body": "<system><event type=\"startup\" severity=\"info\"> System initializing...<message>Check configuration settings.</message></event>System initialized.</system>",
		"resource": {...},
		"timestamp": 1733458517830
	}
]

The output includes the bare text nodes wrapped in <value> elements.

Double

The Double converter converts a given value to a double precision floating point type (float64). Use Int when you need whole numbers (e.g., status codes, counts). Use Double when dealing with measurements that may require precision or when the input might be a floating point number (e.g., time durations, temperatures).

Syntax: Double(value)

  • value: the bracket notation location of the field to convert.

Value types:

  • float64: Returns the value without changes.
  • string: Tries to parse a double from the string; returns nil if the parsing fails.
  • bool: Returns 1.0 if true, 0.0 if false.
  • int64: Converts the integer to a double.

Input

[
	{
		"_type": "log",
		"attributes": {
			"latency": "1025.9658"
		},
		"body": "2024-12-11T03:26:54.681811Z Successful NotificationService:229 request api_request spec:{uri:/api/v1/order method:POST latency:1025ms}",
		"resource": {...},
		"timestamp": 1733889840195
	}
]

Statement

set(attributes["latency_int"], Double(attributes["latency"]))

Output

[
	{
		"_type": "log",
		"attributes": {
			"latency": "1025.9658",
			"latency_int": 1025.9658
		},
		"body": "2024-12-11T03:26:54.681811Z Successful NotificationService:229 request api_request spec:{uri:/api/v1/order method:POST latency:1025ms}",
		"resource": {...},
		"timestamp": 1733889828934
	}
]

The http_code string "403" was converted to a double 403.

ExtractPatterns

The ExtractPatterns converter extracts regex matches from a string.

Syntax: ExtractPatterns(string, pattern)

  • string: the bracket notation location of the string field
  • pattern: the regex pattern to use for extraction, including a capture group to name the key.

Input

[
	{
		"_type": "log",
		"attributes": {
			"decoded_body": "\"error 404 at /home/reports failed"
		},
		"body": "\"error 404 at /home/reports failed",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "ED_TEST",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733892944490
	}
]

Statement

set(attributes["extracted"], ExtractPatterns(attributes["decoded_body"], "(?P<error_code>\\d{3})"))

Output

[
	{
		"_type": "log",
		"attributes": {
			"decoded_body": "\"error 404 at /home/reports failed",
			"extracted": {
				"error_code": "404"
			}
		},
		"body": "\"error 404 at /home/reports failed",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "ED_TEST",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733892979045
	}
]

The statement extracted three consecutive digits from the decoded_body using the named capture group error_code in the regex pattern.

ExtractGrokPatterns

The ExtractGrokPatterns converter uses Grok patterns to extract data from a string.

Syntax: ExtractGrokPatterns(string, grokPattern)

  • string: the bracket notation location of the string field
  • grokPattern: the grok pattern to use for extraction

Input

[
	{
		"_type": "log",
		"attributes": {
			"decoded_body": "time=1724177404|hostname=CPLPOL32|product=Firewall|layer_name=ENGCORE_MASTER"
		},
		"body": "time=1724177404|hostname=CPLPOL32|product=Firewall|layer_name=ENGCORE_MASTER",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "ED_TEST",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733727200176
	}
]

Statement

set(attributes["grokked"], ExtractGrokPatterns(attributes["decoded_body"], "time=(?P<log_timestamp>\\d+)\\|hostname=(?P<log_hostname>[^|]+)\\|product=(?P<log_product>[^|]+)\\|layer_name=(?P<log_layer_name>[^|]+)", true))

Output

[
	{
		"_type": "log",
		"attributes": {
			"decoded_body": "time=1724177404|hostname=CPLPOL32|product=Firewall|layer_name=ENGCORE_MASTER",
			"grokked": {
				"log_hostname": "CPLPOL32",
				"log_layer_name": "ENGCORE_MASTER",
				"log_product": "Firewall",
				"log_timestamp": "1724177404"
			}
		},
		"body": "time=1724177404|hostname=CPLPOL32|product=Firewall|layer_name=ENGCORE_MASTER",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "ED_TEST",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733727245095
	}
]

The ExtractGrokPatterns function was applied to extract structured data from the decoded_body attribute, which contained log information in a single string format. The transformation used a regular expression pattern to parse and extract parts of the log into key-value pairs, which were then stored in an attribute map called grokked.

FNV

The FNV converter hashes a string using the Fowler-Noll-Vo algorithm.

Syntax: FNV(value)

  • value: the bracket notation location of the string field to hash

Input

[
	{
		"_type": "log",
		"attributes": {
			"decoded_body": "time=1724177404|hostname=CPLPOL32|product=Firewall|layer_name=ENGCORE_MASTER"
		},
		"body": "time=1724177404|hostname=CPLPOL32|product=Firewall|layer_name=ENGCORE_MASTER",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "ED_TEST",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733737798161
	}
]

Statement

set(attributes["body_hash"], FNV(attributes["decoded_body"]))

Output

[
	{
		"_type": "log",
		"attributes": {
			"body_hash": 8015179274000194000,
			"decoded_body": "time=1724177404|hostname=CPLPOL32|product=Firewall|layer_name=ENGCORE_MASTER"
		},
		"body": "time=1724177404|hostname=CPLPOL32|product=Firewall|layer_name=ENGCORE_MASTER",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "ED_TEST",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733737825070
	}
]

The decoded_body attribute was hashed using the FNV algorithm and saved as the body_hash attribute.

Format

The Format converter formats a string with specified variables.

Syntax: Format(formatString, values)

  • formatString: the base string with placeholders for variables.
  • values: an array of values to fill into the placeholders. The placeholders in the format string are mapped to the values in the array based on their order. This means that the first placeholder corresponds to the first element in the values array.

You can use the following format Specifiers in the formatString:

  • %s: This specifier is used for strings. It replaces %s in the format string with the corresponding string value provided in the values array.
  • %d: This specifier is used for integers. It replaces %d in the format string with the integer value provided in the values array, formatted as a decimal number.
  • %f: Used for floating-point numbers. You can specify the precision (number of decimal places) as well, for example, %.2f for two decimal places.
  • %x and %X: Used for hexadecimal representation of numbers. %x produces lowercase hex letters (e.g., a to f), and %X produces uppercase hex letters (e.g., A to F).
  • %o: Used for octal representation of numbers.
  • %%: Used to insert a literal % character.

Match the type of the variable with the appropriate specifier to avoid runtime errors or incorrect formatting.

Input

[
	{
		"_type": "log",
		"attributes": {
			"bytes_sent": 152305,
			"device_name": "Router-X9000",
			"session_duration": 2735,
			"timestamp": "\"2024-12-09T10:26:47.487742422Z\""
		},
		"body": "High throughput observed. Device performance logged.",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "ED_TEST",
			"location": "DataCenter-5",
			"operator": "NetworkOperations",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733740007487
	}
]

Statement

set(attributes["formatted_device_report"], Format("Report - Device: %s; Operator: %s; Location: %s; Timestamp: %s; Details: Sent %d bytes over a session lasting %d seconds.", [attributes["device_name"], resource["operator"], resource["location"], attributes["timestamp"], attributes["bytes_sent"], attributes["session_duration"]]))

Output

[
	{
		"_type": "log",
		"attributes": {
			"bytes_sent": 152305,
			"device_name": "Router-X9000",
			"formatted_device_report": "Report - Device: Router-X9000; Operator: NetworkOperations; Location: DataCenter-5; Timestamp: \"2024-12-09T10:27:35.283863127Z\"; Details: Sent 152305 bytes over a session lasting 2735 seconds.",
			"session_duration": 2735,
			"timestamp": "\"2024-12-09T10:27:35.283863127Z\""
		},
		"body": "High throughput observed. Device performance logged.",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "ED_TEST",
			"location": "DataCenter-5",
			"operator": "NetworkOperations",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733740055283
	}
]

The statement created a formatted_device_report attribute that collates and formats various other fields into a new message.

GetXML

The GetXML converter extracts a part of an XML document using an XPath expression.

Syntax: GetXML(xml_string, xpath)

  • xml_string: the bracket notation location of the XML string field
  • xpath: the XPath query to extract the desired XML part

Input

[
	{
		"_type": "log",
		"attributes": {
			"decoded_body": "<log><timestamp>1730511053177</timestamp><level>info</level></log>"
		},
		"body": "<log><timestamp>1730511053177</timestamp><level>info</level></log>",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "ED_TEST",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733787219746
	}
]

Statement

set(attributes["log_level"], GetXML(attributes["decoded_body"], "/log/level"))

Output

[
	{
		"_type": "log",
		"attributes": {
			"decoded_body": "<log><timestamp>1730511053177</timestamp><level>info</level></log>",
			"log_level": "<level>info</level>"
		},
		"body": "<log><timestamp>1730511053177</timestamp><level>info</level></log>",
		"resource": {
			"ed.conf.id": "123456789",
			"ed.domain": "pipeline",
			"ed.org.id": "987654321",
			"ed.source.name": "__ed_dummy_test_input",
			"ed.source.type": "memory_input",
			"ed.tag": "loggen",
			"host.ip": "10.0.0.1",
			"host.name": "ED_TEST",
			"service.name": "ed-tester",
			"src_type": "memory_input"
		},
		"timestamp": 1733787262978
	}
]

The XPath query extracted the log_level XML object from the XML decoded_body.

Hex

The Hex converter converts a value to its hexadecimal representation.

Syntax: Hex(value)

  • value: a literal or the bracket notation location of the string field to convert. The value type must be a float64, string, bool, int64 or []byte.

Input

[
	{
		"_type": "log",
		"attributes": {
			"address": "0x3A28213A"
		},
		"body": "2023-12-01 12:34:56 [INFO] Memory allocation successful at address 0x3A28213A for process 1234.",
		"resource": {...}
]

Statement

set(attributes["hex_address"], Hex(attributes["address"]))

Output

[
	{
		"_type": "log",
		"attributes": {
			"address": "0x3A28213A",
			"hex_address": "30783341323832313341"
		},
		"body": "2023-12-01 12:34:56 [INFO] Memory allocation successful at address 0x3A28213A for process 1234.",
		"resource": {...},
		"timestamp": 1733809768919
	}
]

The memory address was converted to its hexadecimal string.

InsertXML

The InsertXML converter inserts a value into an XML document at a specified XPath location.

Syntax: InsertXML(xml_string, xpath, value)

  • xml_string: the bracket notation location of the XML string field
  • xpath: the XPath location to insert the new value
  • value: the value to insert

Input

[
	{
		"_type": "log",
		"body": "<log><message>SYSTEM</message></log>",
		"resource": {...},
		"timestamp": 1733886431434
	}
]

Statement

set(cache["body"], Decode(body, "utf-8"))
set(attributes["inserted_xml"], InsertXML(cache["body"], "/log", "<level>info</level>"))

See Working with the body and Working with a cache for more information.

Output

[
	{
		"_type": "log",
		"attributes": {
			"inserted_xml": "<log><message>SYSTEM</message><level>info</level></log>"
		},
		"body": "<log><message>SYSTEM</message></log>",
		"resource": {...},
		"timestamp": 1733886447480
	}
]

The XML data initially stored as a byte array in the body field was first decoded into a UTF-8 string format using the Decode function and temporarily stored in a cache for manipulation. This decoded XML string was then modified by inserting a new element <level>info</level> at the specified XPath location /log using the InsertXML function. The modified XML, now containing the newly added element, was stored under the attributes field as inserted_xml.

Int

Converts a given value to an integer type (int64). Use Int when you need whole numbers (e.g., status codes, counts). Use Double when dealing with measurements that may require precision or when the input might be a floating point number (e.g., time durations, temperatures).

Syntax: Int(value)

  • value: the bracket notation location of the field to convert.

Value types:

  • float64: The fractional part is discarded (truncation towards zero).
  • string: Attempts to parse an integer from the string; returns nil if the parsing fails.
  • bool: Returns 1 if true, 0 if false.
  • int64: Returns the value without changes.

Input

[
	{
		"_type": "log",
		"attributes": {
			"http_code": "307"
		},
		"body": "{\"host\": \"10.37.232.225\", \"user-identifier\": \"07af2ad8-a96c-4664-92a5-eb5629c41b6e\", \"time_local\": \"2024-12-11T03:26:53.801093Z\", \"method\": \"GET\", \"request\": \"/styles/main.css\", \"protocol\": \"HTTP/2\", \"status\": 307, \"bytes_sent\": 1151}",
		"resource": {...}
]

Statement

set(attributes["http_code_int"], Int(attributes["http_code"]))

Output

[
	{
		"_type": "log",
		"attributes": {
			"http_code": "307",
			"http_code_int": 307
		},
		"body": "{\"host\": \"10.37.232.225\", \"user-identifier\": \"07af2ad8-a96c-4664-92a5-eb5629c41b6e\", \"time_local\": \"2024-12-11T03:26:53.801093Z\", \"method\": \"GET\", \"request\": \"/styles/main.css\", \"protocol\": \"HTTP/2\", \"status\": 307, \"bytes_sent\": 1151}",
		"resource": {...},
		"timestamp": 1733892615586
	}
]

The http_code string was converted to an integer 307 and saved as http_code_int.

Len

The Len converter returns the length of the string, list, or map.

Syntax: Len(value)

  • value: the location of the field to measure

Input

[
	{
		"_type": "log",
		"timestamp": 1734491167973,
		"body": "time=hostname=SIMPLE|product=Firewall1",
		"resource": {...}
	}
]

Statement

set(attributes["body_length"], Len(body))

Output

[
	{
		"_type": "log",
		"timestamp": 1734491167973,
		"body": "time=hostname=SIMPLE|product=Firewall1",
		"resource": {...},
		"attributes": {
			"body_length": 38
		}
	}
]

The length of the list body was calculated as 38 characters.

MD5

The MD5 converter hashes a string using the MD5 hashing algorithm.

Syntax: MD5(value)

  • value: the bracket notation location of the string field to hash

Input

[
	{
		"_type": "log",
		"timestamp": 1734491967419,
		"body": "time=hostname=SIMPLE|product=Firewall1",
		"resource": {...},
		"attributes": {
			"decoded_body": "time=hostname=SIMPLE|product=Firewall1"
		}
	}
]

Statement

set(attributes["data_hash"], MD5(attributes["decoded_body"]))

Output

[
	{
		"_type": "log",
		"timestamp": 1734492005310,
		"body": "time=hostname=SIMPLE|product=Firewall1",
		"resource": {...},
		"attributes": {
			"data_hash": "2a6a4623ccbdb37abeb4eb3902a8acad",
			"decoded_body": "time=hostname=SIMPLE|product=Firewall1"
		}
	}
]

The string decoded_body-data was hashed using MD5 resulting in data_hash.

Duration, Hours, Microseconds, Milliseconds, Minutes, Nanoseconds, Seconds

The Duration converter converts a duration string into a time.Duration type.

Hours, Microseconds, Milliseconds, Minutes, Nanoseconds and Seconds return a float64 value from a time.Duration type. These are different to the converters such as Minute, Hour, Day, Month and Year converters, which extract a value from a time.Time type timestamp.

Syntax: Duration(string)

  • string: A string to convert to a duration type.

Syntax: Hours|Microseconds|Milliseconds|Minutes|Nanoseconds|Seconds(value)

  • value: a time.Duration.

Input

[
	{
		"_type": "log",
		"attributes": {
			"Duration": "3596s",
			"user": "user68565"
		},
		"body": "<83>Dec 11 00:32:46 firewall02 %FTD-4-113019: Group = sales-group, Username = user, IP = 192.168.10.5, Session disconnected. Session Type: VPN, Duration: 3596, Bytes xmt: 204800, Bytes rcv: 153600, Reason: idle timeout",
		"resource": {...},
		"timestamp": 1733878055814
	}
]

Statement

set(cache["inactive_hours"], Hours(Duration(attributes["Duration"])))
set(attributes["session_reason"], Format(" The session for %s has been terminated after %f hours of inactivity", [attributes["user"],cache["inactive_hours"]]))

See Working with a cache and Format.

Output

[
	{
		"_type": "log",
		"attributes": {
			"Duration": "3596s",
			"session_reason": " The session for user68565 has been terminated after 0.998889 hours of inactivity",
			"user": "user68565"
		},
		"body": "<83>Dec 11 00:32:46 firewall02 %FTD-4-113019: Group = sales-group, Username = user, IP = 192.168.10.5, Session disconnected. Session Type: VPN, Duration: 3596, Bytes xmt: 204800, Bytes rcv: 153600, Reason: idle timeout",
		"resource": {...},
		"timestamp": 1733878120460
	}
]

The session_reason attribute was calculated by converting the session duration from seconds to hours using the Hours function, which converts a given duration into hours. The Format function was then used to construct a descriptive message that incorporates both the username and the calculated inactive hours, enhancing the log’s clarity and usefulness for monitoring and analysis purposes.

The Duration function was necessary because the “Duration” attribute in the log’s attributes was provided as a string in the format “3596s”. To use this duration with the Hours function, which requires a time.Duration type as input, it was essential to first convert the string representation of the duration into an actual time.Duration type.

Minute, Hour, Day, Month, Year

The Minute, Hour, Day, Month and Year converters each extract an int64 value from a time.Time type timestamp. These are different to the converters such as Hours, Microseconds, Milliseconds, Minutes, Nanoseconds and Seconds, which return a value from a time.Duration type.

Syntax: Minute|Hour|Day|Month|Year(value)

  • value is a date in the time.Time format. Other formats cause it to fail.

Note: the timestamp field in Edge Delta is a UnixMilli format, not time.Time.

Input

[
	{
		"_type": "log",
		"body": "High throughput observed. Device performance logged.",
		"resource": {...},
		"timestamp": 1733742090432
	}
]

Statement

set(attributes["date_time"], Format("%04d-%02d-%02d %02dh%02d UTC", [Year(Now()), Month(Now()), Day(Now()), Hour(Now()), Minute(Now())]))

See Format and Now.

Output

[
	{
		"_type": "log",
		"attributes": {
			"date_time": "2024-12-09 11h01 UTC"
		},
		"body": "High throughput observed. Device performance logged.",
		"resource": {...},
		"timestamp": 1733742076089
	}
]

A new timestamp was created using Now functions and formatted using the Format function.

Now

The Now converter returns the current timestamp of type time.Time.

Syntax: Now()

Input

[
	{
		"_type": "log",
		"timestamp": 1734492333499,
		"body": "time=hostname=SIMPLE|product=Firewall1",
		"resource": {...}
	}
]

Statement

set(attributes["processed_timestamp"], UnixMilli(Now()))

See UnixMilli

Output

[
	{
		"_type": "log",
		"timestamp": 1734492333499,
		"body": "time=hostname=SIMPLE|product=Firewall1",
		"resource": {...},
		"attributes": {
			"processed_timestamp": 1734492333500
		}
	}
]

The current timestamp was recorded at the time of processing and converted into UnixMilli.

ParseCSV

The ParseCSV converter parses a CSV row with headers into an array of fields.

Syntax: ParseCSV(value, headers)

  • value: the bracket notation location or literal of a CSV row.
  • headers: the bracket notation location or literal of the CSV headers.

Input

[
	{
		"_type": "log",
		"timestamp": 1734493785759,
		"body": "log message",
		"resource": {...},
		"attributes": {
			"csv": "ABC123,user1,login,success",
			"csv_headers": "Session_ID,User_ID,Event_Type,Event_Details"
		}
	}
]

Statement

set(attributes["csv_parsed"], ParseCSV(attributes["csv"], attributes["csv_headers"]))

Output

[
	{
		"_type": "log",
		"timestamp": 1734493808937,
		"body": "log message",
		"resource": {...},
		"attributes": {
			"csv": "ABC123,user1,login,success",
			"csv_headers": "Session_ID,User_ID,Event_Type,Event_Details",
			"csv_parsed": {
				"Event_Details": "success",
				"Event_Type": "login",
				"Session_ID": "ABC123",
				"User_ID": "user1"
			}
		}
	}
]

The CSV row was parsed using the headers as field names.

ParseJSON

The ParseJSON converter parses a JSON string into an object.

Syntax: ParseJSON(value)

  • value: the bracket notation location of the JSON string to parse

Input

[
	{
		"_type": "log",
		"timestamp": 1734494063084,
		"body": "{\"host\": \"172.17.15.39\", \"user-identifier\": \"68b148de-7ce3-423c-b72d-64a4f21ecfc0\", \"time_local\": \"2024-12-15T22:40:53.723160Z\", \"method\": \"POST\", \"request\": \"/styles/main.css\", \"protocol\": \"HTTP/2\", \"status\": 403, \"bytes_sent\": 1043}",
		"resource": {...}
	}
]

Statement

set(attributes["decoded_body"], Decode(body, "utf-8"))
set(attributes["parsed_body"], ParseJSON(attributes["decoded_body"]))

See Working with the body for more information.

Output

[
	{
		"_type": "log",
		"timestamp": 1734494114238,
		"body": "{\"host\": \"172.17.15.39\", \"user-identifier\": \"68b148de-7ce3-423c-b72d-64a4f21ecfc0\", \"time_local\": \"2024-12-15T22:40:53.723160Z\", \"method\": \"POST\", \"request\": \"/styles/main.css\", \"protocol\": \"HTTP/2\", \"status\": 403, \"bytes_sent\": 1043}",
		"resource": {...},
		"attributes": {
			"decoded_body": "{\"host\": \"172.17.15.39\", \"user-identifier\": \"68b148de-7ce3-423c-b72d-64a4f21ecfc0\", \"time_local\": \"2024-12-15T22:40:53.723160Z\", \"method\": \"POST\", \"request\": \"/styles/main.css\", \"protocol\": \"HTTP/2\", \"status\": 403, \"bytes_sent\": 1043}",
			"parsed_body": {
				"bytes_sent": 1043,
				"host": "172.17.15.39",
				"method": "POST",
				"protocol": "HTTP/2",
				"request": "/styles/main.css",
				"status": 403,
				"time_local": "2024-12-15T22:40:53.723160Z",
				"user-identifier": "68b148de-7ce3-423c-b72d-64a4f21ecfc0"
			}
		}
	}
]

The JSON string was parsed into the parsed_body attribute.

ParseKeyValue

The ParseKeyValue converter parses a key-value string into a map object.

Syntax: ParseKeyValue(value, delimiter, pair-delimiter)

  • value: the location of the key-value string
  • delimiter (optional): the delimiter character for the key-value pairs. The default is a space but other characters will be attempted
  • pair-delimiter (optional): the delimiter character between the keys and their values. The default is =.

Input

[
	{
		"_type": "log",
		"timestamp": 1734600722163,
		"body": "host=172.17.15.39 user-identifier=68b148de-7ce3-423c-b72d-64a4f21ecfc0 time_local=2024-12-15T22:40:53.723160Z method=POST request=/styles/main.css protocol=HTTP/2 status=403 bytes_sent=1043",
		"resource": {...},
		"attributes": {
			"decoded_body": "host=172.17.15.39 user-identifier=68b148de-7ce3-423c-b72d-64a4f21ecfc0 time_local=2024-12-15T22:40:53.723160Z method=POST request=/styles/main.css protocol=HTTP/2 status=403 bytes_sent=1043"
		}
	}
]

Statement

set(attributes["kv_map"], ParseKeyValue(attributes["decoded_body"]))

Output

[
	{
		"_type": "log",
		"timestamp": 1734600738701,
		"body": "host=172.17.15.39 user-identifier=68b148de-7ce3-423c-b72d-64a4f21ecfc0 time_local=2024-12-15T22:40:53.723160Z method=POST request=/styles/main.css protocol=HTTP/2 status=403 bytes_sent=1043",
		"resource": {...},
		"attributes": {
			"decoded_body": "host=172.17.15.39 user-identifier=68b148de-7ce3-423c-b72d-64a4f21ecfc0 time_local=2024-12-15T22:40:53.723160Z method=POST request=/styles/main.css protocol=HTTP/2 status=403 bytes_sent=1043",
			"kv_map": {
				"bytes_sent": "1043",
				"host": "172.17.15.39",
				"method": "POST",
				"protocol": "HTTP/2",
				"request": "/styles/main.css",
				"status": "403",
				"time_local": "2024-12-15T22:40:53.723160Z",
				"user-identifier": "68b148de-7ce3-423c-b72d-64a4f21ecfc0"
			}
		}
	}
]

The decoded_body attribute is parsed into the kv_map.

ParseSimplifiedXML

The ParseSimplifiedXML converter parses an XML string into structured data. This function is designed for situations where simplicity and readability are prioritized over maintaining the full complexity of the original XML. It excludes attributes, comments, and any text that is not directly an element or a straightforward value. The ParseXML converter maintains the entire structure of the XML document, including attributes, content within tags, and the hierarchy of elements.

Syntax: ParseSimplifiedXML(value)

  • value: the bracket notation location of the XML string to parse

Input

[
	{
		"_type": "log",
		"timestamp": 1734570317034,
		"body": "<log><host>172.17.15.39</host><userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier><timeLocal>2024-12-15T22:40:53.723160Z</timeLocal><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol><status>403</status><bytesSent>1043</bytesSent></log>\n",
		"resource": {...},
		"attributes": {
			"decoded_body": "<log><host>172.17.15.39</host><userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier><timeLocal>2024-12-15T22:40:53.723160Z</timeLocal><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol><status>403</status><bytesSent>1043</bytesSent></log>\n"
		}
	}
]

Statement

set(attributes["map"], ParseSimplifiedXML(attributes["decoded_body"]))

Output

[
	{
		"_type": "log",
		"timestamp": 1734570335844,
		"body": "<log><host>172.17.15.39</host><userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier><timeLocal>2024-12-15T22:40:53.723160Z</timeLocal><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol><status>403</status><bytesSent>1043</bytesSent></log>\n",
		"resource": {...},
		"attributes": {
			"decoded_body": "<log><host>172.17.15.39</host><userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier><timeLocal>2024-12-15T22:40:53.723160Z</timeLocal><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol><status>403</status><bytesSent>1043</bytesSent></log>\n",
			"map": {
				"log": {
					"bytesSent": "1043",
					"host": "172.17.15.39",
					"method": "POST",
					"protocol": "HTTP/2",
					"request": "/styles/main.css",
					"status": "403",
					"timeLocal": "2024-12-15T22:40:53.723160Z",
					"userIdentifier": "68b148de-7ce3-423c-b72d-64a4f21ecfc0"
				}
			}
		}
	}
]

The XML string in decoded_body is parsed into map.

ParseXML

The ParseXML converter parses an XML string into structured data. Unlike ParseSimplifiedXML it maintains the entire structure of the XML document, including attributes, content within tags, and the hierarchy of elements.

Syntax: ParseXML(value)

  • value: the bracket notation location of the XML string to parse

Input

[
	{
		"_type": "log",
		"timestamp": 1734571176415,
		"body": "<log type=\"access\"><!-- Log entry for a web request --><details><host>172.17.15.39</host><userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier><timeLocal>2024-12-15T22:40:53.723160Z</timeLocal></details><requestInfo><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol></requestInfo><response><status>403</status><bytesSent>1043</bytesSent></response><message>This is a sample log entry</message></log>",
		"resource": {...},
		"attributes": {
			"decoded_body": "<log type=\"access\"><!-- Log entry for a web request --><details><host>172.17.15.39</host><userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier><timeLocal>2024-12-15T22:40:53.723160Z</timeLocal></details><requestInfo><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol></requestInfo><response><status>403</status><bytesSent>1043</bytesSent></response><message>This is a sample log entry</message></log>"
		}
	}
]

Statement

set(attributes["map"], ParseXML(attributes["decoded_body"]))

Output

[
	{
		"_type": "log",
		"timestamp": 1734571204472,
		"body": "<log type=\"access\"><!-- Log entry for a web request --><details><host>172.17.15.39</host><userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier><timeLocal>2024-12-15T22:40:53.723160Z</timeLocal></details><requestInfo><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol></requestInfo><response><status>403</status><bytesSent>1043</bytesSent></response><message>This is a sample log entry</message></log>",
		"resource": {...},
		"attributes": {
			"decoded_body": "<log type=\"access\"><!-- Log entry for a web request --><details><host>172.17.15.39</host><userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier><timeLocal>2024-12-15T22:40:53.723160Z</timeLocal></details><requestInfo><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol></requestInfo><response><status>403</status><bytesSent>1043</bytesSent></response><message>This is a sample log entry</message></log>",
			"map": {
				"attributes": {
					"type": "access"
				},
				"children": [
					{
						"children": [
							{
								"content": "172.17.15.39",
								"tag": "host"
							},
							{
								"content": "68b148de-7ce3-423c-b72d-64a4f21ecfc0",
								"tag": "userIdentifier"
							},
							{
								"content": "2024-12-15T22:40:53.723160Z",
								"tag": "timeLocal"
							}
						],
						"tag": "details"
					},
					{
						"children": [
							{
								"content": "POST",
								"tag": "method"
							},
							{
								"content": "/styles/main.css",
								"tag": "request"
							},
							{
								"content": "HTTP/2",
								"tag": "protocol"
							}
						],
						"tag": "requestInfo"
					},
					{
						"children": [
							{
								"content": "403",
								"tag": "status"
							},
							{
								"content": "1043",
								"tag": "bytesSent"
							}
						],
						"tag": "response"
					},
					{
						"content": "This is a sample log entry",
						"tag": "message"
					}
				],
				"tag": "log"
			}
		}
	}
]

The ParseXML function processed decoded_body and mapped its structure into a JSON-compatible hierarchical object. Attributes, such as type="access", were extracted and stored in an attributes dictionary for the corresponding tag. Content within tags, like "172.17.15.39" in <host>, was placed under a content key for each tag object. Comments, such as Log entry for a web request, are ignored. The nested XML structure was reflected as nested children arrays, preserving the hierarchy of elements like <details>, <requestInfo>, and <response>. Each tag was identified by its tag key, with its immediate children listed under children.

RemoveXML

The RemoveXML converter removes elements from an XML document based on an XPath query.

Syntax: RemoveXML(xml_string, xpath)

  • xml_string: the bracket notation location of the XML string
  • xpath: string XPath to locate the element that needs to be removed

Input

[
	{
		"_type": "log",
		"timestamp": 1734576565217,
		"body": "<log type=\"access\"><!-- Log entry for a web request --><details><host>172.17.15.39</host><userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier><timeLocal>2024-12-15T22:40:53.723160Z</timeLocal></details><requestInfo><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol></requestInfo><response><status>403</status><bytesSent>1043</bytesSent></response><message>This is a sample log entry</message></log>",
		"resource": {...},
		"attributes": {
			"decoded_body": "<log type=\"access\"><!-- Log entry for a web request --><details><host>172.17.15.39</host><userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier><timeLocal>2024-12-15T22:40:53.723160Z</timeLocal></details><requestInfo><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol></requestInfo><response><status>403</status><bytesSent>1043</bytesSent></response><message>This is a sample log entry</message></log>"
		}
	}
]

Statement

set(attribute["trimmed_xml"], RemoveXML(attributes["decoded_body"], "/log/details"))

Output

[
	{
		"_type": "log",
		"timestamp": 1734576600936,
		"body": "<log type=\"access\"><!-- Log entry for a web request --><details><host>172.17.15.39</host><userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier><timeLocal>2024-12-15T22:40:53.723160Z</timeLocal></details><requestInfo><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol></requestInfo><response><status>403</status><bytesSent>1043</bytesSent></response><message>This is a sample log entry</message></log>",
		"resource": {...},
		"attributes": {
			"decoded_body": "<log type=\"access\"><!-- Log entry for a web request --><details><host>172.17.15.39</host><userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier><timeLocal>2024-12-15T22:40:53.723160Z</timeLocal></details><requestInfo><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol></requestInfo><response><status>403</status><bytesSent>1043</bytesSent></response><message>This is a sample log entry</message></log>"
		},
		"attribute": {
			"trimmed_xml": "<log type=\"access\"><!-- Log entry for a web request --><requestInfo><method>POST</method><request>/styles/main.css</request><protocol>HTTP/2</protocol></requestInfo><response><status>403</status><bytesSent>1043</bytesSent></response><message>This is a sample log entry</message></log>"
		}
	}
]

The details object was removed. For readability, the XML was changed from this:

<log type="access"> <!-- Log entry for a web request -->
    <details>
        <host>172.17.15.39</host>
        <userIdentifier>68b148de-7ce3-423c-b72d-64a4f21ecfc0</userIdentifier>
        <timeLocal>2024-12-15T22:40:53.723160Z</timeLocal>
    </details>
    <requestInfo>
        <method>POST</method>
        <request>/styles/main.css</request>
        <protocol>HTTP/2</protocol>
    </requestInfo>
    <response>
        <status>403</status>
        <bytesSent>1043</bytesSent>
    </response>
    <message>This is a sample log entry</message>
</log>

to this:

<log type="access"> <!-- Log entry for a web request -->
    <requestInfo>
        <method>POST</method>
        <request>/styles/main.css</request>
        <protocol>HTTP/2</protocol>
    </requestInfo>
    <response>
        <status>403</status>
        <bytesSent>1043</bytesSent>
    </response>
    <message>This is a sample log entry</message>
</log>

SHA1, SHA256 and SHA512

The SHA converters hash a string using the SHA-1, SHA-256 or SHA-512 hashing algorithm.

Syntax: SHA1|SHA-256|SHA-512(value)

  • value: the bracket notation location of the string field to hash

Input

[
	{
		"_type": "log",
		"timestamp": 1734577609907,
		"body": "{\"timestamp\": \"2024-12-19T02:57:53.138740Z\", \"level\": \"Critical\", \"msg\": \"processing hit rate limits\", \"user\": {\"email\": \"michael.johnson@mymailservice.com\", \"id\": \"8ff729af-c291-47b5-a342-e66d8a207b2a\", \"name\": \"537fe94b-9f36-4451-830f-2774c1c7b1d5\"}, \"request\": {\"ip\": \"10.221.199.58\", \"method\": [\"GET\", 200], \"path\": \"/json/view\"}, \"response_time_ms\": 500000}",
		"resource": {...},
		"attributes": {
			"parsed": {
				"level": "Critical",
				"msg": "processing hit rate limits",
				"request": {
					"ip": "10.221.199.58",
					"method": [
						"GET",
						200
					],
					"path": "/json/view"
				},
				"response_time_ms": 500000,
				"timestamp": "2024-12-19T02:57:53.138740Z",
				"user": {
					"email": "michael.johnson@mymailservice.com",
					"id": "8ff729af-c291-47b5-a342-e66d8a207b2a",
					"name": "537fe94b-9f36-4451-830f-2774c1c7b1d5"
				}
			}
		}
	}
]

Statement

set(attributes["parsed"]["user"]["id"], SHA512(attributes["parsed"]["user"]["id"]))

Output

[
	{
		"_type": "log",
		"timestamp": 1734577656090,
		"body": "{\"timestamp\": \"2024-12-19T02:57:53.138740Z\", \"level\": \"Critical\", \"msg\": \"processing hit rate limits\", \"user\": {\"email\": \"michael.johnson@mymailservice.com\", \"id\": \"8ff729af-c291-47b5-a342-e66d8a207b2a\", \"name\": \"537fe94b-9f36-4451-830f-2774c1c7b1d5\"}, \"request\": {\"ip\": \"10.221.199.58\", \"method\": [\"GET\", 200], \"path\": \"/json/view\"}, \"response_time_ms\": 500000}",
		"resource": {...},
		"attributes": {
			"parsed": {
				"level": "Critical",
				"msg": "processing hit rate limits",
				"request": {
					"ip": "10.221.199.58",
					"method": [
						"GET",
						200
					],
					"path": "/json/view"
				},
				"response_time_ms": 500000,
				"timestamp": "2024-12-19T02:57:53.138740Z",
				"user": {
					"email": "michael.johnson@mymailservice.com",
					"id": "2f4316717df6f903288fd5d841359329e25254ddaada117e3ecdcfdd882377fe911fd7f635960df17c30a29dc4c58e7940b6fcb5119d82d991204a4f8ef9a891",
					"name": "537fe94b-9f36-4451-830f-2774c1c7b1d5"
				}
			}
		}
	}
]

The attributes["parsed"]["user"]["id"] field has been hashed using the SHA-512 hashing algorithm.

Note: In this example, the original field still exists in the body, be sure to sanitize the data downstream if required.

Split

The Split converter splits a string into an array based on a specified delimiter.

Syntax: Split(value, separator)

  • value: the bracket notation location of the string to split
  • separator: the delimiter string to use for splitting

Input

[
	{
		"_type": "log",
		"timestamp": 1734585789794,
		"body": "host=172.17.15.39,user-identifier=68b148de-7ce3-423c-b72d-64a4f21ecfc0,time_local=2024-12-15T22:40:53.723160Z,method=POST,request=/styles/main.css,protocol=HTTP/2,status=403,bytes_sent=1043",
		"resource": {...},
		"attributes": {
			"decoded_body": "host=172.17.15.39,user-identifier=68b148de-7ce3-423c-b72d-64a4f21ecfc0,time_local=2024-12-15T22:40:53.723160Z,method=POST,request=/styles/main.css,protocol=HTTP/2,status=403,bytes_sent=1043"
		}
	}
]

Statement

set(attributes["split"], Split(attributes["decoded_body"], ","))

Output

[
	{
		"_type": "log",
		"timestamp": 1734585827627,
		"body": "host=172.17.15.39,user-identifier=68b148de-7ce3-423c-b72d-64a4f21ecfc0,time_local=2024-12-15T22:40:53.723160Z,method=POST,request=/styles/main.css,protocol=HTTP/2,status=403,bytes_sent=1043",
		"resource": {...},
		"attributes": {
			"decoded_body": "host=172.17.15.39,user-identifier=68b148de-7ce3-423c-b72d-64a4f21ecfc0,time_local=2024-12-15T22:40:53.723160Z,method=POST,request=/styles/main.css,protocol=HTTP/2,status=403,bytes_sent=1043",
			"split": [
				"host=172.17.15.39",
				"user-identifier=68b148de-7ce3-423c-b72d-64a4f21ecfc0",
				"time_local=2024-12-15T22:40:53.723160Z",
				"method=POST",
				"request=/styles/main.css",
				"protocol=HTTP/2",
				"status=403",
				"bytes_sent=1043"
			]
		}
	}
]

The string decoded_body was split into an array split.

String

The String converter converts a non-string field to a string.

Syntax: String(value)

  • value: the bracket notation location of the field to convert

Input

[
	{
		"_type": "log",
		"timestamp": 1734586243207,
		"body": "{\"host\": \"172.17.15.39\", \"user-identifier\": \"68b148de-7ce3-423c-b72d-64a4f21ecfc0\", \"time_local\": \"2024-12-15T22:40:53.723160Z\", \"method\": \"POST\", \"request\": \"/styles/main.css\", \"protocol\": \"HTTP/2\", \"status\": 403, \"bytes_sent\": 1043}",
		"resource": {...},
		"attributes": {
			"parsed_body": {
				"bytes_sent": 1043,
				"host": "172.17.15.39",
				"method": "POST",
				"protocol": "HTTP/2",
				"request": "/styles/main.css",
				"status": 403,
				"time_local": "2024-12-15T22:40:53.723160Z",
				"user-identifier": "68b148de-7ce3-423c-b72d-64a4f21ecfc0"
			}
		}
	}
]

Statement

set(attributes["parsed_body"]["status"], String(attributes["parsed_body"]["status"]))

Output

[
	{
		"_type": "log",
		"timestamp": 1734586277255,
		"body": "{\"host\": \"172.17.15.39\", \"user-identifier\": \"68b148de-7ce3-423c-b72d-64a4f21ecfc0\", \"time_local\": \"2024-12-15T22:40:53.723160Z\", \"method\": \"POST\", \"request\": \"/styles/main.css\", \"protocol\": \"HTTP/2\", \"status\": 403, \"bytes_sent\": 1043}",
		"resource": {...},
		"attributes": {
			"parsed_body": {
				"bytes_sent": 1043,
				"host": "172.17.15.39",
				"method": "POST",
				"protocol": "HTTP/2",
				"request": "/styles/main.css",
				"status": "403",
				"time_local": "2024-12-15T22:40:53.723160Z",
				"user-identifier": "68b148de-7ce3-423c-b72d-64a4f21ecfc0"
			}
		}
	}
]

The numeric value 403 was converted to its string representation "403".