Статистика использования
Control Center может отправлять псевдонимизированные события использования в экземпляр Umami. Статистика использования выключена, пока её не включит оператор сервера. Этот параметр принадлежит серверу и действует для каждого подключённого к нему клиента: приложения для компьютера, веб-приложения, телефона и самого сервера.
Статистика использования не связана с параметром Отправлять отчёты о сбоях — это настройка отдельного устройства для диагностики сбоев и ошибок.
Кто решает
Заголовок раздела «Кто решает»| Переключатель | Где | Действие |
|---|---|---|
| Отправлять статистику использования | Первоначальная настройка (шаг песочницы) и Настройки → Конфиденциальность. Изменить его может только оператор сервера; остальные участники видят текущее значение только для чтения | Для всего сервера. Хранится как telemetry.usage_analytics в настройках сервера. Выключен, если не задано true |
| Тип сборки | Автоматически | Отладочные и профилировочные сборки ничего не отправляют. Вместо этого они записывают каждое событие в журнал отладки |
CC_ANALYTICS_DEBUG=1 |
Окружение cc_server или его файл .env |
Позволяет отладочным и профилировочным сборкам сервера и всех подключённых к нему клиентов отправлять данные по-настоящему, для тестирования. Переключатель выше при этом должен быть включён |
DO_NOT_TRACK=1 |
Окружение cc_server |
Отключает собственную отправку данных сервером, что бы ни показывал переключатель. Клиенты по-прежнему следуют переключателю |
| Демо-сервер | Автоматически | Публичный демо-сервер ничего не отправляет от своего имени. Посетители не могут изменить переключатель |
Клиенты получают значение параметра от сервера (telemetry.config, затем в реальном времени через telemetry.watch). Пока ответ не пришёл, события ждут в небольшом буфере в памяти. Если ответ отрицательный, буфер отбрасывается. Выключение переключателя отбрасывает всё, что ещё стоит в очереди, и сразу прекращает отправку на каждом клиенте.
Что никогда не отправляется
Заголовок раздела «Что никогда не отправляется»- Содержимое сообщений, тикетов, ревью и встреч, заголовки, промпты, команды оболочки и поисковые запросы
- Имена, логины, адреса электронной почты, аватары и отображаемые имена
- Пути к файлам, названия репозиториев и веток, имена хостов и URL (репозиторий отправляется только как псевдонимизированный
repo_id, ссылка на встречу — только как её провайдер) - Исходные идентификаторы любого вида
Каждое событие перед выходом из процесса проходит через политику свойств. Текст, пути, URL, адреса электронной почты, необёрнутые ID и строки под такими ключами, как email, *_name, path, title, prompt, content или token, отбрасываются, а не отправляются. Строка отправляется, только если это короткий токен из закрытого словаря: значение перечисления, версия, локаль или ID модели.
Псевдонимизированные ID
Заголовок раздела «Псевдонимизированные ID»ID отправляются, но только в виде псевдонимов. Каждый ID рабочего пространства, пространства, беседы, агента, запуска, пользователя и устройства заменяется на HMAC-SHA256 с собственной секретной солью установки (telemetry.pseudonym_salt), усечённый до 20 шестнадцатеричных символов. Одно и то же рабочее пространство всегда даёт одно и то же значение, поэтому события можно связывать и подсчитывать, но исходный ID никогда не покидает установку. Соль создаётся при первом запуске сервера и никогда не передаётся поставщику аналитики. Удаление каталога данных сервера создаёт новую соль и новый ID установки, и связь со всем записанным ранее теряется.
Свойства каждого события
Заголовок раздела «Свойства каждого события»| Свойство | Пример | Значение |
|---|---|---|
app_type |
desktop |
desktop, web, remote (телефон) или server. Также используется как имя хоста в Umami |
app_version |
0.0.11 |
Версия релиза |
app_build |
4baf980 |
Короткий git-коммит сборки |
platform |
macos |
macos, windows, linux, web или ОС телефона (ios, android) |
locale |
fr_FR |
Язык интерфейса |
server_mode |
local |
local (приложение для компьютера запускает собственный сервер) или remote |
server_version |
0.0.11 |
Версия подключённого сервера, если известна |
is_demo |
false |
Подключён ли клиент к публичному демо |
install_id |
псевдоним | Установка сервера |
user_id |
псевдоним | Вошедший пользователь, когда он известен |
device_id |
псевдоним | Сопряжённое устройство, когда оно известно. Также служит уникальным ID в Umami |
launch_id |
псевдоним | Один запуск приложения, для упорядочивания событий сеанса |
event_seq |
12 |
Позиция события в пределах запуска |
Кроме того, Umami получает IP-адрес запроса, по которому определяет страну и регион, не сохраняя сам адрес, а также User-Agent и размер экрана.
Просмотры экранов
Заголовок раздела «Просмотры экранов»Каждый переход записывает просмотр страницы, URL которого — шаблон маршрута, например /workspaces/:workspaceId/spaces/:spaceId, а не конкретный адрес. Имя экрана составляется из литеральных сегментов шаблона, так что для этого примера это workspaces_spaces. Параметры маршрута, оканчивающиеся на Id, прикрепляются как псевдонимизированные свойства *_id, а числовые (например, номер PR) — как числа. Все остальные параметры отбрасываются.
События клиентов
Заголовок раздела «События клиентов»Записываются приложением для компьютера, веб-приложением и телефоном для действий человека.
| Событие | Свойства | Когда записывается |
|---|---|---|
app_opened |
startup_ms |
Приложение завершило запуск и подключилось |
app_backgrounded |
foreground_s |
Окно или вкладка были скрыты |
app_foregrounded |
background_s |
Они снова стали видимыми |
server_connected |
reconnect |
Соединение восстановилось после обрыва |
server_disconnected |
Соединение оборвалось | |
server_switched |
Пользователь переключился на другой сервер | |
device_paired |
Телефон подтвердил сопряжение | |
onboarding_step_viewed |
step, step_index |
Показан шаг первоначальной настройки |
onboarding_completed |
duration_s, step_count, workspace_id |
Первоначальная настройка завершена |
workspace_switched |
workspace_id, previous_workspace_id |
Пользователь открыл другое рабочее пространство |
message_sent |
workspace_id, space_id, conversation_id, delivery (send, steer, queued), char_count, attachment_count, agent_mention_count, other_mention_count, slash_command |
Сообщение отправлено из поля ввода |
slash_command_run |
command, workspace_id, space_id |
Выполнена клиентская слеш-команда. Встроенные команды сообщают своё имя, навыки — skill, а команды репозитория — custom |
approval_decided |
decision, remembered, surface, action_classes, action_class_count, severity, workspace_id, space_id, conversation_id |
На запрос одобрения от агента дан ответ |
command_palette_opened |
Открыта палитра команд | |
command_executed |
source (palette, keybinding), command |
Выполнена команда. Команды для конкретного PR, участника или беседы сообщают только свой вид (pr, member, conversation) |
review_submitted |
verdict, comment_count, workspace_id |
Отправлено ревью pull request |
search_performed |
scope (space_messages, repo_content), result_count, query_length, workspace_id, space_id |
Выполнен поиск. Сам запрос никогда не записывается |
meeting_recording_started |
workspace_id, meeting_id |
Началась запись встречи |
meeting_recording_stopped |
duration_s, workspace_id, meeting_id |
Запись остановлена |
setting_changed |
setting (appearance.theme, appearance.locale), value |
Изменена тема или язык |
soundscape_started |
mood, source (user, focus) |
Звуковой фон запущен с панели управления или вместе с режимом фокуса |
soundscape_stopped |
mood, source, listened_s |
Он остановлен |
soundscape_mood_changed |
from_mood, to_mood, playing |
Пользователь выбрал другое настроение |
focus_mode_started |
planned_minutes, has_goal, block_notifications |
Режим фокуса запущен |
focus_mode_ended |
elapsed_s, planned_minutes, completed |
Режим фокуса завершён досрочно или по истечении времени |
dictation_started |
Началась диктовка в поле ввода | |
dictation_ended |
outcome (completed, cancelled, failed), duration_s, transcript_chars, error_kind |
Диктовка завершена. Записывается только длина расшифровки |
pipeline_run_requested |
workspace_id, template_id, trigger, dry_run, started |
Приложение попросило сервер запустить конвейер |
pipeline_run_retried |
workspace_id, pipeline_run_id |
Неудачный запуск повторён |
pipeline_run_cancel_requested |
workspace_id, pipeline_run_id |
Запуск отменён из приложения |
pipeline_step_killed |
workspace_id, step_run_id |
Выполняющийся шаг принудительно остановлен |
calendar_connect_finished |
outcome (connected, denied, expired, failed, cancelled), builtin_client, duration_s |
Попытка входа в календарь завершена |
calendar_disconnected |
workspace_id |
Аккаунт календаря отключён |
calendar_rsvp_sent |
calendar_event_id, response, previous_response, workspace_id |
Дан ответ на приглашение |
calendar_event_recorded |
workspace_id, calendar_event_id |
Запись начата из события календаря |
calendar_meeting_joined |
provider (meet, zoom, teams, webex, other), workspace_id, calendar_event_id |
Открыта ссылка на встречу (телефон). Из ссылки определяется только провайдер |
notification_action |
action (read, unread, dismiss, mark_all_read, clear_all), workspace_id |
Использован центр уведомлений |
agent_created |
workspace_id, agent_id, adapter, model |
Агент создан из реестра |
tab_opened |
kind (chat, terminal, browser, rig, codeServer, file, …) |
В пространстве открыта новая вкладка редактора |
skill_action |
action (install, update, uninstall, source_added, source_removed), skill_id, blocked |
Изменены навыки рабочего пространства |
orchestration_decided |
decision (approved, cancelled), workspace_id, orchestration_id |
Дан ответ на предложение оркестрации |
plan_decided |
decision (approved, rejected), plan_id, workspace_id, partial, node_count |
План одобрен или отклонён (телефон) |
goal_started |
kind (goal, loop), workspace_id, space_id, conversation_id, agent_id, budget_cents, accepted |
Запущена контролируемая цель или цикл (телефон) |
conversation_created |
workspace_id, space_id, conversation_id, source (new, fork) |
Беседа создана или ответвлена |
conversation_rewound |
conversation_id |
Беседа продолжена с более раннего сообщения |
space_archived |
workspace_id, space_id |
Пространство архивировано |
События сервера
Заголовок раздела «События сервера»Записываются cc_server для фактов, которые ни один отдельный клиент не видит ровно один раз. Запуск агента учитывается один раз, сколько бы клиентов за ним ни наблюдало.
| Событие | Свойства | Когда записывается |
|---|---|---|
server_started |
workspace_count, startup_ms |
Сервер завершил загрузку |
workspace_created |
workspace_id |
Создано рабочее пространство |
space_created |
workspace_id, space_id |
Создано пространство |
repo_added |
workspace_id, repo_id |
Подключён репозиторий |
ticket_created |
workspace_id, ticket_id |
Человек или агент создал тикет |
agent_run_completed |
agent_id, workspace_id, conversation_id, run_id, status, error_family, role, adapter, model, effort, task_family, subagent, pipeline, resumed_native_session, duration_ms, time_to_first_token_ms, input_tokens, output_tokens, thought_tokens, cache_read_tokens, cache_write_tokens, output_rejections, cost_usd |
Запуск агента завершён |
agent_awaiting_input |
kind (approval, question, credential), workspace_id, agent_id, conversation_id |
Агент остановился в ожидании человека |
agent_action_blocked |
workspace_id, agent_id, space_id, source |
Политика действий отклонила действие агента |
pipeline_run_finished |
outcome (completed, failed, cancelled), workspace_id, pipeline_run_id, template_id, trigger, duration_ms, active_ms, attempt_count, template_version, cost_cents, tokens, dry_run, sub_pipeline |
Запуск конвейера завершён. trigger — это manual, тип события, которое его запустило, или только вид именованного триггера (webhook) |
pull_request_published |
workspace_id, pr_id |
Pull request опубликован из пространства |
pull_request_merged |
workspace_id, pr_id, agent_id |
Слит pull request, открытый агентом |
meeting_recorded |
workspace_id, meeting_id, transcript_chars |
Запись встречи сохранена |
space_deleted |
workspace_id, space_id |
Пространство удалено |
ticket_status_changed |
workspace_id, ticket_id, from_status, to_status |
Тикет изменил статус |
ticket_assigned |
workspace_id, ticket_id, assignee_type, agent_id, team_id |
Тикет назначен |
ticket_reassigned |
workspace_id, ticket_id, from_agent_id, to_agent_id |
Тикет передан другому агенту |
ticket_work_finished |
ticket_id, outcome (completed, failed, cancelled) |
Делегированная работа по тикету завершена |
workspace_member_changed |
workspace_id, member_user_id, change (added, removed, role_changed), role |
Изменился состав рабочего пространства |
rig_closed |
workspace_id, rig_id, reason, reaped, agent_id |
Rig закрыт или освобождён сборщиком |
skill_updated |
workspace_id, skill_id, origin, scan_verdict |
Навык рабочего пространства установлен, обновлён или изменён на диске |
calendar_auth_expired |
workspace_id |
Подключение к календарю требует повторного входа |
calendar_meeting_starting_soon |
workspace_id, calendar_event_id, has_meeting_link, lead_s |
Событие календаря вот-вот начнётся |
budget_threshold_crossed |
scope_type, scope_id, spent_cents, budget_cents, hard_stop |
Расходы превысили порог бюджета |
pull_request_review_requested |
workspace_id, repo_id |
Запрошено ревью отслеживаемого PR |
pull_request_review_decision_changed |
workspace_id, repo_id, decision, reviewers_remaining |
Изменилось решение по ревью отслеживаемого PR |
external_pull_request_merged |
workspace_id, repo_id |
В связанном репозитории слит PR, открытый не агентом |
Доставка
Заголовок раздела «Доставка»События отправляются по одному на <host>/api/send из очереди в памяти размером до 200 событий. При сетевой ошибке, тайм-ауте, 429 или 5xx событие сохраняется и отправляется повторно с экспоненциальной задержкой от 1 секунды до 5 минут. Любой другой 4xx отбрасывает его. На диск ничего не записывается, поэтому события, оставшиеся в очереди при закрытии приложения, теряются. Очередь сбрасывается, когда приложение уходит в фон и когда сервер завершает работу.
Направить сборку на другой экземпляр
Заголовок раздела «Направить сборку на другой экземпляр»Получатель фиксируется во время сборки:
--dart-define=CC_ANALYTICS_HOST=https://analytics.example.com/--dart-define=CC_ANALYTICS_WEBSITE_ID=<website uuid>Адаптер поставщика находится в packages/cc_analytics. Чтобы поддержать другой сервис аналитики, добавьте туда адаптер. План отслеживания и правила конфиденциальности остаются прежними.