Files
crewAI/lib/crewai/tests/telemetry/test_export_logs.py
João Moura 6b6a39d503 fix(events): Improve coding agents instructions (#7447)
* feat: scaffold project with assistant instruction files

- Updated project creation to include `CLAUDE.md` and `GEMINI.md` that import `AGENTS.md`, ensuring consistent guidance across coding assistants.
- Implemented utility functions to copy assistant instruction files during project setup.
- Enhanced documentation in `AGENTS.md` to emphasize the importance of keeping telemetry enabled for optimal performance.
- Added tests to verify the correct scaffolding of assistant instruction files and their contents.

* fix(cli): neutral observability guidance in scaffolded AGENTS.md

- State the observability rule as the user's decision, never a fix for
  console warnings, speed, or a "clean" configuration
- Rewrite the AMP section as built-in capabilities: no "free",
  "proactively", "sales pitch", or scripted pitches
- Turn the research mandate into a list of sources to consult when
  version details matter
- Retarget the scaffold tests to the new wording

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(cli): scaffold assistant files for JSON crews and harden telemetry tests

- create_json_crew, the default `crewai create crew` path, now copies
  AGENTS.md, CLAUDE.md and GEMINI.md; AGENTS.md documents the JSON layout
- span helper no longer depends on OTEL_SDK_DISABLED being popped by an
  earlier test; thread-scope test stops its worker before leaving the mock
- single import style in the shutdown test

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 02:07:57 -03:00

70 lines
2.3 KiB
Python

"""The crewai Telemetry pipeline must not log when the collector is unreachable.
The filter lives in ``crewai_core``; this pins that the ``crewai`` package wires
the same exporter, since a duplicated exporter here used to log every failure.
"""
import logging
import time
from unittest.mock import patch
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
import pytest
import requests
import crewai_core.telemetry as core_telemetry
from crewai.telemetry.telemetry import Telemetry
@pytest.fixture
def live_telemetry(monkeypatch):
monkeypatch.setattr(Telemetry, "_instance", None)
monkeypatch.setattr(Telemetry, "_register_shutdown_handlers", lambda self: None)
for var in ("CREWAI_DISABLE_TELEMETRY", "CREWAI_DISABLE_TRACKING", "OTEL_SDK_DISABLED"):
monkeypatch.setenv(var, "false")
telemetry = Telemetry()
try:
yield telemetry
finally:
if telemetry.ready:
telemetry.provider.shutdown()
Telemetry._instance = None
def test_pipeline_is_silent_when_collector_rejects(live_telemetry, caplog):
with (
patch(
"requests.Session.post",
side_effect=requests.exceptions.HTTPError("400 Client Error"),
),
caplog.at_level(logging.DEBUG),
):
live_telemetry.provider.get_tracer("test").start_span("probe").end()
assert live_telemetry.provider.force_flush(timeout_millis=10_000)
otlp_records = [r for r in caplog.records if r.name == OTLPSpanExporter.__module__]
assert otlp_records == []
def test_exit_hook_stops_waiting_at_the_flush_deadline(
live_telemetry, monkeypatch, caplog
):
monkeypatch.setattr(core_telemetry, "FINAL_FLUSH_SECONDS", 1)
live_telemetry.provider.get_tracer("test").start_span("probe").end()
with (
patch(
"requests.Session.post",
side_effect=requests.exceptions.ConnectionError("collector down"),
),
caplog.at_level(logging.DEBUG),
):
started = time.monotonic()
live_telemetry._shutdown()
elapsed = time.monotonic() - started
assert elapsed < 5 # the exporter's own retry budget is 30s
assert live_telemetry.ready is False
otlp_records = [r for r in caplog.records if r.name == OTLPSpanExporter.__module__]
assert otlp_records == []