תיעוד 48
ניטור שימוש (OpenTelemetry חיצוני)
סטטוס: אלפא. הסכמה להלן מנוהלת בגרסאות (
grok_code.schema.version = v1), שינויים תוספתיים עשויים להתרחש ללא הודעה מוקדמת, שינויי שמות או הסרות יעלו את מספר הגרסה ויצוינו ב-changelog.
Grok CLI יכול לייצא מדדים (metrics) ואירועים (events) של שימוש אל אספן OpenTelemetry של הארגון שלך, כך שצוותי פלטפורמה יוכלו לנטר אימוץ, צריכת טוקנים, החלטות הרשאה של כלים ושגיאות בכל הצי, ללא כל מעבר נתונים דרך SpaceXAI.
#הגדרות קשורות
מתגים אלה אינם תלויים זה בזה (וגם לא בתזרים ה-OTEL החיצוני של מדריך זה):
| הגדרה | כיצד להגדיר אותה |
|---|---|
| מתג ראשי לטלמטריה | [features] telemetry / GROK_TELEMETRY_ENABLED |
| נתוני כתיבת קוד, שמירת מידע ואימון | Settings: הפקודה /privacy פותחת את השורה |
| העלאת עקבות (Trace upload) | [telemetry] trace_upload / GROK_TELEMETRY_TRACE_UPLOAD |
| OpenTelemetry חיצוני | GROK_EXTERNAL_OTEL / [telemetry] otel_* (מדריך זה) |
ראה גם Authentication ו-Configuration.
#תזרים OTEL חיצוני
התזרים החיצוני:
- כבוי כברירת מחדל, ודורש הסכמה כפולה (double opt-in) (מתג ראשי וגם בחירה מפורשת של מייצא).
- נטול תוכן כברירת מחדל: ללא הנחיות (prompts), ללא קוד, ללא נתיבי קבצים (סיומת בלבד), ללא ארגומנטים של כלים, ללא פקודות
bash, ושמות של MCP, מיומנויות (skills) ותוספים (plugins) מכווצים לקטגוריות. שערי תוכן אופציונליים מאפשרים להפעיל מחדש חלק מאלה. - נפרד מבנית מטלמטריה פנימית של SpaceXAI: המייצאים שלו נושאים אך ורק את הכותרות שאתה מגדיר, לעולם לא פרטי אימות של SpaceXAI.
- בלתי תלוי בביטולי שמירת מידע (opt-outs) של SpaceXAI: הוא פועל גם כאשר
telemetryמושבת ועבור צוותי ZDR (אפס שמירת מידע, zero-data-retention). הגדרות אלו שולטות בשמירה בצד של SpaceXAI, התזרים החיצוני נשלט אך ורק על ידי תצורת ה-OTEL שלך.
#התחלה מהירה
export GROK_EXTERNAL_OTEL=1
# master switch
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
# or grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=https://collector.corp.example:4318
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <collector-token>"
grokההגדרה GROK_EXTERNAL_OTEL=1 לבדה אינה מפעילה דבר: עליך לבחור גם לפחות מייצא אחד. לעומת זאת, משתני OTEL_* לבדם אינם מפעילים דבר ללא המתג הראשי.
#משתני סביבה
| משתנה | ברירת מחדל | משמעות |
|---|---|---|
GROK_EXTERNAL_OTEL | 0 | מתג ראשי. נבדל מ-GROK_TELEMETRY_ENABLED, אשר שולט בניתוח מוצר פנימי של SpaceXAI: השניים שולטים בזרימות נתונים בעלות כיוונים מנוגדים. |
OTEL_METRICS_EXPORTER | none | otlp | console | none. |
OTEL_LOGS_EXPORTER | none | otlp | console | none. שולט בשער תזרים האירועים. |
OTEL_EXPORTER_OTLP_PROTOCOL | http/protobuf | http/protobuf | grpc. פרוטוקול בסיס עבור שני האותות. |
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL / ..._METRICS_PROTOCOL | ללא | עקיפות פרוטוקול לכל אות (אותם ערכים כמו פרוטוקול הבסיס). ערכים לא מוכרים משביתים את התזרים. |
OTEL_EXPORTER_OTLP_ENDPOINT | http://localhost:4318 עבור HTTP, http://localhost:4317 עבור gRPC | נקודת קצה בסיסית. עבור http/protobuf, מתווספים /v1/logs ו-/v1/metrics לפי מפרט OTLP, עבור grpc, נקודת הקצה של האספן משמשת כפי שהיא. הוספת הנתיב משתמשת בפרוטוקול של אותו אות. |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT / ..._METRICS_ENDPOINT | ללא | עקיפות ספציפיות לאות, בשימוש מדויק כפי שהן. עבור gRPC אלה צריכות להיות בדרך כלל נקודות קצה של אספן ללא נתיבי /v1/.... |
OTEL_EXPORTER_OTLP_HEADERS (+ גרסאות ספציפיות לאות) | ללא | אימות אספן (k=v,k2=v2). הכותרות היחידות שהמייצאים החיצוניים שולחים, ומנגנון אימות האספן הנתמך היחיד (אין מפתח headers בקובץ התצורה, טוקנים לעולם אינם נשמרים בדיסק). |
OTEL_EXPORTER_OTLP_CERTIFICATE (+ גרסאות ספציפיות לאות) | ללא | נתיב למארז PEM עם תעודות CA מהימנות נוספות לאימות האספן, עבור אספנים שמאחורי CA פרטי או ארגוני. מתווסף לשורשי המהימנות של ברירת המחדל (מאגר המערכת ושורשי Mozilla מוטמעים). ניתן להגדרה גם דרך [telemetry] otel_certificate. |
OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE / OTEL_EXPORTER_OTLP_CLIENT_KEY (+ גרסאות ספציפיות לאות ..._LOGS_... / ..._METRICS_...) | ללא | נתיבי PEM לזהות לקוח mTLS. חובה להגדיר גם תעודה וגם מפתח (בסיסי או עבור אותו אות), תצורה חלקית זוכה להתעלמות עם אזהרה. מפתחות PEM שאינם מוצפנים בלבד. ניתן להגדרה גם דרך [telemetry] otel_client_certificate / otel_client_key. |
OTEL_EXPORTER_OTLP_TIMEOUT | 10000 (מילישניות) | פסק זמן לייצוא. |
OTEL_METRIC_EXPORT_INTERVAL | 60000 (מילישניות) | מרווח ייצוא מדדים. |
OTEL_BLRP_SCHEDULE_DELAY (או הכינוי OTEL_LOGS_EXPORT_INTERVAL) | 5000 (מילישניות) | מרווח אצוות יומנים. |
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | delta | delta | cumulative. |
OTEL_METRICS_INCLUDE_SESSION_ID | 1 | צירוף session.id למדדים (ביטול לפי קרדינליות). |
OTEL_METRICS_INCLUDE_VERSION | 0 | צירוף app.version למדדים. |
OTEL_LOG_USER_PROMPTS | 0 | שער תוכן: טקסט ההנחיה ב-grok_code.user_prompt (מגבלה של 60 קילובייט, מנוקה מסודות). |
OTEL_LOG_TOOL_DETAILS | 0 | שער תוכן: פרמטרים של כלים (מגבלה של 4 קילובייט), נתיבי קבצים מלאים, שמות MCP, מיומנויות ותוספים כלשונם. טקסט של פקודות bash לעולם אינו מיוצא ב-v1, אפילו עם שער זה. |
מהמשתנה OTEL_RESOURCE_ATTRIBUTES מתעלמים במכוון: המשאב נבנה מתוך קבוצת תכונות קבועה ומבוקרת.
הערת שדרוג: גרסאות ישנות יותר יכלו לחלוק את
OTEL_EXPORTER_OTLP_*עם צינור הניתוח של המוצר עצמו. התנהגות זו מיושנת (deprecated): כאשרGROK_EXTERNAL_OTELמוגדר, ניתוח המוצר מתעלם ממשתנים אלה, וה-CLI מסרב להפעיל את התזרים החיצוני בכל תצורה שבה ניתוח המוצר כבר צרך אותם, האספן שלך מקבל אך ורק את התזרים החיצוני שבחרת להפעיל.
#קובץ תצורה
ברירות המחדל של הארגון נמצאות תחת טבלת [telemetry] הקיימת ב-config.toml (משתני סביבה קודמים). המפתחות הם מקבילים עם הקידומת _otel להגדרות [telemetry] האחרות:
[telemetry]
otel_enabled = true
otel_metrics_exporter = "otlp"
otel_logs_exporter = "otlp"
otel_endpoint = "https://collector.corp.example:4318"
otel_protocol = "http/protobuf"
# or "grpc"
# Optional PEM *paths* for private-CA trust and mTLS (never PEM contents):
otel_certificate = "/etc/ssl/corp-ca.pem"
otel_client_certificate = "/etc/ssl/client.crt"
otel_client_key = "/etc/ssl/client.key"
otel_log_user_prompts = false
# admins can pin these via requirements
otel_log_tool_details = falseמפתחות התצורה הם otel_* תחת [telemetry], משתני הסביבה שומרים על שמות ה-OTEL הסטנדרטיים שלהם (GROK_EXTERNAL_OTEL, OTEL_*) לצורך תאימות עם המערכת האקולוגית, כך ששתי השכבות משתמשות במכוון במרחבי שמות שונים. מפתח התצורה otel_protocol ממפה אל OTEL_EXPORTER_OTLP_PROTOCOL. משתני סביבה קודמים לנתיבים שבקובץ התצורה עבור CA וזהות לקוח.
במכוון אין מפתח headers: ספק אימות אספן דרך OTEL_EXPORTER_OTLP_HEADERS כדי שטוקנים לעולם לא יישמרו בדיסק. מפתחות תצורה של תעודה ומפתח הם נתיבים בלבד, לעולם אל תטמיע תוכן של מפתח פרטי בתוך TOML.
התזרים החיצוני מייצא יומנים ומדדים בלבד (אין מייצא עקבות הפונה ללקוח).
פריסות מנוהלות יכולות בנוסף להפעיל טלמטריה לכל הארגון על ידי הפצת מפתחות ה-otel_* של [telemetry] דרך תצורה מנוהלת או הצמדות דרישות (requirements pins) של grok setup, או להשבית אותה בכפייה בכל הצי באמצעות אותן שכבות תצורה מקומיות (external_otel_disabled, נעילות של שערי תוכן).
#השהיית הפעלה (מדוע שום דבר לא מגיע בשניות הראשונות)
מכיוון ש-xAI יכולה להשבית בכפייה תזרים זה בכל הצי, ה-CLI משהה את הפליטה בעת ההפעלה עד שהוא יודע אם מתג זה מוגדר: הוא מביא את מדיניות הצי מ-/v1/settings ורק אז מתחיל לייצא. בהתקנה תקינה זה לוקח הרבה פחות משנייה ואינו מורגש.
ההמתנה מוגבלת בזמן, כך שפריסה שאינה יכולה להגיע אל xAI עדיין מייצאת:
- אם שום מדיניות צי אינה יכולה לחול כלל, כאשר
[features] remote_fetch = false, או כאשר[endpoints] cli_chat_proxy_base_urlמצביע למקום אחר שאינו xAI, התזרים מתחיל מיד, ונשלט על ידי התצורה המקומית שלך. - אם הבאת המדיניות נכשלת או אינה מסתיימת לעולם (מחשב מאחורי חומת אש, מחשב נייד לא מקוון), הפליטה מתחילה בכל מקרה ברגע שהניסיון מוצה, ובכל המקרים לא יאוחר מ-30 שניות לאחר ההפעלה.
מדיניות צי שמגיעה לאחר מכן עדיין חלה, היא יכולה רק להחמיר (להשבית את התזרים או לכפות כיבוי של שערי התוכן), לעולם לא להפעיל משהו שהתצורה המקומית שלך לא אפשרה.
אם האספן שלך אינו מקבל דבר כלל, בדוק ביומן הניפוי (grok --debug) שורות המכילות external otel:, הן מתעדות האם התזרים פענח את התצורה שלו, והאם הוא מייצא או מושהה.
#תכונות משאב (Resource attributes)
| תכונה | ערך |
|---|---|
service.name | grok-cli |
service.version, client.version | גרסאות build/client |
app.entrypoint | cli | headless | agent |
terminal.type | מותג מדמה המסוף (terminal emulator) |
grok_code.schema.version | v1 |
תכונות זהות (user.id, ו-organization.id / team.id / deployment.id כאשר הן ידועות) מצורפות לכל נקודת נתונים של מדד ולכל אירוע ברגע שהאימות מסתיים. prompt.id (מזהה UUID ייחודי לכל הנחיה) מופיע באירועים בלבד, לעולם לא במדדים.
#מדדים (היקף מונה ai.xai.grok_code)
| מדד | יחידה | תכונות |
|---|---|---|
grok_code.session.count | {session} | תכונות בסיס בלבד |
grok_code.token.usage | {token} | type = input | output | reasoning | cache_read; model |
grok_code.turn.count | {turn} | outcome = completed | cancelled | error; model |
grok_code.tool.decision | {decision} | tool_name, decision = allow | deny | cancelled | followup, access_kind, permission_mode |
grok_code.tool.usage | {call} | tool_name, outcome |
grok_code.error.count | {error} | error_category, model |
grok_code.startup.total | ms | outcome = ok | timeout | error; auth_mode |
grok_code.startup.phase_duration | ms | phase, outcome, auth_mode |
grok_code.startup.timeout | {timeout} | stuck_in, auth_mode |
המדד startup.total מודד את הזמן מתחילת התהליך ועד להפעלה (session) שמישה, ונרשם פעם אחת לכל תהליך. outcome = timeout או error פירושו שההפעלה הסתיימה ללא הפעלה שמישה.
המדד phase_duration מפרק את ניסיון ההתחברות לפי שלב (config_load, managed_policy, bootstrap, model_catalog, worker_spawn, leader_connect, acp_initialize, eager_auth). סנן לפי ה-outcome שלו (ok | timeout | cancelled | error) כדי שדגימות קטועות לא יטו את אחוזוני ה-ok. שלבי app_init ו-session_create המאוחרים יותר מופיעים בציר הזמן של היומנים ובמחרוזות הסיכום, ולא במדד זה.
המאפיין stuck_in במקרה של פסק זמן (timeout) מציין את השלב שלא הסתיים. לעתים קרובות זה אינו השלב שלקח את הזמן הארוך ביותר, מכיוון ששלב שרץ ללא השהיה מסתיים לפני שפסק הזמן נרשם. הודעת השגיאה ש-Grok מדפיס מציינת במקום זאת את השלב הארוך ביותר, כך שהשניים יכולים לציין שלבים שונים עבור אותו פסק זמן. השתמש ב-phase_duration כדי להשוות ביניהם.
המאפיין auth_mode הוא personal, team, deployment או unknown: עלות ההפעלה שונה לפי הסוג, לכן פצל לפיו לפני ההשוואה.
אין מדד cost.usage: בצע הצלבה (join) של grok_code.token.usage עם מחירון משלך. המדדים lines_of_code.count ו-active_time.total מתוכננים לשלב מאוחר יותר.
ערכי tool_name: שמות של כלים מובנים מועברים כלשונם, כלי MCP מכווצים ל-mcp_tool וכלים אחרים שאינם מובנים מכווצים ל-custom_tool, אלא אם OTEL_LOG_TOOL_DETAILS=1.
#אירועים (רשומות יומן OTLP)
כל אירוע נושא את event.sequence, session.id, turn_number (בתוך התור), prompt.id, בתוספת תכונות הזהות. מקרא שערים: details = דורש את OTEL_LOG_TOOL_DETAILS, prompts = דורש את OTEL_LOG_USER_PROMPTS, כל השאר מיוצא תמיד כאשר התזרים פעיל.
event.name | תכונות |
|---|---|
grok_code.session_start | model, permission_mode, mcp_server_count, plugin_count, skill_count, hook_count, memory_enabled, is_git_repo, client_identifier |
grok_code.session_end | duration_secs, turn_count, tool_call_count, compaction_count, model |
grok_code.user_prompt | prompt_length, model, screen_mode? (fullscreen | inline | minimal | headless | other); prompt (prompts) |
grok_code.turn_completed | outcome, duration_ms, tool_call_count, model, error_category?, cancellation_category? |
grok_code.api_request | model, duration_ms, stop_reason?, input_tokens, output_tokens, reasoning_tokens, cache_read_tokens |
grok_code.api_error | error_category, model, status_code?, duration_ms? |
grok_code.tool_result | tool_name, outcome, success, duration_ms, file_extension; tool_parameters, file_path (details) |
grok_code.tool_decision | tool_name, decision, access_kind, permission_mode, source |
grok_code.mcp_server_connection | status, transport_type, duration_ms, tool_count?, error_type?; mcp_server.name (details; מכווץ ל-mcp_server אחרת) |
grok_code.permission_mode_changed | to_mode, trigger |
grok_code.skill_activated | skill_source, trigger = slash_command | skill_md_read | skill_tool; skill.name (details) |
grok_code.plugin_loaded | install_kind?, success, error_category?; plugin_name (details) |
grok_code.compaction | duration_ms, tokens_before, tokens_after, model? |
grok_code.subagent | phase = launched | completed, subagent_type?, outcome?, duration_ms? |
grok_code.auth | auth_method |
grok_code.internal_error | error_type (מחלקה בלבד, ללא הודעה, ללא מיקום) |
grok_code.model_switched | from_model, to_model, success, error_code? |
#מודל פרטיות
שלושה מנגנוני fail-closed עצמאיים מגנים על פורמט התעבורה:
- סכמה מוגדרת טיפוסים (typed schema): מפתחות התכונות הם טיפוס enum סגור, שום דבר מחוצה לו אינו יכול להצטרף.
- הסתרת מידע בעת הפליטה (Emit-time redaction): כל מחרוזת עוברת ניקוי תבניות סודיות וניקוי ספריית הבית, יחד עם קיצוץ (512 ל-128 תווים לכל ערך, 4 קילובייט לפרמטרים של כלים, מגבלה של 60 קילובייט להנחיה).
- מאמתי זמן ייצוא (Export-time validators): כל רשומה הנושאת מפתח שאינו מופיע בסכמה, מפתח של שער סגור, או תבנית סודית שלא נוקתה, נשמטת לפני עזיבת התהליך. ייצויי מדדים עם מפתחות תכונה שמחוץ לסכמה נשמטים במלואם.
לעולם אינם מיוצאים: טקסט של פקודות bash, גופי הודעות שגיאה, טקסט הנחיות (ללא השער), נתיבי קבצים (ללא השער), api_key.id, טביעות אצבע של מכונות, כתובות דוא"ל, דרגת מנוי.
#תצורת אספן לדוגמה
receivers:
otlp:
protocols:
http:
endpoint: 0.0.0.0:4318
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
exporters:
prometheus:
endpoint: 0.0.0.0:9464
service:
pipelines:
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheus]
logs:
receivers: [otlp]
processors: [batch]
exporters: []
# point at your log backend (loki, elasticsearch, …)שאילתות לדוגמה (PromQL, עם מייצא ה-Prometheus לעיל):
# Tokens by model and type across the org, 1h rate
sum by (model, type) (rate(grok_code_token_usage_total[1h]))
# Sessions per team per day
sum by (team_id) (increase(grok_code_session_count_total[1d]))
# Tool-permission denial ratio
sum(rate(grok_code_tool_decision_total{decision="deny"}[1h]))
/ sum(rate(grok_code_tool_decision_total[1h]))#ניפוי שגיאות
הגדר את OTEL_LOGS_EXPORTER=console / OTEL_METRICS_EXPORTER=console כדי להדפיס רשומות מוסתרות אל stderr (מושתק בנקודות כניסה של agent/headless כדי לשמור על ניקיון היומנים שנלכדו). שגיאות ייצוא לעולם אינן מוצגות ב-TUI, בדוק את יומן הניפוי.