Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: Added return of the original function result when tracer not defined #1268

Merged
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 45 additions & 9 deletions chromadb/telemetry/opentelemetry/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from functools import wraps
from enum import Enum
from typing import Any, Callable, Dict, Optional, Union
from typing import Any, Callable, Dict, Optional, Sequence, Union, cast

from opentelemetry import trace
from opentelemetry.util import types
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
Expand Down Expand Up @@ -61,6 +62,13 @@ def __init__(self, system: System):
granularity: OpenTelemetryGranularity = OpenTelemetryGranularity("none")


def _transform_attributes(
tazarov marked this conversation as resolved.
Show resolved Hide resolved
attributes: Dict[str, Any]
) -> Dict[str, types.AttributeValue]:
"""Transform attributes to the format expected by OpenTelemetry."""
return {k: cast(types.AttributeValue, v) for k, v in attributes.items()}


def otel_init(
otel_service_name: Optional[str],
otel_collection_endpoint: Optional[str],
Expand All @@ -72,8 +80,10 @@ def otel_init(
Parameters match the environment variables which configure OTel as documented
at https://docs.trychroma.com/observability.
- otel_service_name: The name of the service for OTel tagging and aggregation.
- otel_collection_endpoint: The endpoint to which OTel spans are sent (e.g. api.honeycomb.com).
- otel_collection_headers: The headers to send with OTel spans (e.g. {"x-honeycomb-team": "abc123"}).
- otel_collection_endpoint: The endpoint to which OTel spans are sent
(e.g. api.honeycomb.com).
- otel_collection_headers: The headers to send with OTel spans
(e.g. {"x-honeycomb-team": "abc123"}).
- otel_granularity: The granularity of the spans to emit.
"""
if otel_granularity == OpenTelemetryGranularity.NONE:
Expand All @@ -99,18 +109,32 @@ def otel_init(
def trace_method(
trace_name: str,
trace_granularity: OpenTelemetryGranularity,
attributes: Dict[str, Union[str, bool, float, int]] = {},
attributes: Optional[
Dict[
str,
Union[
str,
bool,
float,
int,
Sequence[str],
Sequence[bool],
Sequence[float],
Sequence[int],
],
]
] = None,
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
"""A decorator that traces a method."""

def decorator(f: Callable[..., Any]) -> Callable[..., Any]:
@wraps(f)
def wrapper(*args: Any, **kwargs: Dict[Any, Any]) -> Any:
global tracer, granularity, _transform_attributes
global tracer, granularity
if trace_granularity < granularity:
return f(*args, **kwargs)
if not tracer:
return
return f(*args, **kwargs)
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice.

with tracer.start_as_current_span(trace_name, attributes=attributes):
return f(*args, **kwargs)

Expand All @@ -120,13 +144,25 @@ def wrapper(*args: Any, **kwargs: Dict[Any, Any]) -> Any:


def add_attributes_to_current_span(
attributes: Dict[str, Union[str, bool, float, int]]
attributes: Dict[
str,
Union[
str,
bool,
float,
int,
Sequence[str],
Sequence[bool],
Sequence[float],
Sequence[int],
],
]
) -> None:
"""Add attributes to the current span."""
global tracer, granularity, _transform_attributes
global tracer, granularity
if granularity == OpenTelemetryGranularity.NONE:
return
if not tracer:
return
span = trace.get_current_span()
span.set_attributes(_transform_attributes(attributes)) # type: ignore
span.set_attributes(attributes)