Skip to content

Commit 0110eda

Browse files
fix(ollama): pre-imported funcs instrumentation failure
1 parent d886b64 commit 0110eda

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/__init__.py

+40
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import os
55
import json
66
import time
7+
import sys
8+
import inspect
9+
import functools
710
from typing import Collection
811
from opentelemetry.instrumentation.ollama.config import Config
912
from opentelemetry.instrumentation.ollama.utils import dont_throw
@@ -431,6 +434,22 @@ def is_metrics_collection_enabled() -> bool:
431434
return (os.getenv("TRACELOOP_METRICS_ENABLED") or "true").lower() == "true"
432435

433436

437+
# Proxy class to dynamically call the latest ollama function implementations
438+
class InstrumentedFunction:
439+
"""Proxy function that always invokes the latest ollama function implementation"""
440+
def __init__(self, func_name):
441+
self.func_name = func_name
442+
import ollama
443+
original = getattr(ollama, func_name)
444+
functools.update_wrapper(self, original)
445+
self.__wrapped__ = original
446+
447+
def __call__(self, *args, **kwargs):
448+
import ollama
449+
actual_func = getattr(ollama, self.func_name)
450+
return actual_func(*args, **kwargs)
451+
452+
434453
class OllamaInstrumentor(BaseInstrumentor):
435454
"""An instrumentor for Ollama's client library."""
436455

@@ -477,6 +496,27 @@ def _instrument(self, **kwargs):
477496
_wrap(tracer, token_histogram, duration_histogram, wrapped_method),
478497
)
479498

499+
# replace imported ollama functions in other modules
500+
try:
501+
# Iterate through all loaded modules to find modules that reference imported ollama functions
502+
for module_name, module in list(sys.modules.items()):
503+
if module_name != "ollama" and hasattr(module, "__dict__"):
504+
for attr_name, attr_value in list(module.__dict__.items()):
505+
for wrapped_method in WRAPPED_METHODS:
506+
method_name = wrapped_method.get("method")
507+
if (
508+
attr_name == method_name
509+
and (
510+
inspect.isfunction(attr_value)
511+
or inspect.ismethod(attr_value)
512+
)
513+
and attr_value.__module__.startswith("ollama")
514+
):
515+
module.__dict__[attr_name] = InstrumentedFunction(method_name)
516+
logger.debug(f"Replaced {method_name} in module {module_name}")
517+
except Exception as e:
518+
logger.warning(f"Error instrumenting imported ollama methods: {e}")
519+
480520
def _uninstrument(self, **kwargs):
481521
for wrapped_method in WRAPPED_METHODS:
482522
unwrap(

packages/sample-app/sample_app/ollama_streaming.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
base_model = "gemma3:1b"
77

8+
89
def ollama_chat():
910
stream_response = chat(
1011
model=base_model,
@@ -30,4 +31,4 @@ def main():
3031

3132

3233
if __name__ == "__main__":
33-
main()
34+
main()

0 commit comments

Comments
 (0)