Skip to content

doc: Tracing design proposal#3185

Draft
adarsh0728 wants to merge 7 commits intomainfrom
tracing-doc
Draft

doc: Tracing design proposal#3185
adarsh0728 wants to merge 7 commits intomainfrom
tracing-doc

Conversation

@adarsh0728
Copy link
Copy Markdown
Member

Proposal: OpenTelemetry Tracing Design for Numaflow

Signed-off-by: adarsh0728 <gooneriitk@gmail.com>
Signed-off-by: adarsh0728 <gooneriitk@gmail.com>
Signed-off-by: adarsh0728 <gooneriitk@gmail.com>
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.08%. Comparing base (1af0d2e) to head (a0450a8).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3185      +/-   ##
==========================================
- Coverage   81.09%   81.08%   -0.01%     
==========================================
  Files         318      318              
  Lines       73398    73398              
==========================================
- Hits        59519    59513       -6     
- Misses      13323    13329       +6     
  Partials      556      556              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread docs/specifications/tracing.md Outdated
- Receives Request.
- Extracts `T1-S3`.
- Starts Span `S4` (Parent: `S3`). runs user code... Ends `S4`.
- **Crucial**: SDK sends Span `S4` data to Collector.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expecting the sdk to handle data sending?

Copy link
Copy Markdown
Member Author

@adarsh0728 adarsh0728 Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thought of both core and sdk to send data

Trace X:
  Core Span: Vertex Processing
    SDK will start Span for: UDF Execution
      User starts Span (optional): some calculation

For sdk/user spans to work, user has to initiate tracing(we can provide a helper fn via sdk to set up global tracer for udf process with same OTEL endpoint env variable)

Signed-off-by: adarsh0728 <gooneriitk@gmail.com>
Signed-off-by: adarsh0728 <gooneriitk@gmail.com>
@adarsh0728 adarsh0728 changed the title doc: Tracing design proposal [Do Not Merge] doc: Tracing design proposal Feb 23, 2026
@adarsh0728 adarsh0728 marked this pull request as ready for review February 25, 2026 03:47
Comment thread docs/specifications/tracing.md Outdated
## 2. Key Architectural Decisions

### 2.1 Format: W3C Trace Context
We will use the **W3C Trace Context** standard (`traceparent`, `tracestate`) for context propagation.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hyperlink to the spec?

Comment thread docs/specifications/tracing.md Outdated
- **Key**: `"tracing"`
- **Value**: A `KeyValueGroup` containing the W3C headers.

**Message Structure:**
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do not need to add anything to our proto spec, right? since this is already in place

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

Comment thread docs/specifications/tracing.md Outdated
- **Implementation**: The Core injects the **same** current span context (parent) into `sys_metadata` for **every** output message.
- **Result**: Downstream vertices will create N separate spans, all pointing back to the same parent span from the Map vertex.

## 4. Implementation Plan: Numaflow SDKs (e.g., Go/Rust/Python)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's not worry about SDKs, we just need server spans. Adding dependencies on SDK might be an overkill.

@adarsh0728 adarsh0728 marked this pull request as draft March 8, 2026 14:48
@th0ger
Copy link
Copy Markdown
Contributor

th0ger commented Mar 27, 2026

I applaude the objective of this proposal 👍🏼Great synergy with #2645.

@vigith
Copy link
Copy Markdown
Member

vigith commented Mar 31, 2026

@adarsh0728 let's work on this PR itself since there are lot of eyes on this 😄

Comment thread docs/specifications/tracing.md Outdated

1. **Source**:
- Generates data.
- Starts Trace `T1`, Span `S1`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we create the trace id in SDK after receiving messages from UDF ? Only then we can propagate traceparent coming from external systems like Kafka right?

Comment thread docs/specifications/tracing.md Outdated
- `Consumer`: Describes a child of an asynchronous request (e.g., receiving from a queue).
- `Internal`: Default. Represents an internal operation within an application.
4. **Process**:
- **Before UDF**: Create a child span (e.g., `kind=Client`) for the UDF call. Inject this context into a *copy* of the metadata passed to the UDF.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, should we set kind=Producer and kind=Consumer when writing to ISB and reading from ISB ?

Comment thread docs/specifications/tracing.md Outdated
4. **Process**:
- **Before UDF**: Create a child span (e.g., `kind=Client`) for the UDF call. Inject this context into a *copy* of the metadata passed to the UDF.
- **After UDF**: Receive results.
5. **Write**:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think handling traces in Sink should be a separate section.
We could add more details for retries, dropped etc. Eg:

  // Record a Span Event with details
  span.add_event("message.dropped", vec![
      KeyValue::new("drop.reason", "fallback_strategy"),
      KeyValue::new("drop.after_retries", 5),
  ]);

Tracing backend will see something like:

{
  "trace_id": "4bf92f...",
  "span_id": "aabb...",
  "name": "numaflow.my-pipeline.sink-vertex.process",
  "events": [
    {
      "name": "message.dropped",
      "timestamp": "2026-04-01T12:00:00Z",
      "attributes": {
        "drop.reason": "fallback_strategy",
        "drop.after_retries": 5
      }
    }
  ]
}

Comment thread docs/specifications/tracing.md Outdated
- Extracts context `T1-S1`.
- Starts Span `S2` (Parent: `S1`) -> **"Vertex Processing"**.
- Covers overhead (ISB read/write, serialization).
- Prepares UDF Request. Starts Span `S3` (Parent: `S2`) -> **"UDF RPC Call"**.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use predictable span names? eg

numaflow.{pipeline}.{vertex}.process
numaflow.{pipeline}.{vertex}.udf
numaflow.{pipeline}.{vertex}.sink.retry

Comment thread docs/specifications/tracing.md Outdated
- **Limit**: To prevent span bloat in massive windows, limit the number of links (e.g., max 50). If more, sample representative links (e.g., first 10, last 10).

### 3.6 Handling FlatMap (Fan-Out)
When a Map vertex produces multiple output messages from a single input (1 -> N):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this work with batchmap (N inputs to N outputs in one grpc invocation) ?

@yhl25
Copy link
Copy Markdown
Contributor

yhl25 commented Apr 2, 2026

I think we should User Metadata for Trace Propagation When UDF is Instrumented

If a UDF is instrumented, it should inject its active span context into outgoing user metadata (e.g. user_metadata["tracing"]). Downstream UDFs should then prefer this over sys_metadata["tracing"].

Order would be:

  1. user_metadata["tracing"] — set by upstream UDF (preferred)
  2. sys_metadata["tracing"] — set by platform (fallback)
  3. Fresh root context

sys_metadata["tracing"] carries the platform's span context, not the UDF's. Without this, downstream UDF spans become siblings of upstream UDF spans instead of children.

Signed-off-by: adarsh0728 <gooneriitk@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants