telemetry

Logolás

Hogyan komponálja a telemetry.Setup a default slog loggert a logx-ből, az OTel log-bridge-ből és a Sentry handlerből.

A gpsystemben a default log/slog logger nem csak egy handler: a telemetry.Setup egy rekordot egyszerre három sinkbe fanoutol, egyetlen minimum-szint szűrő mögött. Az alkalmazáskód kizárólag a standard log/slog-ot importálja, semmi framework-specifikusat; maga a kompozíció az önálló logx modulból épül.

A kompozíció

A telemetry.Setup pontosan így építi a default loggert:

slog.SetDefault(slog.New(
    logx.LevelFilter(cfg.Log.Level, logx.Fanout(
        logx.ConsoleHandler(os.Stdout, cfg.Log, dev, serviceName), // dev vagy LOG_STDOUT esetén
        otelHandle.SlogHandler(),   // OTLP bridge, prodban
        sentryHandle.SlogHandler(), // Sentry capture, ha a DSN be van állítva
    )),
))

A LevelFilter azért ül legkívül, mert nem minden leaf-handler szűr magától: az OTLP bridge például mindent továbbít, amit kap. A Fanout minden handlernek a rekord saját klónját adja, és az Enabled-et handlerenkénti gate-ként tiszteli: egyetlen handler esetén allokáció nélkül, önmagaként tér vissza. Mindkét kombinátor, és maga a konzol-handler is, a logx-ből jön; a telemetry csak a másik két handlert adja (az OTel-bridge-et, a Sentry capture handlert), és a hármat drótozza össze, ez az oldal pontosan erről szól.

Ez a kompozíció csak azt változtatja, hova megy egy rekord, a formáját nem. A LOG_FORMAT (egy logx.Config mező) csak a konzol-handler renderelését választja ki: az OTLP-bridge és a Sentry-handler mindig ugyanazt a strukturált rekordot kapja.

Chassis-on belül ezt sosem írod meg: a server.Run / worker.Run / realtime.Run megkapja készen. Ha egy nem-chassis binárisban (CLI, migrátor) ugyanezt a konzol-élményt akarod, vagy egy saját plusz sinket (pl. fájl-handlert) fűznél a fanoutba, nyúlj közvetlenül a logx-hez: a Config mezők és a ConsoleHandler/LevelFilter/Fanout kompozíció önállóan, a logx: Áttekintés oldalon van dokumentálva.

A Monolog-formátumú dev konzol

A LOG_FORMAT=monolog-gal (dev módban ezt érdemes) a konzol PHP/Monolog-stílusú sorokat renderel, [dátum] channel.SZINT: üzenet {context}, alatta egy errs hibából kinyert, teljes útvonalú, PHP-ból ismerős stack trace-szel. Ez a formázó a logx/monolog, és a logx többi részével együtt önálló modulba költözött: maga a formátum, a Laravel/Symfony-fogalommegfeleltetés és a "miért csak stdout" indoklás a logx: Monolog-formázó oldalon van.

(Dev módban a kérésenkénti access-log sorokat a framework strukturált slog access logja írja (az accesslog stack-bejegyzés), így követik a LOG_FORMAT-ot, és az OTel bridge-en át ugyanúgy trace-korreláltak, mint minden más rekord.)

Hogyan logolj a service-ekben

Két szabály van, és mindkettő a context.Context-ről szól:

func (s *OrderService) PlaceOrder(ctx context.Context, in PlaceOrder) error {
    // 1. Mindig a *Context változatot, a kérés ctx-ével:
    slog.InfoContext(ctx, "order placed",
        slog.String("order_id", order.ID),
        slog.Int("total", order.Total))
    // ...
}
  1. slog.InfoContext / WarnContext / ErrorContext, sosem slog.Info. A ctx hordozza az aktív trace-t: az otelslog bridge ebből fűzi a trace/span ID-t a rekordhoz, a Sentry handler ebből linkeli a hibát a trace waterfallhoz, és a breadcrumb-ok is a kérés hubjára kerülnek. Ctx nélküli log = korrelálatlan log.
  2. Hibát slog.Any("error", err)-rel adj át, ne err.Error() stringgel: így marad meg a strukturált lánc, a stack és a kód minden sink számára, konzol, OTLP és Sentry egyaránt.

Loggert injektálni, konstruálni, DI-ba kötni nem kell: a chassis a slog.Default()-ot állítja be, a csomag-szintű slog.*Context hívások pont jók. Az ERROR szint pedig nem „hangos log": az egyben Sentry event is: 5xx-et a framework logol helyetted, te akkor logolj ERROR-t, ha valami tényleg incidens.

A várható, kliens-hibás kimeneteket (404, 409, validáció) nem logolod és nem is kell: egy státusz-mappelt errs hiba 4xx-ként megy ki, request failed sor és Sentry event nélkül.

Merre tovább

  • logx: Áttekintés: a Config mezők (LOG_LEVEL/LOG_STDOUT/LOG_FORMAT), és a ConsoleHandler/LevelFilter/Fanout önálló használathoz, telemetry nélkül.
  • logx: Monolog-formázó: a PHP-stílusú dev konzolformátum, teljes egészében, a Laravel/Symfony-fogalommegfeleltetéssel.
  • OpenTelemetry: az OTLP log-bridge, amibe ez az oldal fanoutja táplál.
  • Sentry: a capture handler, amibe ez az oldal fanoutja táplál, és a kód-alapú issue-csoportosítás.
Copyright © 2026