Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/cli-docs/src/fragments/commands/alert.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ sentry alert issues delete my-org/my-project/12345 --dry-run
sentry alert metrics create my-org \
--name "P95 Latency" \
--query "environment:prod" \
--aggregate "p95(transaction.duration)" \
--dataset transactions \
--aggregate "p95(span.duration)" \
--dataset spans \
--time-window 5 \
--trigger '{"alertThreshold":500,"actions":[{"id":"sentry.mail.actions.NotifyEmailAction","targetType":"Team","targetIdentifier":1}]}'
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ List recent agent conversations
**Flags:**
- `-n, --limit <value> - Number of conversations (1-1000) - (default: "25")`
- `-q, --query <value> - Search query`
- `-t, --period <value> - Time range: "7d", "2026-07-01..2026-08-01", ">=2026-07-01" - (default: "7d")`
- `-t, --period <value> - Time range: "7d", "2026-08-01..2026-09-01", ">=2026-08-01" - (default: "7d")`
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`
- `-c, --cursor <value> - Navigate pages: "next", "prev", "first" (or raw cursor string)`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ Create a metric alert rule
**Flags:**
- `--name <value> - Rule name`
- `--query <value> - Metric query filter string`
- `--aggregate <value> - Aggregate expression (for example count(), p95(transaction.duration))`
- `--dataset <value> - Dataset: errors (error-events), transactions (transaction-like), sessions, events, spans, metrics`
- `--aggregate <value> - Aggregate expression (for example count(), p95(span.duration))`
- `--dataset <value> - Dataset: errors (error-events), sessions, events, spans, metrics (transaction(s) routes to spans)`
- `--time-window <value> - Evaluation window in minutes`
- `-t, --trigger <value>... - Trigger object JSON (repeatable, or pass one JSON array)`
- `-p, --project <value>... - Project slug filter (repeatable or comma-separated)`
Expand All @@ -170,8 +170,8 @@ Create a metric alert rule
sentry alert metrics create my-org \
--name "P95 Latency" \
--query "environment:prod" \
--aggregate "p95(transaction.duration)" \
--dataset transactions \
--aggregate "p95(span.duration)" \
--dataset spans \
--time-window 5 \
--trigger '{"alertThreshold":500,"actions":[{"id":"sentry.mail.actions.NotifyEmailAction","targetType":"Team","targetIdentifier":1}]}'
```
Expand Down Expand Up @@ -201,7 +201,7 @@ Edit a metric alert rule
- `--status <value> - active or disabled`
- `--query <value> - Metric query filter`
- `--aggregate <value> - Aggregate expression`
- `--dataset <value> - Dataset: errors (error-events), transactions (transaction-like), sessions, events, spans, metrics`
- `--dataset <value> - Dataset: errors (error-events), sessions, events, spans, metrics (transaction(s) routes to spans)`
- `--time-window <value> - Evaluation window in minutes`
- `-t, --trigger <value>... - Trigger object JSON (repeatable, or pass one JSON array)`
- `-p, --project <value>... - Project slug filter (repeatable or comma-separated)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ View a dashboard
- `-w, --web - Open in browser`
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`
- `-r, --refresh <value> - Auto-refresh interval in seconds (default: 60, min: 10)`
- `-t, --period <value> - Time range: "7d", "2026-07-01..2026-08-01", ">=2026-07-01"`
- `-t, --period <value> - Time range: "7d", "2026-08-01..2026-09-01", ">=2026-08-01"`
- `--renderer <value> - Graphics renderer (defaults to auto; falls back to auto when unavailable) - (default: "auto")`

**Examples:**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ List events for an issue
- `-n, --limit <value> - Number of events (1-1000) - (default: "25")`
- `-q, --query <value> - Search query (Sentry search syntax)`
- `--full - Include full event body (stacktraces)`
- `-t, --period <value> - Time range: "7d", "2026-07-01..2026-08-01", ">=2026-07-01" - (default: "7d")`
- `-t, --period <value> - Time range: "7d", "2026-08-01..2026-09-01", ">=2026-08-01" - (default: "7d")`
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`
- `-c, --cursor <value> - Navigate pages: "next", "prev", "first" (or raw cursor string)`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Query aggregate event data (Explore)
- `-s, --sort <value> - Sort field (prefix with - for desc, e.g., "-count()")`
- `-e, --environment <value>... - Environment filter (repeatable, comma-separated)`
- `-n, --limit <value> - Number of rows (1-1000) - (default: "25")`
- `-t, --period <value> - Time range: "7d", "2026-07-01..2026-08-01", ">=2026-07-01" - (default: "24h")`
- `-t, --period <value> - Time range: "7d", "2026-08-01..2026-09-01", ">=2026-08-01" - (default: "24h")`
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`
- `-c, --cursor <value> - Navigate pages: "next", "prev", "first" (or raw cursor string)`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ List and search User Feedback
- `--status <value> - Mailbox: unresolved, resolved, spam, or all - (default: "unresolved")`
- `-n, --limit <value> - Number of feedback items (1-1000) - (default: "25")`
- `-q, --query <value> - Search query (Sentry issue search syntax)`
- `-t, --period <value> - Time range: "7d", "2026-07-01..2026-08-01", ">=2026-07-01" - (default: "14d")`
- `-t, --period <value> - Time range: "7d", "2026-08-01..2026-09-01", ">=2026-08-01" - (default: "14d")`
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`
- `-c, --cursor <value> - Navigate pages: "next", "prev", "first" (or raw cursor string)`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ List issues in a project
- `-q, --query <value> - Search query (Sentry syntax, implicit AND, no OR operator)`
- `-n, --limit <value> - Maximum number of issues to list - (default: "25")`
- `-s, --sort <value> - Sort by: recommended, date, new, freq, user (default: recommended on sentry.io, else date)`
- `-t, --period <value> - Time range: "7d", "2026-07-01..2026-08-01", ">=2026-07-01" - (default: "90d")`
- `-t, --period <value> - Time range: "7d", "2026-08-01..2026-09-01", ">=2026-08-01" - (default: "90d")`
- `-c, --cursor <value> - Pagination cursor (use "next" for next page, "prev" for previous)`
- `--compact - Single-line rows for compact output (auto-detects if omitted)`
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`
Expand Down Expand Up @@ -92,7 +92,7 @@ List events for a specific issue
- `-n, --limit <value> - Number of events (1-1000) - (default: "25")`
- `-q, --query <value> - Search query (Sentry search syntax)`
- `--full - Include full event body (stacktraces)`
- `-t, --period <value> - Time range: "7d", "2026-07-01..2026-08-01", ">=2026-07-01" - (default: "7d")`
- `-t, --period <value> - Time range: "7d", "2026-08-01..2026-09-01", ">=2026-08-01" - (default: "7d")`
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`
- `-c, --cursor <value> - Navigate pages: "next", "prev", "first" (or raw cursor string)`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ List logs from a project
- `-n, --limit <value> - Number of log entries (1-1000) - (default: "100")`
- `-q, --query <value> - Filter query (e.g., "severity:error", "project:backend", "project:[a,b]")`
- `-f, --follow <value> - Stream logs (optionally specify poll interval in seconds)`
- `-t, --period <value> - Time range: "7d", "2026-07-01..2026-08-01", ">=2026-07-01"`
- `-t, --period <value> - Time range: "7d", "2026-08-01..2026-09-01", ">=2026-08-01"`
- `-s, --sort <value> - Sort order: "newest" (default) or "oldest" - (default: "newest")`
- `--fresh - Bypass cache, re-detect projects, and fetch fresh data`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ List recent Session Replays
- `-q, --query <value> - Search query (Sentry replay search syntax)`
- `-e, --environment <value>... - Filter by environment (repeatable, comma-separated)`
- `-s, --sort <value> - Sort by: date, oldest, duration, errors, activity, or a raw replay sort field - (default: "date")`
- `-t, --period <value> - Time range: "7d", "2026-07-01..2026-08-01", ">=2026-07-01" - (default: "7d")`
- `-t, --period <value> - Time range: "7d", "2026-08-01..2026-09-01", ">=2026-08-01" - (default: "7d")`
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`
- `-c, --cursor <value> - Navigate pages: "next", "prev", "first" (or raw cursor string)`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ List spans in a project or trace
- `-n, --limit <value> - Number of spans (<=1000) - (default: "25")`
- `-q, --query <value> - Filter spans (e.g., "op:db", "project:backend", "project:[cli,api]")`
- `-s, --sort <value> - Sort order: date, duration - (default: "date")`
- `-t, --period <value> - Time range: "7d", "2026-07-01..2026-08-01", ">=2026-07-01" - (default: "7d")`
- `-t, --period <value> - Time range: "7d", "2026-08-01..2026-09-01", ">=2026-08-01" - (default: "7d")`
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`
- `-c, --cursor <value> - Navigate pages: "next", "prev", "first" (or raw cursor string)`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ List recent traces in a project
- `-n, --limit <value> - Number of traces (1-1000) - (default: "25")`
- `-q, --query <value> - Search query (Sentry search syntax)`
- `-s, --sort <value> - Sort by: date, duration - (default: "date")`
- `-t, --period <value> - Time range: "7d", "2026-07-01..2026-08-01", ">=2026-07-01" - (default: "7d")`
- `-t, --period <value> - Time range: "7d", "2026-08-01..2026-09-01", ">=2026-08-01" - (default: "7d")`
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`
- `-c, --cursor <value> - Navigate pages: "next", "prev", "first" (or raw cursor string)`

Expand Down Expand Up @@ -91,7 +91,7 @@ View logs associated with a trace

**Flags:**
- `-w, --web - Open trace in browser`
- `-t, --period <value> - Time range: "7d", "2026-07-01..2026-08-01", ">=2026-07-01" - (default: "14d")`
- `-t, --period <value> - Time range: "7d", "2026-08-01..2026-09-01", ">=2026-08-01" - (default: "14d")`
- `-n, --limit <value> - Number of log entries (<=1000) - (default: "100")`
- `-q, --query <value> - Filter query (e.g., "severity:error", "project:backend", "project:[a,b]")`
- `-s, --sort <value> - Sort order: "newest" (default) or "oldest" - (default: "newest")`
Expand Down
23 changes: 15 additions & 8 deletions packages/cli/src/commands/alert/metrics/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import { createMetricAlertRule } from "../../../lib/api-client.js";
import { parseOrgProjectArg } from "../../../lib/arg-parsing.js";
import { buildCommand, numberParser } from "../../../lib/command.js";
import { ContextError, ValidationError } from "../../../lib/errors.js";
import { warning } from "../../../lib/formatters/colors.js";
import { CommandOutput } from "../../../lib/formatters/output.js";
import { DRY_RUN_ALIASES, DRY_RUN_FLAG } from "../../../lib/mutate-command.js";
import { resolveOrg } from "../../../lib/resolve-target.js";
import {
normalizeMetricDataset,
normalizeProjectList,
parseJsonObjectList,
resolveMetricDataset,
validateMetricDataset,
validateMetricTimeWindow,
validateMetricTriggers,
Expand Down Expand Up @@ -85,8 +86,8 @@ export const createCommand = buildCommand({
" --environment, --owner\n\n" +
"Examples:\n" +
" sentry alert metrics create my-org --name 'P95 latency' \\\n" +
" --query 'environment:prod' --aggregate 'p95(transaction.duration)' \\\n" +
" --dataset transactions --time-window 5 \\\n" +
" --query 'environment:prod' --aggregate 'p95(span.duration)' \\\n" +
" --dataset spans --time-window 5 \\\n" +
' --trigger \'{"alertThreshold":500,"actions":[{"id":"sentry.mail.actions.NotifyEmailAction","targetType":"Team","targetIdentifier":1}]}\'\n\n' +
" sentry alert metrics create my-org --name 'Error volume' \\\n" +
" --query 'event.type:error' --aggregate 'count()' --dataset errors \\\n" +
Expand Down Expand Up @@ -122,14 +123,13 @@ export const createCommand = buildCommand({
aggregate: {
kind: "parsed",
parse: String,
brief:
"Aggregate expression (for example count(), p95(transaction.duration))",
brief: "Aggregate expression (for example count(), p95(span.duration))",
},
dataset: {
kind: "parsed",
parse: String,
brief:
"Dataset: errors (error-events), transactions (transaction-like), sessions, events, spans, metrics",
"Dataset: errors (error-events), sessions, events, spans, metrics (transaction(s) routes to spans)",
},
"time-window": {
kind: "parsed",
Expand Down Expand Up @@ -178,9 +178,16 @@ export const createCommand = buildCommand({
throw new ValidationError("aggregate cannot be empty.", "aggregate");
}

const dataset = normalizeMetricDataset(flags.dataset);
const {
dataset,
query,
notice: datasetNotice,
} = resolveMetricDataset(flags.dataset, flags.query);
validateMetricDataset(dataset);
validateMetricTimeWindow(flags["time-window"]);
if (datasetNotice) {
this.stderr.write(`${warning(`Tip: ${datasetNotice}`)}\n`);
}

const triggers = parseJsonObjectList(flags.trigger, "trigger");
validateMetricTriggers(triggers);
Expand All @@ -196,7 +203,7 @@ export const createCommand = buildCommand({

const body: Record<string, unknown> = {
name: flags.name,
query: flags.query,
query,
aggregate: flags.aggregate,
dataset,
timeWindow: flags["time-window"],
Expand Down
28 changes: 20 additions & 8 deletions packages/cli/src/commands/alert/metrics/edit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import {
} from "../../../lib/api-client.js";
import { buildCommand, numberParser } from "../../../lib/command.js";
import { ValidationError } from "../../../lib/errors.js";
import { warning } from "../../../lib/formatters/colors.js";
import { CommandOutput } from "../../../lib/formatters/output.js";
import { resolveOrgOptionalProjectFromArg } from "../../../lib/resolve-target.js";
import {
normalizeMetricDataset,
normalizeProjectList,
parseJsonObjectList,
parseStatusFlag,
resolveMetricDataset,
statusToMetricValue,
validateMetricDataset,
validateMetricTimeWindow,
Expand Down Expand Up @@ -76,7 +78,8 @@ function validateMetricEditFlags(flags: EditFlags): void {
function applyMetricCoreFields(
body: Record<string, unknown>,
flags: EditFlags
): Record<string, unknown> {
): string | undefined {
let notice: string | undefined;
if (flags.name !== undefined) {
body.name = flags.name;
}
Expand All @@ -93,15 +96,21 @@ function applyMetricCoreFields(
body.aggregate = flags.aggregate;
}
if (flags.dataset !== undefined) {
const dataset = normalizeMetricDataset(flags.dataset);
validateMetricDataset(dataset);
body.dataset = dataset;
// Resolve against the effective query (the just-applied --query flag, or the
// rule's existing query) so a `transaction(s)` request routes to `spans`
// with `is_transaction:true` added even when --query is not also passed.
const currentQuery = typeof body.query === "string" ? body.query : "";
const resolved = resolveMetricDataset(flags.dataset, currentQuery);
validateMetricDataset(resolved.dataset);
body.dataset = resolved.dataset;
body.query = resolved.query;
notice = resolved.notice;
}
if (flags["time-window"] !== undefined) {
validateMetricTimeWindow(flags["time-window"]);
body.timeWindow = flags["time-window"];
}
return body;
return notice;
}

function applyMetricOptionalFields(
Expand Down Expand Up @@ -166,7 +175,7 @@ export const editCommand = buildCommand({
"Examples:\n" +
" sentry alert metrics edit my-org/9 --name 'Error budget'\n" +
" sentry alert metrics edit my-org/9 --status disabled\n" +
" sentry alert metrics edit my-org/9 --time-window 15 --dataset transactions",
" sentry alert metrics edit my-org/9 --time-window 15 --dataset spans",
},
output: {
human: formatEdited,
Expand Down Expand Up @@ -213,7 +222,7 @@ export const editCommand = buildCommand({
parse: String,
optional: true,
brief:
"Dataset: errors (error-events), transactions (transaction-like), sessions, events, spans, metrics",
"Dataset: errors (error-events), sessions, events, spans, metrics (transaction(s) routes to spans)",
},
"time-window": {
kind: "parsed",
Expand Down Expand Up @@ -271,9 +280,12 @@ export const editCommand = buildCommand({
const body = {
...(await getMetricAlertRuleDocument(orgSlug, rule.id)),
} as Record<string, unknown>;
applyMetricCoreFields(body, flags);
const datasetNotice = applyMetricCoreFields(body, flags);
applyMetricOptionalFields(body, flags);
validateMetricBody(body, flags);
if (datasetNotice) {
this.stderr.write(`${warning(`Tip: ${datasetNotice}`)}\n`);
}
const updated = await putMetricAlertRule(orgSlug, rule.id, body);
yield new CommandOutput({
...updated,
Expand Down
Loading
Loading