Skip to content

POC: add telemetry to localprocess backend.#444

Draft
sujalshah-bit wants to merge 1 commit intokubeflow:mainfrom
sujalshah-bit:add_telemetry_POC
Draft

POC: add telemetry to localprocess backend.#444
sujalshah-bit wants to merge 1 commit intokubeflow:mainfrom
sujalshah-bit:add_telemetry_POC

Conversation

@sujalshah-bit
Copy link
Copy Markdown

What this PR does / why we need it:

Which issue(s) this PR fixes (optional, in Fixes #<issue number>, #<issue number>, ... format, will close the issue(s) when PR gets merged):

Fixes #

Checklist:

  • Docs included if any changes are user facing

Signed-off-by: Sujal Shah <sujalshah28092004@gmail.com>
Copilot AI review requested due to automatic review settings March 31, 2026 15:22
@google-oss-prow
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign astefanutti for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@github-actions
Copy link
Copy Markdown
Contributor

🎉 Welcome to the Kubeflow SDK! 🎉

Thanks for opening your first PR! We're happy to have you as part of our community 🚀

Here's what happens next:

  • If you haven't already, please check out our Contributing Guide for repo-specific guidelines and the Kubeflow Contributor Guide for general community standards
  • Our team will review your PR soon! cc @kubeflow/kubeflow-sdk-team

Join the community:

Feel free to ask questions in the comments if you need any help or clarification!
Thanks again for contributing to Kubeflow! 🙏

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds OpenTelemetry telemetry instrumentation to the Kubeflow Trainer SDK's local process backend. The changes include adding OpenTelemetry dependencies, instrumenting key functions with spans, and propagating tracer providers through the call stack while handling thread boundaries correctly. A new example file demonstrates how to configure and use the telemetry system with different backends (Jaeger, OTel Collector, console).

Changes:

  • Added OpenTelemetry dependencies (api, sdk, exporter-otlp-proto-grpc) to pyproject.toml and uv.lock
  • Instrumented LocalProcessBackend and its utility functions with distributed tracing spans
  • Added TrainerClient-level spans and proper exception handling
  • Implemented span context propagation across thread boundaries in LocalJob
  • Added test_client.py demonstrating how to build and use a TracerProvider

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pyproject.toml Added opentelemetry-api, opentelemetry-sdk, and opentelemetry-exporter-otlp-proto-grpc to dev dependencies
uv.lock Updated lock file with new OpenTelemetry package versions and transitive dependencies
kubeflow/trainer/backends/localprocess/utils.py Added span instrumentation to get_dependencies_command, get_command_using_train_func, and get_local_train_job_script with tracer_provider parameter passing
kubeflow/trainer/backends/localprocess/job.py Added parent span context and tracer_provider parameters; implemented LocalJob.run() with telemetry spans and proper context propagation across thread boundary
kubeflow/trainer/backends/localprocess/backend.py Added tracer_provider parameter to LocalProcessBackend; wrapped all public methods with instrumentation spans
kubeflow/trainer/api/trainer_client.py Added tracer_provider parameter to TrainerClient; wrapped all public methods with telemetry spans
kubeflow/test_client.py New example demonstrating telemetry configuration with build_tracer_provider() and MNIST training example

Comment on lines +79 to +83
self.backend = KubernetesBackend(backend_config, tracer_provider=_provider)
elif isinstance(backend_config, LocalProcessBackendConfig):
self.backend = LocalProcessBackend(backend_config)
self.backend = LocalProcessBackend(backend_config, tracer_provider=_provider)
elif isinstance(backend_config, ContainerBackendConfig):
self.backend = ContainerBackend(backend_config)
self.backend = ContainerBackend(backend_config, tracer_provider=_provider)
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

KubernetesBackend and ContainerBackend do not have a tracer_provider parameter, but the code attempts to pass it. This will raise a TypeError when TrainerClient is initialized with these backends. The other backends need to be updated to accept this parameter.

Copilot uses AI. Check for mistakes.
Comment on lines +139 to +141
span.set_status(StatusCode.ERROR, "Job cancelled")
span.set_attribute("job.cancelled", True)
return
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

The context.detach() at line 183 will not be called when an early return occurs at line 141 inside the try block. This leaves the context stack corrupted for future use on that OS thread. The context.attach/detach pattern should be outside the inner try-except-finally block to ensure detach always executes.

Copilot uses AI. Check for mistakes.
Comment on lines +198 to 209
result.append(
types.TrainJob(
name=_job.name,
creation_timestamp=_job.created,
runtime=runtime,
num_nodes=1,
steps=[
types.Step(name=s.step_name, pod_name=s.step_name, status=s.job.status)
for s in _job.steps
],
)
)
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

In list_jobs, the TrainJob constructor is passed runtime=runtime (the filter parameter), but it should be runtime=_job.runtime (the actual job's runtime) to be consistent with get_job and to correctly return the runtime for each job.

Copilot uses AI. Check for mistakes.
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.

2 participants