You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/en/ninja-workshops/10-advanced-otel/70-transform-data/1-test-transform.md
+25-2Lines changed: 25 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -53,7 +53,9 @@ In this exercise, we will **remove the** `com.splunk/source` and `os.type` **met
53
53
{{% /tab %}}
54
54
{{% /tabs %}}
55
55
56
-
-**Check the debug output** of both the `Agent` and `Gateway` to confirm that the `SeverityText` in the `LogRecord` is now defined with the matching severity from the log body
56
+
-**Check the debug output** of both the `Agent` and `Gateway` to confirm that the `SeverityText` in the `LogRecord` is now defined with the severity from the log body, along with the matching severity number.
57
+
58
+
Confirm that the JSON fields from the body can be accessed as top-level log attributes.
57
59
58
60
{{% tabs %}}
59
61
{{% tab title="New Debug Output" %}}
@@ -63,10 +65,13 @@ In this exercise, we will **remove the** `com.splunk/source` and `os.type` **met
63
65
ObservedTimestamp: 2025-01-31 21:49:29.924017 +0000 UTC
64
66
Timestamp: 1970-01-01 00:00:00 +0000 UTC
65
67
SeverityText: WARN
66
-
SeverityNumber: Unspecified(0)
68
+
SeverityNumber: Warn(13)
67
69
Body: Str(2025-01-31 15:49:29 [WARN] - Do or do not, there is no try.)
68
70
Attributes:
69
71
-> log.file.path: Str(quotes.log)
72
+
-> timestamp: Str(2025-01-31 15:49:29)
73
+
-> level: Str(WARN)
74
+
-> message: Str(Do or do not, there is no try.)
70
75
Trace ID:
71
76
Span ID:
72
77
Flags: 0
@@ -138,6 +143,24 @@ In this exercise, we will **remove the** `com.splunk/source` and `os.type` **met
Copy file name to clipboardExpand all lines: content/en/ninja-workshops/10-advanced-otel/70-transform-data/_index.md
+19-6Lines changed: 19 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -34,7 +34,7 @@ WORKSHOP
34
34
35
35
In this section, we will update the `agent.yaml` file to include a **transform** processor. This processor will help filter log resource attributes and set the log severity text based on the message body.
36
36
37
-
Previously, you may have noticed that the `SeverityText` and `SeverityNumber` values are undefined in the log record, but are included in the log message body
37
+
Previously, you may have noticed that the `SeverityText` and `SeverityNumber` values are undefined in the log record, but the severity is included in the `level` field of the log body
38
38
39
39
```text
40
40
<snip>
@@ -71,16 +71,29 @@ In this case, we will be filtering the resource attributes and keeping only rele
71
71
72
72
Notice that the `keep_keys` statement is only applicable to the log resource context.
73
73
74
-
- **Add another context block for the log along with set statements to set the severity_text of the log record based on the matching severity level from the unstructured log.
74
+
Logs often contain structured data encoded as JSON within the log body. Extracting these fields into attributes allows for better indexing, filtering, and querying. Instead of manually parsing JSON in downstream systems, OTTL enables automatic transformation at the telemetry pipeline level.
75
+
76
+
- **Add another context block** for the log along with set statements to set the severity_text and severity_number of the log record based on the matching severity level from the log body.
75
77
76
78
```yaml
77
79
- context: log
78
80
statements:
79
-
- set(severity_text, "INFO") where IsMatch(body, "\\[INFO\\]")
80
-
- set(severity_text, "WARN") where IsMatch(body, "\\[WARN\\]")
81
-
- set(severity_text, "DEBUG") where IsMatch(body, "\\[DEBUG\\]")
82
-
- set(severity_text, "ERROR") where IsMatch(body, "\\[ERROR\\]")
81
+
- context: log
82
+
statements:
83
+
- set(cache, ParseJSON(body)) where IsMatch(body, "^\\{")
84
+
- flatten(cache, "")
85
+
- merge_maps(attributes, cache, "upsert")
86
+
- set(severity_text, attributes["level"])
87
+
- set(severity_number, 1) where severity_text == "TRACE"
88
+
- set(severity_number, 5) where severity_text == "DEBUG"
89
+
- set(severity_number, 9) where severity_text == "INFO"
90
+
- set(severity_number, 13) where severity_text == "WARN"
91
+
- set(severity_number, 17) where severity_text == "ERROR"
92
+
- set(severity_number, 21) where severity_text == "FATAL"
83
93
```
94
+
This transformation checks if the log body contains a JSON object, then extracts its fields into log attributes while preserving nested structures. The flatten(cache) step ensures that deeply nested JSON fields can be accessed as top-level attributes.
95
+
96
+
84
97
85
98
- **Update the `logs` pipeline**: Add the `transform` processor into the `logs:` pipeline:
0 commit comments