Skip to content

feat(observability): backend metrics + tracing primitives - #5376

Open
Ma77Ball wants to merge 2 commits into
apache:mainfrom
Ma77Ball:obs/pr2/backend-emit
Open

Ma77Ball wants to merge 2 commits into
apache:mainfrom
Ma77Ball:obs/pr2/backend-emit

Conversation

@Ma77Ball

@Ma77Ball Ma77Ball commented Jun 5, 2026 •

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Adds the libraries services use to emit metrics and distributed traces. These stay dormant until the SDK is enabled in PR1.

  • TexeraMetrics: metric instruments for workflow lifecycle and throughput. The active-executions metric is modeled as an observable gauge read from the live registry, correcting the phantom-active count a manual up/down counter produced.
  • TexeraTracer and SpanAttrs: helpers for creating spans and attaching standardized attributes.
  • TraceparentValidator: parses and validates W3C traceparent headers for context propagation.
  • Pure additions to the Config module; no behavior changes when telemetry is disabled.

Any related issues, documentation, or discussions?

Closes: #5368
Part of #4070. Stacked on #5375.

How was this PR tested?

  • Unit specs for the metrics, tracer, span-attribute, and traceparent-validator classes.
  • sbt scalafmtCheckAll passes; compile and tests run in this PR's CI.

Was this PR authored or co-authored using generative AI tooling?

Co-authored with Claude Opus 4.8 in compliance with ASF

@codecov-commenter

codecov-commenter commented Jun 5, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.37825% with 83 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.52%. Comparing base (2cd44ee) to head (b372b82).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
...ala/org/apache/texera/observability/OtelInit.scala 70.86% 25 Missing and 12 partials ⚠️
...rg/apache/texera/web/service/WorkflowService.scala 74.13% 11 Missing and 4 partials ⚠️
.../apache/texera/observability/WorkflowMetrics.scala 84.93% 4 Missing and 7 partials ⚠️
...e/texera/observability/TexeraOtelLogAppender.scala 78.04% 2 Missing and 7 partials ⚠️
...org/apache/texera/observability/TexeraTracer.scala 0.00% 4 Missing ⚠️
...ra/web/observability/WorkflowMetricsRecorder.scala 83.33% 2 Missing and 1 partial ⚠️
...org/apache/texera/observability/LogSanitizer.scala 92.50% 0 Missing and 3 partials ⚠️
.../scala/org/apache/texera/service/FileService.scala 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #5376      +/-   ##
============================================
- Coverage     92.59%   92.52%   -0.07%     
- Complexity     5043     5061      +18     
============================================
  Files          1252     1261       +9     
  Lines         53583    53955     +372     
  Branches       6672     6743      +71     
============================================
+ Hits          49617    49924     +307     
- Misses         2319     2353      +34     
- Partials       1647     1678      +31     
Flag Coverage Δ
access-control-service 77.44% <100.00%> (+0.06%) ⬆️
agent-service 99.16% <ø> (ø)
amber 87.97% <80.33%> (-0.10%) ⬇️
computing-unit-managing-service 60.45% <100.00%> (+0.03%) ⬆️
config-service 87.50% <100.00%> (+0.12%) ⬆️
file-service 81.45% <0.00%> (-0.09%) ⬇️
frontend 96.58% <ø> (-0.01%) ⬇️
notebook-migration-service 83.77% <100.00%> (+0.03%) ⬆️
pyamber 98.58% <ø> (-0.01%) ⬇️
workflow-compiling-service 74.25% <100.00%> (+0.15%) ⬆️

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

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions Bot added the platform Non-amber Scala service paths label Jun 5, 2026
@github-actions

github-actions Bot commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 2 better · 🔴 8 worse · ⚪ 5 noise (<±5%) · 0 without baseline

Compared against main 9d768b7 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 379 0.232 25,290/33,182/33,182 us 🟢 -13.3% / 🔴 +145.5%
🔴 bs=100 sw=10 sl=64 773 0.472 128,073/171,626/171,626 us 🔴 +18.9% / 🔴 +83.0%
⚪ bs=1000 sw=10 sl=64 903 0.551 1,108,779/1,168,693/1,168,693 us ⚪ within ±5% / 🔴 +29.2%
Baseline details

