Skip to content

Regarding Browser detection inside opentelemetry instrumentation #6574

@fis3tracetracker

Description

@fis3tracetracker

Hi Team,

My Current requirement is to identify the existing browser which is firing my fetch calls [NOTE: currently I'm using fetch instrumentation]. When I tried to implement "opentelemetry-browser-detector" it added the details to resource attributes and those details did not have the exact browser name in it. Then I tried a manual approach to detect the browser using userAgent, But again that approach has its own limitation of increasing the code complexity and maintainability.

NOTE: I Can't use any external packages other than open telemetry package as we maintain within our code implementation guidelines.

Kindly suggest if there is any other ways in openTelemetry pkg to detect the exact browser. I have given the approaches I tried.

Manual Approach:

// Browser Detection Utility
type BrowserCategory = 'real' | 'regional' | 'webview';

export function getBrowserAttributes() {
  const ua = navigator.userAgent;
  const uaData = (navigator as any).userAgentData;

  let browserName = 'unknown';
  let browserVersion = 'unknown';
  let browserCategory: BrowserCategory = 'real';

  // 1. WebView Detection
  const isWebView = /WebView|wv/.test(ua);

  // 2. Regional Browsers (WeChat, QQ, UC, Baidu, Yandex)
  const regionalMatchers = [
    [/MicroMessenger\/(\d+)/, 'wechat'],
    [/QQBrowser\/(\d+)/, 'qq'],
    [/UCBrowser\/(\d+)/, 'uc'],
    [/Baidu/i, 'baidu'],
    [/YaBrowser\/(\d+)/, 'yandex'],
  ];

  for (const [regex, name] of regionalMatchers) {
    const match = ua.match(regex);
    if (match) {
      browserName = name;
      browserVersion = match[1] || 'unknown';
      browserCategory = 'regional';
      break;
    }
  }

  // 3. Client Hints API (modern browsers)
  if (browserName === 'unknown' && uaData) {
    const brands = uaData.brands || [];
    const primaryBrand = brands.find((b: any) => !/Not.A.Brand/i.test(b.brand));
    browserName = normalizeBrand(primaryBrand?.brand);
    browserVersion = primaryBrand?.version || 'unknown';
  }

  // 4. User-Agent Fallback
  if (browserName === 'unknown') {
    const matchers = [
      [/Edg\/(\d+)/, 'edge'],
      [/Chrome\/(\d+)/, 'chrome'],
      [/Firefox\/(\d+)/, 'firefox'],
      [/Safari\/(\d+)/, 'safari'],
    ];
    // ... match logic
  }

  // 5. OS & Device Detection
  const osName = /Windows/.test(ua) ? 'Windows' : 
                 /Android/.test(ua) ? 'Android' : 'unknown';
  const deviceType = /Tablet|iPad/.test(ua) ? 'tablet' :
                     /Mobi|Android/.test(ua) ? 'mobile' : 'desktop';

  return { browserName, browserVersion, browserCategory, osName, deviceType };
}

OUTPUT:

// launched in chrome but there are lot of browsers used around the globe we can't cover all in manual approach
{
    "name": "chrome",
    "version": "147",
    "platform": "Windows",
    "mobile": false,
    "os.name": "Windows",
    "os.version": "10.0",
    "device.type": "desktop",
    "device.is_webview": false,
    "browser.category": "real"
}

opentelemetry-browser-detector Approach:

import { browserDetector } from '@opentelemetry/opentelemetry-browser-detector';

    const detectedBrowserResource = browserDetector.detect();
    
    console.log('Browser Detection Resource:', detectedBrowserResource.attributes);

    const resource = defaultResource()
        .merge(resourceFromAttributes(detectedBrowserResource.attributes ?? {}))
        .merge(
            resourceFromAttributes({
                [ATTR_SERVICE_NAME]: SERVICE_NAME,
                [ATTR_SERVICE_VERSION]: SERVICE_VERSION,
            })
        );

OUTPUT

//  launched in chrome but the exact name is not directly retrivable
{
    "browser.platform": "Windows",
    "browser.brands": [
        "Google Chrome 147",
        "Not.A/Brand 8",
        "Chromium 147"
    ],
    "browser.mobile": false,
    "browser.language": "en-GB"
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions