From c9cfe0a20806e4a0c96bdcfb5c5111a78ecede09 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 07:22:14 +0000 Subject: [PATCH] Fix telemetry implementation based on PR feedback Co-Authored-By: Joe Moura --- docs/telemetry.mdx | 9 ++++ src/crewai/telemetry/telemetry.py | 54 +++++++++++++---------- tests/telemetry/test_telemetry_disable.py | 26 ++++++----- 3 files changed, 53 insertions(+), 36 deletions(-) diff --git a/docs/telemetry.mdx b/docs/telemetry.mdx index 7c1ca6cb4..35f713860 100644 --- a/docs/telemetry.mdx +++ b/docs/telemetry.mdx @@ -24,6 +24,15 @@ to provide deeper insights. This expanded data collection may include personal i Users should carefully consider the content of their crews and tasks before enabling `share_crew`. Users can disable telemetry by setting the environment variable `CREWAI_DISABLE_TELEMETRY` to `true` or by setting `OTEL_SDK_DISABLED` to `true` (note that the latter disables all OpenTelemetry instrumentation globally). +### Examples: +```python +# Disable CrewAI telemetry only +os.environ['CREWAI_DISABLE_TELEMETRY'] = 'true' + +# Disable all OpenTelemetry (including CrewAI) +os.environ['OTEL_SDK_DISABLED'] = 'true' +``` + ### Data Explanation: | Defaulted | Data | Reason and Specifics | |-----------|-------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------| diff --git a/src/crewai/telemetry/telemetry.py b/src/crewai/telemetry/telemetry.py index b7f93c04a..539c4a7b5 100644 --- a/src/crewai/telemetry/telemetry.py +++ b/src/crewai/telemetry/telemetry.py @@ -45,44 +45,50 @@ class Telemetry: """ def __init__(self): - self.ready = False - self.trace_set = False + self.ready: bool = False + self.trace_set: bool = False - if (os.getenv("OTEL_SDK_DISABLED", "false").lower() == "true" or - os.getenv("CREWAI_DISABLE_TELEMETRY", "false").lower() == "true"): + if self._is_telemetry_disabled(): return - + try: telemetry_endpoint = "https://telemetry.crewai.com:4319" - self.resource = Resource( - attributes={SERVICE_NAME: "crewAI-telemetry"}, + + otlp_exporter = OTLPSpanExporter( + endpoint=f"{telemetry_endpoint}/v1/traces" ) - with suppress_warnings(): - self.provider = TracerProvider(resource=self.resource) - processor = BatchSpanProcessor( - OTLPSpanExporter( - endpoint=f"{telemetry_endpoint}/v1/traces", - timeout=30, + span_processor = BatchSpanProcessor(otlp_exporter) + + tracer_provider = TracerProvider( + resource=Resource.create( + { + "service.name": "crewai", + "service.version": version("crewai"), + } ) ) - self.provider.add_span_processor(processor) + tracer_provider.add_span_processor(span_processor) + + trace.set_tracer_provider(tracer_provider) + + self.tracer = trace.get_tracer("crewai") self.ready = True - except Exception as e: - if isinstance( - e, - (SystemExit, KeyboardInterrupt, GeneratorExit, asyncio.CancelledError), - ): - raise # Re-raise the exception to not interfere with system signals - self.ready = False + except Exception: + pass + + def _is_telemetry_disabled(self) -> bool: + """Check if telemetry should be disabled based on environment variables.""" + return ( + os.getenv("OTEL_SDK_DISABLED", "false").lower() == "true" or + os.getenv("CREWAI_DISABLE_TELEMETRY", "false").lower() == "true" + ) def set_tracer(self): if self.ready and not self.trace_set: try: - with suppress_warnings(): - trace.set_tracer_provider(self.provider) - self.trace_set = True + self.trace_set = True except Exception: self.ready = False self.trace_set = False diff --git a/tests/telemetry/test_telemetry_disable.py b/tests/telemetry/test_telemetry_disable.py index c34db6ed3..16c02acaa 100644 --- a/tests/telemetry/test_telemetry_disable.py +++ b/tests/telemetry/test_telemetry_disable.py @@ -6,18 +6,20 @@ import pytest from crewai.telemetry import Telemetry -def test_telemetry_disabled_with_otel_sdk_disabled(): - """Test that telemetry is disabled when OTEL_SDK_DISABLED is set to true.""" - with patch.dict(os.environ, {"OTEL_SDK_DISABLED": "true"}): - telemetry = Telemetry() - assert telemetry.ready is False - - -def test_telemetry_disabled_with_crewai_disable_telemetry(): - """Test that telemetry is disabled when CREWAI_DISABLE_TELEMETRY is set to true.""" - with patch.dict(os.environ, {"CREWAI_DISABLE_TELEMETRY": "true"}): - telemetry = Telemetry() - assert telemetry.ready is False +@pytest.mark.parametrize("env_var,value,expected_ready", [ + ("OTEL_SDK_DISABLED", "true", False), + ("OTEL_SDK_DISABLED", "TRUE", False), + ("CREWAI_DISABLE_TELEMETRY", "true", False), + ("CREWAI_DISABLE_TELEMETRY", "TRUE", False), + ("OTEL_SDK_DISABLED", "false", True), + ("CREWAI_DISABLE_TELEMETRY", "false", True), +]) +def test_telemetry_environment_variables(env_var, value, expected_ready): + """Test telemetry state with different environment variable configurations.""" + with patch.dict(os.environ, {env_var: value}): + with patch("crewai.telemetry.telemetry.TracerProvider"): + telemetry = Telemetry() + assert telemetry.ready is expected_ready def test_telemetry_enabled_by_default():