Learn about the different transformation types and pipeline order.
Parse and process incoming logs with transformations.
Block logs based on certain conditions.
Inputs
Filter: Specify the filter in filter-expression format.
Cloud Observability doesn’t ingest logs that match the filter.
All other logs continue through the pipeline.
Transformations support every filter expression except phrase_match
.
Examples
Block all INFO
logs with this Drop matching transformation:
sev == "INFO"
Logs before:
1
2
INFO Spaceship 'Lightstep' reached orbit around Saturn.
ERROR Navigation malfunction: Unable to plot course through asteroid field.
Logs after:
1
ERROR Navigation malfunction: Unable to plot course through asteroid field.
Block INFO
logs for the StellarNav
service with this Drop matching transformation:
sev == "INFO" && service == "StellarNav"
Logs before:
1
2
INFO StellarNav Spaceship 'Lightstep' reached orbit around Saturn.
ERROR StellarNav Navigation malfunction: Unable to plot course through asteroid field.
Logs after:
1
ERROR StellarNav Navigation malfunction: Unable to plot course through asteroid field.
Move nested attributes in a JSON object to the top level.
Inputs
message
.For Flatten transformations, the target attribute must be a JSON object. If the target attribute isn’t a JSON object – for example, a string – the attribute goes through the log ingestion pipeline untouched.
These inputs are optional for Flatten transformations:
Filter
Specify the filter in filter-expression format.
Transformations support every filter expression except phrase_match
.
Cloud Observability only flattens logs that match the filter. Other logs are unaffected by the transformation.
Delimiter
Specify the character that separates the flattened attribute keys.
For example, if you set Delimiter to -
, {"message": {"action": "Spacecraft launched"}}
flattens to {message-action:"Spacecraft launched"}
.
The default delimiter is .
.
Max depth
Specify the maximum nesting level for Cloud Observability to flatten. By default, Cloud Observability flattens all levels.
For example, if Max depth is 1, Cloud Observability flattens only the first level in the JSON object. Cloud Observability leaves deeper levels unchanged.
Examples
Move every nested attribute in message
to the top level:
message
Logs before:
1
2
3
4
5
6
7
8
"message": {
"action": "Spacecraft launched",
"details": {
"destination": "Mars",
"launch_pad": "LC-39A",
"payload": "Exploration Rover"
}
}
Logs after:
1
2
3
4
"message.action": "Spacecraft launched",
"message.details.destination": "Mars",
"message.details.launch_pad": "LC-39A",
"message.details.payload": "Exploration Rover"
Move only attributes at level 1 to the top level:
message
Logs before:
1
2
3
4
5
6
7
8
"message": {
"action": "Spacecraft launched",
"details": {
"destination": "Mars",
"launch_pad": "LC-39A",
"payload": "Exploration Rover"
}
}
Logs after:
1
2
3
4
5
6
"message.action": "Spacecraft launched",
"message.details": {
"destination": "Mars",
"launch_pad": "LC-39A",
"payload": "Exploration Rover"
}
The OpenTelemetry (OTel) Collector sends log information to Cloud Observability as a string in body
.
To flatten attributes in body
, use the Parse JSON transformation to turn body
attributes into JSON objects.
Then use the Flatten transformation on the JSON-object attributes.
Transformation 1: Parse body
:
body
Transformation 2: Flatten message:
message
Logs before:
1
"body": "{\"message\": {\"action\": \"Spacecraft launched\", \"details\": {\"launch_pad\": \"LC-39A\", \"destination\": \"Mars\", \"payload\": \"Exploration Rover\"}}}"
Logs after transformation 1:
1
2
3
4
5
6
7
8
9
"body": "{\"message\": {\"action\": \"Spacecraft launched\", \"details\": {\"launch_pad\": \"LC-39A\", \"destination\": \"Mars\", \"payload\": \"Exploration Rover\"}}}",
"message": {
"action": "Spacecraft launched",
"details": {
"destination": "Mars",
"launch_pad": "LC-39A",
"payload": "Exploration Rover"
}
}
Logs after transformation 2:
1
2
3
4
5
"body": "{\"message\": {\"action\": \"Spacecraft launched\", \"details\": {\"launch_pad\": \"LC-39A\", \"destination\": \"Mars\", \"payload\": \"Exploration Rover\"}}}",
"message.action": "Spacecraft launched",
"message.details.destination": "Mars",
"message.details.launch_pad": "LC-39A",
"message.details.payload": "Exploration Rover"
Aggregate attributes into a single attribute.
Inputs
%{attribute-name}
.
For example, if moon==europa
and planet==saturn
, %{moon}_%{planet}
generates europa_saturn
.Format doesn’t work with attributes such as signal{strength}%
.
If your attribute keys include {
,}
, or %
, consider using a different transformation, such as Rename,
to change those keys first.
This input is optional for Format transformations:
Filter
Specify the filter in filter-expression format.
Transformations support every filter expression except phrase_match
.
Cloud Observability only applies Format to logs matching the filter. Other logs are unaffected by the transformation.
Examples
Aggregate two existing attributes into a new attribute called mission_event
.
mission
and event
mission_event
%{mission}_%{event}
Logs before:
1
2
3
4
{
"event": "LunarLanding",
"mission":"ServiceNow24"
}
Logs after:
1
2
3
4
5
{
"event": "LunarLanding",
"mission":"ServiceNow24",
"mission_event": "ServiceNow24_LunarLanding"
}
Create two transformations to aggregate attributes nested in body
.
First, use Parse JSON to move the attributes to the top level of the log.
Second, use Format to aggregate the top-level attributes into a new attribute.
Format only works on top-level attributes.
It doesn’t support nested syntax, for example,
%{body{mission}}_%{body{event}}
.
body
body
mission
and event
mission_event
%{mission}_%{event}
Logs before:
1
2
3
{
"body":"{"mission":"ServiceNow24","event": "LunarLanding"}"
}
Logs after transformation 1:
1
2
3
4
5
{
"body":"{"mission":"ServiceNow24","event": "LunarLanding"}",
"event": "LunarLanding",
"mission":"ServiceNow24"
}
Logs after transformation 2:
1
2
3
4
5
6
{
"body":"{"mission":"ServiceNow24","event": "LunarLanding"}",
"event": "LunarLanding",
"mission":"ServiceNow24",
"mission_event": "ServiceNow24_LunarLanding"
}
Ingest logs based on certain conditions.
Inputs
Filter: Specify the filter in filter-expression format.
Cloud Observability only ingests logs that match the filter.
It drops all other logs.
Transformations support every filter expression except phrase_match
.
Examples
Only keep sect 8
logs with this Keep matching transformation:
contains(body, "sect 8")
Logs before:
1
2
3
INFO StellarNav Spaceship 'Lightstep' reached orbit around Saturn in sect 8.
ERROR Lightstep Navigation malfunction in sect 4: Unable to plot course through asteroid field.
FATAL Juno core meltdown. Evacuate the ship immediately! Everything in sect 8 is compromised.
Logs after:
1
2
INFO StellarNav Spaceship 'Lightstep' reached orbit around Saturn in sect 8.
FATAL Juno core meltdown. Evacuate the ship immediately! Everything in sect 8 is compromised.
Parse JSON-encoded strings into logical attributes.
Inputs
body
.These inputs are optional for Parse JSON transformations:
Drop target attribute
Toggle this option to remove the target attribute once it’s parsed.
Filter
Specify the filter in filter-expression format.
Transformations support every filter expression except phrase_match
.
Cloud Observability only parses logs that match the filter. Other logs are unaffected by the transformation.
Attributes to promote
Extract specific JSON attributes and promote them to the top level of the log.
For example, enter action
to promote the action
attribute in the target body
attribute.
If you specify a prefix in Prefix new attributes (see below), Cloud Observability adds the prefix to action
.
Select Add attribute to promote multiple attributes.
Prefix new attributes
Add context to the front of new top-level attribute names.
For example, station
results in attribute names like station.destination
and station.launch_pad
.
JSON max depth
Specify the maximum nesting level for Cloud Observability to parse.
For example, if JSON max depth is 3, Cloud Observability only parses up to 3 levels in the JSON structure.
Examples
Parse the body
attribute with this Parse JSON transformation:
body
Log before:
1
"body": "{\"severity\": \"INFO\", \"message\": {\"action\": \"Spacecraft launched\", \"details\": {\"launch_pad\": \"LC-39A\", \"destination\": \"Mars\"}}}"
Log after:
1
2
3
4
5
6
7
8
9
"body": "{\"severity\": \"INFO\", \"message\": {\"action\": \"Spacecraft launched\", \"details\": {\"launch_pad\": \"LC-39A\", \"destination\": \"Mars\"}}}",
"message": {
"action": "Spacecraft launched",
"details": {
"destination": "Mars",
"launch_pad": "LC-39A"
}
},
"severity": "INFO"
Parse the body
attribute and add information with this Parse JSON transformation:
body
context
Log before:
1
"body": "{\"severity\": \"INFO\", \"message\": {\"action\": \"Spacecraft launched\", \"details\": {\"launch_pad\": \"LC-39A\", \"destination\": \"Mars\"}}}"
Log after:
1
2
3
4
5
6
7
8
9
"body": "{\"severity\": \"INFO\", \"message\": {\"action\": \"Spacecraft launched\", \"details\": {\"launch_pad\": \"LC-39A\", \"destination\": \"Mars\"}}}",
"context.message": {
"action": "Spacecraft launched",
"details": {
"destination": "Mars",
"launch_pad": "LC-39A"
}
},
"context.severity": "INFO"
Parse body
and promote its message
attribute with the Parse JSON transformation below.
Because the transformation sets Drop target attribute to true, the other body
attributes (event_type
and location
) don’t appear in Cloud Observability.
body
message
Log before:
1
"body": "{\"message\": \"Launch successful\", \"event_type\": \"Launch\", \"location\": \"Sector 7G\"}"
Log after:
1
"message": "Launch successful"
Give new names to specific attributes.
Inputs
This input is optional for Rename transformations:
Filter
Specify the filter in filter-expression format.
Transformations support every filter expression except phrase_match
.
Cloud Observability only renames attributes in logs that match the filter. Other logs are unaffected by the transformation.
Examples
Rename the message
attribute to body
with the Rename transformation below.
Because body
is tokenized, Cloud Observability automatically tokenizes any attributes you rename to body
.
message
-> body
Logs before:
1
"message": "Spacecraft launched"
Logs after:
1
"body": "Spacecraft launched"
Assign values to new or existing attributes.
Inputs
Target attribute: Specify a new or existing attribute key to set values for.
If your target attribute includes periods (.
), use quotations: "client.browser"
.
This input is optional for Set transformations:
Filter
Specify the filter in filter-expression format.
Transformations support every filter expression except phrase_match
.
Cloud Observability only applies Set to logs matching the filter. Other logs are unaffected by the transformation.
Example
To assign log statuses (OK
, Notice
, Warning
, Error
, and Info
) based on HTTP status codes, create the five Set transformations below:
Transformation input | Transformation 1 |
Transformation 2 |
Transformation 3 |
Transformation 4 |
Transformation 5 |
---|---|---|---|---|---|
Name | Set OK | Set Notice | Set Warning | Set Error | Set Info |
Configuration | Set | Set | Set | Set | Set |
Target attribute | status |
status |
status |
status |
status |
Overwrite existing attribute | True | True | True | True | True |
Filter: | "\"http.status_code\"" >= 200 && "\"http.status_code\"" <= 299 |
"\"http.status_code\"" >= 300 && "\"http.status_code\"" <= 399 |
"\"http.status_code\"" >= 400 && "\"http.status_code\"" <= 499 |
"\"http.status_code\"" >= 500 && "\"http.status_code\"" <= 599 |
"\"http.status_code\"" <= 100 |
Value | OK | Notice | Warning | Error | Info |
If an attribute key has a period (.
), use this syntax: "\"<attribute.name>\""
.
The syntax indicates a full attribute key, not a nested JSON attribute.
For example, the transformations above use "\"http.status_code\""
.
Logs before:
1
2
3
4
5
6
7
8
9
10
11
12
{
"http.status_code": 200,
"message": "Mission status: Observability has landed."
}
{
"http.status_code": 302,
"message": "Mission status: Redirected for data relay."
}
{
"http.status_code": 404,
"message": "Error: Satellite communication lost."
}
Logs after:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"http.status_code": 200,
"status": "OK",
"message": "Mission status: Observability has landed."
}
{
"http.status_code": 302,
"status": "Notice",
"message": "Mission status: Redirected for data relay."
}
{
"http.status_code": 404,
"status": "Warning",
"message": "Error: Satellite communication lost."
}
Parse attributes using regular expressions.
Inputs
body
.Regular expression: Use a regular expression to match patterns in logs and extract attribute values.
Regular expressions use the RE2 syntax.
For example, user ID '(?<userID>\w+)'
captures a user ID from a string and assigns it to the userID
attribute.
This input is optional for Regex extract transformations:
Filter
Specify the filter in filter-expression format.
Transformations support every filter expression except phrase_match
.
Cloud Observability only applies Regex extract to logs matching the filter. Other logs are unaffected by the transformation.
Example
Capture two IDs from message
and assign them to the userID
and resourceID
attributes:
message
"\"service.name\"" == auth
user ID '(?<userID>\w+)'.* resource ID '(?<resourceID>\w+)'
If an attribute key has a period (.
), use this syntax: "\"<attribute.name>\""
.
The syntax indicates a full attribute key, not a nested JSON attribute.
For example, the transformation above uses "\"service.name\""
.
Logs before:
1
2
3
4
5
6
7
8
9
10
11
12
{
"message": "user ID 'commander123' successfully authenticated for resource ID 'mars_42'",
"service.name":"auth"
}
{
"message": "user ID 'pilot890' requested control of resource ID 'satellite_beta'",
"service.name":"auth"
}
{
"message": "user ID 'navigator124' initiated diagnostics on resource ID 'space_station_clouds'",
"service.name":"billing"
}
Logs after:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"message": "user ID 'commander123' successfully authenticated for resource ID 'mars_42'",
"service.name":"auth",
"resourceID": "mars_42",
"userID": "commander123"
}
{
"message": "user ID 'pilot890' requested control of resource ID 'satellite_beta'",
"service.name":"auth",
"resourceID": "satellite_beta",
"userID": "pilot890"
}
{
"message": "user ID 'navigator124' initiated diagnostics on resource ID 'space_station_clouds'",
"service.name":"billing"
}
In log ingestion pipelines, the order of operations affects how Cloud Observability transforms your data.
In Cloud Observability, the log ingestion pipeline page has three tabs:
The All pipeline is a catch-all for all incoming logs. The source-specific pipelines – Datadog and OTLP – take precedence over the All pipeline for logs from those sources.
For example, if you only have an All pipeline, all logs flow through that pipeline. If you then create an OTLP pipeline, Cloud Observability directs logs from the OTel Collector through the OTLP pipeline.
Filter behavior determines how logs flow through pipelines.
In Keep matching and Drop matching transformations, filters are destructive.
The filters decide which logs appear in Cloud Observability and which logs are dropped.
For example, if a Keep matching transformation uses sev == "INFO"
, Cloud Observability ingests INFO
logs and drops all other logs.
In other transformations, such as Parse JSON, filters determine which logs the transformation applies to.
For example, if a Parse JSON transformation uses sev == "INFO"
, Cloud Observability only applies the transformation to INFO
logs.
Other logs, such as ERROR
or DEBUG
logs, pass through unaffected.
If a pipeline has several transformations, Cloud Observability runs the transformations in order. To change the order, point to a transformation and select the up or down arrow.
Example
To drop JSON logs where destination == Earth
, parse the logs first and drop the logs second.
If you reverse the transformation order, both sample logs appear in Cloud Observability.
Transformation 1: Parse body
:
body
Transformation 2: Drop matching:
message.details.destination == "Earth"
Logs before:
1
2
"body": "{\"severity\": \"INFO\", \"message\": {\"action\": \"Spacecraft launched\", \"details\": {\"launch_pad\": \"LC-39A\", \"destination\": \"Mars\"}}}",
"body": "{\"severity\": \"INFO\", \"message\": {\"action\": \"Spacecraft launched\", \"details\": {\"launch_pad\": \"LC-39A\", \"destination\": \"Earth\"}}}"
Logs after:
1
"body": "{\"severity\": \"INFO\", \"message\": {\"action\": \"Spacecraft launched\", \"details\": {\"launch_pad\": \"LC-39A\", \"destination\": \"Mars\"}}}"
Updated Sep 25, 2024