[{"data":1,"prerenderedAt":1102},["ShallowReactive",2],{"navigation_docs_en":3,"-en-observability-overview":342,"-en-observability-overview-surround":1097},[4,45,61,96,132,166,196,217,241,265],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":44},"Getting Started","i-lucide-rocket","\u002Fen\u002Fgetting-started","en\u002F1.getting-started",[10,15,20,24,29,34,39],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fen\u002Fgetting-started\u002Fintroduction","en\u002F1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Coming from Laravel","\u002Fen\u002Fgetting-started\u002Fcoming-from-laravel","en\u002F1.getting-started\u002F2.coming-from-laravel","i-lucide-arrow-right-left",{"title":21,"path":22,"stem":23,"icon":19},"Coming from Symfony","\u002Fen\u002Fgetting-started\u002Fcoming-from-symfony","en\u002F1.getting-started\u002F3.coming-from-symfony",{"title":25,"path":26,"stem":27,"icon":28},"Installation","\u002Fen\u002Fgetting-started\u002Finstallation","en\u002F1.getting-started\u002F4.installation","i-lucide-download",{"title":30,"path":31,"stem":32,"icon":33},"Your first module","\u002Fen\u002Fgetting-started\u002Ffirst-module","en\u002F1.getting-started\u002F5.first-module","i-lucide-package-plus",{"title":35,"path":36,"stem":37,"icon":38},"Project structure","\u002Fen\u002Fgetting-started\u002Fproject-structure","en\u002F1.getting-started\u002F6.project-structure","i-lucide-folder-tree",{"title":40,"path":41,"stem":42,"icon":43},"The shop sample application","\u002Fen\u002Fgetting-started\u002Fsample-app","en\u002F1.getting-started\u002F7.sample-app","i-lucide-shopping-cart",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"Reference","i-lucide-book-open","\u002Fen\u002Freference","en\u002F10.reference",[51,56],{"title":52,"path":53,"stem":54,"icon":55},"Configuration","\u002Fen\u002Freference\u002Fconfiguration","en\u002F10.reference\u002F1.configuration","i-lucide-settings",{"title":57,"path":58,"stem":59,"icon":60},"External dependencies","\u002Fen\u002Freference\u002Fdependencies","en\u002F10.reference\u002F2.dependencies","i-lucide-package",{"title":62,"icon":63,"path":64,"stem":65,"children":66,"page":44},"Concepts","i-lucide-lightbulb","\u002Fen\u002Fconcepts","en\u002F2.concepts",[67,72,77,82,86,91],{"title":68,"path":69,"stem":70,"icon":71},"Architecture","\u002Fen\u002Fconcepts\u002Farchitecture","en\u002F2.concepts\u002F1.architecture","i-lucide-layers",{"title":73,"path":74,"stem":75,"icon":76},"Application lifecycle","\u002Fen\u002Fconcepts\u002Fapplication-lifecycle","en\u002F2.concepts\u002F2.application-lifecycle","i-lucide-power",{"title":78,"path":79,"stem":80,"icon":81},"Error model","\u002Fen\u002Fconcepts\u002Ferror-model","en\u002F2.concepts\u002F3.error-model","i-lucide-shield-alert",{"title":52,"path":83,"stem":84,"icon":85},"\u002Fen\u002Fconcepts\u002Fconfiguration","en\u002F2.concepts\u002F4.configuration","i-lucide-settings-2",{"title":87,"path":88,"stem":89,"icon":90},"Codegen pipeline","\u002Fen\u002Fconcepts\u002Fcodegen-pipeline","en\u002F2.concepts\u002F5.codegen-pipeline","i-lucide-file-json",{"title":92,"path":93,"stem":94,"icon":95},"Design patterns","\u002Fen\u002Fconcepts\u002Fdesign-patterns","en\u002F2.concepts\u002F6.design-patterns","i-lucide-puzzle",{"title":97,"icon":98,"path":99,"stem":100,"children":101,"page":44},"HTTP & Routing","i-lucide-globe","\u002Fen\u002Fhttp","en\u002F3.http",[102,107,112,117,122,127],{"title":103,"path":104,"stem":105,"icon":106},"The server core","\u002Fen\u002Fhttp\u002Fserver","en\u002F3.http\u002F1.server","i-lucide-server",{"title":108,"path":109,"stem":110,"icon":111},"The Fiber engine","\u002Fen\u002Fhttp\u002Ffiber","en\u002F3.http\u002F2.fiber","i-lucide-zap",{"title":113,"path":114,"stem":115,"icon":116},"The chi engine","\u002Fen\u002Fhttp\u002Fchi","en\u002F3.http\u002F3.chi","i-lucide-route",{"title":118,"path":119,"stem":120,"icon":121},"Error responses","\u002Fen\u002Fhttp\u002Ferror-responses","en\u002F3.http\u002F4.error-responses","i-lucide-octagon-alert",{"title":123,"path":124,"stem":125,"icon":126},"Validation","\u002Fen\u002Fhttp\u002Fvalidation","en\u002F3.http\u002F5.validation","i-lucide-badge-check",{"title":128,"path":129,"stem":130,"icon":131},"Pagination","\u002Fen\u002Fhttp\u002Fpagination","en\u002F3.http\u002F6.pagination","i-lucide-list-ordered",{"title":133,"icon":134,"path":135,"stem":136,"children":137,"page":44},"Database","i-lucide-database","\u002Fen\u002Fdatabase","en\u002F4.database",[138,142,147,151,156,161],{"title":139,"path":140,"stem":141,"icon":134},"Overview","\u002Fen\u002Fdatabase\u002Foverview","en\u002F4.database\u002F1.overview",{"title":143,"path":144,"stem":145,"icon":146},"pgx","\u002Fen\u002Fdatabase\u002Fpgx","en\u002F4.database\u002F2.pgx","i-lucide-plug",{"title":148,"path":149,"stem":150,"icon":71},"bun","\u002Fen\u002Fdatabase\u002Fbun","en\u002F4.database\u002F3.bun",{"title":152,"path":153,"stem":154,"icon":155},"Transactions","\u002Fen\u002Fdatabase\u002Ftransactions","en\u002F4.database\u002F4.transactions","i-lucide-git-merge",{"title":157,"path":158,"stem":159,"icon":160},"Migrations","\u002Fen\u002Fdatabase\u002Fmigrations","en\u002F4.database\u002F5.migrations","i-lucide-file-stack",{"title":162,"path":163,"stem":164,"icon":165},"Seeders","\u002Fen\u002Fdatabase\u002Fseeding","en\u002F4.database\u002F6.seeding","i-lucide-sprout",{"title":167,"icon":168,"path":169,"stem":170,"children":171,"page":44},"Async & Background","i-lucide-workflow","\u002Fen\u002Fasync","en\u002F5.async",[172,176,181,186,191],{"title":173,"path":174,"stem":175,"icon":131},"Queue","\u002Fen\u002Fasync\u002Fqueue","en\u002F5.async\u002F1.queue",{"title":177,"path":178,"stem":179,"icon":180},"Events","\u002Fen\u002Fasync\u002Fevents","en\u002F5.async\u002F2.events","i-lucide-radio",{"title":182,"path":183,"stem":184,"icon":185},"Outbox","\u002Fen\u002Fasync\u002Foutbox","en\u002F5.async\u002F3.outbox","i-lucide-inbox",{"title":187,"path":188,"stem":189,"icon":190},"Scheduling","\u002Fen\u002Fasync\u002Fscheduler","en\u002F5.async\u002F4.scheduler","i-lucide-calendar-clock",{"title":192,"path":193,"stem":194,"icon":195},"Worker","\u002Fen\u002Fasync\u002Fworker","en\u002F5.async\u002F5.worker","i-lucide-cog",{"title":197,"icon":198,"path":199,"stem":200,"children":201,"page":44},"Security","i-lucide-shield-check","\u002Fen\u002Fsecurity","en\u002F6.security",[202,207,212],{"title":203,"path":204,"stem":205,"icon":206},"Authentication","\u002Fen\u002Fsecurity\u002Fauthentication","en\u002F6.security\u002F1.authentication","i-lucide-key-round",{"title":208,"path":209,"stem":210,"icon":211},"RBAC","\u002Fen\u002Fsecurity\u002Frbac","en\u002F6.security\u002F2.rbac","i-lucide-users",{"title":213,"path":214,"stem":215,"icon":216},"Policies","\u002Fen\u002Fsecurity\u002Fpolicies","en\u002F6.security\u002F3.policies","i-lucide-gavel",{"title":218,"icon":219,"path":220,"stem":221,"children":222,"page":44},"Observability","i-lucide-activity","\u002Fen\u002Fobservability","en\u002F7.observability",[223,226,231,236],{"title":139,"path":224,"stem":225,"icon":219},"\u002Fen\u002Fobservability\u002Foverview","en\u002F7.observability\u002F1.overview",{"title":227,"path":228,"stem":229,"icon":230},"Logging","\u002Fen\u002Fobservability\u002Flogging","en\u002F7.observability\u002F2.logging","i-lucide-scroll-text",{"title":232,"path":233,"stem":234,"icon":235},"OpenTelemetry","\u002Fen\u002Fobservability\u002Fopentelemetry","en\u002F7.observability\u002F3.opentelemetry","i-lucide-radar",{"title":237,"path":238,"stem":239,"icon":240},"Sentry","\u002Fen\u002Fobservability\u002Fsentry","en\u002F7.observability\u002F4.sentry","i-lucide-bug",{"title":242,"icon":243,"path":244,"stem":245,"children":246,"page":44},"Storage & Mail","i-lucide-hard-drive","\u002Fen\u002Fstorage-mail","en\u002F8.storage-mail",[247,251,256,261],{"title":248,"path":249,"stem":250,"icon":243},"Storage","\u002Fen\u002Fstorage-mail\u002Fstorage","en\u002F8.storage-mail\u002F1.storage",{"title":252,"path":253,"stem":254,"icon":255},"Email","\u002Fen\u002Fstorage-mail\u002Fmail","en\u002F8.storage-mail\u002F2.mail","i-lucide-mail",{"title":257,"path":258,"stem":259,"icon":260},"Notifications","\u002Fen\u002Fstorage-mail\u002Fnotifications","en\u002F8.storage-mail\u002F3.notifications","i-lucide-bell",{"title":262,"path":263,"stem":264,"icon":180},"Realtime","\u002Fen\u002Fstorage-mail\u002Frealtime","en\u002F8.storage-mail\u002F4.realtime",{"title":266,"icon":267,"path":268,"stem":269,"children":270,"page":44},"CLI Reference","i-lucide-terminal","\u002Fen\u002Fcli","en\u002F9.cli",[271,274,279,284,289,294,299,303,308,313,318,323,328,333,337],{"title":139,"path":272,"stem":273,"icon":267},"\u002Fen\u002Fcli\u002Foverview","en\u002F9.cli\u002F1.overview",{"title":275,"path":276,"stem":277,"icon":278},"add db","\u002Fen\u002Fcli\u002Fadd-db","en\u002F9.cli\u002F10.add-db","i-lucide-database-zap",{"title":280,"path":281,"stem":282,"icon":283},"add compose \u002F add docker","\u002Fen\u002Fcli\u002Fadd-compose","en\u002F9.cli\u002F11.add-compose","i-lucide-container",{"title":285,"path":286,"stem":287,"icon":288},"add mail","\u002Fen\u002Fcli\u002Fadd-mail","en\u002F9.cli\u002F12.add-mail","i-lucide-mail-plus",{"title":290,"path":291,"stem":292,"icon":293},"add notification","\u002Fen\u002Fcli\u002Fadd-notification","en\u002F9.cli\u002F13.add-notification","i-lucide-bell-plus",{"title":295,"path":296,"stem":297,"icon":298},"add realtime","\u002Fen\u002Fcli\u002Fadd-realtime","en\u002F9.cli\u002F14.add-realtime","i-lucide-radio-tower",{"title":300,"path":301,"stem":302,"icon":165},"add seeder","\u002Fen\u002Fcli\u002Fadd-seeder","en\u002F9.cli\u002F15.add-seeder",{"title":304,"path":305,"stem":306,"icon":307},"new project","\u002Fen\u002Fcli\u002Fnew-project","en\u002F9.cli\u002F2.new-project","i-lucide-folder-plus",{"title":309,"path":310,"stem":311,"icon":312},"new module","\u002Fen\u002Fcli\u002Fnew-module","en\u002F9.cli\u002F3.new-module","i-lucide-blocks",{"title":314,"path":315,"stem":316,"icon":317},"add surface","\u002Fen\u002Fcli\u002Fadd-surface","en\u002F9.cli\u002F4.add-surface","i-lucide-layers-2",{"title":319,"path":320,"stem":321,"icon":322},"add core","\u002Fen\u002Fcli\u002Fadd-core","en\u002F9.cli\u002F5.add-core","i-lucide-box",{"title":324,"path":325,"stem":326,"icon":327},"add handler","\u002Fen\u002Fcli\u002Fadd-handler","en\u002F9.cli\u002F6.add-handler","i-lucide-webhook",{"title":329,"path":330,"stem":331,"icon":332},"new migration","\u002Fen\u002Fcli\u002Fnew-migration","en\u002F9.cli\u002F7.new-migration","i-lucide-file-plus",{"title":334,"path":335,"stem":336,"icon":195},"worker generators","\u002Fen\u002Fcli\u002Fworker-generators","en\u002F9.cli\u002F8.worker-generators",{"title":338,"path":339,"stem":340,"icon":341},"upgrade templates","\u002Fen\u002Fcli\u002Fupgrade-templates","en\u002F9.cli\u002F9.upgrade-templates","i-lucide-refresh-cw",{"id":343,"title":139,"body":344,"description":1090,"extension":1091,"links":1092,"meta":1093,"navigation":1094,"path":224,"seo":1095,"stem":225,"__hash__":1096},"docs_en\u002Fen\u002F7.observability\u002F1.overview.md",{"type":345,"value":346,"toc":1082},"minimark",[347,382,387,390,483,496,579,585,656,675,679,682,733,740,744,839,854,867,871,891,898,902,905,1023,1034,1049,1053,1078],[348,349,350,351,355,356,360,361,364,365,368,369,372,373,377,378,381],"p",{},"In gpsystem, logging, measurement and error reporting are all booted by ",[352,353,354],"strong",{},"a single call",", and you don't even write that call: the first thing ",[357,358,359],"code",{},"fiberx.Run",", ",[357,362,363],{},"chix.Run"," and ",[357,366,367],{},"worker.Run"," do is ",[357,370,371],{},"telemetry.Setup",". By the time the ",[374,375,376],"a",{"href":41},"shop","'s ",[357,379,380],{},"main.go"," starts serving, logging, tracing and error reporting are already wired, before the first request arrives.",[383,384,386],"h2",{"id":385},"the-telemetry-facade","The telemetry facade",[348,388,389],{},"Three packages each own one capability, and a fourth composes them:",[391,392,393,409],"table",{},[394,395,396],"thead",{},[397,398,399,403,406],"tr",{},[400,401,402],"th",{},"Package",[400,404,405],{},"What it owns",[400,407,408],{},"Page",[410,411,412,436,450,464],"tbody",{},[397,413,414,425,432],{},[415,416,417,420,421,424],"td",{},[357,418,419],{},"logx"," (+ ",[357,422,423],{},"logx\u002Fmonolog",")",[415,426,427,428,431],{},"the default ",[357,429,430],{},"slog"," logger's composition: console format, level filtering, fanout",[415,433,434],{},[374,435,227],{"href":228},[397,437,438,443,446],{},[415,439,440],{},[357,441,442],{},"otelx",[415,444,445],{},"the OpenTelemetry SDK bootstrap: traces, metrics, OTLP log bridge",[415,447,448],{},[374,449,232],{"href":233},[397,451,452,457,460],{},[415,453,454],{},[357,455,456],{},"sentryx",[415,458,459],{},"the optional Sentry integration: span exporter + slog capture handler",[415,461,462],{},[374,463,237],{"href":238},[397,465,466,471,480],{},[415,467,468],{},[357,469,470],{},"telemetry",[415,472,473,476,477,424],{},[352,474,475],{},"the facade the chassis calls"," (composes the other three in a single ",[357,478,479],{},"Setup",[415,481,482],{},"this page",[348,484,485,488,489,364,492,495],{},[357,486,487],{},"telemetry.Config"," is exactly what the ",[357,490,491],{},"server.Config.Telemetry",[357,493,494],{},"worker.Config.Telemetry"," fields hold:",[497,498,503],"pre",{"className":499,"code":500,"language":501,"meta":502,"style":502},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","type Config struct {\n    Otel   otelx.Config   \u002F\u002F OTEL_SERVICE_NAME, OTEL_SERVICE_VERSION, OTEL_DEV_MODE\n    Log    logx.Config    \u002F\u002F LOG_LEVEL, LOG_STDOUT, LOG_FORMAT\n    Sentry sentryx.Config \u002F\u002F SENTRY_DSN, SENTRY_ENVIRONMENT, SENTRY_TRACES, SENTRY_DEBUG\n}\n","go","",[357,504,505,524,543,558,573],{"__ignoreMap":502},[506,507,510,514,518,521],"span",{"class":508,"line":509},"line",1,[506,511,513],{"class":512},"sMK4o","type",[506,515,517],{"class":516},"sBMFI"," Config",[506,519,520],{"class":512}," struct",[506,522,523],{"class":512}," {\n",[506,525,527,531,533,536,539],{"class":508,"line":526},2,[506,528,530],{"class":529},"sTEyZ","    Otel   ",[506,532,442],{"class":516},[506,534,535],{"class":512},".",[506,537,538],{"class":516},"Config",[506,540,542],{"class":541},"sHwdD","   \u002F\u002F OTEL_SERVICE_NAME, OTEL_SERVICE_VERSION, OTEL_DEV_MODE\n",[506,544,546,549,551,553,555],{"class":508,"line":545},3,[506,547,548],{"class":529},"    Log    ",[506,550,419],{"class":516},[506,552,535],{"class":512},[506,554,538],{"class":516},[506,556,557],{"class":541},"    \u002F\u002F LOG_LEVEL, LOG_STDOUT, LOG_FORMAT\n",[506,559,561,564,566,568,570],{"class":508,"line":560},4,[506,562,563],{"class":529},"    Sentry ",[506,565,456],{"class":516},[506,567,535],{"class":512},[506,569,538],{"class":516},[506,571,572],{"class":541}," \u002F\u002F SENTRY_DSN, SENTRY_ENVIRONMENT, SENTRY_TRACES, SENTRY_DEBUG\n",[506,574,576],{"class":508,"line":575},5,[506,577,578],{"class":512},"}\n",[348,580,581,582,535],{},"It embeds without a prefix, so the environment variables load under their standard names: a deployment configures the service exactly like any other OTel-instrumented app. The full variable list: ",[374,583,584],{"href":53},"Configuration reference",[497,586,588],{"className":499,"code":587,"language":501,"meta":502,"style":502},"func Setup(ctx context.Context, cfg Config) (shutdown func(context.Context) error, err error)\n",[357,589,590],{"__ignoreMap":502},[506,591,592,595,599,602,606,609,611,614,617,620,622,624,627,630,633,636,638,640,642,646,648,651,653],{"class":508,"line":509},[506,593,594],{"class":512},"func",[506,596,598],{"class":597},"s2Zo4"," Setup",[506,600,601],{"class":512},"(",[506,603,605],{"class":604},"sHdIc","ctx",[506,607,608],{"class":516}," context",[506,610,535],{"class":512},[506,612,613],{"class":516},"Context",[506,615,616],{"class":512},",",[506,618,619],{"class":604}," cfg",[506,621,517],{"class":516},[506,623,424],{"class":512},[506,625,626],{"class":512}," (",[506,628,629],{"class":604},"shutdown",[506,631,632],{"class":512}," func(",[506,634,635],{"class":516},"context",[506,637,535],{"class":512},[506,639,613],{"class":516},[506,641,424],{"class":512},[506,643,645],{"class":644},"spNyl"," error",[506,647,616],{"class":512},[506,649,650],{"class":604}," err",[506,652,645],{"class":644},[506,654,655],{"class":512},")\n",[348,657,658,660,661,364,663,665,666,668,669,671,672,535],{},[357,659,470],{}," is the only package that imports all three building blocks: ",[357,662,442],{},[357,664,456],{}," know nothing about each other, and ",[357,667,419],{}," has no opinion on where else a log record goes. This is not cosmetics: a non-chassis binary (a CLI, a migrator) that only uses ",[357,670,442],{}," ",[352,673,674],{},"never links sentry-go",[383,676,678],{"id":677},"what-happens-inside-setup","What happens inside Setup",[348,680,681],{},"The order matters, because the pieces wire into each other:",[683,684,685,699,712],"ol",{},[686,687,688,671,691,694,695,698],"li",{},[352,689,690],{},"Sentry first.",[357,692,693],{},"sentryx.Setup"," runs first: without ",[357,696,697],{},"SENTRY_DSN"," every hook of it is a no-op, and everything behaves exactly as if Sentry did not exist.",[686,700,701,671,704,707,708,711],{},[352,702,703],{},"OTel, with Sentry's span exporter.",[357,705,706],{},"otelx.Setup"," receives Sentry's exporter via the ",[357,709,710],{},"otelx.WithSpanExporter(sentryHandle.SpanExporter())"," option: the same spans go to Sentry through an extra batcher, so an error links to the full request trace.",[686,713,714,720,721,724,725,728,729,732],{},[352,715,716,717,535],{},"One ",[357,718,719],{},"slog.Default()"," The console handler (always in dev, in prod only with ",[357,722,723],{},"LOG_STDOUT=true","), the OTLP log bridge and the Sentry capture handler are combined into a single handler with ",[357,726,727],{},"logx.Fanout",", a ",[357,730,731],{},"logx.LevelFilter(LOG_LEVEL, ...)"," goes in front, and the whole thing becomes the process's default logger.",[348,734,735,736,739],{},"So a single ",[357,737,738],{},"slog.InfoContext(ctx, ...)"," call in your service is, at once: a readable console line (dev), a trace-correlated log record exported over OTLP (prod), and, on error, a Sentry event with a breadcrumb trail.",[383,741,743],{"id":742},"what-you-get-with-zero-configuration","What you get with zero configuration",[391,745,746,761],{},[394,747,748],{},[397,749,750,752,758],{},[400,751],{},[400,753,754,755,424],{},"Dev (",[357,756,757],{},"OTEL_DEV_MODE=true",[400,759,760],{},"Prod (default)",[410,762,763,780,798,809,823],{},[397,764,765,768,774],{},[415,766,767],{},"Console log",[415,769,770,771,424],{},"always, readable text (or ",[374,772,773],{"href":228},"Monolog format",[415,775,776,777,779],{},"only with ",[357,778,723],{},", JSON",[397,781,782,785,791],{},[415,783,784],{},"Traces \u002F metrics",[415,786,787,788],{},"no exporters, ",[352,789,790],{},"no collector needed",[415,792,793,794,797],{},"OTLP per the standard ",[357,795,796],{},"OTEL_*"," variables",[397,799,800,803,806],{},[415,801,802],{},"OTLP log bridge",[415,804,805],{},"none",[415,807,808],{},"present (logs ship to the collector too)",[397,810,811,813,819],{},[415,812,237],{},[415,814,815,816,818],{},"off (",[357,817,697],{}," empty)",[415,820,815,821,818],{},[357,822,697],{},[397,824,825,830,833],{},[415,826,827],{},[357,828,829],{},"OTEL_SERVICE_NAME",[415,831,832],{},"optional",[415,834,835,838],{},[352,836,837],{},"required"," (Setup fails without it)",[840,841,842,843,845,846,849,850,853],"tip",{},"Local development is just ",[357,844,757],{},". The service boots with readable logs and a request logger, no infrastructure required. Add ",[357,847,848],{},"LOG_FORMAT=monolog"," and the console prints ",[374,851,852],{"href":228},"Monolog-style lines"," familiar from PHP, with clickable stack traces.",[348,855,856,857,859,860,863,864,535],{},"There is one exception: if you set ",[357,858,697],{}," in dev mode, the kit builds a Sentry-only tracer provider, so you get full traces and errors in Sentry ",[352,861,862],{},"locally, without a collector","; details on the ",[374,865,866],{"href":238},"Sentry page",[383,868,870],{"id":869},"the-flush-runs-last","The flush runs last",[348,872,873,875,876,879,880,360,883,886,887,890],{},[357,874,479],{}," returns an aggregated shutdown function that the chassis runs as the ",[357,877,878],{},"Flush"," step of the ",[374,881,882],{"href":74},"application lifecycle",[352,884,885],{},"last of all",", after the HTTP drain and after all your ",[357,888,889],{},"WithCloser"," closers. That ordering is deliberate: closers themselves emit telemetry (the log line of a pool close, a span opened during cleanup), and those only make it out if the exporters are still alive.",[348,892,893,894,897],{},"There is ordering inside the shutdown too: the OTel providers stop first, and ",[352,895,896],{},"Sentry flushes last",", so events produced while the providers were shutting down still get out.",[383,899,901],{"id":900},"if-you-dont-want-it-or-want-to-own-it","If you don't want it, or want to own it",[348,903,904],{},"All three chassis have an off switch:",[497,906,908],{"className":499,"code":907,"language":501,"meta":502,"style":502},"fiberx.Run(ctx, cfg.Server, register, fiberx.WithoutTelemetry())\nchix.Run(ctx, cfg.Server, register, chix.WithoutTelemetry())\nworker.Run(ctx, cfg.Worker, register, worker.WithoutTelemetry())\n",[357,909,910,951,987],{"__ignoreMap":502},[506,911,912,915,917,920,922,924,926,928,930,933,935,938,940,943,945,948],{"class":508,"line":509},[506,913,914],{"class":529},"fiberx",[506,916,535],{"class":512},[506,918,919],{"class":597},"Run",[506,921,601],{"class":512},[506,923,605],{"class":529},[506,925,616],{"class":512},[506,927,619],{"class":529},[506,929,535],{"class":512},[506,931,932],{"class":529},"Server",[506,934,616],{"class":512},[506,936,937],{"class":529}," register",[506,939,616],{"class":512},[506,941,942],{"class":529}," fiberx",[506,944,535],{"class":512},[506,946,947],{"class":597},"WithoutTelemetry",[506,949,950],{"class":512},"())\n",[506,952,953,956,958,960,962,964,966,968,970,972,974,976,978,981,983,985],{"class":508,"line":526},[506,954,955],{"class":529},"chix",[506,957,535],{"class":512},[506,959,919],{"class":597},[506,961,601],{"class":512},[506,963,605],{"class":529},[506,965,616],{"class":512},[506,967,619],{"class":529},[506,969,535],{"class":512},[506,971,932],{"class":529},[506,973,616],{"class":512},[506,975,937],{"class":529},[506,977,616],{"class":512},[506,979,980],{"class":529}," chix",[506,982,535],{"class":512},[506,984,947],{"class":597},[506,986,950],{"class":512},[506,988,989,992,994,996,998,1000,1002,1004,1006,1008,1010,1012,1014,1017,1019,1021],{"class":508,"line":545},[506,990,991],{"class":529},"worker",[506,993,535],{"class":512},[506,995,919],{"class":597},[506,997,601],{"class":512},[506,999,605],{"class":529},[506,1001,616],{"class":512},[506,1003,619],{"class":529},[506,1005,535],{"class":512},[506,1007,192],{"class":529},[506,1009,616],{"class":512},[506,1011,937],{"class":529},[506,1013,616],{"class":512},[506,1015,1016],{"class":529}," worker",[506,1018,535],{"class":512},[506,1020,947],{"class":597},[506,1022,950],{"class":512},[348,1024,1025,1027,1028,671,1030,1033],{},[357,1026,947],{}," skips ",[357,1029,371],{},[352,1031,1032],{},"and"," the HTTP-side OTel middleware. In tests this is the default posture (no global state fiddling); in production you use it when the process configures its own telemetry: for example, to fit into a pre-existing OTel setup.",[348,1035,1036,1037,1039,1040,1043,1044,1048],{},"In a non-chassis process (a CLI, a one-shot cron-like run) ",[357,1038,371],{}," can be called directly: you get the same composition, you just ",[357,1041,1042],{},"defer"," the shutdown function yourself. If you don't need Sentry either, ",[374,1045,1046],{"href":233},[357,1047,706],{}," stands on its own.",[383,1050,1052],{"id":1051},"where-to-next","Where to next",[1054,1055,1056,1064,1069],"ul",{},[686,1057,1058,1060,1061,1063],{},[374,1059,227],{"href":228},": the ",[357,1062,430],{}," composition and the Monolog-format dev console; through PHP eyes, the most striking part.",[686,1065,1066,1068],{},[374,1067,232],{"href":233},": what the kit instruments on its own, and how the shop's \"follow the order\" trace comes together.",[686,1070,1071,1073,1074,1077],{},[374,1072,237],{"href":238},": error reporting with ",[357,1075,1076],{},"errs","-code issue grouping, layered on top of OTel.",[1079,1080,1081],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"title":502,"searchDepth":526,"depth":526,"links":1083},[1084,1085,1086,1087,1088,1089],{"id":385,"depth":526,"text":386},{"id":677,"depth":526,"text":678},{"id":742,"depth":526,"text":743},{"id":869,"depth":526,"text":870},{"id":900,"depth":526,"text":901},{"id":1051,"depth":526,"text":1052},"The telemetry facade: logging, OpenTelemetry and Sentry in a single call, with one shutdown guarantee.","md",null,{},{"icon":219},{"title":139,"description":1090},"erRdeetE5Fv02CWZ6dY_lKLSjCECEGf8SgB6IsEU_4E",[1098,1100],{"title":213,"path":214,"stem":215,"description":1099,"icon":216,"children":-1},"Per-request, per-user authorization above roles: declared in the contract, enforced from generated code.",{"title":227,"path":228,"stem":229,"description":1101,"icon":230,"children":-1},"Standard log\u002Fslog, composed, and a Monolog-format dev console with PHP-style stack traces.",1784668702969]