[FLINK-40293][table] Add UDF metric config options and instrument sync scalar and table UDF calls - #28879
Draft
weiqingy wants to merge 2 commits into
Draft
[FLINK-40293][table] Add UDF metric config options and instrument sync scalar and table UDF calls#28879weiqingy wants to merge 2 commits into
weiqingy wants to merge 2 commits into
Conversation
Collaborator
Add a reusable UdfMetrics helper that registers udfProcessingTime (a DescriptiveStatisticsHistogram of per-invocation nanoseconds) and udfExceptionCount (a ThreadSafeSimpleCounter) under udf.<udfName> on the executing operator's metric group, and owns the sampling decision, timing, and exception counting shared by the sync and async instrumentation paths. Sampling follows state latency tracking (FLINK-21736), including the interval == 1 case that measures every invocation. The histogram is safe to update from an async callback thread; the sampling counter is only advanced on the task thread at dispatch. No call site is added here; the first caller arrives with the sync instrumentation.
…c scalar and table UDF calls Introduce two opt-in configuration options for FLIP-485 UDF metrics: table.exec.udf-metric-enabled (default false) and table.exec.udf-metric.sample-interval (default 100). Wrap the generated eval call site for sync scalar and table user-defined functions (via the BridgingSqlFunction stack) with sampled udfProcessingTime timing and udfExceptionCount counting, using the UdfMetrics helper registered on the operator metric group under udf.<udfName>. Instrumentation is emitted only when table.exec.udf-metric-enabled is true; the generated operator is byte-identical when disabled. One shared handle is registered per (operator, udfName). Lookup-join, ML-predict, vector-search, legacy CallGens, and PROCESS_TABLE functions are not metered.
weiqingy
force-pushed
the
flink-38071-pr2-sync
branch
from
August 2, 2026 23:50
cf258d6 to
720f7b0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is the second PR of the FLIP-485 implementation, split into a stack of small, independently reviewable PRs under the umbrella issue FLINK-38071. Landing order:
UdfMetricshelper: registration, sampling, timing, exception countingStacked on #28878 and kept as a draft until that merges, so the diff here currently also shows the
UdfMetricscommit.What is the purpose of the change
Adds the two configuration options and the first end-to-end slice of FLIP-485: synchronous scalar and table UDF calls instrumented at code generation, using the
UdfMetricshelper from PR-1.Two metrics are registered on the executing operator's
OperatorMetricGroup, scoped as<operator_name>.udf.<udf_name>.<metric>:udfProcessingTime, a Histogram of per-invocation UDF time.udfExceptionCount, a Counter of exceptions that escape user code.The feature is off by default (
table.exec.udf-metric-enabled = false) with zero overhead when disabled: the instrumentation is emitted at code generation only when the option is on, so the generated operator is byte-identical to today when it is off. When on, only every Nth invocation is timed (table.exec.udf-metric.sample-interval, default 100), while exceptions are counted on every invocation.Brief change log
@PublicEvolvingoptions toExecutionConfigOptions:table.exec.udf-metric-enabled(default false) andtable.exec.udf-metric.sample-interval(default 100), plus the regenerated config docs.evalcall site for synchronous scalar and table UDFs inBridgingFunctionGenUtil, bracketing it with sampled timing and exception counting.UdfMetricshandle per(operator, udf name)inCodeGeneratorContext, so repeated call sites of the same function in one operator share a handle instead of the second registration being dropped.BridgingSqlFunctionstack, via an opt-in name passed fromBridgingSqlFunctionCallGen. Lookup-join, ML-predict, vector-search, legacyCallGens, andPROCESS_TABLEfunctions are not metered.Verifying this change
This change added tests and can be verified as follows:
UdfMetricsITCase(integration, usingInMemoryReporter) covers synchronous scalar and table functions, metric naming and scope, exception counting, the enabled/disabled gate, that a lookup join is not metered, that repeated call sites of one function share a single handle while distinct functions get separate ones, and thatudfProcessingTimereflects a real induced delay rather than only a sample count.ConfigOptionsDocsCompletenessITCaseand the regenerated config docs verify the two new options are documented.On overhead: the disabled path is byte-identical to today, so it is zero by construction. With the feature on, a local micro-benchmark put the non-sampled fast path in the sub-nanosecond range, since it is a single integer increment, with the
nanoTime()and histogram work amortized across the sampling interval. A rigorous JMH benchmark belongs inflink-benchmarksrather than here, and I am happy to follow up with one.Does this pull request potentially affect one of the following parts:
@Public(Evolving): yes, two new@PublicEvolvingConfigOptions inExecutionConfigOptions.Documentation
metrics.mdsection lands in PR-4.Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Anthropic Claude Opus 4.8 and Claude Opus 5)