Sentry
Egy DSN beállítása után a sentryx a Sentry hibariportolást a slog-on és az OpenTelemetryn keresztül kapcsolja be. Ez nem technikai apróság, hanem a lényeg: mivel a httperr handlerek, a chi panic-recovery és a worker már ma is slog-on, trace-hordozó contexttel logolnak minden 5xx-et és task-hibát, egyetlen slog-handler bekötése az összes belépési pontot lefedi: a te kódodban semmi Sentry-specifikus nincs.
Bekapcsolás:
SENTRY_DSN=https://<key>@<org>.ingest.sentry.io/<project>
Ennyi. SENTRY_DSN nélkül az integráció teljesen ki van kapcsolva: minden hook no-op, a viselkedés azonos egy Sentry nélküli kittel.
Konfiguráció
| Változó | Default | Jelentés |
|---|---|---|
SENTRY_DSN | üres | projekt DSN; üresen az integráció teljesen ki |
SENTRY_ENVIRONMENT | dev → development, egyébként production | environment tag minden eventen |
SENTRY_TRACES | true | a kit OTel spanjeinek küldése a Sentrybe; false, ha a collectorod továbbítja őket |
SENTRY_DEBUG | false | a Sentry SDK saját debug-logja stderr-re |
A release minden eventen <service>@<verzió> (az OTEL_SERVICE_NAME / OTEL_SERVICE_VERSION értékéből), a Sentry release-követése külön beállítás nélkül működik.
Az OTel tetején, nem helyette
A sentryx nem hoz saját trace-elést, saját middleware-hálót, saját mérést: az OTel marad a gerinc, a Sentry három ponton csatlakozik rá. Mindhármat a telemetry.Setup drótozza be, te sosem hívod a sentryx.Setup-ot:
- Spanek → Sentry. A
Handle.SpanExporter()egy plusz exporterként kerül azotelxtracer providerére (otelx.WithSpanExporter): ugyanazok a spanek mennek a collectorodba és a Sentrybe. A hiba így a teljes trace-waterfallhoz linkelődik: a HTTP-span, minden DB-query az idejével, a queue-taskok. A sampling OTel-vezérelt marad (OTEL_TRACES_SAMPLER), nincs külön Sentry sample rate. - Hibák → Sentry. A
Handle.SlogHandler()a log-fanout egyik ága: mindenERROR-szintű rekord Sentry event lesz. A rekord első hiba-értékű attr-ja a captured exception; egyerrshiba a keletkezési pontján rögzített stackjét, kódját, publikus üzenetét és wrap-láncát is magával viszi (az eventerrscontextjében). Az alacsonyabb szintű rekordok (DEBUG/INFO/WARN) breadcrumb-ként gyűlnek, így az event alatt ott a hozzá vezető log-nyomvonal, aLOG_LEVEL-t ugyanúgy tisztelik, mint bármely sink. - Hiba ↔ trace linkelés. Az OTel-integráció minden eventre rábélyegzi az aktív trace/span ID-t, így a hiba a helyes spanre kerül a waterfallban.
A breadcrumb-izoláció kérésenkénti: a chassis minden belépési ponton (chi middleware, worker task-middleware) meghívja a sentryx.WithRequestHub-ot, ami a contextre egy friss, klónozott hubot tesz, így az egyik kérés logsorai nem szivárognak át a másik kérés eventjébe. Hub nélküli contextben (pl. egy saját goroutine context.Background()-dal) a breadcrumb-ok inkább eldobódnak, mint hogy a globális hubot szennyezzék.
Egy hiba = egy issue: az errs-kód mint fingerprint
A Sentry alapból a legkülső exception típusa szerint címez és csoportosít. Go-ban ez a típusnév lenne, és mivel egy errs-lánc minden szintje ugyanazt a *errs.Error típust hordozza, minden hibád egyetlen *errs.Error nevű issue-ba folyna össze. A sentryx ezért küldés előtt átírja az eventet:
- Az issue címe a hiba
errs-kódja lesz (kód híján a legkülső wrap-üzenete). - A kód a grouping fingerprint is: egy deklarált hiba minden előfordulása egy issue-ba csoportosul, függetlenül attól, hány különböző kódútvonalon keletkezett.
- A másodlagos sor a
Publicüzenet (ha van): az issue-listakód / kliens felé mutatott szövegformában olvasható, a teljes belső lánc egy kattintásra, az eventerrscontextjében.
A shop kanonikus hibáján ez így fest:
var ErrOutOfStock = errs.Define("shop_out_of_stock",
errs.Public("Egy vagy több tétel nincs elegendő készleten."))
// repository:
return ErrOutOfStock.New("inventory: decrement: insufficient stock")
// service:
return errs.Wrap(err, "shop: place order")
Akárhány rendelés bukik el, akárhogy alakul közben a stack, a Sentryben egyetlen issue: shop_out_of_stock, alatta a publikus üzenettel, minden eventjén a teljes stackkel, a wrap-lánccal, a request breadcrumb-jaival és a trace-linkkel. Amikor pedig eldöntitek, hogy a készlethiány nem incidens, hanem elvárt kliens-viselkedés, adjatok a definícióhoz errs.Status(http.StatusConflict)-ot: onnantól 409-ként megy ki, és se request failed logsor, se Sentry event nem születik belőle, az issue magától elhal.
Dev módban is működik: collector nélkül
OTEL_DEV_MODE=true mellett az OTel nem épít exportert, de ha a SENTRY_DSN be van állítva, a kit egy Sentry-only tracer providert húz fel, így lokálisan, mindenféle collector nélkül megkapod a teljes trace-t és a hibát a Sentryben. Ez a legolcsóbb módja annak, hogy a „kövesd a rendelést" trace-t élőben lásd: dev mód + egy dev Sentry-projekt DSN-je.
Miért wrapper: a kivétel, ami erősíti a szabályt
A kit elve a centralizál, nem absztrahál, és a sentryx a három kimondott kivétel egyike: a sentry-go-t tényleg becsomagolja. Az ok az elhagyhatóság. A Sentry opcionális integráció: env-ből kapcsolható, és mivel kizárólag a telemetry facade és a chassis importálja a sentryx-et, egy nem-chassis bináris (CLI, migrátor, bármi, ami csak otelx-et vagy dbx-et használ) be sem linkeli a sentry-go-t. Ha a sentry-go típusok átfolynának a kit API-ján, ez a garancia elveszne. A napi munkában amúgy sem hívod: a hibáid a return err-rel jutnak el a Sentrybe.
Az API ettől még ott van, ha kell (a telemetry is ezen keresztül dolgozik):
func Setup(ctx context.Context, cfg Config, serviceName, serviceVersion string, dev bool) (*Handle, error)
func (h *Handle) Enabled() bool
func (h *Handle) SpanExporter() sdktrace.SpanExporter // nil, ha ki van kapcsolva / SENTRY_TRACES=false
func (h *Handle) SlogHandler() slog.Handler // nil, ha ki van kapcsolva
func (h *Handle) Flush(ctx context.Context) error // event-transport drain
func WithRequestHub(ctx context.Context) context.Context // kérésenkénti hub, a chassis hívja
Flush a legvégén
A Sentry event-transportja aszinkron: a capture sosem blokkolja a kérést. A lezárást a telemetria-shutdown intézi: a Flush az OTel providerek leállása után fut, legutolsóként az életciklusban, így a leállás közben keletkező hibák is kimennek, mielőtt a processz kilép.
Használt patternek
A sentryx a kit három kimondott interfész-mögé-rejtési kivételének egyike; lásd Design patternek: Architekturális alapelvek. A WithSpanExporter-be illesztés a functional options nil-toleráns variánsának konkrét példája.
A Sentry hivatalos Go-dokumentációja: docs.sentry.io/platforms/go.