|
| 1 | +# Sentry Go SDK |
| 2 | + |
| 3 | +Single-module Go SDK with integration sub-modules in `github.com/getsentry/sentry-go`. |
| 4 | + |
| 5 | +## Commit Attribution |
| 6 | + |
| 7 | +AI commits MUST include: |
| 8 | + |
| 9 | +``` |
| 10 | +Co-Authored-By: <agent model name> <agent-email-or-noreply@example.com> |
| 11 | +``` |
| 12 | + |
| 13 | +## Before Every Commit |
| 14 | + |
| 15 | +1. `make fmt` 2. `make lint` 3. `make vet` 4. `make test-race` |
| 16 | + |
| 17 | +## Architecture |
| 18 | + |
| 19 | +### Core (`/`) |
| 20 | + |
| 21 | +The root package `sentry` contains the entire public API. |
| 22 | + |
| 23 | +### Attribute Package (`/attribute/`) |
| 24 | + |
| 25 | +Type-safe key-value builders used by structured logging and metrics: |
| 26 | + |
| 27 | +```go |
| 28 | +attribute.String("key", "value") |
| 29 | +attribute.Int("count", 42) |
| 30 | +attribute.Float64("ratio", 0.5) |
| 31 | +attribute.Bool("flag", true) |
| 32 | +``` |
| 33 | + |
| 34 | +### Integration Sub-Modules |
| 35 | + |
| 36 | +Each lives in its own directory with a separate `go.mod`: |
| 37 | + |
| 38 | +- **HTTP middleware** — `http/`, `gin/`, `echo/`, `fiber/`, `fasthttp/`, `iris/`, `negroni/` |
| 39 | +- **Logging hooks** — `logrus/`, `zerolog/`, `zap/`, `slog/` |
| 40 | +- **Instrumentation** — `httpclient/`, `otel/` |
| 41 | + |
| 42 | +When adding a new integration, mirror an existing one. |
| 43 | + |
| 44 | +### Transport Architecture |
| 45 | + |
| 46 | +**Current: `transport.go` (active)** — `HTTPTransport` is the default implementation of an async transport. `HTTPSyncTransport` is the blocking variant for serverless. |
| 47 | + |
| 48 | +**Next: `internal/telemetry/` + `internal/http/` (not yet enabled)** — Processor/buffer/scheduler architecture. Wired up in `client.go` (`setupTelemetryProcessor`) but **commented out** behind `DisableTelemetryBuffer`. Key parts: |
| 49 | + |
| 50 | +- `internal/telemetry/processor.go` — orchestrator; routes items to category-specific buffers |
| 51 | +- `internal/telemetry/scheduler.go` — weighted round-robin; errors get 5x priority over logs |
| 52 | +- `internal/telemetry/ring_buffer.go` — circular buffer with overflow policies and batch/timeout flushing |
| 53 | +- `internal/telemetry/bucketed_buffer.go` — groups items by trace ID |
| 54 | +- `internal/http/transport.go` — `AsyncTransport` with `HasCapacity()` backpressure |
| 55 | +- `internal/protocol/` — `Envelope`, `TelemetryItem` interfaces; log/metric batch types |
| 56 | + |
| 57 | +The `internalAsyncTransportAdapter` in `transport.go` bridges old `Transport` to new `TelemetryTransport`. |
| 58 | + |
| 59 | +## Coding Standards |
| 60 | + |
| 61 | +- Follow existing conventions — check neighboring files first |
| 62 | +- Maintain existing Go versions and dependencies unless explicitly asked to change them |
| 63 | +- `gofmt -s` formatting, doc comments on exports |
| 64 | +- Public API in root package; internals in `/internal` |
| 65 | +- Thread safety required — guard shared state with mutexes |
| 66 | +- Update tests when modifying behavior |
| 67 | + |
| 68 | +## Testing |
| 69 | + |
| 70 | +Test tier preference (use the highest tier that covers what you need): |
| 71 | + |
| 72 | +1. **Integration tests** (default) — `sentry.Init` with `BeforeSend` callbacks, `httptest.Server` with real framework routers, `sentry.Flush` to collect events. Prefer tests that use the public API. |
| 73 | +2. **Context-level tests** — `NewTestContext` with `MockTransport` for span/transaction behavior when no HTTP server is needed. |
| 74 | +3. **Unit tests** (sparingly) — Direct `NewClient` + `MockScope` only for self-contained logic like `BeforeSend` callbacks or sampling decisions. |
| 75 | + |
| 76 | +Conventions: |
| 77 | + |
| 78 | +- Table-driven tests for multiple inputs through the same code path |
| 79 | +- `t.Parallel()` for tests that don't share global state |
| 80 | +- `cmp.Diff` with `cmpopts.IgnoreFields` for `*Event` comparison — ignore `EventID`, `Timestamp`, `Sdk`, `sdkMetaData` |
| 81 | +- `testutils.FlushTimeout()` when calling `sentry.Flush` (longer timeout in CI) |
| 82 | +- `testify` for assertions, `internal/testutils/` for mocks |
| 83 | +- All tests must pass `make test-race` |
| 84 | + |
| 85 | +What to test: |
| 86 | + |
| 87 | +- Behavior users observe: Does middleware capture panics? Does `Flush` deliver events? Do trace headers propagate? |
| 88 | +- Edge cases at system boundaries: malformed DSN, nil `Hub`, concurrent captures, context cancellation |
| 89 | +- Regressions: reproduce the failure before applying the fix |
| 90 | + |
| 91 | +Thread safety: |
| 92 | + |
| 93 | +- The SDK is used concurrently. Any test touching shared state (`Hub`, `Scope`, `CurrentHub`) must either use `t.Parallel()` with isolated instances, or explicitly verify safety with goroutines and `sync.WaitGroup`. |
| 94 | + |
| 95 | +## Reference |
| 96 | + |
| 97 | +- [SDK Development Guide](https://develop.sentry.dev/sdk/) |
| 98 | +- [Commit Guidelines](https://develop.sentry.dev/engineering-practices/commit-messages/) |
| 99 | +- [Hubs & Scopes](https://develop.sentry.dev/sdk/unified-api/#hub) |
| 100 | + |
| 101 | +## Skills |
| 102 | + |
| 103 | +- `/commit` — Commit with Sentry conventional format |
| 104 | +- `/create-pr` — Create PRs following Sentry conventions |
| 105 | +- `/code-review` — Review PRs following Sentry practices |
| 106 | +- `/find-bugs` — Audit local changes for bugs and security issues |
0 commit comments