Skip to content

Instantly share code, notes, and snippets.

@Seklfreak
Last active February 27, 2026 19:44
Show Gist options
  • Select an option

  • Save Seklfreak/99ec4c357017eb9943de3ddaa2e588d0 to your computer and use it in GitHub Desktop.

Select an option

Save Seklfreak/99ec4c357017eb9943de3ddaa2e588d0 to your computer and use it in GitHub Desktop.
Analyze claude cost
package main
import (
"encoding/csv"
"fmt"
"io"
"os"
"sort"
"strconv"
"strings"
)
func extractUsername(apiKey string) string {
// Strip prefix "claude_code_key_"
s := strings.TrimPrefix(apiKey, "claude_code_key_")
// Strip the last "_XXXX" suffix (4-char random segment)
idx := strings.LastIndex(s, "_")
if idx != -1 {
s = s[:idx]
}
// "sebastian.winkler" -> "Sebastian Winkler"
parts := strings.Split(s, ".")
for i, p := range parts {
if len(p) > 0 {
parts[i] = strings.ToUpper(p[:1]) + p[1:]
}
}
return strings.Join(parts, " ")
}
func main() {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "Usage: analyze_costs <file.csv>")
os.Exit(1)
}
f, err := os.Open(os.Args[1])
if err != nil {
fmt.Fprintf(os.Stderr, "Error opening file: %v\n", err)
os.Exit(1)
}
defer f.Close()
r := csv.NewReader(f)
header, err := r.Read()
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading header: %v\n", err)
os.Exit(1)
}
colIndex := func(name string) int {
for i, h := range header {
if h == name {
return i
}
}
return -1
}
apiKeyCol := colIndex("api_key")
costCol := colIndex("cost_usd")
if apiKeyCol == -1 || costCol == -1 {
fmt.Fprintln(os.Stderr, "Required columns 'api_key' or 'cost_usd' not found")
os.Exit(1)
}
totals := make(map[string]float64)
for {
record, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading row: %v\n", err)
continue
}
user := extractUsername(record[apiKeyCol])
cost, err := strconv.ParseFloat(record[costCol], 64)
if err != nil {
continue
}
totals[user] += cost
}
type entry struct {
user string
cost float64
}
rows := make([]entry, 0, len(totals))
var grand float64
for user, cost := range totals {
rows = append(rows, entry{user, cost})
grand += cost
}
sort.Slice(rows, func(i, j int) bool {
return rows[i].cost > rows[j].cost
})
fmt.Printf("%-25s %12s %8s\n", "User", "Cost (USD)", "Share")
fmt.Println(strings.Repeat("-", 48))
for _, e := range rows {
share := e.cost / grand * 100
fmt.Printf("%-25s %12.2f %7.1f%%\n", e.user, e.cost, share)
}
fmt.Println(strings.Repeat("-", 48))
fmt.Printf("%-25s %12.2f %8s\n", "TOTAL", grand, "")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment