Last active
March 26, 2023 21:39
-
-
Save jessitron/7be742d32408497c8ac6194954be6f5b to your computer and use it in GitHub Desktop.
OpenTelemetry instrumentation for JavaScript in the Browser: it sends a trace with a span for each CWV (Core Web Vitals) metric. By Purvi Kanal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { onFID, onLCP, onCLS, onINP, onTTFB } from 'web-vitals'; // you'll need to install this | |
import { InstrumentationBase, InstrumentationModuleDefinition } from '@opentelemetry/instrumentation'; | |
import { trace, context } from '@opentelemetry/api'; | |
import { hrTime } from '@opentelemetry/core'; | |
export class WebVitalsInstrumentation extends InstrumentationBase { | |
constructor() { | |
super('web-vitals-instrumentation', 'v0.1.0'); | |
} | |
protected init(): void | InstrumentationModuleDefinition<any> | InstrumentationModuleDefinition<any>[] { | |
} | |
private enabled: boolean = false; | |
onReport(metric, parentSpanContext) { | |
const now = hrTime(); | |
const webVitalsSpan = this.tracer.startSpan(metric.name, { startTime: now }, parentSpanContext); | |
webVitalsSpan.setAttributes({ | |
[`webvitals.${metric.name}.name`]: metric.name, | |
[`webvitals.${metric.name}.id`]: metric.id, | |
[`webvitals.${metric.name}.navigationType`]: metric.navigationType, | |
[`webvitals.${metric.name}.delta`]: metric.delta, | |
[`webvitals.${metric.name}.rating`]: metric.rating, | |
[`webvitals.${metric.name}.value`]: metric.value, | |
// can expand these into their own attributes! | |
[`webvitals.${metric.name}.entries`]: JSON.stringify(metric.entries), | |
}); | |
webVitalsSpan.end(); | |
} | |
enable() { | |
if (this.enabled) { | |
return; | |
} | |
this.enabled = true; | |
// create a parent span that will have all web vitals spans as children | |
const parentSpan = this.tracer.startSpan('web-vitals'); | |
const ctx = trace.setSpan(context.active(), parentSpan); | |
parentSpan.end(); | |
onFID(metric => { | |
this.onReport(metric, ctx); | |
}); | |
onCLS(metric => { | |
this.onReport(metric, ctx); | |
}); | |
onLCP(metric => { | |
this.onReport(metric, ctx); | |
}); | |
onINP(metric => { | |
this.onReport(metric, ctx); | |
}); | |
onTTFB(metric => { | |
this.onReport(metric, ctx); | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// where you're registering instrumentations, add this one: | |
registerInstrumentations({ | |
tracerProvider: provider, | |
instrumentations: [ | |
new WebVitalsInstrumentation() | |
]}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment