Repository navigation
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #5378 +/- ##
============================================
- Coverage 92.60% 92.13% -0.47%
- Complexity 5043 5093 +50
============================================
Files 1252 1277 +25
Lines 53587 54516 +929
Branches 6673 6840 +167
============================================
+ Hits 49623 50231 +608
- Misses 2315 2580 +265
- Partials 1649 1705 +56
☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
| config | throughput | MB/s | latency | max Δ latest / 7d | |
|---|---|---|---|---|---|
| 🔴 | bs=10 sw=10 sl=64 | 388 | 0.237 | 23,866/32,686/32,686 us | 🔴 -13.2% / 🔴 +122.8% |
| ⚪ | bs=100 sw=10 sl=64 | 823 | 0.502 | 120,996/131,016/131,016 us | ⚪ within ±5% / 🔴 +28.0% |
| 🔴 | bs=1000 sw=10 sl=64 | 928 | 0.566 | 1,080,678/1,177,038/1,177,038 us | 🔴 +7.8% / 🔴 +19.6% |
Baseline details
Latest main be65bf8 from same runner
| config | metric | PR | latest main | 7d avg | Δ latest | Δ 7d |
|---|---|---|---|---|---|---|
| bs=10 sw=10 sl=64 | throughput | 388 tuples/sec | 447 tuples/sec | 866.99 tuples/sec | -13.2% | -55.2% |
| bs=10 sw=10 sl=64 | MB/s | 0.237 MB/s | 0.273 MB/s | 0.529 MB/s | -13.2% | -55.2% |
| bs=10 sw=10 sl=64 | p50 | 23,866 us | 21,380 us | 11,989 us | +11.6% | +99.1% |
| bs=10 sw=10 sl=64 | p95 | 32,686 us | 30,534 us | 14,672 us | +7.0% | +122.8% |
| bs=10 sw=10 sl=64 | p99 | 32,686 us | 30,534 us | 17,906 us | +7.0% | +82.5% |
| bs=100 sw=10 sl=64 | throughput | 823 tuples/sec | 850 tuples/sec | 1,111 tuples/sec | -3.2% | -25.9% |
| bs=100 sw=10 sl=64 | MB/s | 0.502 MB/s | 0.519 MB/s | 0.678 MB/s | -3.3% | -26.0% |
| bs=100 sw=10 sl=64 | p50 | 120,996 us | 117,059 us | 95,405 us | +3.4% | +26.8% |
| bs=100 sw=10 sl=64 | p95 | 131,016 us | 126,323 us | 102,332 us | +3.7% | +28.0% |
| bs=100 sw=10 sl=64 | p99 | 131,016 us | 126,323 us | 115,219 us | +3.7% | +13.7% |
| bs=1000 sw=10 sl=64 | throughput | 928 tuples/sec | 938 tuples/sec | 1,141 tuples/sec | -1.1% | -18.6% |
| bs=1000 sw=10 sl=64 | MB/s | 0.566 MB/s | 0.573 MB/s | 0.696 MB/s | -1.2% | -18.7% |
| bs=1000 sw=10 sl=64 | p50 | 1,080,678 us | 1,066,908 us | 938,794 us | +1.3% | +15.1% |
| bs=1000 sw=10 sl=64 | p95 | 1,177,038 us | 1,091,841 us | 984,521 us | +7.8% | +19.6% |
| bs=1000 sw=10 sl=64 | p99 | 1,177,038 us | 1,091,841 us | 1,008,827 us | +7.8% | +16.7% |
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,515.45,200,128000,388,0.237,23865.86,32685.87,32685.87
1,100,10,64,20,2429.27,2000,1280000,823,0.502,120996.38,131015.84,131015.84
2,1000,10,64,20,21555.49,20000,12800000,928,0.566,1080678.43,1177038.46,1177038.46
Automated Reviewer SuggestionsBased on the
|
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).
6852c5c to
dc4490e
Compare
Add the local deployment wiring that receives and stores the telemetry emitted by PR 2: an OpenTelemetry Collector plus logs, metrics, traces, and profiles backends, for both the single-node docker-compose stack and the Kubernetes Helm chart. Infrastructure only; the application runs unchanged whether or not these services are started. This is PR 3 of the observability stack. Single-node compose (bin/single-node, bin/observability): - otel-collector as the single OTLP ingress, routing to VictoriaLogs (logs), VictoriaMetrics (metrics), and Jaeger (traces); the collector config caps OTLP message size and bounds memory via memory_limiter. - Parca server + eBPF agent for continuous profiling, configured in bin/observability/parca. - Each signal is its own compose profile and is OFF by default: COMPOSE_PROFILES is empty, so observability is opt-in. docker compose reads COMPOSE_PROFILES natively via the canonical launcher. - Emission is gated by OTEL_SDK_DISABLED (default disabled); nothing is emitted unless an operator opts in alongside the collector profile. Kubernetes Helm chart (bin/k8s): - Templates for the collector, Jaeger, VictoriaLogs, and VictoriaMetrics under templates/base/observability, plus values.yaml knobs and an install.sh helper. - Service deployments gain the OTLP endpoint wiring. Every observability port binds to loopback (127.0.0.1) or stays on the bridge network; no 0.0.0.0 host bindings. Tests: ObservabilityComposeSpec and ParcaConfigSpec (string-level smoke tests over the compose, collector, and Parca config, pinning image versions, the opt-in default, loopback binding, and the no-high- cardinality-label rule). All 24 pass; sbt scalafmtCheckAll is clean. Review follow-ups addressed: observability is opt-in rather than on by default, and the privileged eBPF agent is opt-in with its host-wide scope documented; removed the non-canonical up.sh launcher so COMPOSE_PROFILES is the single switch; corrected the Parca README (the agent profiles every host process, and profiles cannot be joined to traces by trace_id); moved the local-dev-only OTLP host ports into docker-compose.override.yml so the base compose stays deploy-clean; the release workflow now ships bin/observability and rewrites the mount paths so the compose works from the released single-node bundle; and removed the inter-PR references from the configs, comments, and specs. Stacked on PR 2 (obs/pr2/backend-emit).
dc4490e to
5e21599
Compare
|
/request-review @zuozhiw |
5e21599 to
907d120
Compare
Add the tenant-scoped read path the dashboard queries, plus the Angular shell that hosts the per-signal panels. This is the first user-visible observability surface: it enforces tenancy and rate limiting on every query and gates each panel on signal reachability. This is PR 4 of the observability stack. Query gateway (amber, org.apache.texera.web.observability.gateway): - BackendClient issues the read-only HTTP queries to the telemetry backends (VictoriaLogs, VictoriaMetrics, Jaeger). - ScopeResolver derives the caller's tenant scope and constrains every query to it, so a user never reads another tenant's telemetry. - RateLimiter, AuditLogger, and GatewayContext add per-request rate limiting, audit logging, and the shared request context. - dtos.scala and builders.scala define the typed request objects and their validators (time window, page size, free text, service name). - ObservabilityResources exposes /observability/health and is registered in TexeraWebApplication. - RequestContextMdcFilter and UserContextMdcFilter inject the request and user context into the logging MDC. - ObservabilityGatewayConfig plus observability-gateway.conf hold the gateway settings. Dashboard shell (frontend): - Admin-only Observability page, route, and navigation entry, plus the observability service, its types, and the traces-pivot service. - Each tab is guarded by the per-signal reachability check: an unreachable signal renders an explicit state rather than a broken panel. The signal panels themselves follow in later PRs of the stack. Tests: backend specs for the gateway core, DTO validation, scope resolver, rate limiter, and the MDC filters, plus frontend component and service specs. sbt scalafmtCheckAll is clean. Stacked on PR 3 (obs/pr3/deployment). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
907d120 to
681c046
Compare
What changes were proposed in this PR?
Introduces the tenant-scoped read path the dashboard queries, plus the Angular shell that hosts the per-signal panels. This PR warrants the closest review: it enforces tenancy and rate limiting and is the first user-visible surface.
Backend:
BackendClient: HTTP client to the telemetry backends.ScopeResolver: derives the caller's tenant scope and constrains every query to it.RateLimiter,AuditLogger,GatewayContext: per-request rate limiting, audit logging, and shared request context.dtos.scala: typed request objects with validators (time window, page size, free text, service name).ObservabilityResourceswith the/observability/healthendpoint, registered inTexeraWebApplication.RequestContextMdcFilterandUserContextMdcFilter: inject request and user context into the logging MDC.ObservabilityGatewayConfigand its configuration file.Frontend:
observability.service,observability.types, and thetraces-pivot.service.Any related issues, documentation, or discussions?
Closes: #5370
Part of #4070. Stacked on #5377.
How was this PR tested?
sbt scalafmtCheckAllpasses.prettier-eslintandeslintpass.Was this PR authored or co-authored using generative AI tooling?
Co-authored with Claude Opus 4.8 in compliance with ASF