OTTL Converter Functions in Edge Delta
22 minute read
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())]))
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"
.