Latest main 9d768b7 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 379 tuples/sec 408 tuples/sec 963.37 tuples/sec -7.1% -60.7%
bs=10 sw=10 sl=64 MB/s 0.232 MB/s 0.249 MB/s 0.588 MB/s -6.8% -60.5%
bs=10 sw=10 sl=64 p50 25,290 us 22,652 us 10,998 us +11.6% +129.9%
bs=10 sw=10 sl=64 p95 33,182 us 38,262 us 13,515 us -13.3% +145.5%
bs=10 sw=10 sl=64 p99 33,182 us 38,262 us 16,850 us -13.3% +96.9%
bs=100 sw=10 sl=64 throughput 773 tuples/sec 831 tuples/sec 1,235 tuples/sec -7.0% -37.4%
bs=100 sw=10 sl=64 MB/s 0.472 MB/s 0.507 MB/s 0.754 MB/s -6.9% -37.4%
bs=100 sw=10 sl=64 p50 128,073 us 118,048 us 87,833 us +8.5% +45.8%
bs=100 sw=10 sl=64 p95 171,626 us 144,387 us 93,795 us +18.9% +83.0%
bs=100 sw=10 sl=64 p99 171,626 us 144,387 us 103,718 us +18.9% +65.5%
bs=1000 sw=10 sl=64 throughput 903 tuples/sec 916 tuples/sec 1,273 tuples/sec -1.4% -29.1%
bs=1000 sw=10 sl=64 MB/s 0.551 MB/s 0.559 MB/s 0.777 MB/s -1.4% -29.1%
bs=1000 sw=10 sl=64 p50 1,108,779 us 1,095,722 us 861,707 us +1.2% +28.7%
bs=1000 sw=10 sl=64 p95 1,168,693 us 1,113,056 us 904,523 us +5.0% +29.2%
bs=1000 sw=10 sl=64 p99 1,168,693 us 1,113,056 us 931,473 us +5.0% +25.5%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,527.28,200,128000,379,0.232,25290.08,33181.81,33181.81
1,100,10,64,20,2587.09,2000,1280000,773,0.472,128072.53,171625.91,171625.91
2,1000,10,64,20,22144.59,20000,12800000,903,0.551,1108779.26,1168693.39,1168693.39

@github-actions

github-actions Bot commented Jun 23, 2026 •

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Committers with relevant context: @parshimers
    You can request their reviews formally with /request-review @parshimers.

  • Contributors with relevant context: @bobbai00, @aicam, @yrenat
    You can notify them by mentioning @bobbai00, @aicam, @yrenat in a comment.

Comment thread common/config/src/main/scala/org/apache/texera/observability/TexeraTracer.scala Outdated
Comment thread common/config/src/main/scala/org/apache/texera/observability/TexeraMetrics.scala Outdated
Comment thread common/config/src/main/scala/org/apache/texera/observability/SpanAttrs.scala Outdated
Comment thread amber/src/main/scala/org/apache/texera/web/service/WorkflowService.scala Outdated
Comment thread amber/src/main/scala/org/apache/texera/web/service/WorkflowService.scala Outdated
Comment thread amber/src/main/scala/org/apache/texera/web/service/WorkflowService.scala Outdated
@zuozhiw

zuozhiw commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

I left some comments in this PR, specifically in one of these comments I put a link to otel official demo app written in Java and we should follow official guidelines m.

Ma77Ball added a commit to Ma77Ball/texera that referenced this pull request Jul 16, 2026
…WorkflowMetrics rename

Follow the OTel Java demo patterns instead of custom wrappers (zuozhiw
review):

- WorkflowService: start the run-level span with the standard OTel API,
name it WorkflowService.initExecutionService, and drop the
initExecutionServiceSpanned split so no span is passed as an argument.
The real execution failure is now recorded onto the span from
errorHandler, where it is actually caught.

- TexeraTracer: drop the withSpan wrapper, keeping only the tracer
accessor (single instrumentation scope) and currentContext.

- SpanAttrs: drop the awkward with*/set* setter helpers, keep the
standard label keys and sanitizeFreeText; callers set attributes via the
OTel API.

- Rename TexeraMetrics to WorkflowMetrics, document that this facade is
only for the workflow-execution cluster, and add an example of calling
the OTel meter API directly at a call site.

Update SpanAttrsSpec and WorkflowMetricsSpec to match.
@Ma77Ball
Ma77Ball requested a review from zuozhiw July 20, 2026 19:36

@zuozhiw zuozhiw left a comment

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.

