# CubeAPM CLI > Command-line interface for querying distributed traces (Jaeger-compatible), metrics (Prometheus/PromQL), and logs (VictoriaLogs/LogsQL) from a CubeAPM observability server, built to be driven both interactively and programmatically by scripts and coding agents. `cubeapm` is a single static Go binary that talks to a CubeAPM server's HTTP APIs. It groups its functionality into command groups, `traces`, `metrics`, `logs`, `ingest`, `config`, plus the top-level `login`, `version`, and `update` commands. Every command supports `table` (default), `json`, and `yaml` output via `-o`/`--output`; JSON is the format intended for scripting and agents. This is an **independent, unofficial** tool. It is not affiliated with, endorsed by, or sponsored by CubeAPM or its makers. "CubeAPM" is the name of the third-party product this CLI connects to. - Binary name: `cubeapm` - Supported platforms: macOS (darwin), Linux, and Windows; on `amd64` and `arm64` (Windows ships `amd64` only). Released as `.tar.gz` archives (`.zip` on Windows). - Written in Go (module `github.com/piyush-gambhir/cubeapm-cli`). - The CLI itself stores no telemetry; it only sends requests to the CubeAPM server you configure. ## Links - Home: https://cubeapm-cli.pages.dev/ - Source: https://github.com/piyush-gambhir/cubeapm-cli - Issues: https://github.com/piyush-gambhir/cubeapm-cli/issues - Releases: https://github.com/piyush-gambhir/cubeapm-cli/releases - Privacy: https://cubeapm-cli.pages.dev/privacy-policy - Terms: https://cubeapm-cli.pages.dev/terms-of-service - Contact: https://cubeapm-cli.pages.dev/contact - Skill (Claude Code agent skill): https://github.com/piyush-gambhir/cubeapm-cli/blob/main/cubeapm/SKILL.md ## Skill (Claude Code / agents) A ready-made Claude Code skill ships in the repo: https://github.com/piyush-gambhir/cubeapm-cli/blob/main/cubeapm/SKILL.md . Point your agent at that file, or install it as a skill (copy it to `~/.claude/skills/cubeapm/SKILL.md`, or load it via your agent's skill mechanism) to teach an agent how to drive `cubeapm`. ## Install ### Install script (macOS / Linux) Downloads the latest release binary for your OS/arch and installs it (default `/usr/local/bin`). ```bash curl -sSfL https://raw.githubusercontent.com/piyush-gambhir/cubeapm-cli/main/install.sh | sh ``` Install a specific version: ```bash curl -sSfL https://raw.githubusercontent.com/piyush-gambhir/cubeapm-cli/main/install.sh | VERSION=0.1.0 sh ``` Install to a custom directory (e.g. one already on your `PATH`): ```bash curl -sSfL https://raw.githubusercontent.com/piyush-gambhir/cubeapm-cli/main/install.sh | INSTALL_DIR=~/.local/bin sh ``` The script requires `curl` and `tar`. If the install directory is not writable it falls back to `sudo`. ### go install (Go 1.25+) ```bash go install github.com/piyush-gambhir/cubeapm-cli@latest ``` Note: the produced binary is named after the module (`cubeapm-cli`). Symlink or rename it to `cubeapm` if you want the canonical command name used throughout this document. ### Build from source ```bash git clone https://github.com/piyush-gambhir/cubeapm-cli.git cd cubeapm-cli make build # Produces the binary ./cubeapm in the repo root ``` Other Makefile targets: `make install` (`go install` with version ldflags), `make test`, `make lint`, `make fmt`, `make vet`, `make tidy`, `make clean`. ### Prebuilt release archives Download the archive for your platform from the GitHub Releases page and extract the `cubeapm` binary onto your `PATH`: https://github.com/piyush-gambhir/cubeapm-cli/releases ### Self-update Once a release build is installed, it can update itself in place: ```bash cubeapm update # check and install the latest release cubeapm update --check # only report whether an update is available ``` Self-update does not work on a `dev` build (one built from source without a version tag), it errors out and tells you so. ## Authentication A CubeAPM server may or may not require authentication. The CLI supports exactly two auth methods: 1. **`kratos`**, email + password. CubeAPM fronts its UI/API with Ory Kratos; the CLI performs the full Kratos browser login flow (initiate flow, fetch CSRF token, POST credentials) and receives a session cookie. The cookie (and its expiry) are cached so subsequent invocations reuse it. When a request returns HTTP 401 and credentials are stored, the CLI automatically re-authenticates once and retries, then persists the refreshed cookie back into the active profile. 2. **`none`**, no authentication. For CubeAPM instances exposed without auth (local dev, or networks with their own access control). The CLI connects directly to the API ports. Auto-detection: if `auth_method` is unset, the CLI picks `kratos` when both email and password are present, otherwise `none`. ### Log in interactively `cubeapm login` walks through profile name, server address, auth method, and the three ports, tests the connection (using the Prometheus-standard `/api/v1/labels` endpoint), and saves the profile. ```bash cubeapm login # Preseed the server (still prompts for everything else) cubeapm login --server cube.example.com ``` `login` requires an interactive terminal; it fails under `--no-input` (use `cubeapm config set` or environment variables instead). ### Non-interactive auth (CI / agents) Provide credentials via environment variables or flags and skip `login` entirely: ```bash export CUBEAPM_SERVER=cube.example.com export CUBEAPM_EMAIL=user@example.com export CUBEAPM_PASSWORD=your-password export CUBEAPM_NO_INPUT=true # fail instead of prompting if anything is missing cubeapm traces services -o json ``` Or all on one line (flags beat everything; avoid putting secrets in shell history): ```bash cubeapm --server cube.example.com --email user@example.com --password secret traces services ``` ### Config file - Path: `~/.config/cubeapm-cli/config.yaml` - Override the directory with `XDG_CONFIG_HOME` → `$XDG_CONFIG_HOME/cubeapm-cli/config.yaml` - Created with `0600` permissions (directory `0700`) because it can hold credentials and a session cookie. - Format: YAML. See "Configuration & profiles" below for the schema. ### Resolution precedence For every setting, values are layered in this order (highest wins): 1. **CLI flags** (`--server`, `--email`, `--password`, `--query-port`, `--ingest-port`, `--admin-port`, `--output`, `--profile`, `--read-only`, `--no-input`, `--quiet`) 2. **Environment variables** (`CUBEAPM_*`, see below) 3. **The active profile** in the config file (selected by `--profile`, else `current_profile`) ### Environment variables | Variable | Effect | |----------|--------| | `CUBEAPM_SERVER` | Server address (hostname, IP, or full URL) | | `CUBEAPM_EMAIL` | Login email (Kratos auth) | | `CUBEAPM_PASSWORD` | Login password (Kratos auth) | | `CUBEAPM_QUERY_PORT` | Query API port (default `3140`) | | `CUBEAPM_INGEST_PORT` | Ingest API port (default `3130`) | | `CUBEAPM_ADMIN_PORT` | Admin API port (default `3199`) | | `CUBEAPM_READ_ONLY` | Block write/delete commands when `true`/`1` | | `CUBEAPM_NO_INPUT` | Disable all interactive prompts when `true`/`1` | | `CUBEAPM_QUIET` | Suppress informational output when `true`/`1` | | `XDG_CONFIG_HOME` | Relocate the config directory | There is no environment variable for output format or profile selection, use `-o`/`--output` and `--profile` (or set `output` in the profile via `cubeapm config set output ...`). ## Global flags These persistent flags apply to every command: | Flag | Short | Type | Default | Description | |------|-------|------|---------|-------------| | `--output` | `-o` | string | `table` | Output format: `table`, `json`, or `yaml` | | `--profile` | | string | | Connection profile to use (overrides `current_profile`) | | `--server` | | string | | CubeAPM server address override | | `--email` | | string | | Login email override | | `--password` | | string | | Login password override | | `--query-port` | | int | `3140` | Query API port override | | `--ingest-port` | | int | `3130` | Ingest API port override | | `--admin-port` | | int | `3199` | Admin API port override | | `--no-color` | | bool | `false` | Disable colored/bold output | | `--verbose` | | bool | `false` | Log the full HTTP request/response cycle (auth headers redacted) | | `--read-only` | | bool | `false` | Block write/delete operations (safety mode for agents) | | `--no-input` | | bool | `false` | Disable all interactive prompts (CI/agent use) | | `--quiet` | `-q` | bool | `false` | Suppress informational (non-data) output | ### Ports CubeAPM exposes three ports. Most commands only use the query port. | Port | Default | Used by | |------|---------|---------| | Query | `3140` | all `traces`, `metrics`, and `logs` read commands | | Ingest | `3130` | `ingest metrics`, `ingest logs` | | Admin | `3199` | `logs delete run`, `logs delete list`, `logs delete stop` | Behind a reverse proxy on HTTPS, all three are usually the same host on port 443, set all three ports to the same value (e.g. `443`) or pass the server as a full `https://` URL. ### Time-range flags Most read commands accept `--from`, `--to`, and `--last`. If none are given, the default window is the **last 1 hour**. - `--last `, relative duration from now: `30m`, `1h`, `2d`, `1d12h`, `90s`. Units: `ns`, `us`, `ms`, `s`, `m`, `h`, `d` (note: Go's stdlib lacks `d`, so this CLI adds it). When set, `--last` takes precedence over `--from`/`--to`. - `--from`/`--to`, accept RFC3339 (`2024-01-15T10:00:00Z`), date-only (`2024-01-15`), date+time without a zone (`2024-01-15T10:00:00`, interpreted as **local** time), Unix seconds (`1705312800`) or milliseconds (`>= 1e12`), or relative (`-1h`, `now-30m`, `now`). - Only `--from` → `--to` defaults to now. Only `--to` → `--from` defaults to one hour before `--to`. The `metrics query` command uses a single `--time` flag (same accepted formats) for the instant evaluation timestamp instead of a range. ### Read-only mode When read-only is active (via `--read-only`, or `read_only: true` in the profile, or `CUBEAPM_READ_ONLY=true`), the four mutating commands are blocked with an error: `ingest metrics`, `ingest logs`, `logs delete run`, `logs delete stop`. The flag overrides the profile/env value; use `--read-only=false` to force-enable writes for one invocation. ## Commands Top-level commands: `traces`, `metrics`, `logs`, `ingest`, `config`, `login`, `version`, `update`. Built-in `help` and `completion` are provided by the CLI framework. Group aliases: `traces`→`trace`, `metrics`→`metric`, `logs`→`log`. PromQL and LogsQL expressions are passed as **positional arguments**, not flags. Always wrap them in single quotes to protect `{`, `}`, `(`, `)`, `|`, and `*` from the shell. --- ### traces, distributed traces (Jaeger-compatible API) Search, retrieve, and analyze spans. Group alias: `trace`. Uses the query port. #### traces search ``` cubeapm traces search [flags] ``` Search for traces matching filters. Table output shows the root span per matching trace: `TRACE_ID`, `SERVICE`, `OPERATION`, `DURATION`, `STATUS`, `TIMESTAMP`. **Required on many CubeAPM deployments:** both `--service` and `--env` must be provided. The server returns a clear error if either is missing. Environment values are UPPER-CASE (e.g. `PROD`, `UAT`). Flags: - `--service `, filter by service name (e.g. `api-gateway`) - `--env `, filter by environment (UPPER-CASE values: `PROD`, `UAT`, etc.) - `--query `, filter by operation name (e.g. `GET /api/users`) - `--status `, `error` matches the `error=true` tag; `ok` matches `otel.status_code=OK` - `--min-duration `, only traces slower than this (`500ms`, `1s`, `100us`) - `--max-duration `, only traces faster than this (`5s`, `10s`) - `--tags `, span tag filter, repeatable (e.g. `--tags http.method=POST --tags http.status_code=500`) - `--span-kind `, `client`, `server`, `producer`, `consumer`, `internal`. **Default `server`** (some CubeAPM deployments require a non-empty value). - `--index `, CubeAPM trace index to query (default `cube:latency`; also `cube:error`) - `--limit `, max traces to return (default `20`) - `--from` / `--to` / `--last`, time range (default last 1h) ```bash # Errors slower than 500ms for a service in the last hour cubeapm traces search --service payments --env PROD --status error --min-duration 500ms --last 1h # Filter by operation and tags, output JSON, extract trace IDs cubeapm traces search --service api-gateway --env PROD --query "GET /api/users" \ --tags http.status_code=500 -o json | jq -r '.[].TRACE_ID' ``` #### traces get ``` cubeapm traces get [flags] ``` Retrieve one trace by its (hex) trace ID. In table mode renders a span waterfall tree (service / operation / duration / status, with parent-child indentation). In JSON/YAML returns the full Jaeger-format trace (all spans, tags, logs, processes). Flags: `--from` / `--to` / `--last`, optional, narrows the lookup window. ```bash cubeapm traces get abc123def456789 cubeapm traces get abc123def456789 -o json ``` #### traces services ``` cubeapm traces services [flags] ``` List all services that have reported traces (sorted). Alias: `svc`. Column: `SERVICE`. With `--env`, list only services visible in a specific environment (e.g. `PROD`, `UAT`). This path is metrics-derived: it queries label-values filtered by `env` and `cube.environment` labels, then unions `service` and `service.name` label values. A service that emits only traces (no metrics) in that environment may not appear. Flags: - `--env `, list only services seen in this environment (metrics-derived; UPPER-CASE values) - `--from` / `--to` / `--last`, time range for the metrics lookup (default last 1h; only used with `--env`) ```bash cubeapm traces services cubeapm traces svc -o json # List services active in PROD (env values are UPPER-CASE) cubeapm traces services --env PROD cubeapm traces services --env PROD --last 24h -o json ``` #### traces operations ``` cubeapm traces operations [flags] ``` List operations (endpoints/methods) reported by a service. Alias: `ops`. Columns: `OPERATION`, `SPAN_KIND`. **Caveat:** this endpoint is not exposed by all CubeAPM deployments. When not exposed, the server returns a "unsupported path requested" error. The CLI surfaces this as a clear message: run `cubeapm traces search --service --env ` and read the OPERATION column instead. Flags: `--span-kind `, filter by span kind (no default; empty = all kinds). ```bash cubeapm traces operations api-gateway cubeapm traces ops api-gateway --span-kind server -o json ``` #### traces dependencies ``` cubeapm traces dependencies [flags] ``` Service dependency graph over a time range. Alias: `deps`. Columns: `PARENT`, `CHILD`, `CALL_COUNT`. **Caveat:** this endpoint is not exposed by all CubeAPM deployments. When not exposed, the server returns a "unsupported path requested" error and the CLI surfaces it as a clear message. Flags: - `--dot`, emit Graphviz DOT instead of a table (pipe to `dot`) - `--from` / `--to` / `--last`, time range (default last 1h) ```bash cubeapm traces dependencies --last 24h cubeapm traces deps --last 24h --dot | dot -Tpng -o deps.png ``` #### traces callers ``` cubeapm traces callers [flags] ``` Rank the services making outbound HTTP calls to a host (or reaching a target service), by call rate. This is a convenience wrapper over the PromQL query `topk(N, sum by (service) (rate(cube_apm_latency_count{group_name="HTTP ",span_kind="client"}[])))`. Columns: `CALLER_SERVICE`, `CALLS_PER_SEC`. Flags: - `--host `, target host, matched against the `group_name` label (e.g. `api.spyne.ai`). Either `--host` or `--service` is required. - `--service `, restrict to callers of this target service (host is inferred if `--host` is omitted) - `--window `, rate window (default `2m`; shorter = more responsive but noisier) - `--topk `, max callers to return (default `10`) - `--from` / `--to` / `--last`, time range; the query evaluates instantly at the end of the window (default last 1h) ```bash # Who's calling api.spyne.ai right now? cubeapm traces callers --host api.spyne.ai --last 1h # Biggest callers during an incident window, top 20, 5m rate window cubeapm traces callers --host api.spyne.ai --window 5m --topk 20 \ --from 2026-04-19T13:20:00Z --to 2026-04-19T13:50:00Z ``` --- ### metrics, Prometheus-compatible metrics (PromQL) Run PromQL and explore label/series metadata. Group alias: `metric`. Uses the query port. #### metrics query ``` cubeapm metrics query [flags] ``` Instant PromQL query at a single point in time. Table columns for a vector result: `METRIC`, `VALUE`, `TIMESTAMP` (scalar/string results print the value). JSON/YAML returns the raw Prometheus API response. Flags: `--time `, evaluation timestamp (RFC3339, Unix, or relative like `now-1h`; default now). ```bash cubeapm metrics query 'up' cubeapm metrics query 'sum by (service) (rate(http_requests_total[5m]))' cubeapm metrics query 'histogram_quantile(0.99, sum by (le) (rate(http_duration_seconds_bucket[5m])))' --time now-1h ``` #### metrics query-range ``` cubeapm metrics query-range [flags] ``` Range PromQL query over a window. Alias: `range`. Table columns: `METRIC`, `SAMPLES`, `VALUES` (a sampled summary). JSON/YAML returns the full matrix. Flags: - `--step `, resolution between data points (`15s`, `1m`, `5m`, `1h`). If omitted, auto-calculated to ~250 points. - `--from` / `--to` / `--last`, time range (default last 1h) ```bash cubeapm metrics query-range 'rate(http_requests_total[5m])' --last 1h --step 1m cubeapm metrics query-range 'sum by (service) (rate(http_requests_total[5m]))' --last 6h --step 5m -o json ``` #### metrics labels ``` cubeapm metrics labels [flags] ``` List all metric label names (sorted). Column: `LABEL`. Flags: `--from` / `--to` / `--last` (default last 1h). ```bash cubeapm metrics labels --last 24h ``` #### metrics label-values ``` cubeapm metrics label-values