fix(cloudzero): update CBF field mappings per LIT-1907 (#20906)

* fix(cloudzero): update CBF field mappings per LIT-1907

Phase 1 field updates for CloudZero integration:

ADD/UPDATE:
- resource/account: Send concat(api_key_alias, '|', api_key_prefix)
- resource/service: Send model_group instead of service_type
- resource/usage_family: Send provider instead of hardcoded 'llm-usage'
- action/operation: NEW - Send team_id
- resource/id: Send model name instead of CZRN
- resource/tag:organization_alias: Add if exists
- resource/tag:project_alias: Add if exists
- resource/tag:user_alias: Add if exists

REMOVE:
- resource/tag:total_tokens: Removed
- resource/tag:team_id: Removed (team_id now in action/operation)

Fixes LIT-1907

* Update litellm/integrations/cloudzero/transform.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix: define api_key_alias variable, update CBFRecord docstring

- Fix F821 lint error: api_key_alias was used but not defined
- Update CBFRecord docstring to reflect LIT-1907 field mappings
- Remove unused Optional import

---------

Co-authored-by: Ishaan Jaff <ishaanjaffer0324@gmail.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This commit is contained in:
shin-bot-litellm 2026-02-10 17:33:16 -08:00 • committed by GitHub
parent c68383068a
commit 26d561081b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 15 deletions

View file

@ -103,10 +103,15 @@ class CBFTransformer:
# Use team_alias if available, otherwise team_id, otherwise fallback to 'unknown'
entity_id = str(team_alias) if team_alias else (str(team_id) if team_id else 'unknown')
# Get alias fields if they exist
api_key_alias = row.get('api_key_alias')
organization_alias = row.get('organization_alias')
project_alias = row.get('project_alias')
user_alias = row.get('user_alias')
dimensions = {
'entity_type': CZEntityType.TEAM.value,
'entity_id': entity_id,
'team_id': str(team_id) if team_id else 'unknown',
'team_alias': str(team_alias) if team_alias else 'unknown',
'model': model,
'model_group': str(row.get('model_group', '')),
@ -119,28 +124,37 @@ class CBFTransformer:
'failed_requests': str(row.get('failed_requests', 0)),
'cache_creation_tokens': str(row.get('cache_creation_input_tokens', 0)),
'cache_read_tokens': str(row.get('cache_read_input_tokens', 0)),
'organization_alias': str(organization_alias) if organization_alias else '',
'project_alias': str(project_alias) if project_alias else '',
'user_alias': str(user_alias) if user_alias else '',
}
# Extract CZRN components to populate corresponding CBF columns
czrn_components = self.czrn_generator.extract_components(resource_id)
service_type, provider, region, owner_account_id, resource_type, cloud_local_id = czrn_components
# Build resource/account as concat of api_key_alias and api_key_prefix
resource_account = f"{api_key_alias}|{api_key_hash}" if api_key_alias else api_key_hash
# CloudZero CBF format with proper column names
cbf_record = {
# Required CBF fields
'time/usage_start': usage_date.isoformat() if usage_date else None, # Required: ISO-formatted UTC datetime
'cost/cost': float(row.get('spend', 0.0)), # Required: billed cost
'resource/id': resource_id, # Required when resource tags are present
'resource/id': model, # Send model name
# Usage metrics for token consumption
'usage/amount': total_tokens, # Numeric value of tokens consumed
'usage/units': 'tokens', # Description of token units
# CBF fields that correspond to CZRN components
'resource/service': service_type, # Maps to CZRN service-type (litellm)
'resource/account': owner_account_id, # Maps to CZRN owner-account-id (entity_id)
# CBF fields - updated per LIT-1907
'resource/service': str(row.get('model_group', '')), # Send model_group
'resource/account': resource_account, # Send api_key_alias|api_key_prefix
'resource/region': region, # Maps to CZRN region (cross-region)
'resource/usage_family': resource_type, # Maps to CZRN resource-type (llm-usage)
'resource/usage_family': str(row.get('custom_llm_provider', '')), # Send provider
# Action field
'action/operation': str(team_id) if team_id else '', # Send team_id
# Line item details
'lineitem/type': 'Usage', # Standard usage line item
@ -155,13 +169,11 @@ class CBFTransformer:
if value and value != 'N/A' and value != 'unknown': # Only add meaningful tags
cbf_record[f'resource/tag:{key}'] = str(value)
# Add token breakdown as resource tags for analysis
# Add token breakdown as resource tags for analysis (excluding total_tokens per LIT-1907)
if prompt_tokens > 0:
cbf_record['resource/tag:prompt_tokens'] = str(prompt_tokens)
if completion_tokens > 0:
cbf_record['resource/tag:completion_tokens'] = str(completion_tokens)
if total_tokens > 0:
cbf_record['resource/tag:total_tokens'] = str(total_tokens)
return CBFRecord(cbf_record)

View file

@ -1,4 +1,4 @@
from typing import Any, Dict, Optional
from typing import Any, Dict
class CBFRecord(Dict[str, Any]):
@ -9,19 +9,23 @@ class CBFRecord(Dict[str, Any]):
(e.g., 'time/usage_start', 'cost/cost'), we use a Dict base class rather
than TypedDict to accommodate the special characters in field names.
Expected CBF fields:
Expected CBF fields (per LIT-1907):
- time/usage_start: ISO-formatted UTC datetime (Optional[str])
- cost/cost: Billed cost (float)
- resource/id: CloudZero Resource Name (CZRN) (str)
- resource/id: Model name (str)
- usage/amount: Numeric value of tokens consumed (int)
- usage/units: Description of units, e.g., 'tokens' (str)
- resource/service: Maps to CZRN service-type, e.g., 'litellm' (str)
- resource/account: Maps to CZRN owner-account-id (entity_id) (str)
- resource/service: Model group (str)
- resource/account: api_key_alias|api_key_prefix (str)
- resource/region: Maps to CZRN region, e.g., 'cross-region' (str)
- resource/usage_family: Maps to CZRN resource-type, e.g., 'llm-usage' (str)
- resource/usage_family: Provider (str)
- action/operation: Team ID (str)
- lineitem/type: Standard usage line item, e.g., 'Usage' (str)
- resource/tag:provider: CZRN provider component (str)
- resource/tag:model: CZRN cloud-local-id component (model) (str)
- resource/tag:organization_alias: Organization alias if available (Optional[str])
- resource/tag:project_alias: Project alias if available (Optional[str])
- resource/tag:user_alias: User alias if available (Optional[str])
- resource/tag:{key}: Various resource tags for dimensions and metrics (Optional[str])
"""
pass