[{"data":1,"prerenderedAt":1615},["ShallowReactive",2],{"navigation":3,"docs-path-index":268,"-docs-modules-telemetry-overview":348,"-docs-modules-telemetry-overview-surround":1610},[4],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":56},"Docs","i-lucide-book-marked","\u002Fdocs","docs",[10,26,57,229,250],{"title":11,"path":12,"stem":13,"children":14,"icon":25},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started\u002F1.index",[15,17,21],{"title":16,"path":12,"stem":13},"Introduction",{"title":18,"path":19,"stem":20},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F1.getting-started\u002F2.installation",{"title":22,"path":23,"stem":24},"Examples","\u002Fdocs\u002Fgetting-started\u002Fexamples","docs\u002F1.getting-started\u002F3.examples","i-lucide-rocket",{"title":27,"icon":28,"path":29,"stem":30,"children":31,"page":56},"Core features","i-lucide-square-function","\u002Fdocs\u002Fcore-features","docs\u002F2.core-features",[32,36,40,44,48,52],{"title":33,"path":34,"stem":35},"Configuration","\u002Fdocs\u002Fcore-features\u002Fconfiguration","docs\u002F2.core-features\u002F0.configuration",{"title":37,"path":38,"stem":39},"Dependency Injection","\u002Fdocs\u002Fcore-features\u002Fcontainer","docs\u002F2.core-features\u002F1.container",{"title":41,"path":42,"stem":43},"Controllers","\u002Fdocs\u002Fcore-features\u002Fcontrollers","docs\u002F2.core-features\u002F2.controllers",{"title":45,"path":46,"stem":47},"Middlewares","\u002Fdocs\u002Fcore-features\u002Fmiddlewares","docs\u002F2.core-features\u002F3.middlewares",{"title":49,"path":50,"stem":51},"Validation","\u002Fdocs\u002Fcore-features\u002Fvalidation","docs\u002F2.core-features\u002F4.validation",{"title":53,"path":54,"stem":55},"Introspection","\u002Fdocs\u002Fcore-features\u002Fintrospection","docs\u002F2.core-features\u002F5.introspection",false,{"title":58,"icon":59,"defaultOpen":60,"path":61,"stem":62,"children":63,"page":56},"Modules","i-lucide-boxes",true,"\u002Fdocs\u002Fmodules","docs\u002F3.modules",[64,81,92,108,127,142,150,165,176,191,210,218],{"title":65,"icon":56,"defaultOpen":56,"path":66,"stem":67,"children":68,"page":56},"Auth","\u002Fdocs\u002Fmodules\u002Fauth","docs\u002F3.modules\u002F1.auth",[69,73,77],{"title":70,"path":71,"stem":72},"Overview","\u002Fdocs\u002Fmodules\u002Fauth\u002Foverview","docs\u002F3.modules\u002F1.auth\u002F0.overview",{"title":74,"path":75,"stem":76},"Decorators","\u002Fdocs\u002Fmodules\u002Fauth\u002Fdecorators","docs\u002F3.modules\u002F1.auth\u002F1.decorators",{"title":78,"path":79,"stem":80},"API Reference","\u002Fdocs\u002Fmodules\u002Fauth\u002Fapi","docs\u002F3.modules\u002F1.auth\u002F2.api",{"title":82,"icon":56,"defaultOpen":56,"path":83,"stem":84,"children":85,"page":56},"Devtools","\u002Fdocs\u002Fmodules\u002Fdevtools","docs\u002F3.modules\u002F10.devtools",[86,89],{"title":70,"path":87,"stem":88},"\u002Fdocs\u002Fmodules\u002Fdevtools\u002Foverview","docs\u002F3.modules\u002F10.devtools\u002F0.overview",{"title":33,"path":90,"stem":91},"\u002Fdocs\u002Fmodules\u002Fdevtools\u002Fconfiguration","docs\u002F3.modules\u002F10.devtools\u002F1.configuration",{"title":93,"path":94,"stem":95,"children":96,"page":56},"Telemetry","\u002Fdocs\u002Fmodules\u002Ftelemetry","docs\u002F3.modules\u002F11.telemetry",[97,100,104],{"title":70,"path":98,"stem":99},"\u002Fdocs\u002Fmodules\u002Ftelemetry\u002Foverview","docs\u002F3.modules\u002F11.telemetry\u002F0.overview",{"title":101,"path":102,"stem":103},"API","\u002Fdocs\u002Fmodules\u002Ftelemetry\u002Fapi","docs\u002F3.modules\u002F11.telemetry\u002F1.api",{"title":105,"path":106,"stem":107},"Instrumentation","\u002Fdocs\u002Fmodules\u002Ftelemetry\u002Finstrumentation","docs\u002F3.modules\u002F11.telemetry\u002F2.instrumentation",{"title":109,"path":110,"stem":111,"children":112,"page":56},"Queue","\u002Fdocs\u002Fmodules\u002Fqueue","docs\u002F3.modules\u002F12.queue",[113,116,120,124],{"title":70,"path":114,"stem":115},"\u002Fdocs\u002Fmodules\u002Fqueue\u002Foverview","docs\u002F3.modules\u002F12.queue\u002F0.overview",{"title":117,"path":118,"stem":119},"Consumers","\u002Fdocs\u002Fmodules\u002Fqueue\u002Fconsumers","docs\u002F3.modules\u002F12.queue\u002F1.consumers",{"title":121,"path":122,"stem":123},"Strategies","\u002Fdocs\u002Fmodules\u002Fqueue\u002Fstrategies","docs\u002F3.modules\u002F12.queue\u002F2.strategies",{"title":101,"path":125,"stem":126},"\u002Fdocs\u002Fmodules\u002Fqueue\u002Fapi","docs\u002F3.modules\u002F12.queue\u002F3.api",{"title":128,"icon":56,"defaultOpen":56,"path":129,"stem":130,"children":131,"page":56},"Logger","\u002Fdocs\u002Fmodules\u002Flogger","docs\u002F3.modules\u002F2.logger",[132,135,139],{"title":70,"path":133,"stem":134},"\u002Fdocs\u002Fmodules\u002Flogger\u002Foverview","docs\u002F3.modules\u002F2.logger\u002F0.overview",{"title":136,"path":137,"stem":138},"Drains & Adapters","\u002Fdocs\u002Fmodules\u002Flogger\u002Fdrivers","docs\u002F3.modules\u002F2.logger\u002F1.drivers",{"title":101,"path":140,"stem":141},"\u002Fdocs\u002Fmodules\u002Flogger\u002Fapi","docs\u002F3.modules\u002F2.logger\u002F2.api",{"title":143,"icon":56,"defaultOpen":56,"path":144,"stem":145,"children":146,"page":56},"Serverless","\u002Fdocs\u002Fmodules\u002Fserverless","docs\u002F3.modules\u002F3.serverless",[147],{"title":70,"path":148,"stem":149},"\u002Fdocs\u002Fmodules\u002Fserverless\u002Foverview","docs\u002F3.modules\u002F3.serverless\u002F0.overview",{"title":151,"icon":56,"defaultOpen":56,"path":152,"stem":153,"children":154,"page":56},"Storage","\u002Fdocs\u002Fmodules\u002Fstorage","docs\u002F3.modules\u002F4.storage",[155,158,162],{"title":70,"path":156,"stem":157},"\u002Fdocs\u002Fmodules\u002Fstorage\u002Foverview","docs\u002F3.modules\u002F4.storage\u002F0.overview",{"title":159,"path":160,"stem":161},"Drivers","\u002Fdocs\u002Fmodules\u002Fstorage\u002Fdrivers","docs\u002F3.modules\u002F4.storage\u002F1.drivers",{"title":101,"path":163,"stem":164},"\u002Fdocs\u002Fmodules\u002Fstorage\u002Fapi","docs\u002F3.modules\u002F4.storage\u002F2.api",{"title":166,"icon":56,"defaultOpen":56,"path":167,"stem":168,"children":169,"page":56},"Web Sockets","\u002Fdocs\u002Fmodules\u002Fweb-sockets","docs\u002F3.modules\u002F5.web-sockets",[170,173],{"title":70,"path":171,"stem":172},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002Foverview","docs\u002F3.modules\u002F5.web-sockets\u002F0.overview",{"title":101,"path":174,"stem":175},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002Fapi","docs\u002F3.modules\u002F5.web-sockets\u002F1.api",{"title":177,"icon":56,"defaultOpen":56,"path":178,"stem":179,"children":180,"page":56},"Schema","\u002Fdocs\u002Fmodules\u002Fschema","docs\u002F3.modules\u002F6.schema",[181,184,187],{"title":70,"path":182,"stem":183},"\u002Fdocs\u002Fmodules\u002Fschema\u002Foverview","docs\u002F3.modules\u002F6.schema\u002F0.overview",{"title":74,"path":185,"stem":186},"\u002Fdocs\u002Fmodules\u002Fschema\u002Fdecorators","docs\u002F3.modules\u002F6.schema\u002F1.decorators",{"title":188,"path":189,"stem":190},"Scalar","\u002Fdocs\u002Fmodules\u002Fschema\u002Fscalar","docs\u002F3.modules\u002F6.schema\u002F2.scalar",{"title":192,"icon":56,"defaultOpen":56,"path":193,"stem":194,"children":195,"page":56},"Nitro","\u002Fdocs\u002Fmodules\u002Fnitro","docs\u002F3.modules\u002F7.nitro",[196,199,202,206],{"title":70,"path":197,"stem":198},"\u002Fdocs\u002Fmodules\u002Fnitro\u002Foverview","docs\u002F3.modules\u002F7.nitro\u002F0.overview",{"title":151,"path":200,"stem":201},"\u002Fdocs\u002Fmodules\u002Fnitro\u002Fstorage","docs\u002F3.modules\u002F7.nitro\u002F1.storage",{"title":203,"path":204,"stem":205},"File-Based Routes","\u002Fdocs\u002Fmodules\u002Fnitro\u002Ffile-based-routes","docs\u002F3.modules\u002F7.nitro\u002F2.file-based-routes",{"title":207,"path":208,"stem":209},"Middleware","\u002Fdocs\u002Fmodules\u002Fnitro\u002Fmiddleware","docs\u002F3.modules\u002F7.nitro\u002F3.middleware",{"title":211,"icon":56,"defaultOpen":56,"path":212,"stem":213,"children":214,"page":56},"Vite","\u002Fdocs\u002Fmodules\u002Fvite","docs\u002F3.modules\u002F8.vite",[215],{"title":70,"path":216,"stem":217},"\u002Fdocs\u002Fmodules\u002Fvite\u002Foverview","docs\u002F3.modules\u002F8.vite\u002F0.overview",{"title":219,"icon":56,"defaultOpen":56,"path":220,"stem":221,"children":222,"page":56},"Cache","\u002Fdocs\u002Fmodules\u002Fcache","docs\u002F3.modules\u002F9.cache",[223,226],{"title":70,"path":224,"stem":225},"\u002Fdocs\u002Fmodules\u002Fcache\u002Foverview","docs\u002F3.modules\u002F9.cache\u002F0.overview",{"title":101,"path":227,"stem":228},"\u002Fdocs\u002Fmodules\u002Fcache\u002Fapi","docs\u002F3.modules\u002F9.cache\u002F1.api",{"title":230,"icon":231,"path":232,"stem":233,"children":234,"page":56},"Deployment","i-lucide-cloud-upload","\u002Fdocs\u002Fdeployment","docs\u002F4.deployment",[235,238,242,246],{"title":70,"path":236,"stem":237},"\u002Fdocs\u002Fdeployment\u002Foverview","docs\u002F4.deployment\u002F0.overview",{"title":239,"path":240,"stem":241},"Vercel","\u002Fdocs\u002Fdeployment\u002Fvercel","docs\u002F4.deployment\u002F1.vercel",{"title":243,"path":244,"stem":245},"AWS Lambda","\u002Fdocs\u002Fdeployment\u002Faws-lambda","docs\u002F4.deployment\u002F2.aws-lambda",{"title":247,"path":248,"stem":249},"Azure Functions","\u002Fdocs\u002Fdeployment\u002Fazure-functions","docs\u002F4.deployment\u002F3.azure-functions",{"title":251,"icon":252,"path":253,"stem":254,"children":255,"page":56},"Advanced","i-lucide-brain","\u002Fdocs\u002Fadvanced","docs\u002F99.advanced",[256,260,264],{"title":257,"path":258,"stem":259},"Custom Decorator","\u002Fdocs\u002Fadvanced\u002Fcustom-decorator","docs\u002F99.advanced\u002F1.custom-decorator",{"title":261,"path":262,"stem":263},"Plugins","\u002Fdocs\u002Fadvanced\u002Fcustom-plugin","docs\u002F99.advanced\u002F2.custom-plugin",{"title":265,"path":266,"stem":267},"Custom CLI Command","\u002Fdocs\u002Fadvanced\u002Fcustom-cli-command","docs\u002F99.advanced\u002F3.custom-cli-command",[269,271,273,274,275,276,278,279,280,281,282,283,284,286,288,289,290,291,293,294,295,296,297,298,299,300,301,302,304,305,306,307,309,310,312,313,314,315,317,318,319,321,322,323,324,326,327,328,329,330,332,333,335,336,337,339,340,341,342,343,345,346,347],{"path":270},"\u002Fdocs\u002F.navigation",{"path":272},"\u002Fdocs\u002Fgetting-started\u002F.navigation",{"path":12},{"path":19},{"path":23},{"path":277},"\u002Fdocs\u002Fcore-features\u002F.navigation",{"path":34},{"path":38},{"path":42},{"path":46},{"path":50},{"path":54},{"path":285},"\u002Fdocs\u002Fmodules\u002F.navigation",{"path":287},"\u002Fdocs\u002Fmodules\u002Fauth\u002F.navigation",{"path":71},{"path":75},{"path":79},{"path":292},"\u002Fdocs\u002Fmodules\u002Fdevtools\u002F.navigation",{"path":87},{"path":90},{"path":98},{"path":102},{"path":106},{"path":114},{"path":118},{"path":122},{"path":125},{"path":303},"\u002Fdocs\u002Fmodules\u002Flogger\u002F.navigation",{"path":133},{"path":137},{"path":140},{"path":308},"\u002Fdocs\u002Fmodules\u002Fserverless\u002F.navigation",{"path":148},{"path":311},"\u002Fdocs\u002Fmodules\u002Fstorage\u002F.navigation",{"path":156},{"path":160},{"path":163},{"path":316},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002F.navigation",{"path":171},{"path":174},{"path":320},"\u002Fdocs\u002Fmodules\u002Fschema\u002F.navigation",{"path":182},{"path":185},{"path":189},{"path":325},"\u002Fdocs\u002Fmodules\u002Fnitro\u002F.navigation",{"path":197},{"path":200},{"path":204},{"path":208},{"path":331},"\u002Fdocs\u002Fmodules\u002Fvite\u002F.navigation",{"path":216},{"path":334},"\u002Fdocs\u002Fmodules\u002Fcache\u002F.navigation",{"path":224},{"path":227},{"path":338},"\u002Fdocs\u002Fdeployment\u002F.navigation",{"path":236},{"path":240},{"path":244},{"path":248},{"path":344},"\u002Fdocs\u002Fadvanced\u002F.navigation",{"path":258},{"path":262},{"path":266},{"id":349,"title":70,"body":350,"description":1604,"extension":1605,"links":1606,"meta":1607,"navigation":60,"path":98,"seo":1608,"stem":99,"__hash__":1609},"docs\u002Fdocs\u002F3.modules\u002F11.telemetry\u002F0.overview.md",{"type":351,"value":352,"toc":1594},"minimark",[353,357,360,364,432,435,451,455,458,586,589,672,679,683,690,698,701,717,740,751,755,766,989,998,1002,1202,1208,1218,1222,1232,1235,1309,1312,1524,1530,1536,1565,1568,1572,1583,1590],[354,355,356],"p",{},"The Telemetry module turns every request into an OpenTelemetry span, records the standard HTTP metrics, and stamps each log line with the trace it belongs to. It speaks the OpenTelemetry API rather than a Vercube-specific one, so any OTLP backend works: Jaeger, Grafana Tempo, Honeycomb, Datadog, or a collector of your own.",[354,358,359],{},"By default it is on in development and off in production, because tracing every request costs real throughput and a production deployment should turn it on together with an exporter.",[361,362,18],"h2",{"id":363},"installation",[365,366,367,397,415],"code-group",{},[368,369,375],"pre",{"className":370,"code":371,"filename":372,"language":373,"meta":374,"style":374},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","$ pnpm add @vercube\u002Ftelemetry\n","pnpm","bash","",[376,377,378],"code",{"__ignoreMap":374},[379,380,383,387,391,394],"span",{"class":381,"line":382},"line",1,[379,384,386],{"class":385},"sBMFI","$",[379,388,390],{"class":389},"sfazB"," pnpm",[379,392,393],{"class":389}," add",[379,395,396],{"class":389}," @vercube\u002Ftelemetry\n",[368,398,401],{"className":370,"code":399,"filename":400,"language":373,"meta":374,"style":374},"$ npm install @vercube\u002Ftelemetry\n","npm",[376,402,403],{"__ignoreMap":374},[379,404,405,407,410,413],{"class":381,"line":382},[379,406,386],{"class":385},[379,408,409],{"class":389}," npm",[379,411,412],{"class":389}," install",[379,414,396],{"class":389},[368,416,419],{"className":370,"code":417,"filename":418,"language":373,"meta":374,"style":374},"$ bun install @vercube\u002Ftelemetry\n","bun",[376,420,421],{"__ignoreMap":374},[379,422,423,425,428,430],{"class":381,"line":382},[379,424,386],{"class":385},[379,426,427],{"class":389}," bun",[379,429,412],{"class":389},[379,431,396],{"class":389},[354,433,434],{},"That is the whole installation. This is the only package in the framework that depends on OpenTelemetry, and it ships the tracer and meter providers, the samplers and the in-memory test providers with it. Exporting to an OTLP collector is the one thing that needs more, because the exporter pulls a protobuf stack an application doing purely local tracing has no use for:",[368,436,438],{"className":370,"code":437,"language":373,"meta":374,"style":374},"$ pnpm add @opentelemetry\u002Fexporter-trace-otlp-http\n",[376,439,440],{"__ignoreMap":374},[379,441,442,444,446,448],{"class":381,"line":382},[379,443,386],{"class":385},[379,445,390],{"class":389},[379,447,393],{"class":389},[379,449,450],{"class":389}," @opentelemetry\u002Fexporter-trace-otlp-http\n",[361,452,454],{"id":453},"getting-started","Getting started",[354,456,457],{},"Register the plugin in your configuration:",[368,459,464],{"className":460,"code":461,"filename":462,"language":463,"meta":374,"style":374},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { defineConfig } from '@vercube\u002Fcore';\nimport { TelemetryPlugin } from '@vercube\u002Ftelemetry';\n\nexport default defineConfig({\n  telemetry: true,\n  plugins: [TelemetryPlugin],\n});\n","vercube.config.ts","ts",[376,465,466,498,521,527,545,562,575],{"__ignoreMap":374},[379,467,468,472,476,480,483,486,489,492,495],{"class":381,"line":382},[379,469,471],{"class":470},"s7zQu","import",[379,473,475],{"class":474},"sMK4o"," {",[379,477,479],{"class":478},"sTEyZ"," defineConfig",[379,481,482],{"class":474}," }",[379,484,485],{"class":470}," from",[379,487,488],{"class":474}," '",[379,490,491],{"class":389},"@vercube\u002Fcore",[379,493,494],{"class":474},"'",[379,496,497],{"class":474},";\n",[379,499,501,503,505,508,510,512,514,517,519],{"class":381,"line":500},2,[379,502,471],{"class":470},[379,504,475],{"class":474},[379,506,507],{"class":478}," TelemetryPlugin",[379,509,482],{"class":474},[379,511,485],{"class":470},[379,513,488],{"class":474},[379,515,516],{"class":389},"@vercube\u002Ftelemetry",[379,518,494],{"class":474},[379,520,497],{"class":474},[379,522,524],{"class":381,"line":523},3,[379,525,526],{"emptyLinePlaceholder":60},"\n",[379,528,530,533,536,539,542],{"class":381,"line":529},4,[379,531,532],{"class":470},"export",[379,534,535],{"class":470}," default",[379,537,479],{"class":538},"s2Zo4",[379,540,541],{"class":478},"(",[379,543,544],{"class":474},"{\n",[379,546,548,552,555,559],{"class":381,"line":547},5,[379,549,551],{"class":550},"swJcz","  telemetry",[379,553,554],{"class":474},":",[379,556,558],{"class":557},"sfNiH"," true",[379,560,561],{"class":474},",\n",[379,563,565,568,570,573],{"class":381,"line":564},6,[379,566,567],{"class":550},"  plugins",[379,569,554],{"class":474},[379,571,572],{"class":478}," [TelemetryPlugin]",[379,574,561],{"class":474},[379,576,578,581,584],{"class":381,"line":577},7,[379,579,580],{"class":474},"}",[379,582,583],{"class":478},")",[379,585,497],{"class":474},[354,587,588],{},"That alone gives you W3C trace context propagation and log correlation. Nothing is recorded yet, because the OpenTelemetry API is a no-op until a tracer provider exists. Start one in your entry file:",[368,590,593],{"className":460,"code":591,"filename":592,"language":463,"meta":374,"style":374},"import { startNodeTelemetry } from '@vercube\u002Ftelemetry\u002Fsdk';\n\nawait startNodeTelemetry({\n  serviceName: 'checkout',\n  endpoint: 'http:\u002F\u002Flocalhost:4318',\n});\n","src\u002Findex.ts",[376,594,595,617,621,632,648,664],{"__ignoreMap":374},[379,596,597,599,601,604,606,608,610,613,615],{"class":381,"line":382},[379,598,471],{"class":470},[379,600,475],{"class":474},[379,602,603],{"class":478}," startNodeTelemetry",[379,605,482],{"class":474},[379,607,485],{"class":470},[379,609,488],{"class":474},[379,611,612],{"class":389},"@vercube\u002Ftelemetry\u002Fsdk",[379,614,494],{"class":474},[379,616,497],{"class":474},[379,618,619],{"class":381,"line":500},[379,620,526],{"emptyLinePlaceholder":60},[379,622,623,626,628,630],{"class":381,"line":523},[379,624,625],{"class":470},"await",[379,627,603],{"class":538},[379,629,541],{"class":478},[379,631,544],{"class":474},[379,633,634,637,639,641,644,646],{"class":381,"line":529},[379,635,636],{"class":550},"  serviceName",[379,638,554],{"class":474},[379,640,488],{"class":474},[379,642,643],{"class":389},"checkout",[379,645,494],{"class":474},[379,647,561],{"class":474},[379,649,650,653,655,657,660,662],{"class":381,"line":547},[379,651,652],{"class":550},"  endpoint",[379,654,554],{"class":474},[379,656,488],{"class":474},[379,658,659],{"class":389},"http:\u002F\u002Flocalhost:4318",[379,661,494],{"class":474},[379,663,561],{"class":474},[379,665,666,668,670],{"class":381,"line":564},[379,667,580],{"class":474},[379,669,583],{"class":478},[379,671,497],{"class":474},[354,673,674,675,678],{},"Call it before ",[376,676,677],{},"createApp()"," so application bootstrap is traced too.",[361,680,682],{"id":681},"what-you-get","What you get",[354,684,685,686,689],{},"Every request produces a ",[376,687,688],{},"SERVER"," span named after its route, carrying the stable HTTP semantic conventions:",[368,691,696],{"className":692,"code":694,"language":695},[693],"language-text","GET \u002Fusers\u002F:id\n  http.request.method     GET\n  http.route              \u002Fusers\u002F:id\n  http.response.status_code 200\n  url.path                \u002Fusers\u002F42\n  server.address          api.example.com\n  vercube.controller      UsersController\n  vercube.handler         byId\n","text",[376,697,694],{"__ignoreMap":374},[354,699,700],{},"Alongside it:",[702,703,704,711,714],"ul",{},[705,706,707,710],"li",{},[376,708,709],{},"http.server.request.duration",", a histogram keyed by method, route and status. The URL is deliberately not an attribute, because one time series per URL is how a metrics backend gets destroyed.",[705,712,713],{},"Process gauges: heap usage, resident set size, CPU utilisation, event loop delay and utilisation.",[705,715,716],{},"Container construction replayed as a trace, so application startup shows up as an ordinary waterfall.",[354,718,719,720,723,724,727,728,731,732,735,736,739],{},"Instrumented modules add their own spans automatically. ",[376,721,722],{},"@vercube\u002Fstorage"," traces each operation, ",[376,725,726],{},"@vercube\u002Fcache"," traces lookups and counts hits and misses, ",[376,729,730],{},"@vercube\u002Fws"," traces messages, ",[376,733,734],{},"@vercube\u002Fqueue"," traces published and processed jobs, and ",[376,737,738],{},"@vercube\u002Fauth"," records each authentication decision. They appear nested under the request that caused them without any wiring on your side.",[354,741,742,743,746,747,750],{},"They all do it through ",[376,744,745],{},"@vercube\u002Ftelemetry\u002Finstrument",", which is public: see ",[748,749,105],"a",{"href":106}," to do the same in a library of your own.",[361,752,754],{"id":753},"trace-context","Trace context",[354,756,757,758,761,762,765],{},"Incoming ",[376,759,760],{},"traceparent"," and ",[376,763,764],{},"tracestate"," headers are read, so a request that arrives from another service continues the same trace. Going the other way, inject the current context into an outgoing call:",[368,767,769],{"className":460,"code":768,"language":463,"meta":374,"style":374},"import { Inject } from '@vercube\u002Fdi';\nimport { Telemetry } from '@vercube\u002Ftelemetry';\n\nclass InvoiceClient {\n  @Inject(Telemetry)\n  private gTelemetry!: Telemetry;\n\n  public async fetchInvoice(id: string) {\n    const headers = new Headers();\n    this.gTelemetry.inject(headers);\n\n    return fetch(`https:\u002F\u002Fbilling.internal\u002Finvoices\u002F${id}`, { headers });\n  }\n}\n",[376,770,771,793,814,818,830,841,856,860,887,910,934,939,977,983],{"__ignoreMap":374},[379,772,773,775,777,780,782,784,786,789,791],{"class":381,"line":382},[379,774,471],{"class":470},[379,776,475],{"class":474},[379,778,779],{"class":478}," Inject",[379,781,482],{"class":474},[379,783,485],{"class":470},[379,785,488],{"class":474},[379,787,788],{"class":389},"@vercube\u002Fdi",[379,790,494],{"class":474},[379,792,497],{"class":474},[379,794,795,797,799,802,804,806,808,810,812],{"class":381,"line":500},[379,796,471],{"class":470},[379,798,475],{"class":474},[379,800,801],{"class":478}," Telemetry",[379,803,482],{"class":474},[379,805,485],{"class":470},[379,807,488],{"class":474},[379,809,516],{"class":389},[379,811,494],{"class":474},[379,813,497],{"class":474},[379,815,816],{"class":381,"line":523},[379,817,526],{"emptyLinePlaceholder":60},[379,819,820,824,827],{"class":381,"line":529},[379,821,823],{"class":822},"spNyl","class",[379,825,826],{"class":385}," InvoiceClient",[379,828,829],{"class":474}," {\n",[379,831,832,835,838],{"class":381,"line":547},[379,833,834],{"class":474},"  @",[379,836,837],{"class":538},"Inject",[379,839,840],{"class":478},"(Telemetry)\n",[379,842,843,846,849,852,854],{"class":381,"line":564},[379,844,845],{"class":822},"  private",[379,847,848],{"class":550}," gTelemetry",[379,850,851],{"class":474},"!:",[379,853,801],{"class":385},[379,855,497],{"class":474},[379,857,858],{"class":381,"line":577},[379,859,526],{"emptyLinePlaceholder":60},[379,861,863,866,869,872,874,878,880,883,885],{"class":381,"line":862},8,[379,864,865],{"class":822},"  public",[379,867,868],{"class":822}," async",[379,870,871],{"class":550}," fetchInvoice",[379,873,541],{"class":474},[379,875,877],{"class":876},"sHdIc","id",[379,879,554],{"class":474},[379,881,882],{"class":385}," string",[379,884,583],{"class":474},[379,886,829],{"class":474},[379,888,890,893,896,899,902,905,908],{"class":381,"line":889},9,[379,891,892],{"class":822},"    const",[379,894,895],{"class":478}," headers",[379,897,898],{"class":474}," =",[379,900,901],{"class":474}," new",[379,903,904],{"class":538}," Headers",[379,906,907],{"class":550},"()",[379,909,497],{"class":474},[379,911,913,916,919,922,925,927,930,932],{"class":381,"line":912},10,[379,914,915],{"class":474},"    this.",[379,917,918],{"class":478},"gTelemetry",[379,920,921],{"class":474},".",[379,923,924],{"class":538},"inject",[379,926,541],{"class":550},[379,928,929],{"class":478},"headers",[379,931,583],{"class":550},[379,933,497],{"class":474},[379,935,937],{"class":381,"line":936},11,[379,938,526],{"emptyLinePlaceholder":60},[379,940,942,945,948,950,953,956,959,961,964,967,969,971,973,975],{"class":381,"line":941},12,[379,943,944],{"class":470},"    return",[379,946,947],{"class":538}," fetch",[379,949,541],{"class":550},[379,951,952],{"class":474},"`",[379,954,955],{"class":389},"https:\u002F\u002Fbilling.internal\u002Finvoices\u002F",[379,957,958],{"class":474},"${",[379,960,877],{"class":478},[379,962,963],{"class":474},"}`",[379,965,966],{"class":474},",",[379,968,475],{"class":474},[379,970,895],{"class":478},[379,972,482],{"class":474},[379,974,583],{"class":550},[379,976,497],{"class":474},[379,978,980],{"class":381,"line":979},13,[379,981,982],{"class":474},"  }\n",[379,984,986],{"class":381,"line":985},14,[379,987,988],{"class":474},"}\n",[354,990,991,992,994,995,997],{},"Trace context also travels through ",[376,993,734],{},": a published job carries ",[376,996,760],{}," in its headers, and the worker that runs it continues that trace, in whatever process it happens to be.",[361,999,1001],{"id":1000},"tracing-your-own-work","Tracing your own work",[368,1003,1005],{"className":460,"code":1004,"language":463,"meta":374,"style":374},"import { Inject } from '@vercube\u002Fdi';\nimport { Telemetry } from '@vercube\u002Ftelemetry';\n\nclass InvoiceService {\n  @Inject(Telemetry)\n  private gTelemetry!: Telemetry;\n\n  public refund(id: string) {\n    return this.gTelemetry.span('invoice.refund', (span) => {\n      span.setAttribute('invoice.id', id);\n      return this.process(id);\n    });\n  }\n}\n",[376,1006,1007,1027,1047,1051,1060,1068,1080,1084,1103,1139,1167,1185,1194,1198],{"__ignoreMap":374},[379,1008,1009,1011,1013,1015,1017,1019,1021,1023,1025],{"class":381,"line":382},[379,1010,471],{"class":470},[379,1012,475],{"class":474},[379,1014,779],{"class":478},[379,1016,482],{"class":474},[379,1018,485],{"class":470},[379,1020,488],{"class":474},[379,1022,788],{"class":389},[379,1024,494],{"class":474},[379,1026,497],{"class":474},[379,1028,1029,1031,1033,1035,1037,1039,1041,1043,1045],{"class":381,"line":500},[379,1030,471],{"class":470},[379,1032,475],{"class":474},[379,1034,801],{"class":478},[379,1036,482],{"class":474},[379,1038,485],{"class":470},[379,1040,488],{"class":474},[379,1042,516],{"class":389},[379,1044,494],{"class":474},[379,1046,497],{"class":474},[379,1048,1049],{"class":381,"line":523},[379,1050,526],{"emptyLinePlaceholder":60},[379,1052,1053,1055,1058],{"class":381,"line":529},[379,1054,823],{"class":822},[379,1056,1057],{"class":385}," InvoiceService",[379,1059,829],{"class":474},[379,1061,1062,1064,1066],{"class":381,"line":547},[379,1063,834],{"class":474},[379,1065,837],{"class":538},[379,1067,840],{"class":478},[379,1069,1070,1072,1074,1076,1078],{"class":381,"line":564},[379,1071,845],{"class":822},[379,1073,848],{"class":550},[379,1075,851],{"class":474},[379,1077,801],{"class":385},[379,1079,497],{"class":474},[379,1081,1082],{"class":381,"line":577},[379,1083,526],{"emptyLinePlaceholder":60},[379,1085,1086,1088,1091,1093,1095,1097,1099,1101],{"class":381,"line":862},[379,1087,865],{"class":822},[379,1089,1090],{"class":550}," refund",[379,1092,541],{"class":474},[379,1094,877],{"class":876},[379,1096,554],{"class":474},[379,1098,882],{"class":385},[379,1100,583],{"class":474},[379,1102,829],{"class":474},[379,1104,1105,1107,1110,1112,1114,1116,1118,1120,1123,1125,1127,1130,1132,1134,1137],{"class":381,"line":889},[379,1106,944],{"class":470},[379,1108,1109],{"class":474}," this.",[379,1111,918],{"class":478},[379,1113,921],{"class":474},[379,1115,379],{"class":538},[379,1117,541],{"class":550},[379,1119,494],{"class":474},[379,1121,1122],{"class":389},"invoice.refund",[379,1124,494],{"class":474},[379,1126,966],{"class":474},[379,1128,1129],{"class":474}," (",[379,1131,379],{"class":876},[379,1133,583],{"class":474},[379,1135,1136],{"class":822}," =>",[379,1138,829],{"class":474},[379,1140,1141,1144,1146,1149,1151,1153,1156,1158,1160,1163,1165],{"class":381,"line":912},[379,1142,1143],{"class":478},"      span",[379,1145,921],{"class":474},[379,1147,1148],{"class":538},"setAttribute",[379,1150,541],{"class":550},[379,1152,494],{"class":474},[379,1154,1155],{"class":389},"invoice.id",[379,1157,494],{"class":474},[379,1159,966],{"class":474},[379,1161,1162],{"class":478}," id",[379,1164,583],{"class":550},[379,1166,497],{"class":474},[379,1168,1169,1172,1174,1177,1179,1181,1183],{"class":381,"line":936},[379,1170,1171],{"class":470},"      return",[379,1173,1109],{"class":474},[379,1175,1176],{"class":538},"process",[379,1178,541],{"class":550},[379,1180,877],{"class":478},[379,1182,583],{"class":550},[379,1184,497],{"class":474},[379,1186,1187,1190,1192],{"class":381,"line":941},[379,1188,1189],{"class":474},"    }",[379,1191,583],{"class":550},[379,1193,497],{"class":474},[379,1195,1196],{"class":381,"line":979},[379,1197,982],{"class":474},[379,1199,1200],{"class":381,"line":985},[379,1201,988],{"class":474},[354,1203,1204,1207],{},[376,1205,1206],{},"span()"," returns whatever your function returns, unchanged. A synchronous function stays synchronous.",[354,1209,1210,1212,1213,1217],{},[376,1211,93],{}," is the token for application code. A reusable library is better off with ",[748,1214,1215],{"href":106},[376,1216,745],{},", which needs no container.",[361,1219,1221],{"id":1220},"logs","Logs",[354,1223,1224,1225,761,1228,1231],{},"With telemetry active, every log line carries ",[376,1226,1227],{},"traceId",[376,1229,1230],{},"spanId",", and the per-request wide event is keyed by the trace id instead of a random one. A backend that ingests both can jump from a log line to the span that produced it.",[354,1233,1234],{},"Shipping logs to the same collector takes one option:",[368,1236,1238],{"className":460,"code":1237,"filename":462,"language":463,"meta":374,"style":374},"export default defineConfig({\n  telemetry: {\n    logs: true,\n    endpoint: 'http:\u002F\u002Flocalhost:4318',\n  },\n  plugins: [TelemetryPlugin],\n});\n",[376,1239,1240,1252,1260,1271,1286,1291,1301],{"__ignoreMap":374},[379,1241,1242,1244,1246,1248,1250],{"class":381,"line":382},[379,1243,532],{"class":470},[379,1245,535],{"class":470},[379,1247,479],{"class":538},[379,1249,541],{"class":478},[379,1251,544],{"class":474},[379,1253,1254,1256,1258],{"class":381,"line":500},[379,1255,551],{"class":550},[379,1257,554],{"class":474},[379,1259,829],{"class":474},[379,1261,1262,1265,1267,1269],{"class":381,"line":523},[379,1263,1264],{"class":550},"    logs",[379,1266,554],{"class":474},[379,1268,558],{"class":557},[379,1270,561],{"class":474},[379,1272,1273,1276,1278,1280,1282,1284],{"class":381,"line":529},[379,1274,1275],{"class":550},"    endpoint",[379,1277,554],{"class":474},[379,1279,488],{"class":474},[379,1281,659],{"class":389},[379,1283,494],{"class":474},[379,1285,561],{"class":474},[379,1287,1288],{"class":381,"line":547},[379,1289,1290],{"class":474},"  },\n",[379,1292,1293,1295,1297,1299],{"class":381,"line":564},[379,1294,567],{"class":550},[379,1296,554],{"class":474},[379,1298,572],{"class":478},[379,1300,561],{"class":474},[379,1302,1303,1305,1307],{"class":381,"line":577},[379,1304,580],{"class":474},[379,1306,583],{"class":478},[379,1308,497],{"class":474},[361,1310,33],{"id":1311},"configuration",[368,1313,1315],{"className":460,"code":1314,"filename":462,"language":463,"meta":374,"style":374},"export default defineConfig({\n  telemetry: {\n    enabled: true,\n    serviceName: 'checkout',\n    sampler: { ratio: 0.1 },\n    exclude: ['\u002Fhealth'],\n    spans: {\n      handler: true,\n      middleware: false,\n      di: true,\n      bodies: false,\n      headers: false,\n    },\n    propagation: true,\n    metrics: true,\n    logs: false,\n  },\n});\n",[376,1316,1317,1329,1337,1348,1363,1384,1406,1415,1426,1438,1449,1460,1471,1476,1487,1499,1510,1515],{"__ignoreMap":374},[379,1318,1319,1321,1323,1325,1327],{"class":381,"line":382},[379,1320,532],{"class":470},[379,1322,535],{"class":470},[379,1324,479],{"class":538},[379,1326,541],{"class":478},[379,1328,544],{"class":474},[379,1330,1331,1333,1335],{"class":381,"line":500},[379,1332,551],{"class":550},[379,1334,554],{"class":474},[379,1336,829],{"class":474},[379,1338,1339,1342,1344,1346],{"class":381,"line":523},[379,1340,1341],{"class":550},"    enabled",[379,1343,554],{"class":474},[379,1345,558],{"class":557},[379,1347,561],{"class":474},[379,1349,1350,1353,1355,1357,1359,1361],{"class":381,"line":529},[379,1351,1352],{"class":550},"    serviceName",[379,1354,554],{"class":474},[379,1356,488],{"class":474},[379,1358,643],{"class":389},[379,1360,494],{"class":474},[379,1362,561],{"class":474},[379,1364,1365,1368,1370,1372,1375,1377,1381],{"class":381,"line":547},[379,1366,1367],{"class":550},"    sampler",[379,1369,554],{"class":474},[379,1371,475],{"class":474},[379,1373,1374],{"class":550}," ratio",[379,1376,554],{"class":474},[379,1378,1380],{"class":1379},"sbssI"," 0.1",[379,1382,1383],{"class":474}," },\n",[379,1385,1386,1389,1391,1394,1396,1399,1401,1404],{"class":381,"line":564},[379,1387,1388],{"class":550},"    exclude",[379,1390,554],{"class":474},[379,1392,1393],{"class":478}," [",[379,1395,494],{"class":474},[379,1397,1398],{"class":389},"\u002Fhealth",[379,1400,494],{"class":474},[379,1402,1403],{"class":478},"]",[379,1405,561],{"class":474},[379,1407,1408,1411,1413],{"class":381,"line":577},[379,1409,1410],{"class":550},"    spans",[379,1412,554],{"class":474},[379,1414,829],{"class":474},[379,1416,1417,1420,1422,1424],{"class":381,"line":862},[379,1418,1419],{"class":550},"      handler",[379,1421,554],{"class":474},[379,1423,558],{"class":557},[379,1425,561],{"class":474},[379,1427,1428,1431,1433,1436],{"class":381,"line":889},[379,1429,1430],{"class":550},"      middleware",[379,1432,554],{"class":474},[379,1434,1435],{"class":557}," false",[379,1437,561],{"class":474},[379,1439,1440,1443,1445,1447],{"class":381,"line":912},[379,1441,1442],{"class":550},"      di",[379,1444,554],{"class":474},[379,1446,558],{"class":557},[379,1448,561],{"class":474},[379,1450,1451,1454,1456,1458],{"class":381,"line":936},[379,1452,1453],{"class":550},"      bodies",[379,1455,554],{"class":474},[379,1457,1435],{"class":557},[379,1459,561],{"class":474},[379,1461,1462,1465,1467,1469],{"class":381,"line":941},[379,1463,1464],{"class":550},"      headers",[379,1466,554],{"class":474},[379,1468,1435],{"class":557},[379,1470,561],{"class":474},[379,1472,1473],{"class":381,"line":979},[379,1474,1475],{"class":474},"    },\n",[379,1477,1478,1481,1483,1485],{"class":381,"line":985},[379,1479,1480],{"class":550},"    propagation",[379,1482,554],{"class":474},[379,1484,558],{"class":557},[379,1486,561],{"class":474},[379,1488,1490,1493,1495,1497],{"class":381,"line":1489},15,[379,1491,1492],{"class":550},"    metrics",[379,1494,554],{"class":474},[379,1496,558],{"class":557},[379,1498,561],{"class":474},[379,1500,1502,1504,1506,1508],{"class":381,"line":1501},16,[379,1503,1264],{"class":550},[379,1505,554],{"class":474},[379,1507,1435],{"class":557},[379,1509,561],{"class":474},[379,1511,1513],{"class":381,"line":1512},17,[379,1514,1290],{"class":474},[379,1516,1518,1520,1522],{"class":381,"line":1517},18,[379,1519,580],{"class":474},[379,1521,583],{"class":478},[379,1523,497],{"class":474},[354,1525,1526,1529],{},[376,1527,1528],{},"exclude"," is worth knowing about: a health check probed once a second is traffic about your application rather than through it, and left in, it dominates the request histogram.",[354,1531,1532,1535],{},[376,1533,1534],{},"spans.bodies"," attaches request and response bodies to the span as events. It is off by default and meant for development: it clones every message and holds the span open until the read finishes, and bodies routinely contain personal data.",[354,1537,1538,1541,1542,1545,1546,1549,1550,1553,1554,761,1557,1560,1561,1564],{},[376,1539,1540],{},"spans.headers"," does the same for headers. ",[376,1543,1544],{},"Authorization",", ",[376,1547,1548],{},"Cookie"," and the other credential-bearing names are always withheld whatever you configure; ",[376,1551,1552],{},"headers: { redact: ['x-internal-token'] }"," adds your own. Query parameters whose name reads like a credential, ",[376,1555,1556],{},"access_token",[376,1558,1559],{},"api_key"," among them, are withheld from ",[376,1562,1563],{},"url.query"," unconditionally.",[354,1566,1567],{},"Enabling devtools turns body and header capture on for you, but only outside production. Both ride on the server span, so every exporter sharing the pipeline sees them; in production you have to ask for them here explicitly.",[361,1569,1571],{"id":1570},"cost","Cost",[354,1573,1574,1575,1578,1579,1582],{},"With ",[376,1576,1577],{},"telemetry: false"," the framework's instrumentation points are a single ",[376,1580,1581],{},"null"," check, and the allocation-free route fast path still returns its response synchronously. Turning telemetry on without registering a provider costs slightly more, because the OpenTelemetry API still creates non-recording spans.",[354,1584,1585,1586,1589],{},"On a serverless platform, call the flush before your invocation returns. The Vercube adapters in ",[376,1587,1588],{},"@vercube\u002Fserverless"," already do.",[1591,1592,1593],"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 .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 .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}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 .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":374,"searchDepth":382,"depth":500,"links":1595},[1596,1597,1598,1599,1600,1601,1602,1603],{"id":363,"depth":500,"text":18},{"id":453,"depth":500,"text":454},{"id":681,"depth":500,"text":682},{"id":753,"depth":500,"text":754},{"id":1000,"depth":500,"text":1001},{"id":1220,"depth":500,"text":1221},{"id":1311,"depth":500,"text":33},{"id":1570,"depth":500,"text":1571},"OpenTelemetry tracing, metrics and log correlation for Vercube applications","md",null,{},{"title":70,"description":1604},"DUcoZGHjG3YYhS-yibaM6vCA5n2L0TUDgRg3VMNYJlk",[1611,1613],{"title":33,"path":90,"stem":91,"description":1612,"children":-1},"Plugin options, access tokens and what devtools refuse to do outside development",{"title":101,"path":102,"stem":103,"description":1614,"children":-1},"The Telemetry token and the package's entry points",1791443501117]