Add OpenLineage extension for Java SDK#39428
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
Adds sdks/java/extensions/openlineage, which emits OpenLineage events describing the datasets a Beam pipeline reads and writes, so lineage backends (Marquez, Atlan, and other OpenLineage consumers) can build a lineage graph for Beam jobs on any runner. The extension follows the architecture of the official OpenLineage Spark and Flink integrations: - Configuration extends io.openlineage.client.OpenLineageConfig and is resolved with the same precedence as the Spark integration: pipeline options over openlineage.yml over OPENLINEAGE__ env vars. Transport, facets, dataset and circuit-breaker settings use the standard openlineage-java config classes. - OpenLineageRunner wraps any runner, extracts datasets from the pipeline graph through classpath-guarded per-IO visitors (PubsubIO, IcebergIO; extensible via the public LineageProvider interface), mints a UUIDv7 run id at submission and propagates it via serialized options, and emits START and terminal COMPLETE/ABORT/FAIL events. - OpenLineageJobTracker emits periodic RUNNING events on the Flink integration's trackingIntervalInSeconds cadence (default 60s) and sweeps lineage reported through the Beam Lineage metrics API. - OpenLineageLineage implements the LineageBase plugin (--lineageType) to capture lineage live in worker JVMs for long-running streaming jobs, teeing FQNs back into the metrics store. - Dataset naming strictly follows the OpenLineage naming conventions; Iceberg datasets use the physical table location with the catalog table identity attached as a TABLE symlink, matching the Spark integration's IcebergHandler. Addresses apache#39427.
77b409a to
d1f1752
Compare
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Checks are failing. Will not request review until checks are succeeding. If you'd like to override that behavior, comment |
|
assign set of reviewers |
|
Assigning reviewers: R: @Abacn for label java. Note: If you would like to opt out of this review, comment Available commands:
The PR bot will only process comments in the main thread (not review comments). |
|
cc: @charlespnh @shnapz since you have both been driving lineage / OpenLineage work in Beam; would appreciate your review or pointers here. |
Adds
sdks/java/extensions/openlineage, a new extension that emits OpenLineage events describing the datasets a Beam pipeline reads and writes, so OpenLineage consumers (Marquez, Atlan, and others) can build lineage graphs for Beam jobs on any runner.addresses #39427
Design. The extension deliberately mirrors the architecture of the official OpenLineage Spark and Flink integrations so it is familiar to both communities:
io.openlineage.client.OpenLineageConfig(likeSparkOpenLineageConfig/FlinkOpenLineageConfig) and resolves with the Spark integration's precedence: pipeline options >openlineage.yml>OPENLINEAGE__env vars. Transport, disabled facets, dataset resolvers and circuit breaker reuse the standard openlineage-java config classes; no secrets flow through pipeline options.OpenLineageRunnerwraps any runner (--runner=OpenLineageRunner --openLineageDelegateRunner=FlinkRunner): extracts datasets from the pipeline graph via classpath-guarded per-IO visitors (PubsubIO typed, IcebergIO reflective since its getters are package-private; extensible through the publicLineageProviderinterface), mints a UUIDv7 run id at submission and propagates it via serialized options, emits START and terminal COMPLETE/ABORT/FAIL (with anerrorMessagefacet on failure), and supports a parent run facet for orchestrator-launched pipelines.OpenLineageJobTrackeremits periodic RUNNING events on the Flink integration'strackingIntervalInSecondscadence (default 60s) and sweeps lineage reported through the BeamLineagemetrics API at each tick and at terminal state.OpenLineageLineageimplements theLineageBaseplugin ([Feature Request]: Make lineage tracking pluggable #36790,--lineageType) to capture lineage live inside worker JVMs for long-running streaming jobs — where runner metrics are not readable mid-run — teeing every FQN back into the metrics store so existing metrics-based consumers keep working unchanged.IcebergHandler. Systems without a spec entry pass through with a conservative generic mapping.Emission can never fail a pipeline: every hook swallows exceptions and emission runs inside the configured OpenLineage circuit breaker.
Relationship to prior work. This realizes the OpenLineage integration requested in #33981 (closed as not-planned) and builds directly on the pluggable lineage mechanism added in #36790 —
OpenLineageLineageis aLineageBaseimplementation selected via--lineageType, i.e. the concrete consumer of that hook. It also incorporates the approach discussed on the dev@ thread of consuming the lineage metrics IOs already report and traversing the pipeline graph for source/sink pairs, without changing any IO. The two are combined: the--lineageTypeplugin captures lineage live in worker JVMs (needed for long-running streaming jobs), while the wrapper runner traverses the graph at submission and sweeps theLineagemetrics at terminal state (covers batch and Beam versions predating the plugin API). Granularity is job-level, matching the direction settled in #36790.cc @charlespnh @shnapz — you have both been driving lineage / OpenLineage work in Beam; would appreciate your review or pointers here.
Testing. 26 unit tests: FQN-to-naming-convention conformance for every spec-listed system, graph extraction against real PubsubIO and real IcebergIO (Hadoop catalog with actual
loadTable()location resolution, plus graceful fallback when a REST catalog is unreachable at submit time), end-to-end runner and plugin pipelines on the direct runner asserting the full emitted event sequence via a file transport, parent-facet and disabled-flag behavior, and config precedence. Also validated end-to-end against a live OpenLineage consumer: START/RUNNING/COMPLETE events from this module were ingested and produced the expected lineage assets.:sdks:java:extensions:openlineage:build(checkstyle, spotless, SpotBugs, javadoc, tests) andratpass.Dependencies. New dependency
io.openlineage:openlineage-java(Apache-2.0), scoped to this module only. GCP and Iceberg IO modules are compile-only; their visitors activate at runtime only when the corresponding IO is already on the user's classpath.Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:
addresses #123), if applicable. This will automatically add a link to the pull request in the issue. If you would like the issue to automatically close on merging the pull request, commentfixes #<ISSUE NUMBER>instead.CHANGES.mdwith noteworthy changes.See the Contributor Guide for more tips on how to make review process smoother.
To check the build health, please visit https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md
GitHub Actions Tests Status (on master branch)
See CI.md for more information about GitHub Actions CI or the workflows README to see a list of phrases to trigger workflows.