Cloud Logging 및 Observability Analytics을 사용하여 AI 개발자 도구(예: Anthropic Claude Opus 5.5 및 Anthropic Claude Sonnet 5.5)에서 서드 파티 모델의 모델, 일, 사용자별 토큰 소비량을 계산할 수 있습니다.
빠른 시작
프로젝트의 _Default 로그 버킷이 이미 Observability Analytics을 위해 업그레이드된 경우 로깅 > Observability Analytics에서 다음 쿼리를 실행하여([PROJECT_ID]를 Google Cloud 프로젝트 ID로 대체) 서드 파티 Anthropic 모델 전반에서 30일간의 토큰 사용량을 확인합니다.
SELECT
JSON_VALUE(labels.model) AS model,
COUNT(*) AS requests,
SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.promptTokenCount) AS INT64)) AS input_tokens,
SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.candidatesTokenCount) AS INT64)) AS output_tokens,
IFNULL(SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.cachedContentTokenCount) AS INT64)), 0) AS cached_tokens,
IFNULL(SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.thoughtsTokenCount) AS INT64)), 0) AS thoughts_tokens,
SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.totalTokenCount) AS INT64)) AS total_tokens
FROM
`[PROJECT_ID].global._Default._Default`
WHERE
log_id = "businessaicode.googleapis.com/inference_response"
AND JSON_VALUE(labels.model_provider) = "Anthropic"
AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
model
ORDER BY
total_tokens DESC
시작하기 전에
튜토리얼 단계를 실행하기 전에 프로젝트가 다음 요구사항을 충족하는지 확인하세요.
- 메타데이터 로깅이 사용 설정되어 있습니다.
inference_response레코드에jsonPayload.metadata토큰 블록이 포함되도록 AI 개발자 도구 관리자 제어에 메타데이터 로깅이 사용 설정되어 있어야 합니다. - 로그 뷰어 역할 (
roles/logging.viewer) 이상을 보유하고 있습니다. 표준roles/logging.viewer역할은 이 가이드 전체에서 사용되는_Default._Default로그 뷰에 대한 SQL 액세스 권한을 부여합니다._Default._AllLogs뷰를 쿼리하려면roles/logging.privateLogViewer또는roles/logging.viewAccessor가 필요합니다. _Default로그 버킷이 Observability Analytics를 위해 업그레이드되었습니다.- Google Cloud 콘솔에서 로깅 > 로그 스토리지로 이동하여
_Default버킷을 찾고 Observability Analytics 열을 확인합니다. - 사용 설정되어 있지 않으면 더보기 > Observability Analytics를 사용하도록 업그레이드를 클릭합니다. 업그레이드는
_Default를 인플레이스로 수정하며 실행취소할 수 없습니다. - 초기 전파 허용: 버킷을 업그레이드한 후 Cloud Logging에서 새 로그 항목의 라우팅 캐시를 새로고침하는 데 30~60분이 걸리고, 이전 로그를 백필하는 데 몇 시간이 걸립니다 (백필은 업그레이드가 완료된 후 1시간 후에 시작됨).
- Google Cloud 콘솔에서 로깅 > 로그 스토리지로 이동하여
로그 레코드의 구조
모든 추론 호출은 businessaicode.googleapis.com%2Finference_response 로그에 단일 InferenceResponseLog 항목을 내보냅니다. 모델 ID는 labels에 기록되고 토큰 수는 jsonPayload.metadata에 기록됩니다.
{
"logName": "projects/[PROJECT_ID]/logs/businessaicode.googleapis.com%2Finference_response",
"timestamp": "2026-10-07T17:23:03.495323480Z",
"labels": {
"model": "claude-sonnet-5-5",
"model_provider": "Anthropic",
"client_name": "antigravity_cli",
"user_id": "user:user@example.com",
"trajectory_id": "25cd0b58-58ea-4beb-b2d7-42e0d3fdd96d",
"request_id": "25cd0b58-58ea-4beb-b2d7-42e0d3fdd96d-19"
},
"jsonPayload": {
"@type": "type.googleapis.com/google.cloud.businessaicode.logging.v1.InferenceResponseLog",
"metadata": {
"promptTokenCount": "70825",
"cachedContentTokenCount": "69079",
"candidatesTokenCount": "14215",
"totalTokenCount": "85040"
}
}
}
필드 참조 및 계산 규칙
| LogEntry 필드 (로그 탐색기 및 로그 기반 측정항목) | SQL 표현식 (Observability Analytics) | 설명 |
|---|---|---|
labels.model |
JSON_VALUE(labels.model) |
모델 식별자 (예: Anthropic Claude Sonnet 5.5의 경우 claude-sonnet-5-5, Anthropic Claude Opus 5.5의 경우 claude-opus-5-5) |
labels.model_provider |
JSON_VALUE(labels.model_provider) |
공급업체 이름 (예: Anthropic 또는 Google) |
labels.user_id |
JSON_VALUE(labels.user_id) |
인증된 주 구성원 (예: user:user@example.com) |
labels.trajectory_id |
JSON_VALUE(labels.trajectory_id) |
대화 또는 상담사 궤적 ID입니다. 하나의 사용자 턴은 일반적으로 하나의 trajectory_id 아래에 있는 여러 request_id 호출에 걸쳐 있습니다. |
jsonPayload.metadata.promptTokenCount |
SAFE_CAST(JSON_VALUE(json_payload.metadata.promptTokenCount) AS INT64) |
통화의 총 입력 토큰 (캐시된 토큰 포함)입니다. |
jsonPayload.metadata.cachedContentTokenCount |
SAFE_CAST(JSON_VALUE(json_payload.metadata.cachedContentTokenCount) AS INT64) |
프롬프트 캐시에서 제공된 promptTokenCount의 하위 집합입니다. 0인 경우 생략됩니다. promptTokenCount 또는 totalTokenCount에 추가하지 마세요. |
jsonPayload.metadata.candidatesTokenCount |
SAFE_CAST(JSON_VALUE(json_payload.metadata.candidatesTokenCount) AS INT64) |
모델에서 생성된 출력 토큰입니다. |
jsonPayload.metadata.thoughtsTokenCount |
SAFE_CAST(JSON_VALUE(json_payload.metadata.thoughtsTokenCount) AS INT64) |
추론 토큰(해당하는 경우) Anthropic 모델의 경우 생략됩니다. |
jsonPayload.metadata.totalTokenCount |
SAFE_CAST(JSON_VALUE(json_payload.metadata.totalTokenCount) AS INT64) |
통화의 공신력 있는 총계입니다. promptTokenCount + candidatesTokenCount(+ thoughtsTokenCount(있는 경우))와 같습니다. |
1단계: 로그 탐색기에서 수신 로그 확인하기
SQL 쿼리를 실행하기 전에 토큰 메타데이터가 포함된 inference_response 레코드가 프로젝트에 도착하는지 확인합니다.
- Google Cloud 콘솔에서 로깅 > 로그 탐색기를 엽니다.
다음 쿼리를 쿼리 편집기에 붙여넣고
[PROJECT_ID]를 프로젝트 ID로 바꿉니다.logName="projects/[PROJECT_ID]/logs/businessaicode.googleapis.com%2Finference_response" labels.model_provider="Anthropic"쿼리 실행을 클릭합니다.
로그 필드 창에서 model을 클릭하여 Anthropic 모델 전반의 요청 분포를 확인합니다. 이 뷰는 토큰이 아닌 요청을 집계합니다.
2단계: Observability Analytics에서 모델별 토큰 합계
- Google Cloud 콘솔에서 로깅 > Observability Analytics을 엽니다.
- 기간 선택기를 지난 30일로 설정합니다 (기간 선택기는 SQL
WHERE절 외에도 쿼리 결과를 제한합니다). 다음 쿼리를 붙여넣고 실행합니다. 이때
[PROJECT_ID]는 프로젝트 ID로 바꿉니다.SELECT JSON_VALUE(labels.model) AS model, COUNT(*) AS requests, SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.promptTokenCount) AS INT64)) AS input_tokens, SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.candidatesTokenCount) AS INT64)) AS output_tokens, IFNULL(SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.cachedContentTokenCount) AS INT64)), 0) AS cached_tokens, IFNULL(SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.thoughtsTokenCount) AS INT64)), 0) AS thoughts_tokens, SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.totalTokenCount) AS INT64)) AS total_tokens FROM `[PROJECT_ID].global._Default._Default` WHERE log_id = "businessaicode.googleapis.com/inference_response" AND JSON_VALUE(labels.model_provider) = "Anthropic" AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY) GROUP BY model ORDER BY total_tokens DESC
3단계: 일반적인 SQL 레시피
로깅 > Observability Analytics에서 다음 SQL 쿼리를 사용하여 일일 토큰 추세와 사용자별 토큰 기여도를 분석합니다.
모델별 일일 토큰 추세
SELECT
TIMESTAMP_TRUNC(timestamp, DAY) AS day,
JSON_VALUE(labels.model) AS model,
COUNT(*) AS requests,
SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.totalTokenCount) AS INT64)) AS total_tokens
FROM
`[PROJECT_ID].global._Default._Default`
WHERE
log_id = "businessaicode.googleapis.com/inference_response"
AND JSON_VALUE(labels.model_provider) = "Anthropic"
AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
day, model
ORDER BY
day DESC, total_tokens DESC
사용자별, 모델별 기여 분석
SELECT
JSON_VALUE(labels.user_id) AS user_id,
JSON_VALUE(labels.model) AS model,
COUNT(*) AS requests,
SUM(SAFE_CAST(JSON_VALUE(json_payload.metadata.totalTokenCount) AS INT64)) AS total_tokens
FROM
`[PROJECT_ID].global._Default._Default`
WHERE
log_id = "businessaicode.googleapis.com/inference_response"
AND JSON_VALUE(labels.model_provider) = "Anthropic"
AND JSON_VALUE(labels.user_id) IS NOT NULL
AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY
user_id, model
ORDER BY
total_tokens DESC
4단계: Cloud Monitoring 대시보드에 고정
대시보드에는 두 가지 옵션이 있습니다. 기록 또는 임시 SQL 분석이 필요한지 아니면 경량의 연속 측정항목이 필요한지에 따라 선택할 수 있습니다.
| 접근 방법 | 용도 | 30일이 지난 기록을 보관하는가? | user_id 그룹화 지원 여부 |
|---|---|---|---|
| 옵션 A: Observability Analytics에서 SQL 차트 저장 | 측정항목 설정이 필요 없는 모델별, 일별, 사용자별 표 및 차트 | 로그 버킷 보관 기간 (기본 30일)에 의해 제한됨 | 예 (카디널리티 한도 없음) |
| 옵션 B: 로그 기반 분포 측정항목 | 지속적 모니터링 시계열 및 카디널리티가 낮은 라벨에 대한 알림 | 예 (Monitoring에 저장됨) | 아니요 (카디널리티가 높으면 측정항목 할당량이 소진됨) |
옵션 A: Observability Analytics에서 직접 저장
- 2단계의 쿼리 또는 모니터링 가능성 분석의 모델별 일일 토큰 추세 쿼리를 실행합니다.
- 시각적 시계열 또는 막대 그래프를 원하는 경우 결과 창을 표에서 차트로 전환합니다.
- 결과 창 툴바에서 대시보드에 저장을 클릭한 후 기존 Monitoring 대시보드를 선택하거나 새 대시보드를 만듭니다.
옵션 B: 로그 기반 분포 측정항목 만들기
- Google Cloud 콘솔에서 로깅 > 로그 기반 측정항목으로 이동한 후 측정항목 만들기를 클릭합니다.
- 측정항목 유형으로 분포를 선택합니다.
- 1단계의 쿼리를 필터 필드에 붙여넣고 필드 이름을
jsonPayload.metadata.totalTokenCount로 설정합니다. - 다음 두 라벨을 추가합니다.
model이labels.model에 매핑됨model_provider이labels.model_provider에 매핑됨