open-telemetry / open-telemetry/opentelemetry-python-contrib
grpc: invoke callable hooks that do not expose __name__
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.1k
- Forks
- 1.1k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 16
Description
Applications registering callable objects or ordinary functools.partial objects as gRPC client hooks silently lose all hook-provided span enrichment and receive an erroneous callback-failure log on every call. The RPC itself still runs. Named functions and bound methods are unaffected.
At instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_client.py:68:
_safe_invoke evaluates function_name = function.__name__ before function(*args) inside the same try block. A callable instance implementing call but not name raises AttributeError at the first statement. The handler logs that error and never invokes the hook. Both _call_request_hook and _call_response_hook explicitly accept any callable at lines 164-172, so this metadata lookup imposes an unintended extra requirement. _BaseAioClientInterceptor inherits these methods in _aio_client.py:46, affecting both sync and async clients. Existing hook tests supply ordinary functions, which all have name.
Proposed fix
Make callback-name lookup optional in _client.py so missing name does not prevent invocation, retaining the existing exception boundary and fallback label. Extend tests/test_client_interceptor_hooks.py and tests/test_aio_client_interceptor_hooks.py with callable-object and partial hooks, successful span enrichment, and throwing-callable coverage. Keep the change scoped to gRPC rather than refactoring other packages' similarly named helpers. Add a root fixed changelog fragment after contribution prerequisites are resolved.
How to see it
Unexecuted, unambiguous Python execution trace. Define Hook with call that appends its arguments to a list and no name attribute. Construct OpenTelemetryClientInterceptor with this object as request_hook and response_hook, and call its two hook dispatch methods with sentinel span and message objects. callable returns True, then _safe_invoke raises AttributeError before call; the list stays empty instead of containing both calls. Test the same inherited dispatch on an aio interceptor. As public-path regression coverage, register callable-object and partial request hooks with GrpcInstrumentorClient and GrpcAioInstrumentorClient using the existing local test server; assert the hook's expected span attribute is present and no callback error is logged. A throwing callable should still be invoked once, logged, and prevented from breaking the RPC. These assertions fail before the fix and pass after it.
If this looks right I can push fix/grpc-callable-hooks on anxkhn/opentelemetry-python-contrib instead of opening a pull request first.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at _safe_invoke in instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_client.py and run the existing hook tests. Extend tests/test_client_interceptor_hooks.py and tests/test_aio_client_interceptor_hooks.py for callable objects, partial hooks, and throwing callables, including span enrichment and logging behavior. Verify the public instrumentor paths with the local test server and add the required root changelog fragment.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- grpc, python
- Domain
- api, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100