Skip to content

Latest commit

 

History

History
99 lines (72 loc) · 9.37 KB

File metadata and controls

99 lines (72 loc) · 9.37 KB

OpenTelemetry Transformation Language

Status
Stability alpha: traces, metrics, logs
Issues Open issues Closed issues
Code Owners @TylerHelmuth, @kentquirk, @bogdandrutu, @evan-bradley, @edmocosta | Seeking more code owners!

The OpenTelemetry Transformation Language (OTTL) is a small, domain-specific programming language intended to process data with OpenTelemetry-native concepts and constructs.

This package implements everything necessary to use OTTL in a Collector component or in another user-facing system.

Getting Started

An OTTL statement is made up of 2 parts:

  1. A function that transforms telemetry
  2. Optionally, a condition that determines whether the function is executed.

Here is an example OTTL statement:

set(span.attributes["test"], "pass") where span.attributes["test"] == nil

This statement sets a new span attribute named "test" with a value of "pass" whenever the span does not already have an attribute named "test". In this example, the function is set, which uses the second parameter to set the value of the first parameter, and the condition is span.attributes["test"] == nil.

Within a statement you utilize OTTL Paths to access telemetry. The example uses the Path span.attributes to access the span's attributes. For each Open Telemetry Signal, OTTL has a Path to every field (plus some extras to help make interacting with the data easier).

To see a list of available Paths for each Open Telemetry Signal, checkout the links below.

Telemetry OTTL Context
Resource Resource
Instrumentation Scope Instrumentation Scope
Span Span
Span Event SpanEvent
Metric Metric
Datapoint DataPoint
Log Log

OTTL does not support cross-signal interactions at this time. That means you cannot write a statement like

set(span.attributes["log body"], log.body)

See OTTL Functions for a list of functions available for use in OTTL statements of most components.

To see more examples of OTTL statements, checkout the Transform Processor

There is a lot more OTTL can do, like nested functions, arithmetic, indexing, and enums. To explore it further check out OTTL's grammar doc.

Where to use OTTL

Troubleshooting

When using OTTL you can enable debug logging in the collector to print out useful information, such as the current Statement/Condition and the current TransformContext, to help you troubleshoot why a statement is not behaving as you expect. This feature is very verbose, but provides you an accurate view into how OTTL views the underlying data.

service:
  telemetry:
    logs:
      level: debug
2024-05-29T16:38:09.600-0600    debug   ottl@v0.101.0/parser.go:265     initial TransformContext        {"kind": "processor", "name": "transform", "pipeline": "logs", "TransformContext": {"resource": {"attributes": {}, "dropped_attribute_count": 0}, "scope": {"attributes": {}, "dropped_attribute_count": 0, "name": "", "version": ""}, "log_record": {"attributes": {"log.file.name": "test.log"}, "body": "test", "dropped_attribute_count": 0, "flags": 0, "observed_time_unix_nano": 1717022289500721000, "severity_number": 0, "severity_text": "", "span_id": "", "time_unix_nano": 0, "trace_id": ""}, "cache": {}}}
2024-05-29T16:38:09.600-0600    debug   ottl@v0.101.0/parser.go:268     TransformContext after statement execution      {"kind": "processor", "name": "transform", "pipeline": "logs", "statement": "set(resource.attributes[\"test\"], \"pass\")", "condition matched": true, "TransformContext": {"resource": {"attributes": {"test": "pass"}, "dropped_attribute_count": 0}, "scope": {"attributes": {}, "dropped_attribute_count": 0, "name": "", "version": ""}, "log_record": {"attributes": {"log.file.name": "test.log"}, "body": "test", "dropped_attribute_count": 0, "flags": 0, "observed_time_unix_nano": 1717022289500721000, "severity_number": 0, "severity_text": "", "span_id": "", "time_unix_nano": 0, "trace_id": ""}, "cache": {}}}
2024-05-29T16:38:09.600-0600    debug   ottl@v0.101.0/parser.go:268     TransformContext after statement execution      {"kind": "processor", "name": "transform", "pipeline": "logs", "statement": "set(instrumentation_scope.attributes[\"test\"], [\"pass\"])", "condition matched": true, "TransformContext": {"resource": {"attributes": {"test": "pass"}, "dropped_attribute_count": 0}, "scope": {"attributes": {"test": ["pass"]}, "dropped_attribute_count": 0, "name": "", "version": ""}, "log_record": {"attributes": {"log.file.name": "test.log"}, "body": "test", "dropped_attribute_count": 0, "flags": 0, "observed_time_unix_nano": 1717022289500721000, "severity_number": 0, "severity_text": "", "span_id": "", "time_unix_nano": 0, "trace_id": ""}, "cache": {}}}
2024-05-29T16:38:09.601-0600    debug   ottl@v0.101.0/parser.go:268     TransformContext after statement execution      {"kind": "processor", "name": "transform", "pipeline": "logs", "statement": "set(attributes[\"test\"], true)", "condition matched": true, "TransformContext": {"resource": {"attributes": {"test": "pass"}, "dropped_attribute_count": 0}, "scope": {"attributes": {"test": ["pass"]}, "dropped_attribute_count": 0, "name": "", "version": ""}, "log_record": {"attributes": {"log.file.name": "test.log", "test": true}, "body": "test", "dropped_attribute_count": 0, "flags": 0, "observed_time_unix_nano": 1717022289500721000, "severity_number": 0, "severity_text": "", "span_id": "", "time_unix_nano": 0, "trace_id": ""}, "cache": {}}}

Resources

These are previous conference presentations given about OTTL: