From 0a22e712bf9f9510c969ba9510c3cb9d585b84d4 Mon Sep 17 00:00:00 2001 From: Quinn Milionis Date: Fri, 11 Sep 2026 10:25:14 -0700 Subject: [PATCH] 1.0 polish: structured output and command edge cases (part of #29) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed for a clean rebase onto main after v0.5.0 landed, and reverted the changelog.d/ fragment system in favor of a direct CHANGELOG.md edit (dropped per team discussion — more process than this repo's PR concurrency warrants). Functional content is unchanged from the original review. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01BK3fzED9ksTWsvoPfsEwpS --- .github/workflows/ci.yml | 11 +++ CHANGELOG.md | 18 ++++ README.md | 36 ++++---- cmd/anomalies.go | 62 ++++++++++++-- cmd/anomalies_test.go | 44 ++++++++++ cmd/apps.go | 24 ++++-- cmd/auth.go | 3 + cmd/billing.go | 5 ++ cmd/billing_test.go | 7 ++ cmd/endpoints.go | 53 ++++++++++-- cmd/errors.go | 35 ++++---- cmd/insights.go | 85 +++++++++++++++++-- cmd/insights_test.go | 115 +++++++++++++++++++++++++ cmd/jobs.go | 64 +++++++------- cmd/jobs_test.go | 33 ++++++-- cmd/metrics.go | 37 +++++++- cmd/metrics_test.go | 43 ++++++++++ cmd/root.go | 113 ++++++++++++++++++------- cmd/root_test.go | 114 +++++++++++++++++++++++++ cmd/setup.go | 18 ++-- cmd/setup_test.go | 44 ++++++---- cmd/traces.go | 85 ++++++++++++++----- cmd/traces_test.go | 27 ++++++ cmd/usage.go | 138 ++++++++++++++++++++++-------- cmd/usage_test.go | 94 +++++++++++++++++++++ go.mod | 3 +- go.sum | 2 - internal/api/client.go | 22 ++++- internal/api/client_test.go | 51 ++++++++++- internal/api/jobs_test.go | 50 +++++++++++ internal/api/types.go | 23 +++++ internal/config/config.go | 3 + internal/config/config_test.go | 13 +++ internal/output/chart.go | 97 ++++++++++++++------- internal/output/chart_test.go | 144 ++++++++++++++++++++++++++++++++ internal/output/progress.go | 8 +- internal/output/style.go | 14 ++++ internal/output/table.go | 12 ++- internal/output/table_test.go | 44 ++++++++++ internal/output/tree.go | 6 +- internal/timeutil/parse.go | 41 ++++++++- internal/timeutil/parse_test.go | 46 ++++++++++ 42 files changed, 1620 insertions(+), 267 deletions(-) create mode 100644 cmd/insights_test.go create mode 100644 cmd/metrics_test.go create mode 100644 cmd/root_test.go create mode 100644 cmd/traces_test.go create mode 100644 internal/output/chart_test.go create mode 100644 internal/output/table_test.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65fe2cd..076ae92 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,4 +27,15 @@ jobs: with: go-version-file: go.mod + - name: gofmt + run: | + unformatted=$(gofmt -l .) + if [ -n "$unformatted" ]; then + echo "Not gofmt-formatted:" + echo "$unformatted" + exit 1 + fi + + - run: go vet ./... + - uses: golangci/golangci-lint-action@v6 diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e88c6a..fb21cdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,27 @@ ## Pending +### Changed + +- `scout usage --app ` (without `--by-day`) now filters to that one app instead of silently reporting every app, matching `--by-day --app ` (#29) +- `scout usage --billing-period --json` now wraps the per-app result in an object carrying `billing_period` and `server_total`, so a script can tell which window it got and what the billed figure was. Without `--billing-period` the shape is unchanged (#29) +- `scout jobs metrics --type latency --json` renames the API's `total` sub-series to `execution_time_total`, which is what it actually holds; other metric types are unchanged (#29) +- `scout errors show` omits the `Count:` line when the API reports 0, which it does for every error group even when `errors list` shows a real count (#29) +- `scout insights show` prints nested fields as indented `key: value` pairs and empty values as `—`, instead of leaking Go's `map[...]` and `` formatting (#29) + ### Fixed - `scout setup ` now links to a real docs page for every framework — the old `/docs/` URLs all 404'd because Scout's docs are organized by language (#27) +- `-n`/`--limit` is now applied to `--json` output, not just the human table, across every list command: `apps list`, `endpoints list`, `jobs list`, `traces list`, `errors list`, `errors occurrences`, `anomalies list`, `insights list`, `insights show`, and all four `usage` modes. Totals and percentages are still computed over the full result set (#29) +- `scout insights list` and `scout insights show` now honor `-n` at all; it previously had no effect on either (#29) +- `scout anomalies --endpoint` now accepts a Base64 endpoint id and a plain endpoint name as well as the scoped name from `anomalies list`, instead of silently matching nothing (#29) +- `--endpoint` and `--job` now reject a blank value client-side rather than passing it to the server (#29) +- A malformed `--job` value, or a job class name copy-pasted without its queue, now gets a clear client-side error instead of a raw `API error (500)` (#29) +- `scout auth logout` no longer fails on a machine with no config directory yet (#29) +- `--from`/`--to` now reject a reversed range and unreasonably large or negative relative durations, which previously produced silently empty or nonsensical results (#29) +- `--app 0` and negative app ids now report an invalid value instead of "no app specified" (#29) +- `scout traces show` on a 404 now explains that background job traces have no detail endpoint (#29) +- `scout insights show` field order is now stable; it previously ranged over a Go map and printed a different order every run (#29) ## [0.5.0] - 2026-09-10 diff --git a/README.md b/README.md index d82701d..2ee6c47 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,15 @@ scout auth status scout auth logout ``` -Credentials are stored in `~/.config/scout-apm/config.json`. You can also set the `SCOUT_API_KEY` environment variable. +Credentials are stored in a per-user config file whose location follows the platform convention: + +| Platform | Path | +| --- | --- | +| macOS | `~/Library/Application Support/scout-apm/config.json` | +| Linux | `$XDG_CONFIG_HOME/scout-apm/config.json`, defaulting to `~/.config/scout-apm/config.json` | +| Windows | `%AppData%\scout-apm\config.json` | + +`scout auth status` prints the path in use. You can also set the `SCOUT_API_KEY` environment variable, which takes precedence over the config file. ## Usage @@ -102,24 +110,28 @@ Job IDs are in the `scout jobs list --json` output (`job_id`), or pass the job's ```bash scout traces list --endpoint YXBpL21ldHJpY3Mvc2hvdw== --app 6 scout traces list --job ZGVmYXVsdC9NeVdvcmtlcg== --app 6 -scout traces show 12345 --app 6 +scout traces show --app 6 ``` +Trace ids come from `scout traces list`. + ### Errors ```bash scout errors list --app 6 -scout errors show 50560 --app 6 -scout errors occurrences 50560 --app 6 +scout errors show --app 6 +scout errors occurrences --app 6 ``` +Error group ids come from `scout errors list`. + ### Anomalies ```bash scout anomalies --app 6 # List anomaly events (default: all states) scout anomalies --app 6 --state open # Only open anomalies scout anomalies --app 6 --metric response_time # Filter by metric -scout anomalies --app 6 --endpoint YXBpL21ldHJpY3M= # Filter by endpoint +scout anomalies --app 6 --endpoint Controller/users/index # Filter by endpoint (a name from 'anomalies list', or a Base64 endpoint id) scout anomalies show 1234 --app 6 # Detail with smart_monitor and deploy context ``` @@ -168,8 +180,7 @@ scout setup rails # Show setup docs for a framework | Flag | Description | |------|-------------| -| `--json` | Output raw JSON | -| `--toon` | Output in [TOON](https://toonformat.dev/) format (auto-enabled when piped) | +| `--json` | Output raw JSON (auto-enabled when piped) | | `--app ` | Application ID (or set `default_app_id` in config) | | `--from