changes look good overall, left a few more comments, after fixing them you can go ahead and merge

): Unit = {
val span = TexeraTracer.tracer
.spanBuilder("WorkflowService.initExecutionService")
.setAttribute("texera.workflow.id", workflowId.id.toString)

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.

minor: use standard keys instead of plain string

Comment thread amber/src/main/scala/org/apache/texera/web/service/WorkflowService.scala Outdated
Comment thread amber/src/main/scala/org/apache/texera/web/service/WorkflowService.scala Outdated
state.withExecutionId(workflowContext.executionId)
)
val errorHandler: Throwable => Unit = { t =>
{

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.

this error handler needs to be extra careful becaue it's passed around as an argument to WorkflowExecutionService, and it will be called beyond this function's lifecycle, we really need to check who calls it. when they call it this specific span object we get here might already ended after this function ends. this handler is also used locally, that is fine, but if other places call it then we have troubles and the error is not attached to the correct span

this one is a bit tricky, as we need to inspect the places that invokes this error handler and see what spans they have, then we either call span.current() again inside this span (but need to make sure the callers has good spans...), or has to pass in a span as optinal argument, please check how we are using this handler and see what's the best way to handle this, maybe passing such error handler around is not a good error handling method

Comment thread amber/src/main/scala/org/apache/texera/web/service/WorkflowService.scala Outdated
@Ma77Ball
Ma77Ball marked this pull request as ready for review August 4, 2026 19:18
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

This pull request has been automatically marked as stale because it has
not had any activity for 30 days. It will be closed in 7 days if no
further activity occurs.

If this PR is still relevant, please:

  • Push new commits or rebase onto the latest main, or
  • Comment with a status update, or
  • Address any open review feedback.

To exempt this PR from auto-close, a maintainer can add the pinned label.
Thank you for your contribution to Apache Texera (incubating)!

@github-actions github-actions Bot added stale ci changes related to CI infra labels Sep 7, 2026
@github-actions github-actions Bot removed the stale label Sep 14, 2026
Introduce the OpenTelemetry foundation for Texera: an SDK bootstrap, a
Logback-to-OTel log bridge, and a log sanitizer, wired into every service
entry point. This is PR 1 of the observability stack; it ships logging only,
with the trace and metric exporters wired but not yet emitted (those arrive in
follow-up PRs).

New module (common/observability):
- OtelInit: one-call SDK bootstrap per service. Reads OTEL_* settings from
  observability.conf, validates the OTLP endpoint (scheme + host allowlist)
  before any exporter is built, wires the span/log/metric providers explicitly
  (no sdk-extension-autoconfigure), clamps the metric export interval, and
  attaches the log appender to the Logback ROOT logger. The whole init body is
  guarded so a missing or malformed config returns None with one WARN instead
  of throwing into a service's run(), even when telemetry is disabled.
- TexeraOtelLogAppender: bridges Logback events to OTel log records. Maps
  severity, forwards MDC, sets exception.type/message/stacktrace semantic
  attributes, and drops records from io.opentelemetry loggers so export-failure
  diagnostics are not fed back to the collector that just failed.
- LogSanitizer: strips C0 control characters, redacts secrets, and caps body
  length (MaxBodyChars) to keep individual records bounded.

Config (common/config):
- observability.conf with the OTEL_* defaults, ObservabilityConfig to read it,
  and ENV_OTEL_* entries in EnvironmentalVariable.

Wiring:
- build.sbt defines the Observability module and adds dependsOn(Observability)
  to the eight Dropwizard services.
- Each service entry point calls OtelInit.init with its own service name, and
  each service config gains a logging block.

Deployment:
- OTEL_* env entries in bin/single-node/.env, bin/k8s/values.yaml, and
  bin/k8s/values-development.yaml (kept a name-for-name mirror).
- LICENSE-binary manifests updated with the pinned OTel 1.50.0 jars.

Tests: OtelInitSpec, TexeraOtelLogAppenderSpec, LogSanitizerSpec, and
ObservabilityConfigSpec cover endpoint validation, interval clamping,
severity/MDC/exception mapping, self-diagnostic filtering, redaction, and
truncation.

Rebased onto current main.
Build on the logging foundation (PR 1) with the backend emit path: workflow
lifecycle metrics and a run-level setup trace span, plus the tracing/metrics
primitives they use. This is PR 2 of the observability stack.

Primitives (common/observability):
- TexeraTracer: lazy accessor for the process tracer off GlobalOpenTelemetry.
- SpanAttrs: typed AttributeKey constants so span attributes use standard keys
  rather than ad hoc strings.
- WorkflowMetrics: the OTel instruments (start/completion/failure/cancellation
  counters and run-duration histogram) keyed by workflow kind.
- TraceparentValidator: validates W3C traceparent headers before use.

Emit path (amber):
- WorkflowMetricsRecorder: single owner of the metric instruments. init() wires
  them once; onStart stamps a run's start; onStateChange records terminal
  counters and duration exactly once on the first transition into a terminal
  state (idempotent, safe to call on every transition).
- WorkflowService.initExecutionService runs inside a run-level setup span so
  setup-path logs carry its trace id. The span covers only the synchronous
  setup; synchronous setup failures are recorded on it in the catch block, and
  the span is ended in finally. The async errorHandler deliberately does not
  touch the span: it is invoked after setup returns and the span has ended, so
  the failure is surfaced through the metadata store instead.
- ExecutionStateStore.updateWorkflowState is the single chokepoint that feeds
  every state transition to WorkflowMetricsRecorder.onStateChange.
- ComputingUnitMaster initializes the recorder at startup.

All observability sources live under common/observability (the module from
PR 1); the tracing/metrics classes are not duplicated into common/config.

Tests: WorkflowMetricsSpec, SpanAttrsSpec, and TraceparentValidatorSpec.

Review follow-ups addressed: span attributes use SpanAttrs keys instead of
plain strings; the error handler no longer records onto a span that may have
already ended (documented and handled via the metadata store).

Stacked on PR 1 (obs/pr1/foundations).
@Ma77Ball
Ma77Ball force-pushed the obs/pr2/backend-emit branch from 2dee2bd to b372b82 Compare October 7, 2026 11:04

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci changes related to CI common dependencies Pull requests that update a dependency file engine infra platform Non-amber Scala service paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Observability] Backend metrics and tracing emission primitives

3 participants