Skip to content

Commit b546982

Browse files
fix: ensure instrumentation flags
1 parent d7bdac1 commit b546982

24 files changed

+3625
-1150
lines changed

docs/en/concepts/cli.mdx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,77 @@ crewai config reset
402402
After resetting configuration, re-run `crewai login` to authenticate again.
403403
</Tip>
404404

405+
### 14. Trace Management
406+
407+
Manage trace collection preferences for your Crew and Flow executions.
408+
409+
```shell Terminal
410+
crewai traces [COMMAND]
411+
```
412+
413+
#### Commands:
414+
415+
- `enable`: Enable trace collection for crew/flow executions
416+
```shell Terminal
417+
crewai traces enable
418+
```
419+
420+
- `disable`: Disable trace collection for crew/flow executions
421+
```shell Terminal
422+
crewai traces disable
423+
```
424+
425+
- `status`: Show current trace collection status
426+
```shell Terminal
427+
crewai traces status
428+
```
429+
430+
#### How Tracing Works
431+
432+
Trace collection is controlled by checking three settings in priority order:
433+
434+
1. **Explicit flag in code** (highest priority - can enable OR disable):
435+
```python
436+
crew = Crew(agents=[...], tasks=[...], tracing=True) # Always enable
437+
crew = Crew(agents=[...], tasks=[...], tracing=False) # Always disable
438+
crew = Crew(agents=[...], tasks=[...]) # Check lower priorities (default)
439+
```
440+
- `tracing=True` will **always enable** tracing (overrides everything)
441+
- `tracing=False` will **always disable** tracing (overrides everything)
442+
- `tracing=None` or omitted will check lower priority settings
443+
444+
2. **Environment variable** (second priority):
445+
```env
446+
CREWAI_TRACING_ENABLED=true
447+
```
448+
- Checked only if `tracing` is not explicitly set to `True` or `False` in code
449+
- Set to `true` or `1` to enable tracing
450+
451+
3. **User preference** (lowest priority):
452+
```shell Terminal
453+
crewai traces enable
454+
```
455+
- Checked only if `tracing` is not set in code and `CREWAI_TRACING_ENABLED` is not set to `true`
456+
- Running `crewai traces enable` is sufficient to enable tracing by itself
457+
458+
<Note>
459+
**To enable tracing**, use any one of these methods:
460+
- Set `tracing=True` in your Crew/Flow code, OR
461+
- Add `CREWAI_TRACING_ENABLED=true` to your `.env` file, OR
462+
- Run `crewai traces enable`
463+
464+
**To disable tracing**, use any ONE of these methods:
465+
- Set `tracing=False` in your Crew/Flow code (overrides everything), OR
466+
- Remove or set to `false` the `CREWAI_TRACING_ENABLED` env var, OR
467+
- Run `crewai traces disable`
468+
469+
Higher priority settings override lower ones.
470+
</Note>
471+
472+
<Tip>
473+
For more information about tracing, see the [Tracing documentation](/observability/tracing).
474+
</Tip>
475+
405476
<Tip>
406477
CrewAI CLI handles authentication to the Tool Repository automatically when adding packages to your project. Just append `crewai` before any `uv` command to use it. E.g. `crewai uv add requests`. For more information, see [Tool Repository](https://docs.crewai.com/enterprise/features/tool-repository) docs.
407478
</Tip>

lib/crewai/src/crewai/cli/cli.py

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,5 +493,206 @@ def config_reset():
493493
config_command.reset_all_settings()
494494

495495

496+
@crewai.group()
497+
def env():
498+
"""Environment variable commands."""
499+
500+
501+
@env.command("view")
502+
def env_view():
503+
"""View tracing-related environment variables."""
504+
import os
505+
from pathlib import Path
506+
507+
from rich.console import Console
508+
from rich.panel import Panel
509+
from rich.table import Table
510+
511+
console = Console()
512+
513+
# Check for .env file
514+
env_file = Path(".env")
515+
env_file_exists = env_file.exists()
516+
517+
# Create table for environment variables
518+
table = Table(show_header=True, header_style="bold cyan", expand=True)
519+
table.add_column("Environment Variable", style="cyan", width=30)
520+
table.add_column("Value", style="white", width=20)
521+
table.add_column("Source", style="yellow", width=20)
522+
523+
# Check CREWAI_TRACING_ENABLED
524+
crewai_tracing = os.getenv("CREWAI_TRACING_ENABLED", "")
525+
if crewai_tracing:
526+
table.add_row(
527+
"CREWAI_TRACING_ENABLED",
528+
crewai_tracing,
529+
"Environment/Shell",
530+
)
531+
else:
532+
table.add_row(
533+
"CREWAI_TRACING_ENABLED",
534+
"[dim]Not set[/dim]",
535+
"[dim]—[/dim]",
536+
)
537+
538+
# Check other related env vars
539+
crewai_testing = os.getenv("CREWAI_TESTING", "")
540+
if crewai_testing:
541+
table.add_row("CREWAI_TESTING", crewai_testing, "Environment/Shell")
542+
543+
crewai_user_id = os.getenv("CREWAI_USER_ID", "")
544+
if crewai_user_id:
545+
table.add_row("CREWAI_USER_ID", crewai_user_id, "Environment/Shell")
546+
547+
crewai_org_id = os.getenv("CREWAI_ORG_ID", "")
548+
if crewai_org_id:
549+
table.add_row("CREWAI_ORG_ID", crewai_org_id, "Environment/Shell")
550+
551+
# Check if .env file exists
552+
table.add_row(
553+
".env file",
554+
"✅ Found" if env_file_exists else "❌ Not found",
555+
str(env_file.resolve()) if env_file_exists else "N/A",
556+
)
557+
558+
panel = Panel(
559+
table,
560+
title="Tracing Environment Variables",
561+
border_style="blue",
562+
padding=(1, 2),
563+
)
564+
console.print("\n")
565+
console.print(panel)
566+
567+
# Show helpful message
568+
if env_file_exists:
569+
console.print(
570+
"\n[dim]💡 Tip: To enable tracing via .env, add: CREWAI_TRACING_ENABLED=true[/dim]"
571+
)
572+
else:
573+
console.print(
574+
"\n[dim]💡 Tip: Create a .env file in your project root and add: CREWAI_TRACING_ENABLED=true[/dim]"
575+
)
576+
console.print()
577+
578+
579+
@crewai.group()
580+
def traces():
581+
"""Trace collection management commands."""
582+
583+
584+
@traces.command("enable")
585+
def traces_enable():
586+
"""Enable trace collection for crew/flow executions."""
587+
from rich.console import Console
588+
from rich.panel import Panel
589+
590+
from crewai.events.listeners.tracing.utils import (
591+
_load_user_data,
592+
_save_user_data,
593+
)
594+
595+
console = Console()
596+
597+
# Update user data to enable traces
598+
user_data = _load_user_data()
599+
user_data["trace_consent"] = True
600+
user_data["first_execution_done"] = True
601+
_save_user_data(user_data)
602+
603+
panel = Panel(
604+
"✅ Trace collection has been enabled!\n\n"
605+
"Your crew/flow executions will now send traces to CrewAI+.\n"
606+
"Use 'crewai traces disable' to turn off trace collection.",
607+
title="Traces Enabled",
608+
border_style="green",
609+
padding=(1, 2),
610+
)
611+
console.print(panel)
612+
613+
614+
@traces.command("disable")
615+
def traces_disable():
616+
"""Disable trace collection for crew/flow executions."""
617+
from rich.console import Console
618+
from rich.panel import Panel
619+
620+
from crewai.events.listeners.tracing.utils import (
621+
_load_user_data,
622+
_save_user_data,
623+
)
624+
625+
console = Console()
626+
627+
# Update user data to disable traces
628+
user_data = _load_user_data()
629+
user_data["trace_consent"] = False
630+
user_data["first_execution_done"] = True
631+
_save_user_data(user_data)
632+
633+
panel = Panel(
634+
"❌ Trace collection has been disabled!\n\n"
635+
"Your crew/flow executions will no longer send traces.\n"
636+
"Use 'crewai traces enable' to turn trace collection back on.",
637+
title="Traces Disabled",
638+
border_style="red",
639+
padding=(1, 2),
640+
)
641+
console.print(panel)
642+
643+
644+
@traces.command("status")
645+
def traces_status():
646+
"""Show current trace collection status."""
647+
import os
648+
649+
from rich.console import Console
650+
from rich.panel import Panel
651+
from rich.table import Table
652+
653+
from crewai.events.listeners.tracing.utils import (
654+
_load_user_data,
655+
is_tracing_enabled,
656+
)
657+
658+
console = Console()
659+
user_data = _load_user_data()
660+
661+
table = Table(show_header=False, box=None)
662+
table.add_column("Setting", style="cyan")
663+
table.add_column("Value", style="white")
664+
665+
# Check environment variable
666+
env_enabled = os.getenv("CREWAI_TRACING_ENABLED", "false")
667+
table.add_row("CREWAI_TRACING_ENABLED", env_enabled)
668+
669+
# Check user consent
670+
trace_consent = user_data.get("trace_consent")
671+
if trace_consent is True:
672+
consent_status = "✅ Enabled (user consented)"
673+
elif trace_consent is False:
674+
consent_status = "❌ Disabled (user declined)"
675+
else:
676+
consent_status = "⚪ Not set (first-time user)"
677+
table.add_row("User Consent", consent_status)
678+
679+
# Check overall status
680+
if is_tracing_enabled():
681+
overall_status = "✅ ENABLED"
682+
border_style = "green"
683+
else:
684+
overall_status = "❌ DISABLED"
685+
border_style = "red"
686+
table.add_row("Overall Status", overall_status)
687+
688+
panel = Panel(
689+
table,
690+
title="Trace Collection Status",
691+
border_style=border_style,
692+
padding=(1, 2),
693+
)
694+
console.print(panel)
695+
696+
496697
if __name__ == "__main__":
497698
crewai()

lib/crewai/src/crewai/cli/settings/main.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
from datetime import datetime
2+
import os
13
from typing import Any
24

35
from rich.console import Console
46
from rich.table import Table
57

68
from crewai.cli.command import BaseCommand
79
from crewai.cli.config import HIDDEN_SETTINGS_KEYS, READONLY_SETTINGS_KEYS, Settings
10+
from crewai.events.listeners.tracing.utils import _load_user_data
811

912

1013
console = Console()
@@ -39,6 +42,42 @@ def list(self) -> None:
3942

4043
table.add_row(field_name, display_value, description)
4144

45+
# Add trace-related settings from user data
46+
user_data = _load_user_data()
47+
48+
# CREWAI_TRACING_ENABLED environment variable
49+
env_tracing = os.getenv("CREWAI_TRACING_ENABLED", "")
50+
env_tracing_display = env_tracing if env_tracing else "Not set"
51+
table.add_row(
52+
"CREWAI_TRACING_ENABLED",
53+
env_tracing_display,
54+
"Environment variable to enable/disable tracing",
55+
)
56+
57+
# Trace consent status
58+
trace_consent = user_data.get("trace_consent")
59+
if trace_consent is True:
60+
consent_display = "✅ Enabled"
61+
elif trace_consent is False:
62+
consent_display = "❌ Disabled"
63+
else:
64+
consent_display = "Not set"
65+
table.add_row(
66+
"trace_consent", consent_display, "Whether trace collection is enabled"
67+
)
68+
69+
# First execution timestamp
70+
if user_data.get("first_execution_at"):
71+
timestamp = datetime.fromtimestamp(user_data["first_execution_at"])
72+
first_exec_display = timestamp.strftime("%Y-%m-%d %H:%M:%S")
73+
else:
74+
first_exec_display = "Not set"
75+
table.add_row(
76+
"first_execution_at",
77+
first_exec_display,
78+
"Timestamp of first crew/flow execution",
79+
)
80+
4281
console.print(table)
4382

4483
def set(self, key: str, value: str) -> None:

0 commit comments

Comments
 (0)