Back to Blog
    DevelopmentFebruary 6, 20261 min read

    Building a Lightweight Monitoring SDK in JavaScript

    Share
    Building a Lightweight Monitoring SDK in JavaScript

    Building Your Own Monitoring SDK

    While Xitoring handles server-side monitoring, you may want lightweight frontend observability. Here's how to build a minimal SDK.

    Core Module

    javascript
    class MonitorSDK {
      constructor({ endpoint, apiKey, batchSize = 10 }) {
        this.endpoint = endpoint;
        this.apiKey = apiKey;
        this.batchSize = batchSize;
        this.queue = [];
        this.flushInterval = setInterval(() => this.flush(), 5000);
      }
    
      track(event, data = {}) {
        this.queue.push({
          event,
          data,
          timestamp: Date.now(),
          url: window.location.href,
          userAgent: navigator.userAgent,
        });
    
        if (this.queue.length >= this.batchSize) {
          this.flush();
        }
      }
    
      async flush() {
        if (this.queue.length === 0) return;
    
        const batch = this.queue.splice(0, this.batchSize);
        try {
          await fetch(this.endpoint, {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              "X-API-Key": this.apiKey,
            },
            body: JSON.stringify({ events: batch }),
          });
        } catch (err) {
          this.queue.unshift(...batch);
          console.warn("[MonitorSDK] Flush failed, will retry", err);
        }
      }
    
      destroy() {
        clearInterval(this.flushInterval);
        this.flush();
      }
    }
    

    Error Tracking

    javascript
    function setupErrorTracking(sdk) {
      window.addEventListener("error", (event) => {
        sdk.track("error", {
          message: event.message,
          filename: event.filename,
          lineno: event.lineno,
          colno: event.colno,
          stack: event.error?.stack,
        });
      });
    
      window.addEventListener("unhandledrejection", (event) => {
        sdk.track("unhandled_rejection", {
          reason: String(event.reason),
          stack: event.reason?.stack,
        });
      });
    }
    

    Performance Metrics

    javascript
    function trackWebVitals(sdk) {
      const observer = new PerformanceObserver((list) => {
        for (const entry of list.getEntries()) {
          sdk.track("web_vital", {
            name: entry.name,
            value: entry.startTime,
            type: entry.entryType,
          });
        }
      });
    
      observer.observe({ entryTypes: ["largest-contentful-paint", "layout-shift"] });
    
      window.addEventListener("load", () => {
        const [fcp] = performance.getEntriesByName("first-contentful-paint");
        if (fcp) {
          sdk.track("web_vital", { name: "FCP", value: fcp.startTime });
        }
      });
    }
    

    Usage with TypeScript

    typescript
    interface SDKConfig {
      endpoint: string;
      apiKey: string;
      batchSize?: number;
    }
    
    const monitor = new MonitorSDK({
      endpoint: "https://api.xitoring.com/events",
      apiKey: "your-api-key",
      batchSize: 20,
    });
    
    setupErrorTracking(monitor);
    trackWebVitals(monitor);
    
    // Custom events
    monitor.track("button_click", { id: "signup-cta" });
    

    What's Next

    This SDK covers the basics. For production, add request deduplication, offline support with IndexedDB, and sampling to control volume.

    Tired of alert fatigue?

    Smart alerting with root cause analysis and 20+ notification channels. Alerts that actually matter.

    See How It Works