[{"data":1,"prerenderedAt":1315},["ShallowReactive",2],{"navigation_docs_en":3,"-en-telemetry-overview":441,"-en-telemetry-overview-surround":1310},[4,45,60,81,112,129,146,173,197,213,242,279,356,372,384,403,429],{"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},"queue","i-lucide-layers","\u002Fen\u002Fqueue","en\u002F10.queue",[51,56],{"title":52,"path":53,"stem":54,"icon":55},"Overview","\u002Fen\u002Fqueue\u002Foverview","en\u002F10.queue\u002F1.overview","i-lucide-list-ordered",{"title":57,"path":58,"stem":59,"icon":47},"Tasks","\u002Fen\u002Fqueue\u002Ftasks","en\u002F10.queue\u002F2.tasks",{"title":61,"icon":62,"path":63,"stem":64,"children":65,"page":44},"events","i-lucide-workflow","\u002Fen\u002Fevents","en\u002F11.events",[66,71,76],{"title":67,"path":68,"stem":69,"icon":70},"Events","\u002Fen\u002Fevents\u002Foverview","en\u002F11.events\u002F1.overview","i-lucide-radio",{"title":72,"path":73,"stem":74,"icon":75},"Outbox","\u002Fen\u002Fevents\u002Foutbox","en\u002F11.events\u002F2.outbox","i-lucide-inbox",{"title":77,"path":78,"stem":79,"icon":80},"Scheduling","\u002Fen\u002Fevents\u002Fscheduler","en\u002F11.events\u002F3.scheduler","i-lucide-calendar-clock",{"title":82,"icon":83,"path":84,"stem":85,"children":86,"page":44},"auth","i-lucide-shield-check","\u002Fen\u002Fauth","en\u002F12.auth",[87,92,97,102,107],{"title":88,"path":89,"stem":90,"icon":91},"Authentication","\u002Fen\u002Fauth\u002Foverview","en\u002F12.auth\u002F1.overview","i-lucide-key-round",{"title":93,"path":94,"stem":95,"icon":96},"RBAC","\u002Fen\u002Fauth\u002Frbac","en\u002F12.auth\u002F2.rbac","i-lucide-users",{"title":98,"path":99,"stem":100,"icon":101},"Policies","\u002Fen\u002Fauth\u002Fpolicy","en\u002F12.auth\u002F3.policy","i-lucide-gavel",{"title":103,"path":104,"stem":105,"icon":106},"Using auth standalone","\u002Fen\u002Fauth\u002Fstandalone","en\u002F12.auth\u002F4.standalone","i-lucide-plug",{"title":108,"path":109,"stem":110,"icon":111},"Social login with goth, standalone","\u002Fen\u002Fauth\u002Fsocial-standalone","en\u002F12.auth\u002F5.social-standalone","i-lucide-log-in",{"title":113,"icon":114,"path":115,"stem":116,"children":117,"page":44},"mail","i-lucide-mail","\u002Fen\u002Fmail","en\u002F13.mail",[118,121,125],{"title":52,"path":119,"stem":120,"icon":114},"\u002Fen\u002Fmail\u002Foverview","en\u002F13.mail\u002F1.overview",{"title":122,"path":123,"stem":124,"icon":114},"SMTP","\u002Fen\u002Fmail\u002Fsmtp","en\u002F13.mail\u002F2.smtp",{"title":126,"path":127,"stem":128,"icon":114},"MJML","\u002Fen\u002Fmail\u002Fmjml","en\u002F13.mail\u002F3.mjml",{"title":130,"icon":131,"path":132,"stem":133,"children":134,"page":44},"notify","i-lucide-bell","\u002Fen\u002Fnotify","en\u002F14.notify",[135,138,142],{"title":52,"path":136,"stem":137,"icon":131},"\u002Fen\u002Fnotify\u002Foverview","en\u002F14.notify\u002F1.overview",{"title":139,"path":140,"stem":141,"icon":131},"Database channel","\u002Fen\u002Fnotify\u002Fdatabase","en\u002F14.notify\u002F2.database",{"title":143,"path":144,"stem":145,"icon":131},"Broadcast channel","\u002Fen\u002Fnotify\u002Fbroadcast","en\u002F14.notify\u002F3.broadcast",{"title":147,"icon":148,"path":149,"stem":150,"children":151,"page":44},"storage","i-lucide-hard-drive","\u002Fen\u002Fstorage","en\u002F15.storage",[152,155,159,163,168],{"title":52,"path":153,"stem":154,"icon":148},"\u002Fen\u002Fstorage\u002Foverview","en\u002F15.storage\u002F1.overview",{"title":156,"path":157,"stem":158},"Disk API","\u002Fen\u002Fstorage\u002Fdisk-api","en\u002F15.storage\u002F2.disk-api",{"title":160,"path":161,"stem":162,"icon":148},"Memory and local disk","\u002Fen\u002Fstorage\u002Flocal","en\u002F15.storage\u002F3.local",{"title":164,"path":165,"stem":166,"icon":167},"S3","\u002Fen\u002Fstorage\u002Fs3","en\u002F15.storage\u002F4.s3","i-lucide-cloud",{"title":169,"path":170,"stem":171,"icon":172},"Testing","\u002Fen\u002Fstorage\u002Ftesting","en\u002F15.storage\u002F5.testing","i-lucide-flask-conical",{"title":174,"icon":175,"path":176,"stem":177,"children":178,"page":44},"telemetry","i-lucide-activity","\u002Fen\u002Ftelemetry","en\u002F16.telemetry",[179,182,187,192],{"title":52,"path":180,"stem":181,"icon":175},"\u002Fen\u002Ftelemetry\u002Foverview","en\u002F16.telemetry\u002F1.overview",{"title":183,"path":184,"stem":185,"icon":186},"Logging","\u002Fen\u002Ftelemetry\u002Flogging","en\u002F16.telemetry\u002F2.logging","i-lucide-scroll-text",{"title":188,"path":189,"stem":190,"icon":191},"OpenTelemetry","\u002Fen\u002Ftelemetry\u002Fopentelemetry","en\u002F16.telemetry\u002F3.opentelemetry","i-lucide-radar",{"title":193,"path":194,"stem":195,"icon":196},"Sentry","\u002Fen\u002Ftelemetry\u002Fsentry","en\u002F16.telemetry\u002F4.sentry","i-lucide-bug",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":44},"Reference","i-lucide-book-open","\u002Fen\u002Freference","en\u002F17.reference",[203,208],{"title":204,"path":205,"stem":206,"icon":207},"Configuration","\u002Fen\u002Freference\u002Fconfiguration","en\u002F17.reference\u002F1.configuration","i-lucide-settings",{"title":209,"path":210,"stem":211,"icon":212},"External dependencies","\u002Fen\u002Freference\u002Fdependencies","en\u002F17.reference\u002F2.dependencies","i-lucide-package",{"title":214,"icon":215,"path":216,"stem":217,"children":218,"page":44},"Concepts","i-lucide-lightbulb","\u002Fen\u002Fconcepts","en\u002F2.concepts",[219,223,228,232,237],{"title":220,"path":221,"stem":222,"icon":47},"Architecture","\u002Fen\u002Fconcepts\u002Farchitecture","en\u002F2.concepts\u002F1.architecture",{"title":224,"path":225,"stem":226,"icon":227},"Error model","\u002Fen\u002Fconcepts\u002Ferror-model","en\u002F2.concepts\u002F2.error-model","i-lucide-shield-alert",{"title":204,"path":229,"stem":230,"icon":231},"\u002Fen\u002Fconcepts\u002Fconfiguration","en\u002F2.concepts\u002F3.configuration","i-lucide-settings-2",{"title":233,"path":234,"stem":235,"icon":236},"Codegen pipeline","\u002Fen\u002Fconcepts\u002Fcodegen-pipeline","en\u002F2.concepts\u002F4.codegen-pipeline","i-lucide-file-json",{"title":238,"path":239,"stem":240,"icon":241},"Design patterns","\u002Fen\u002Fconcepts\u002Fdesign-patterns","en\u002F2.concepts\u002F5.design-patterns","i-lucide-puzzle",{"title":243,"icon":244,"path":245,"stem":246,"children":247,"page":44},"Kit","i-lucide-box","\u002Fen\u002Fkit","en\u002F3.kit",[248,251,256,261,266,270,275],{"title":52,"path":249,"stem":250,"icon":244},"\u002Fen\u002Fkit\u002Foverview","en\u002F3.kit\u002F1.overview",{"title":252,"path":253,"stem":254,"icon":255},"Application lifecycle","\u002Fen\u002Fkit\u002Fapp","en\u002F3.kit\u002F2.app","i-lucide-power",{"title":257,"path":258,"stem":259,"icon":260},"Server","\u002Fen\u002Fkit\u002Fserver","en\u002F3.kit\u002F3.server","i-lucide-server",{"title":262,"path":263,"stem":264,"icon":265},"Worker","\u002Fen\u002Fkit\u002Fworker","en\u002F3.kit\u002F4.worker","i-lucide-cog",{"title":267,"path":268,"stem":269,"icon":70},"Realtime","\u002Fen\u002Fkit\u002Frealtime","en\u002F3.kit\u002F5.realtime",{"title":271,"path":272,"stem":273,"icon":274},"Migrations","\u002Fen\u002Fkit\u002Fmigrations","en\u002F3.kit\u002F6.migrations","i-lucide-file-stack",{"title":276,"path":277,"stem":278,"icon":111},"Social login","\u002Fen\u002Fkit\u002Fsocial-login","en\u002F3.kit\u002F7.social-login",{"title":280,"icon":281,"path":282,"stem":283,"children":284,"page":44},"CLI Reference","i-lucide-terminal","\u002Fen\u002Fcli","en\u002F4.cli",[285,288,293,298,303,308,313,318,323,328,333,337,342,347,351],{"title":52,"path":286,"stem":287,"icon":281},"\u002Fen\u002Fcli\u002Foverview","en\u002F4.cli\u002F1.overview",{"title":289,"path":290,"stem":291,"icon":292},"add db","\u002Fen\u002Fcli\u002Fadd-db","en\u002F4.cli\u002F10.add-db","i-lucide-database-zap",{"title":294,"path":295,"stem":296,"icon":297},"add compose \u002F add docker","\u002Fen\u002Fcli\u002Fadd-compose","en\u002F4.cli\u002F11.add-compose","i-lucide-container",{"title":299,"path":300,"stem":301,"icon":302},"add mail","\u002Fen\u002Fcli\u002Fadd-mail","en\u002F4.cli\u002F12.add-mail","i-lucide-mail-plus",{"title":304,"path":305,"stem":306,"icon":307},"add notification","\u002Fen\u002Fcli\u002Fadd-notification","en\u002F4.cli\u002F13.add-notification","i-lucide-bell-plus",{"title":309,"path":310,"stem":311,"icon":312},"add realtime","\u002Fen\u002Fcli\u002Fadd-realtime","en\u002F4.cli\u002F14.add-realtime","i-lucide-radio-tower",{"title":314,"path":315,"stem":316,"icon":317},"add seeder","\u002Fen\u002Fcli\u002Fadd-seeder","en\u002F4.cli\u002F15.add-seeder","i-lucide-sprout",{"title":319,"path":320,"stem":321,"icon":322},"new project","\u002Fen\u002Fcli\u002Fnew-project","en\u002F4.cli\u002F2.new-project","i-lucide-folder-plus",{"title":324,"path":325,"stem":326,"icon":327},"new module","\u002Fen\u002Fcli\u002Fnew-module","en\u002F4.cli\u002F3.new-module","i-lucide-blocks",{"title":329,"path":330,"stem":331,"icon":332},"add surface","\u002Fen\u002Fcli\u002Fadd-surface","en\u002F4.cli\u002F4.add-surface","i-lucide-layers-2",{"title":334,"path":335,"stem":336,"icon":244},"add core","\u002Fen\u002Fcli\u002Fadd-core","en\u002F4.cli\u002F5.add-core",{"title":338,"path":339,"stem":340,"icon":341},"add handler","\u002Fen\u002Fcli\u002Fadd-handler","en\u002F4.cli\u002F6.add-handler","i-lucide-webhook",{"title":343,"path":344,"stem":345,"icon":346},"new migration","\u002Fen\u002Fcli\u002Fnew-migration","en\u002F4.cli\u002F7.new-migration","i-lucide-file-plus",{"title":348,"path":349,"stem":350,"icon":265},"worker generators","\u002Fen\u002Fcli\u002Fworker-generators","en\u002F4.cli\u002F8.worker-generators",{"title":352,"path":353,"stem":354,"icon":355},"upgrade templates","\u002Fen\u002Fcli\u002Fupgrade-templates","en\u002F4.cli\u002F9.upgrade-templates","i-lucide-refresh-cw",{"title":357,"icon":227,"path":358,"stem":359,"children":360,"page":44},"errs","\u002Fen\u002Ferrs","en\u002F5.errs",[361,364,368],{"title":52,"path":362,"stem":363,"icon":227},"\u002Fen\u002Ferrs\u002Foverview","en\u002F5.errs\u002F1.overview",{"title":365,"path":366,"stem":367},"API","\u002Fen\u002Ferrs\u002Fapi","en\u002F5.errs\u002F2.api",{"title":369,"path":370,"stem":371,"icon":227},"Integration","\u002Fen\u002Ferrs\u002Fintegration","en\u002F5.errs\u002F3.integration",{"title":373,"icon":231,"path":374,"stem":375,"children":376,"page":44},"envconf","\u002Fen\u002Fenvconf","en\u002F6.envconf",[377,380],{"title":52,"path":378,"stem":379,"icon":231},"\u002Fen\u002Fenvconf\u002Foverview","en\u002F6.envconf\u002F1.overview",{"title":381,"path":382,"stem":383},"Recipes","\u002Fen\u002Fenvconf\u002Frecipes","en\u002F6.envconf\u002F2.recipes",{"title":385,"icon":386,"path":387,"stem":388,"children":389,"page":44},"httperr","i-lucide-globe","\u002Fen\u002Fhttperr","en\u002F7.httperr",[390,393,398],{"title":52,"path":391,"stem":392,"icon":386},"\u002Fen\u002Fhttperr\u002Foverview","en\u002F7.httperr\u002F1.overview",{"title":394,"path":395,"stem":396,"icon":397},"Error responses","\u002Fen\u002Fhttperr\u002Ferror-responses","en\u002F7.httperr\u002F2.error-responses","i-lucide-octagon-alert",{"title":399,"path":400,"stem":401,"icon":402},"Validation","\u002Fen\u002Fhttperr\u002Fvalidation","en\u002F7.httperr\u002F3.validation","i-lucide-badge-check",{"title":404,"icon":405,"path":406,"stem":407,"children":408,"page":44},"dbx","i-lucide-database","\u002Fen\u002Fdbx","en\u002F8.dbx",[409,412,416,420,425],{"title":52,"path":410,"stem":411,"icon":405},"\u002Fen\u002Fdbx\u002Foverview","en\u002F8.dbx\u002F1.overview",{"title":413,"path":414,"stem":415,"icon":106},"pgx","\u002Fen\u002Fdbx\u002Fpg","en\u002F8.dbx\u002F2.pg",{"title":417,"path":418,"stem":419,"icon":47},"bun","\u002Fen\u002Fdbx\u002Fbunx","en\u002F8.dbx\u002F3.bunx",{"title":421,"path":422,"stem":423,"icon":424},"Transactions","\u002Fen\u002Fdbx\u002Ftransactions","en\u002F8.dbx\u002F4.transactions","i-lucide-git-merge",{"title":426,"path":427,"stem":428,"icon":317},"Seeders","\u002Fen\u002Fdbx\u002Fseed","en\u002F8.dbx\u002F5.seed",{"title":430,"icon":55,"path":431,"stem":432,"children":433,"page":44},"paginate","\u002Fen\u002Fpaginate","en\u002F9.paginate",[434,437],{"title":52,"path":435,"stem":436,"icon":55},"\u002Fen\u002Fpaginate\u002Foverview","en\u002F9.paginate\u002F1.overview",{"title":438,"path":439,"stem":440,"icon":19},"Cursor pagination","\u002Fen\u002Fpaginate\u002Fcursor","en\u002F9.paginate\u002F2.cursor",{"id":442,"title":52,"body":443,"description":1303,"extension":1304,"links":1305,"meta":1306,"navigation":1307,"path":180,"seo":1308,"stem":181,"__hash__":1309},"docs_en\u002Fen\u002F16.telemetry\u002F1.overview.md",{"type":444,"value":445,"toc":1294},"minimark",[446,493,498,537,609,615,619,622,705,718,792,798,869,888,892,895,946,953,957,1052,1067,1080,1084,1105,1112,1116,1119,1236,1247,1262,1266,1290],[447,448,449,452,453,456,457,456,460,456,463,466,467,471,472,475,476,479,480,483,484,488,489,492],"p",{},[450,451,174],"code",{}," is a standalone Go module (",[450,454,455],{},"github.com\u002Fgp-system\u002Ftelemetry",", +",[450,458,459],{},"telemetry\u002Flogx",[450,461,462],{},"telemetry\u002Fotelx",[450,464,465],{},"telemetry\u002Fsentryx","): logging, measurement and error reporting, all booted by ",[468,469,470],"strong",{},"a single call",". In a generated project you don't even write that call: the first thing ",[450,473,474],{},"server.Run"," and ",[450,477,478],{},"worker.Run"," do is ",[450,481,482],{},"telemetry.Setup",". By the time the ",[485,486,487],"a",{"href":41},"shop","'s ",[450,490,491],{},"main.go"," starts serving, logging, tracing and error reporting are already wired, before the first request arrives.",[494,495,497],"h2",{"id":496},"install","Install",[499,500,505],"pre",{"className":501,"code":502,"language":503,"meta":504,"style":504},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com\u002Fgp-system\u002Ftelemetry@v0.1.0 # the kit itself uses this tag\ngo get github.com\u002Fgp-system\u002Ftelemetry@latest\n","sh","",[450,506,507,527],{"__ignoreMap":504},[508,509,512,516,520,523],"span",{"class":510,"line":511},"line",1,[508,513,515],{"class":514},"sBMFI","go",[508,517,519],{"class":518},"sfazB"," get",[508,521,522],{"class":518}," github.com\u002Fgp-system\u002Ftelemetry@v0.1.0",[508,524,526],{"class":525},"sHwdD"," # the kit itself uses this tag\n",[508,528,530,532,534],{"class":510,"line":529},2,[508,531,515],{"class":514},[508,533,519],{"class":518},[508,535,536],{"class":518}," github.com\u002Fgp-system\u002Ftelemetry@latest\n",[538,539,540,553],"table",{},[541,542,543],"thead",{},[544,545,546,550],"tr",{},[547,548,549],"th",{},"Import path",[547,551,552],{},"What it adds",[554,555,556,570,589,599],"tbody",{},[544,557,558,563],{},[559,560,561],"td",{},[450,562,455],{},[559,564,565,566,569],{},"the facade: ",[450,567,568],{},"Setup"," composes the three below into one call",[544,571,572,582],{},[559,573,574,577,578,581],{},[450,575,576],{},"github.com\u002Fgp-system\u002Ftelemetry\u002Flogx"," (+",[450,579,580],{},"\u002Fmonolog",")",[559,583,584,585,588],{},"the ",[450,586,587],{},"slog"," composition: console format, level filtering, fanout",[544,590,591,596],{},[559,592,593],{},[450,594,595],{},"github.com\u002Fgp-system\u002Ftelemetry\u002Fotelx",[559,597,598],{},"the OpenTelemetry SDK bootstrap",[544,600,601,606],{},[559,602,603],{},[450,604,605],{},"github.com\u002Fgp-system\u002Ftelemetry\u002Fsentryx",[559,607,608],{},"the optional Sentry integration",[447,610,611,612,614],{},"A binary that only needs one piece can import just that subpackage: a CLI or migrator that wants OTel tracing but no Sentry imports ",[450,613,462],{}," alone and never links sentry-go.",[494,616,618],{"id":617},"the-telemetry-facade","The telemetry facade",[447,620,621],{},"Three packages each own one capability, and a fourth composes them:",[538,623,624,637],{},[541,625,626],{},[544,627,628,631,634],{},[547,629,630],{},"Package",[547,632,633],{},"What it owns",[547,635,636],{},"Page",[554,638,639,660,674,688],{},[544,640,641,650,656],{},[559,642,643,646,647,581],{},[450,644,645],{},"logx"," (+ ",[450,648,649],{},"logx\u002Fmonolog",[559,651,652,653,655],{},"the default ",[450,654,587],{}," logger's composition: console format, level filtering, fanout",[559,657,658],{},[485,659,183],{"href":184},[544,661,662,667,670],{},[559,663,664],{},[450,665,666],{},"otelx",[559,668,669],{},"the OpenTelemetry SDK bootstrap: traces, metrics, OTLP log bridge",[559,671,672],{},[485,673,188],{"href":189},[544,675,676,681,684],{},[559,677,678],{},[450,679,680],{},"sentryx",[559,682,683],{},"the optional Sentry integration: span exporter + slog capture handler",[559,685,686],{},[485,687,193],{"href":194},[544,689,690,694,702],{},[559,691,692],{},[450,693,174],{},[559,695,696,699,700,581],{},[468,697,698],{},"the facade the chassis calls"," (composes the other three in a single ",[450,701,568],{},[559,703,704],{},"this page",[447,706,707,710,711,475,714,717],{},[450,708,709],{},"telemetry.Config"," is exactly what the ",[450,712,713],{},"server.Config.Telemetry",[450,715,716],{},"worker.Config.Telemetry"," fields hold:",[499,719,722],{"className":720,"code":721,"language":515,"meta":504,"style":504},"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",[450,723,724,739,756,771,786],{"__ignoreMap":504},[508,725,726,730,733,736],{"class":510,"line":511},[508,727,729],{"class":728},"sMK4o","type",[508,731,732],{"class":514}," Config",[508,734,735],{"class":728}," struct",[508,737,738],{"class":728}," {\n",[508,740,741,745,747,750,753],{"class":510,"line":529},[508,742,744],{"class":743},"sTEyZ","    Otel   ",[508,746,666],{"class":514},[508,748,749],{"class":728},".",[508,751,752],{"class":514},"Config",[508,754,755],{"class":525},"   \u002F\u002F OTEL_SERVICE_NAME, OTEL_SERVICE_VERSION, OTEL_DEV_MODE\n",[508,757,759,762,764,766,768],{"class":510,"line":758},3,[508,760,761],{"class":743},"    Log    ",[508,763,645],{"class":514},[508,765,749],{"class":728},[508,767,752],{"class":514},[508,769,770],{"class":525},"    \u002F\u002F LOG_LEVEL, LOG_STDOUT, LOG_FORMAT\n",[508,772,774,777,779,781,783],{"class":510,"line":773},4,[508,775,776],{"class":743},"    Sentry ",[508,778,680],{"class":514},[508,780,749],{"class":728},[508,782,752],{"class":514},[508,784,785],{"class":525}," \u002F\u002F SENTRY_DSN, SENTRY_ENVIRONMENT, SENTRY_TRACES, SENTRY_DEBUG\n",[508,787,789],{"class":510,"line":788},5,[508,790,791],{"class":728},"}\n",[447,793,794,795,749],{},"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: ",[485,796,797],{"href":205},"Configuration reference",[499,799,801],{"className":720,"code":800,"language":515,"meta":504,"style":504},"func Setup(ctx context.Context, cfg Config) (shutdown func(context.Context) error, err error)\n",[450,802,803],{"__ignoreMap":504},[508,804,805,808,812,815,819,822,824,827,830,833,835,837,840,843,846,849,851,853,855,859,861,864,866],{"class":510,"line":511},[508,806,807],{"class":728},"func",[508,809,811],{"class":810},"s2Zo4"," Setup",[508,813,814],{"class":728},"(",[508,816,818],{"class":817},"sHdIc","ctx",[508,820,821],{"class":514}," context",[508,823,749],{"class":728},[508,825,826],{"class":514},"Context",[508,828,829],{"class":728},",",[508,831,832],{"class":817}," cfg",[508,834,732],{"class":514},[508,836,581],{"class":728},[508,838,839],{"class":728}," (",[508,841,842],{"class":817},"shutdown",[508,844,845],{"class":728}," func(",[508,847,848],{"class":514},"context",[508,850,749],{"class":728},[508,852,826],{"class":514},[508,854,581],{"class":728},[508,856,858],{"class":857},"spNyl"," error",[508,860,829],{"class":728},[508,862,863],{"class":817}," err",[508,865,858],{"class":857},[508,867,868],{"class":728},")\n",[447,870,871,873,874,475,876,878,879,881,882,884,885,749],{},[450,872,174],{}," is the only package that imports all three building blocks: ",[450,875,666],{},[450,877,680],{}," know nothing about each other, and ",[450,880,645],{}," 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 ",[450,883,666],{}," ",[468,886,887],{},"never links sentry-go",[494,889,891],{"id":890},"what-happens-inside-setup","What happens inside Setup",[447,893,894],{},"The order matters, because the pieces wire into each other:",[896,897,898,912,925],"ol",{},[899,900,901,884,904,907,908,911],"li",{},[468,902,903],{},"Sentry first.",[450,905,906],{},"sentryx.Setup"," runs first: without ",[450,909,910],{},"SENTRY_DSN"," every hook of it is a no-op, and everything behaves exactly as if Sentry did not exist.",[899,913,914,884,917,920,921,924],{},[468,915,916],{},"OTel, with Sentry's span exporter.",[450,918,919],{},"otelx.Setup"," receives Sentry's exporter via the ",[450,922,923],{},"otelx.WithSpanExporter(sentryHandle.SpanExporter())"," option: the same spans go to Sentry through an extra batcher, so an error links to the full request trace.",[899,926,927,933,934,937,938,941,942,945],{},[468,928,929,930,749],{},"One ",[450,931,932],{},"slog.Default()"," The console handler (always in dev, in prod only with ",[450,935,936],{},"LOG_STDOUT=true","), the OTLP log bridge and the Sentry capture handler are combined into a single handler with ",[450,939,940],{},"logx.Fanout",", a ",[450,943,944],{},"logx.LevelFilter(LOG_LEVEL, ...)"," goes in front, and the whole thing becomes the process's default logger.",[447,947,948,949,952],{},"So a single ",[450,950,951],{},"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.",[494,954,956],{"id":955},"what-you-get-with-zero-configuration","What you get with zero configuration",[538,958,959,974],{},[541,960,961],{},[544,962,963,965,971],{},[547,964],{},[547,966,967,968,581],{},"Dev (",[450,969,970],{},"OTEL_DEV_MODE=true",[547,972,973],{},"Prod (default)",[554,975,976,993,1011,1022,1036],{},[544,977,978,981,987],{},[559,979,980],{},"Console log",[559,982,983,984,581],{},"always, readable text (or ",[485,985,986],{"href":184},"Monolog format",[559,988,989,990,992],{},"only with ",[450,991,936],{},", JSON",[544,994,995,998,1004],{},[559,996,997],{},"Traces \u002F metrics",[559,999,1000,1001],{},"no exporters, ",[468,1002,1003],{},"no collector needed",[559,1005,1006,1007,1010],{},"OTLP per the standard ",[450,1008,1009],{},"OTEL_*"," variables",[544,1012,1013,1016,1019],{},[559,1014,1015],{},"OTLP log bridge",[559,1017,1018],{},"none",[559,1020,1021],{},"present (logs ship to the collector too)",[544,1023,1024,1026,1032],{},[559,1025,193],{},[559,1027,1028,1029,1031],{},"off (",[450,1030,910],{}," empty)",[559,1033,1028,1034,1031],{},[450,1035,910],{},[544,1037,1038,1043,1046],{},[559,1039,1040],{},[450,1041,1042],{},"OTEL_SERVICE_NAME",[559,1044,1045],{},"optional",[559,1047,1048,1051],{},[468,1049,1050],{},"required"," (Setup fails without it)",[1053,1054,1055,1056,1058,1059,1062,1063,1066],"tip",{},"Local development is just ",[450,1057,970],{},". The service boots with readable logs and a request logger, no infrastructure required. Add ",[450,1060,1061],{},"LOG_FORMAT=monolog"," and the console prints ",[485,1064,1065],{"href":184},"Monolog-style lines"," familiar from PHP, with clickable stack traces.",[447,1068,1069,1070,1072,1073,1076,1077,749],{},"There is one exception: if you set ",[450,1071,910],{}," in dev mode, the kit builds a Sentry-only tracer provider, so you get full traces and errors in Sentry ",[468,1074,1075],{},"locally, without a collector","; details on the ",[485,1078,1079],{"href":194},"Sentry page",[494,1081,1083],{"id":1082},"the-flush-runs-last","The flush runs last",[447,1085,1086,1088,1089,1092,1093,1096,1097,1100,1101,1104],{},[450,1087,568],{}," returns an aggregated shutdown function that the chassis runs as the ",[450,1090,1091],{},"Flush"," step of the ",[485,1094,1095],{"href":253},"application lifecycle",", ",[468,1098,1099],{},"last of all",", after the HTTP drain and after all your ",[450,1102,1103],{},"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.",[447,1106,1107,1108,1111],{},"There is ordering inside the shutdown too: the OTel providers stop first, and ",[468,1109,1110],{},"Sentry flushes last",", so events produced while the providers were shutting down still get out.",[494,1113,1115],{"id":1114},"if-you-dont-want-it-or-want-to-own-it","If you don't want it, or want to own it",[447,1117,1118],{},"All three chassis have an off switch:",[499,1120,1122],{"className":720,"code":1121,"language":515,"meta":504,"style":504},"server.Run(ctx, cfg.Server, register, server.WithoutTelemetry())\nworker.Run(ctx, cfg.Worker, register, worker.WithoutTelemetry())\nrealtime.Run(ctx, cfg.Realtime, register, realtime.WithoutTelemetry())\n",[450,1123,1124,1164,1200],{"__ignoreMap":504},[508,1125,1126,1129,1131,1134,1136,1138,1140,1142,1144,1146,1148,1151,1153,1156,1158,1161],{"class":510,"line":511},[508,1127,1128],{"class":743},"server",[508,1130,749],{"class":728},[508,1132,1133],{"class":810},"Run",[508,1135,814],{"class":728},[508,1137,818],{"class":743},[508,1139,829],{"class":728},[508,1141,832],{"class":743},[508,1143,749],{"class":728},[508,1145,257],{"class":743},[508,1147,829],{"class":728},[508,1149,1150],{"class":743}," register",[508,1152,829],{"class":728},[508,1154,1155],{"class":743}," server",[508,1157,749],{"class":728},[508,1159,1160],{"class":810},"WithoutTelemetry",[508,1162,1163],{"class":728},"())\n",[508,1165,1166,1169,1171,1173,1175,1177,1179,1181,1183,1185,1187,1189,1191,1194,1196,1198],{"class":510,"line":529},[508,1167,1168],{"class":743},"worker",[508,1170,749],{"class":728},[508,1172,1133],{"class":810},[508,1174,814],{"class":728},[508,1176,818],{"class":743},[508,1178,829],{"class":728},[508,1180,832],{"class":743},[508,1182,749],{"class":728},[508,1184,262],{"class":743},[508,1186,829],{"class":728},[508,1188,1150],{"class":743},[508,1190,829],{"class":728},[508,1192,1193],{"class":743}," worker",[508,1195,749],{"class":728},[508,1197,1160],{"class":810},[508,1199,1163],{"class":728},[508,1201,1202,1205,1207,1209,1211,1213,1215,1217,1219,1221,1223,1225,1227,1230,1232,1234],{"class":510,"line":758},[508,1203,1204],{"class":743},"realtime",[508,1206,749],{"class":728},[508,1208,1133],{"class":810},[508,1210,814],{"class":728},[508,1212,818],{"class":743},[508,1214,829],{"class":728},[508,1216,832],{"class":743},[508,1218,749],{"class":728},[508,1220,267],{"class":743},[508,1222,829],{"class":728},[508,1224,1150],{"class":743},[508,1226,829],{"class":728},[508,1228,1229],{"class":743}," realtime",[508,1231,749],{"class":728},[508,1233,1160],{"class":810},[508,1235,1163],{"class":728},[447,1237,1238,1240,1241,884,1243,1246],{},[450,1239,1160],{}," skips ",[450,1242,482],{},[468,1244,1245],{},"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.",[447,1248,1249,1250,1252,1253,1256,1257,1261],{},"In a non-chassis process (a CLI, a one-shot cron-like run) ",[450,1251,482],{}," can be called directly: you get the same composition, you just ",[450,1254,1255],{},"defer"," the shutdown function yourself. If you don't need Sentry either, ",[485,1258,1259],{"href":189},[450,1260,919],{}," stands on its own.",[494,1263,1265],{"id":1264},"where-to-next","Where to next",[1267,1268,1269,1277,1282],"ul",{},[899,1270,1271,1273,1274,1276],{},[485,1272,183],{"href":184},": the ",[450,1275,587],{}," composition and the Monolog-format dev console; through PHP eyes, the most striking part.",[899,1278,1279,1281],{},[485,1280,188],{"href":189},": what the kit instruments on its own, and how the shop's \"follow the order\" trace comes together.",[899,1283,1284,1286,1287,1289],{},[485,1285,193],{"href":194},": error reporting with ",[450,1288,357],{},"-code issue grouping, layered on top of OTel.",[1291,1292,1293],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}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":504,"searchDepth":529,"depth":529,"links":1295},[1296,1297,1298,1299,1300,1301,1302],{"id":496,"depth":529,"text":497},{"id":617,"depth":529,"text":618},{"id":890,"depth":529,"text":891},{"id":955,"depth":529,"text":956},{"id":1082,"depth":529,"text":1083},{"id":1114,"depth":529,"text":1115},{"id":1264,"depth":529,"text":1265},"The telemetry facade: logging, OpenTelemetry and Sentry in a single call, with one shutdown guarantee.","md",null,{},{"icon":175},{"title":52,"description":1303},"dfDOw0MHqY4d3U1ydzYx2MUiAtt-HXpZU1L079Tiki0",[1311,1313],{"title":169,"path":170,"stem":171,"description":1312,"icon":172,"children":-1},"The storagetest conformance suite, and what a custom Driver needs to implement.",{"title":183,"path":184,"stem":185,"description":1314,"icon":186,"children":-1},"Standard log\u002Fslog, composed, and a Monolog-format dev console with PHP-style stack traces.",1785445881142]