From d90245a21888858db3eca95c392e1188d77effba Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Wed, 1 Jul 2026 18:42:13 +0200 Subject: [PATCH] Telemetry: add event.name and url.full to CTA events cta_viewed/cta_clicked previously only carried their event name in the log body (a text field), making them hard to filter on with an exact keyword query. Adds event.name per OTel semantic conventions, plus url.full to distinguish the page the user was on from the CTA's destination (cta.url). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/Elastic.Documentation.Site/Assets/main.ts | 19 ++++++++++++++----- .../Assets/telemetry/semconv.ts | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Elastic.Documentation.Site/Assets/main.ts b/src/Elastic.Documentation.Site/Assets/main.ts index a150497052..c2484788e4 100644 --- a/src/Elastic.Documentation.Site/Assets/main.ts +++ b/src/Elastic.Documentation.Site/Assets/main.ts @@ -17,7 +17,9 @@ import { ATTR_CTA_URL, ATTR_CTA_LABEL, ATTR_CTA_LOCATION, + ATTR_EVENT_NAME, ATTR_URL_PATH, + ATTR_URL_FULL, } from './telemetry/semconv' import { initTocNav } from './toc-nav' import 'htmx-ext-head-support' @@ -143,9 +145,19 @@ function ctaAttributes(cta: HTMLAnchorElement) { [ATTR_CTA_LABEL]: cta.dataset.ctaLabel ?? '', [ATTR_CTA_LOCATION]: cta.dataset.ctaLocation ?? '', [ATTR_URL_PATH]: window.location.pathname, + [ATTR_URL_FULL]: window.location.href, } } +// Emit a CTA event: event.name mirrors the body so records can be filtered by +// exact keyword (attributes.event.name) instead of a text match on body. +function logCtaEvent(eventName: string, cta: HTMLAnchorElement) { + logInfo(eventName, { + [ATTR_EVENT_NAME]: eventName, + ...ctaAttributes(cta), + }) +} + let ctaImpressionObserver: IntersectionObserver | null = null // Fires 'cta_viewed' the first time a CTA becomes at least half visible, then stops @@ -157,10 +169,7 @@ function initCtaImpressions() { (entries, observer) => { for (const entry of entries) { if (!entry.isIntersecting) continue - logInfo( - 'cta_viewed', - ctaAttributes(entry.target as HTMLAnchorElement) - ) + logCtaEvent('cta_viewed', entry.target as HTMLAnchorElement) observer.unobserve(entry.target) } }, @@ -210,7 +219,7 @@ document.addEventListener('click', function (event: MouseEvent) { 'a[data-cta]' ) if (!cta) return - logInfo('cta_clicked', ctaAttributes(cta)) + logCtaEvent('cta_clicked', cta) }) // Don't remove style tags because they are used by the elastic global nav. diff --git a/src/Elastic.Documentation.Site/Assets/telemetry/semconv.ts b/src/Elastic.Documentation.Site/Assets/telemetry/semconv.ts index 00078816b6..088938b1bf 100644 --- a/src/Elastic.Documentation.Site/Assets/telemetry/semconv.ts +++ b/src/Elastic.Documentation.Site/Assets/telemetry/semconv.ts @@ -17,6 +17,7 @@ export { ATTR_ERROR_TYPE, ATTR_EXCEPTION_MESSAGE, ATTR_URL_PATH, + ATTR_URL_FULL, } from '@opentelemetry/semantic-conventions' // ============================================================================