File tree Expand file tree Collapse file tree
packages/fresh/src/runtime/server Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -127,3 +127,25 @@ deno task start
127127
128128Open ` http://localhost:16686 ` to browse traces. You'll see each request broken
129129down into its middleware, handler, and rendering spans.
130+
131+ ## Client-side trace correlation
132+
133+ When an OpenTelemetry exporter is active, Fresh automatically injects a
134+ [ W3C Trace Context] ( https://www.w3.org/TR/trace-context/ ) ` <meta> ` tag into the
135+ ` <head> ` of every rendered page:
136+
137+ ``` html
138+ <head >
139+ <meta
140+ name =" traceparent"
141+ content =" 00-ab42124a3c573678d4d8b21ba52df3bf-d21f7bc17caa5aba-01"
142+ >
143+ <!-- ... -->
144+ </head >
145+ ```
146+
147+ This allows client-side OpenTelemetry instrumentation (such as
148+ [ ` @opentelemetry/instrumentation-document-load ` ] ( https://github.com/open-telemetry/opentelemetry-js-contrib/tree/c9d62be989802534c01373e8ab41e13747d7ee3e/packages/instrumentation-document-load ) )
149+ to link browser performance traces back to the server-side span that rendered
150+ the page, giving you end-to-end visibility from server rendering through page
151+ load.
Original file line number Diff line number Diff line change @@ -35,6 +35,7 @@ import { getCodeFrame } from "../../dev/middlewares/error_overlay/code_frame.ts"
3535import { escapeScript } from "../../utils.ts" ;
3636import { HeadContext } from "../head.ts" ;
3737import { useContext } from "preact/hooks" ;
38+ import { isSpanContextValid , trace } from "@opentelemetry/api" ;
3839
3940interface InternalPreactOptions extends PreactOptions {
4041 [ OptionsType . ATTR ] ( name : string , value : unknown ) : string | void ;
@@ -295,6 +296,22 @@ options[OptionsType.DIFF] = (vnode) => {
295296 }
296297 }
297298
299+ // Inject W3C traceparent meta tag when OpenTelemetry is active,
300+ // enabling client-side tracing to connect to the server span.
301+ const activeSpan = trace . getActiveSpan ( ) ;
302+ if ( activeSpan ) {
303+ const spanCtx = activeSpan . spanContext ( ) ;
304+ if ( isSpanContextValid ( spanCtx ) ) {
305+ const flags = ( spanCtx . traceFlags & 1 ) ? "01" : "00" ;
306+ const traceparent =
307+ `00-${ spanCtx . traceId } -${ spanCtx . spanId } -${ flags } ` ;
308+ items . push (
309+ // deno-lint-ignore no-explicit-any
310+ h ( "meta" , { name : "traceparent" , content : traceparent } ) as any ,
311+ ) ;
312+ }
313+ }
314+
298315 // deno-lint-ignore no-explicit-any
299316 items . push ( h ( RemainingHead , null ) as VNode < any > ) ;
300317
You can’t perform that action at this time.
0 commit comments