tosage
🇯🇵 日本語版
A Go application that tracks token usage from Claude Code, Cursor, AWS Bedrock, and Google Vertex AI, and sends metrics to Prometheus. It can run in CLI mode (outputs today's token count) or daemon mode (system tray application with periodic metrics sending).
Features
- Multi-Provider Token Tracking: Monitors token usage from Claude Code, Cursor, AWS Bedrock, and Google Vertex AI
- Prometheus Integration: Sends metrics via remote write API
- Dual Mode Operation: CLI mode for quick checks, daemon mode for continuous monitoring
- macOS System Tray: Native system tray support for daemon mode (Claude Code/Cursor only)
- Automatic Data Discovery: Finds Claude Code data across multiple locations
- CSV Export: Export historical metrics data to CSV format for analysis and reporting
- API Integrations:
- Cursor API for premium request usage and pricing
- AWS CloudWatch for Bedrock metrics
- Google Cloud Monitoring for Vertex AI metrics
flowchart TD
subgraph "Data Sources"
CC[Claude Code<br/>Local Directories]
CA[Cursor API]
AWSCW[AWS CloudWatch<br/>Bedrock Metrics]
GCPM[Google Cloud<br/>Vertex AI Metrics]
end
subgraph "Infrastructure Layer"
JSONL[JSONL Repository<br/>Read Claude Code data files]
CAPI[Cursor API Repository<br/>Fetch usage data]
CDB[Cursor DB Repository<br/>SQLite storage]
BR[Bedrock Repository<br/>CloudWatch API]
VAR[Vertex AI Repository<br/>Monitoring API]
end
subgraph "Use Case Layer"
CCS[Claude Code Service<br/>Process token usage]
CS[Cursor Service<br/>Process API data & track tokens]
BS[Bedrock Service<br/>Process AWS metrics]
VAS[Vertex AI Service<br/>Process GCP metrics]
MS[Metrics Service<br/>Collect & aggregate metrics]
end
subgraph "External Systems"
PROM[Prometheus<br/>Remote Write API]
end
CC --> JSONL
CA --> CAPI
AWSCW --> BR
GCPM --> VAR
JSONL --> CCS
CAPI --> CDB
CDB --> CS
BR --> BS
VAR --> VAS
CCS --> MS
CS --> MS
BS --> MS
VAS --> MS
MS --> PROM
Grafana Dashboard
Monitor your token usage with our pre-configured Grafana dashboard:

Import the Grafana dashboard configuration to visualize:
- Token usage per person per hour
- Team-wide token usage trends
- Daily token totals
- Tool breakdown (Claude Code, Cursor, Bedrock, Vertex AI)
- Multi-cloud AI service cost tracking
Installation
Quick Installation (Recommended)
The easiest way to install tosage is using our automated installation script:
# Download and run the installer
curl -fsSL https://raw.githubusercontent.com/ca-srg/tosage/main/scripts/install.sh | bash
Or download the script first to review it:
# Download the script
curl -fsSL https://raw.githubusercontent.com/ca-srg/tosage/main/scripts/install.sh -o install-tosage.sh
# Review the script
less install-tosage.sh
# Run the installer
bash install-tosage.sh
The installation script will:
- Download the latest tosage DMG for your architecture (arm64/x86_64)
- Install the application to
/Applications/tosage.app
- Guide you through configuration setup interactively
- Create the configuration file at
~/.config/tosage/config.json
Prerequisites
- macOS (the installer is macOS-only)
curl and jq (usually pre-installed)
- Internet connection to download from GitHub
- Administrator password (for installing to /Applications)
Configuration Values Needed
During installation, you'll be prompted for:
- Prometheus Remote Write URL (required): Your Prometheus endpoint (e.g.,
https://prometheus.example.com/api/prom/push)
- Prometheus Username (required): Authentication username
- Prometheus Password (required): Authentication password
- Host Label (optional): Custom label for metrics
- Metrics Interval (optional): How often to send metrics in seconds (default: 600)
- Promtail Configuration (optional): For log forwarding
Pre-built Binaries
Download the latest release from GitHub Releases.
From Source
git clone https://github.com/ca-srg/tosage.git
cd tosage
make build
Configuration
# 1. Run application to generate config.json
# 2. Modify config.json
$ cat ~/.config/tosage/config.json
{
"prometheus": {
"remote_write_url": "https://<prometheus_url>/api/prom/push",
"username": "",
"password": ""
},
"logging": {
"promtail": {
"url": "https://<logs_url>",
"username": "",
"password": ""
}
},
"bedrock": {
"enabled": false,
"regions": ["us-east-1", "us-west-2"],
"aws_profile": "",
"assume_role_arn": "",
"collection_interval_sec": 900
},
"vertex_ai": {
"enabled": false,
"project_id": "",
"locations": ["us-central1", "us-east1", "asia-northeast1"],
"service_account_key_path": "",
"collection_interval_sec": 900
}
}
# 3. Run again
AWS Bedrock Configuration
To enable Bedrock metrics:
- Set
bedrock.enabled to true
- Configure AWS credentials using one of:
aws_profile: AWS profile name from ~/.aws/credentials
assume_role_arn: IAM role ARN to assume
- Default AWS credential chain (environment variables, IAM role, etc.)
- Specify regions to monitor in
bedrock.regions
Google Vertex AI Configuration
To enable Vertex AI metrics:
- Set
vertex_ai.enabled to true
- Set
vertex_ai.project_id to your GCP project ID
- Configure GCP credentials using one of these methods (in priority order):
- Service Account Key JSON (highest priority):
- Config:
service_account_key: JSON content as string
- Environment:
TOSAGE_VERTEX_AI_SERVICE_ACCOUNT_KEY (base64 encoded JSON)
- Service Account Key File:
- Config:
service_account_key_path: Path to JSON key file
- Environment:
TOSAGE_VERTEX_AI_SERVICE_ACCOUNT_KEY_PATH
- Application Default Credentials (lowest priority):
- Environment:
GOOGLE_APPLICATION_CREDENTIALS
- gcloud auth application-default login
- GCP metadata service (when running on GCP)
- Specify locations to monitor in
vertex_ai.locations
Authentication Priority System
The Vertex AI integration uses a three-tier authentication priority system:
- Direct Service Account Key - If
service_account_key is provided in config or via TOSAGE_VERTEX_AI_SERVICE_ACCOUNT_KEY environment variable (must be base64 encoded when using environment variable)
- Service Account Key File - If
service_account_key_path is provided
- Application Default Credentials - Uses Google's default credential discovery
This allows flexible deployment scenarios:
- For local development: Use
gcloud auth application-default login
- For CI/CD: Set service account key as environment variable
- For production: Use service account key file or GCP metadata service
Usage
CLI Mode
Outputs today's token count:
# Claude Code and Cursor tokens (default)
tosage
# AWS Bedrock metrics only
tosage --bedrock
# Google Vertex AI metrics only
tosage --vertex-ai
Note: When using --bedrock or --vertex-ai flags, Claude Code and Cursor metrics are skipped.
CSV Export Mode
Export metrics data to CSV file for analysis:
# Export all metrics for the last 30 days
tosage --export-csv
# Export to specific file
tosage --export-csv --output metrics_report.csv
# Export specific date range
tosage --export-csv --start-time "2025-01-01T00:00:00Z" --end-time "2025-01-31T23:59:59Z"
# Export only specific metric types
tosage --export-csv --metrics-types "claude_code,cursor"
# Combine options
tosage --export-csv \
--output quarterly_report.csv \
--start-time "2025-01-01T00:00:00Z" \
--end-time "2025-03-31T23:59:59Z" \
--metrics-types "claude_code,cursor,bedrock,vertex_ai"
CSV Export Options
--export-csv: Enable CSV export mode
--output: Output file path (default: metrics_YYYYMMDD_HHMMSS.csv)
--start-time: Start time in ISO 8601 format (default: 30 days ago)
--end-time: End time in ISO 8601 format (default: now)
--metrics-types: Comma-separated list of metric types to export
- Available types:
claude_code, cursor, bedrock, vertex_ai
- Default: all available types
The exported CSV includes the following columns:
timestamp: ISO 8601 formatted timestamp
source: Metric source (claude_code, cursor, bedrock, vertex_ai)
project: Project or workspace identifier
value: Numeric value (tokens, requests)
unit: Unit of measurement (tokens, requests)
- Additional metadata columns specific to each source
Example CSV output:
timestamp,source,project,value,unit,input_tokens,output_tokens,cost,currency
2025-01-15T00:00:00Z,claude_code,all_projects,150000.00,tokens,120000,30000,1.2500,USD
2025-01-15T00:00:00Z,cursor,all_workspaces,25.00,requests,,,2.5000,USD
2025-01-15T00:00:00Z,bedrock,all_models,50000.00,tokens,40000,10000,0.7500,USD
Security Features
The CSV export includes several security measures:
- Path traversal prevention
- System directory write protection
- CSV injection prevention
- Secure file permissions (600)
- UTF-8 BOM for proper encoding
Daemon Mode
Runs as a system tray application with periodic metrics sending (Claude Code/Cursor only):
tosage -d
Note: Daemon mode is not supported when using --bedrock or --vertex-ai flags.
Container Usage
tosage is available as a multi-architecture container image on GitHub Container Registry (ghcr.io). The container supports both linux/amd64 and linux/arm64 architectures.
Pull the Image
# Latest version
docker pull ghcr.io/ca-srg/tosage:latest
# Specific version
docker pull ghcr.io/ca-srg/tosage:v1.0.0
# For a specific architecture
docker pull --platform linux/arm64 ghcr.io/ca-srg/tosage:latest
Running the Container
The container runs in CLI mode by default:
# Run with default configuration
docker run --rm ghcr.io/ca-srg/tosage:latest
# Run with custom configuration file
docker run --rm \
-v ~/.config/tosage/config.json:/home/nonroot/.config/tosage/config.json:ro \
ghcr.io/ca-srg/tosage:latest
# Run with environment variables
docker run --rm \
-e TOSAGE_PROMETHEUS_URL="https://prometheus.example.com/api/prom/push" \
-e TOSAGE_PROMETHEUS_USERNAME="user" \
-e TOSAGE_PROMETHEUS_PASSWORD="pass" \
ghcr.io/ca-srg/tosage:latest
# Check Bedrock metrics
docker run --rm \
-e AWS_REGION="us-east-1" \
ghcr.io/ca-srg/tosage:latest --bedrock
# Check Vertex AI metrics with Application Default Credentials
docker run --rm \
-e GOOGLE_CLOUD_PROJECT="my-project" \
-v ~/.config/gcloud:/home/nonroot/.config/gcloud:ro \
ghcr.io/ca-srg/tosage:latest --vertex-ai
# Check Vertex AI metrics with service account key file
docker run --rm \
-e TOSAGE_VERTEX_AI_ENABLED="true" \
-e TOSAGE_VERTEX_AI_PROJECT_ID="my-project" \
-v /path/to/service-account-key.json:/key.json:ro \
-e TOSAGE_VERTEX_AI_SERVICE_ACCOUNT_KEY_PATH="/key.json" \
ghcr.io/ca-srg/tosage:latest --vertex-ai
# Check Vertex AI metrics with service account key as environment variable (base64 encoded)
# First encode your service account key: base64 -i service-account-key.json
docker run --rm \
-e TOSAGE_VERTEX_AI_ENABLED="true" \
-e TOSAGE_VERTEX_AI_PROJECT_ID="my-project" \
-e TOSAGE_VERTEX_AI_SERVICE_ACCOUNT_KEY='base64_encoded_json_here' \
ghcr.io/ca-srg/tosage:latest --vertex-ai
Docker Compose Example
version: '3.8'
services:
tosage:
image: ghcr.io/ca-srg/tosage:latest
restart: unless-stopped
volumes:
- ~/.config/tosage/config.json:/home/nonroot/.config/tosage/config.json:ro
environment:
- TOSAGE_PROMETHEUS_URL=${PROMETHEUS_URL}
- TOSAGE_PROMETHEUS_USERNAME=${PROMETHEUS_USERNAME}
- TOSAGE_PROMETHEUS_PASSWORD=${PROMETHEUS_PASSWORD}
command: ["--mode", "cli"]
Kubernetes Example
apiVersion: batch/v1
kind: CronJob
metadata:
name: tosage-metrics
spec:
schedule: "0 */6 * * *" # Every 6 hours
jobTemplate:
spec:
template:
spec:
containers:
- name: tosage
image: ghcr.io/ca-srg/tosage:latest
env:
- name: TOSAGE_PROMETHEUS_URL
valueFrom:
secretKeyRef:
name: tosage-config
key: prometheus-url
- name: TOSAGE_PROMETHEUS_USERNAME
valueFrom:
secretKeyRef:
name: tosage-config
key: prometheus-username
- name: TOSAGE_PROMETHEUS_PASSWORD
valueFrom:
secretKeyRef:
name: tosage-config
key: prometheus-password
restartPolicy: OnFailure
Container Image Details
- Base Image:
gcr.io/distroless/static:nonroot - Minimal distroless image for security
- User: Runs as non-root user (65532:65532)
- Architectures:
linux/amd64, linux/arm64
- Entry Point:
/tosage
- Default Command:
["--mode", "cli"]
latest - Latest stable release
vX.Y.Z - Specific version (e.g., v1.0.0)
vX.Y - Minor version (e.g., v1.0)
vX - Major version (e.g., v1)
main-<short-sha> - Development builds from main branch
Building
Requirements
Build Requirements
- Go 1.21 or higher
- macOS (for daemon mode)
- Make
Runtime Requirements
- Prometheus Remote Write API endpoint for metrics collection
- Grafana Loki (optional) for log aggregation via Promtail
Build Commands
# Build for current platform
make build
# Build macOS ARM64 binary
make build-darwin
# Build app bundle for macOS
make app-bundle-arm64
# Build DMG installer
make dmg-arm64
# Run all checks (fmt, vet, lint, test)
make check
macOS App Bundle and DMG Creation
App Bundle Targets
app-bundle-arm64
Purpose: Creates a macOS app bundle (.app)
- Binary Build: Executes
build-darwin to create Go binary
- Dependency Check: Runs
dmg-check to verify required tools
- App Bundle Creation: Executes
create-app-bundle.sh to create:
tosage.app/Contents/MacOS/tosage - Executable file
tosage.app/Contents/Info.plist - App metadata
tosage.app/Contents/Resources/app.icns - App icon
tosage.app/Contents/PkgInfo - App type information
DMG Targets
dmg-arm64
Purpose: Creates unsigned DMG installers
- Creates app bundle (executes
app-bundle-*)
- Runs
create-dmg.sh to create DMG:
- Includes app bundle in DMG
- Adds symlink to
/Applications
- Sets background image and window layout
- Output:
tosage-{version}-darwin-{arch}.dmg
dmg-signed-arm64
Purpose: Creates signed DMGs
- Requires
CODESIGN_IDENTITY environment variable
- Adds code signature to app bundle and DMG
dmg-notarized-arm64
Purpose: Creates signed and notarized DMGs
- Adds Apple notarization in addition to signing
- Allows installation without Gatekeeper warnings
Build Process Flow
Go Source Code
↓ (go build)
Executable Binary
↓ (create-app-bundle.sh)
.app Bundle
↓ (create-dmg.sh)
.dmg Installer
↓ (codesign + notarization)
Distributable DMG
Usage Examples
Create unsigned DMG:
make dmg-arm64
Create signed DMG:
export CODESIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)"
make dmg-signed-arm64
Create signed and notarized DMG:
export CODESIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)"
export API_KEY_ID="your-key-id"
export API_KEY_PATH="/path/to/AuthKey_XXXXX.p8"
export API_ISSUER="your-issuer-id"
make dmg-notarized-arm64
Create for all architectures:
make dmg-notarized-all
Architecture
The project follows Clean Architecture with clear separation of concerns:
Domain Layer
- Entities: Core business entities (Claude Code entries, Cursor usage data)
- Repository Interfaces: Abstractions for data access
- Domain Errors: Business logic specific errors
Infrastructure Layer
- Configuration: Application settings management
- Dependency Injection: IoC container for clean dependency management
- Logging: Multiple logger implementations (debug, promtail)
- Repository Implementations:
- Cursor API client for usage data
- SQLite database for Cursor token history
- JSONL reader for Claude Code data
- Prometheus remote write client
Use Case Layer
- Services: Business logic implementation
- Claude Code data processing
- Cursor API integration and token tracking
- AWS Bedrock CloudWatch metrics processing
- Google Vertex AI monitoring metrics processing
- Metrics collection and sending
- Application status tracking
Interface Layer
- Controllers: Application entry points
- CLI controller for command-line interface
- Daemon controller for background service
- System tray controller for UI
Data Sources
Claude Code
Searches for data in:
~/.config/claude/projects/ (new default)
~/.claude/projects/ (legacy)
~/Library/Application Support/claude/projects/ (macOS)
Cursor
Uses Cursor API to fetch:
- Premium (GPT-4) request usage
- Usage-based pricing information
- Team membership status
AWS Bedrock
Uses CloudWatch API to fetch:
- Input/output token counts per model
- Daily aggregated usage
- Multi-region support
Google Vertex AI
Uses Cloud Monitoring API to fetch:
- Token usage by model and location
- Daily aggregated metrics
- Multi-location support
Notes
- macOS only (uses CGO for system tray)
- Time calculations use JST (Asia/Tokyo) timezone
- Configuration file:
~/.config/tosage/config.json
Troubleshooting
Installation Issues
"GitHub API rate limit exceeded"
- Wait for the rate limit to reset (usually 1 hour)
- Or download the DMG manually from GitHub Releases
"Failed to mount DMG"
- Ensure you have sufficient disk space
- Check if another DMG is already mounted
- Try manually mounting the DMG from Finder
"Permission denied" during installation
- The installer requires administrator privileges to copy to /Applications
- Enter your password when prompted by
sudo
"No DMG found for architecture"
- Check that your macOS version is supported
- For Apple Silicon Macs, ensure you're using arm64 builds
- For Intel Macs, x86_64 builds may not be available yet
Configuration Issues
- Ensure your Prometheus URL includes the protocol (http:// or https://)
- Example:
https://prometheus.example.com/api/prom/push
"Configuration file permission denied"
- The config file is created with secure permissions (600)
- Use
sudo if you need to manually edit it
Runtime Issues
"tosage.app is damaged and can't be opened"
- This is a macOS Gatekeeper issue
- The installer automatically removes quarantine attributes
- If the issue persists, run:
sudo xattr -cr /Applications/tosage.app
"Cannot find Claude Code data"
- Ensure Claude Code has been run at least once
- Check that data exists in one of the search directories
- See "Data Sources" section for locations
TODO
- Add Vertex AI token usage tracking
- Add Amazon Bedrock token usage tracking
GitHub Actions Setup
For maintainers who want to build signed releases, see GitHub Secrets Setup Guide for required configuration.
License
MIT License