tosage

command module
v1.0.28 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2025 License: MIT Imports: 12 Imported by: 0

README

tosage

🇯🇵 日本語版

tosage logo

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:

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

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:

  1. Download the latest tosage DMG for your architecture (arm64/x86_64)
  2. Install the application to /Applications/tosage.app
  3. Guide you through configuration setup interactively
  4. 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:

  1. Set bedrock.enabled to true
  2. 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.)
  3. Specify regions to monitor in bedrock.regions
Google Vertex AI Configuration

To enable Vertex AI metrics:

  1. Set vertex_ai.enabled to true
  2. Set vertex_ai.project_id to your GCP project ID
  3. 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)
  4. Specify locations to monitor in vertex_ai.locations
Authentication Priority System

The Vertex AI integration uses a three-tier authentication priority system:

  1. 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)
  2. Service Account Key File - If service_account_key_path is provided
  3. 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
CSV Format

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"]
Available Tags
  • 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)

  1. Binary Build: Executes build-darwin to create Go binary
  2. Dependency Check: Runs dmg-check to verify required tools
  3. 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

  1. Creates app bundle (executes app-bundle-*)
  2. 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
"Invalid URL format"
  • 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

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
infrastructure
di
repository/prompb
This file is intentionally empty - using types.go instead
This file is intentionally empty - using types.go instead
interface
cli
usecase

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL