Skip to content

Commit 1a883b9

Browse files
feat: add send-event and send-envelope commands with DSN auth (#921)
## Summary Implements `sentry event send` for old sentry-cli parity. Ref #600. This is the first command in the new CLI that authenticates via a **DSN** (not a Bearer token), so no `sentry auth login` is needed — provide a DSN via `--dsn` or `SENTRY_DSN` env var. ### Command structure ``` sentry event send ← canonical (under the event group) sentry send-event ← hidden backward-compat alias sentry send-envelope ← hidden deprecation shim → suggests event send --raw ``` ### `sentry event send` Send a Sentry event from CLI flags or a JSON file: ```bash # From flags sentry event send -m "Something went wrong" -l error --tag env:prod # With breadcrumbs from a log file sentry event send -m "Install failed" --logfile /tmp/install.log --with-categories # From JSON file sentry event send ./event.json # Raw mode (send bytes as-is — also supports pre-built envelopes) sentry event send --raw ./captured.envelope ``` Full flag parity with old `sentry-cli send-event`: - `--message`, `--level`, `--release`, `--env`, `--tag`, `--extra`, `--user`, `--fingerprint`, `--timestamp`, `--dist`, `--platform`, `--no-environ` - `--logfile`, `--with-categories` (breadcrumbs from log files, used by self-hosted installer) - `--raw` (send file bytes as-is, replaces `send-envelope`) ### Design decisions - **`event send` under the event group** — follows the mutation pattern (`project create`, `issue resolve`). Discoverable via `sentry event --help`. - **`send-envelope` deprecated** — envelopes are a low-level concept; `--raw` covers the use case. Running `sentry send-envelope` throws with a clear message suggesting `sentry event send --raw <file>`. - **DSN auth** — `auth: "dsn"` on `buildCommand` skips the token guard and RC URL check. DSN resolved from `--dsn` flag or `SENTRY_DSN` env var. ### Shared infrastructure - `src/lib/envelope/transport.ts` — `requireDsn()`, `buildEnvelopeUrl()`, `sendEnvelopeRequest()`, `readFileBytes()` - `src/lib/envelope/event-builder.ts` — `buildEventFromFlags()`, `parseBreadcrumbsFromLogfile()` - Uses `@sentry/core` for envelope creation/serialization and DSN parsing — no new dependencies ### Tests 60 tests across 4 files: - `transport.test.ts` — URL construction, auth params, error handling, DSN whitespace trim - `event-builder.test.ts` — all flags, parseKeyValue, parseUserFields, parseTimestamp edge cases, logfile breadcrumbs (basic, with-categories, ENOENT, 100-cap) - `send.test.ts` — inline mode, JSON output, tags, missing DSN, ENOENT, --raw without files - `send-envelope.test.ts` — deprecation shim error message --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 4cfc841 commit 1a883b9

19 files changed

Lines changed: 1667 additions & 75 deletions

File tree

AGENTS.md

Lines changed: 85 additions & 55 deletions
Large diffs are not rendered by default.

docs/src/content/docs/contributing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ cli/
5555
│ │ ├── auth/ # login, logout, refresh, status, token, whoami
5656
│ │ ├── cli/ # defaults, feedback, fix, import, setup, upgrade
5757
│ │ ├── dashboard/ # list, view, create, add, edit, delete, revisions, restore
58-
│ │ ├── event/ # view, list
58+
│ │ ├── event/ # view, list, send
5959
│ │ ├── issue/ # list, events, explain, plan, view, resolve, unresolve, archive, merge
6060
│ │ ├── local/ # serve, run
6161
│ │ ├── log/ # list, view

docs/src/fragments/commands/event.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,57 @@
11

22

3+
34
## Examples
45

6+
### Sending Events
7+
8+
```bash
9+
# Send an error event (default level)
10+
sentry event send -m "Something went wrong"
11+
12+
# Specify level, release, and environment
13+
sentry event send -m "Deploy check" -l info -r 1.0.0 -E production
14+
15+
# Add tags and extra data
16+
sentry event send -m "Payment failed" --tag env:prod --tag region:us-east --extra amount:99.99
17+
18+
# Set user context
19+
sentry event send -m "Login error" --user id:42 --user email:alice@example.com
20+
21+
# Custom fingerprint to group related events together
22+
sentry event send -m "DB timeout" --fingerprint db-timeout --fingerprint {{ default }}
23+
```
24+
25+
### Send from a JSON file
26+
27+
```bash
28+
# Send a serialized Sentry Event object
29+
sentry event send ./crash.json
30+
31+
# Send without re-parsing (raw mode — also supports pre-built envelopes)
32+
sentry event send --raw ./crash.json
33+
sentry event send --raw ./captured.envelope
34+
```
35+
36+
### DSN authentication
37+
38+
`sentry event send` authenticates via a **DSN** rather than a user token.
39+
No `sentry auth login` is required.
40+
41+
The DSN is resolved in priority order:
42+
43+
1. `--dsn <value>` flag (explicit)
44+
2. `SENTRY_DSN` environment variable
45+
46+
```bash
47+
# Explicit DSN
48+
sentry event send -m "Test" --dsn "https://key@o123.ingest.us.sentry.io/456"
49+
50+
# Via environment variable
51+
export SENTRY_DSN="https://key@o123.ingest.us.sentry.io/456"
52+
sentry event send -m "Test"
53+
```
54+
555
### Listing Events
656

757
```bash
@@ -68,3 +118,11 @@ Event IDs can be found:
68118
1. In the Sentry UI when viewing an issue's events
69119
2. In the output of `sentry issue view` commands
70120
3. In error reports sent to Sentry (as `event_id`)
121+
122+
## Backward compatibility
123+
124+
The old sentry-cli top-level command is available as a hidden alias:
125+
126+
```bash
127+
sentry send-event # same as: sentry event send
128+
```

plugins/sentry-cli/skills/sentry-cli/SKILL.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,11 @@ Manage Sentry issues
323323

324324
### Event
325325

326-
View and list Sentry events
326+
View, list, and send Sentry events
327327

328328
- `sentry event view <org/project/event-id...>` — View details of one or more events
329329
- `sentry event list <issue>` — List events for an issue
330+
- `sentry event send <args...>` — Send a Sentry event
330331

331332
→ Full flags and examples: `references/event.md`
332333

plugins/sentry-cli/skills/sentry-cli/references/event.md

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
---
22
name: sentry-cli-event
33
version: 0.36.0-dev.0
4-
description: View and list Sentry events
4+
description: View, list, and send Sentry events
55
requires:
66
bins: ["sentry"]
77
auth: true
88
---
99

1010
# Event Commands
1111

12-
View and list Sentry events
12+
View, list, and send Sentry events
1313

1414
### `sentry event view <org/project/event-id...>`
1515

@@ -87,4 +87,62 @@ sentry event list PROJ-ABC -c prev
8787
sentry event list PROJ-ABC --json
8888
```
8989

90+
### `sentry event send <args...>`
91+
92+
Send a Sentry event
93+
94+
**Flags:**
95+
- `--dsn <value> - DSN to send events to (overrides SENTRY_DSN env var)`
96+
- `-m, --message <value>... - Event message (repeat for multi-line)`
97+
- `-a, --message-arg <value>... - Arguments for message template (repeat for multiple)`
98+
- `-l, --level <value> - Event severity level - (default: "error")`
99+
- `-r, --release <value> - Release version`
100+
- `-d, --dist <value> - Distribution identifier`
101+
- `-E, --env <value> - Environment name (e.g. production, staging)`
102+
- `-p, --platform <value> - Platform identifier (default: other)`
103+
- `-t, --tag <value>... - Tag as KEY:VALUE (repeat for multiple)`
104+
- `-e, --extra <value>... - Extra data as KEY:VALUE (repeat for multiple)`
105+
- `-u, --user <value>... - User info as KEY:VALUE — id, email, username, ip_address, or custom`
106+
- `-f, --fingerprint <value>... - Custom fingerprint part (repeat for multiple)`
107+
- `--timestamp <value> - Event timestamp (Unix epoch, ISO 8601, or RFC 2822)`
108+
- `--no-environ - Do not include environment variables in the event`
109+
- `--logfile <value> - Path to a log file — last 100 lines are attached as breadcrumbs`
110+
- `--with-categories - Parse 'CATEGORY: message' prefixes from logfile breadcrumbs`
111+
- `--raw - Send file contents as-is without parsing`
112+
113+
**Examples:**
114+
115+
```bash
116+
# Send an error event (default level)
117+
sentry event send -m "Something went wrong"
118+
119+
# Specify level, release, and environment
120+
sentry event send -m "Deploy check" -l info -r 1.0.0 -E production
121+
122+
# Add tags and extra data
123+
sentry event send -m "Payment failed" --tag env:prod --tag region:us-east --extra amount:99.99
124+
125+
# Set user context
126+
sentry event send -m "Login error" --user id:42 --user email:alice@example.com
127+
128+
# Custom fingerprint to group related events together
129+
sentry event send -m "DB timeout" --fingerprint db-timeout --fingerprint {{ default }}
130+
131+
# Send a serialized Sentry Event object
132+
sentry event send ./crash.json
133+
134+
# Send without re-parsing (raw mode — also supports pre-built envelopes)
135+
sentry event send --raw ./crash.json
136+
sentry event send --raw ./captured.envelope
137+
138+
# Explicit DSN
139+
sentry event send -m "Test" --dsn "https://key@o123.ingest.us.sentry.io/456"
140+
141+
# Via environment variable
142+
export SENTRY_DSN="https://key@o123.ingest.us.sentry.io/456"
143+
sentry event send -m "Test"
144+
145+
sentry send-event # same as: sentry event send
146+
```
147+
90148
All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags.

src/app.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import { listCommand as replayListCommand } from "./commands/replay/list.js";
3232
import { repoRoute } from "./commands/repo/index.js";
3333
import { listCommand as repoListCommand } from "./commands/repo/list.js";
3434
import { schemaCommand } from "./commands/schema.js";
35+
import { sendEnvelopeCommand } from "./commands/send-envelope.js";
36+
import { sendEventCommand } from "./commands/send-event.js";
3537
import { sourcemapRoute } from "./commands/sourcemap/index.js";
3638
import { spanRoute } from "./commands/span/index.js";
3739
import { listCommand as spanListCommand } from "./commands/span/list.js";
@@ -107,6 +109,9 @@ export const routes = buildRouteMap({
107109
local: localRoute,
108110
api: apiCommand,
109111
schema: schemaCommand,
112+
// Backward-compat aliases for old sentry-cli — hidden from help
113+
"send-event": sendEventCommand,
114+
"send-envelope": sendEnvelopeCommand,
110115
dashboards: dashboardListCommand,
111116
issues: issueListCommand,
112117
orgs: orgListCommand,
@@ -143,6 +148,8 @@ export const routes = buildRouteMap({
143148
trials: true,
144149
sourcemaps: true,
145150
whoami: true,
151+
"send-event": true,
152+
"send-envelope": true,
146153
},
147154
},
148155
});

src/commands/event/index.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
import { buildRouteMap } from "../../lib/route-map.js";
22
import { listCommand } from "./list.js";
3+
import { sendCommand } from "./send.js";
34
import { viewCommand } from "./view.js";
45

56
export const eventRoute = buildRouteMap({
67
routes: {
78
view: viewCommand,
89
list: listCommand,
10+
send: sendCommand,
911
},
1012
defaultCommand: "view",
1113
docs: {
12-
brief: "View and list Sentry events",
14+
brief: "View, list, and send Sentry events",
1315
fullDescription:
14-
"View and list event data from Sentry.\n\n" +
16+
"View, list, and send event data from Sentry.\n\n" +
1517
"Use 'sentry event view <event-id>' to view a specific event.\n" +
16-
"Use 'sentry event list <issue-id>' to list events for an issue.",
18+
"Use 'sentry event list <issue-id>' to list events for an issue.\n" +
19+
"Use 'sentry event send -m <message>' to send a test event.",
1720
hideRoute: {},
1821
},
1922
});

0 commit comments

Comments
 (0)