### Complete Example Plugin Implementation Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md Demonstrates a full implementation of a custom plugin, including event capturing, setup, and teardown logic. Ensure the plugin is supported in the target environment before setup. ```typescript // src/plugins/ExamplePlugin.ts import { BasePlugin } from "./BasePlugin"; import type { TelemetryEvent } from "../types"; export class ExamplePlugin extends BasePlugin { private handler: (() => void) | null = null; protected isSupported(): boolean { return typeof window !== "undefined"; } private captureEvent = () => { try { const evt: TelemetryEvent = { eventType: "example", eventName: "event_captured", payload: { timestamp: new Date().toISOString(), data: "example data", }, timestamp: new Date().toISOString(), }; this.logger.debug("Example event captured"); this.safeCapture(evt); } catch (error) { this.logger.error("Failed to capture example event", { error: error instanceof Error ? error.message : String(error), }); } }; protected setup(): void { if (!this.isSupported()) { this.logger.warn("ExamplePlugin not supported"); this.isEnabled = false; return; } try { this.handler = this.captureEvent.bind(this); window.addEventListener("example", this.handler); this.logger.info("ExamplePlugin setup complete"); } catch (error) { this.logger.error("Failed to setup ExamplePlugin", { error }); this.isEnabled = false; } } teardown(): void { try { if (this.handler) { window.removeEventListener("example", this.handler); this.handler = null; } this.logger.info("ExamplePlugin teardown complete"); } catch (error) { this.logger.error("Failed to teardown ExamplePlugin", { error }); } } } ``` -------------------------------- ### Example Usage of New Plugin Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Demonstrates how to initialize the SDK and enable your custom plugin. ```typescript import { initTelemetry } from "../src/index"; // Example: Your Plugin Usage const telemetry = initTelemetry({ hyperlookApiKey: "sk_your-api-key", // Enable your plugin enableYourPlugin: true, // Other configuration... }); console.log("Your plugin initialized!"); ``` -------------------------------- ### Install Telemetry SDK Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/README.md Install the SDK using npm. This is the first step before integrating it into your application. ```bash npm install @hyperlook/telemetry-sdk ``` -------------------------------- ### Initialize Telemetry in React (Non-Next.js) Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/README.md Quick start for integrating the Telemetry SDK into a standard React application. This example initializes the SDK and optionally identifies a user. Remember to replace 'your-api-key' with your actual API key. ```tsx import { useEffect } from "react"; import { initTelemetry } from "@hyperlook/telemetry-sdk"; function App() { useEffect(() => { const telemetry = initTelemetry({ hyperlookApiKey: "your-api-key", // Replace with your actual API key }); // Optional: Identify the user telemetry.identify("user-123", { name: "John Doe", email: "john@example.com", }); }, []); return
{/* Your app content */}
; } export default App; ``` -------------------------------- ### Create Example Usage Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md Demonstrate how users can enable and initialize your plugin when setting up the telemetry SDK. ```typescript import { initTelemetry } from "../src/index"; const telemetry = initTelemetry({ enableYourPlugin: true, // Enable your plugin }); ``` -------------------------------- ### Start Development Mode Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Run the SDK in development mode for auto-rebuilding on code changes. ```bash pnpm run dev # or npm run dev # or yarn dev ``` -------------------------------- ### Build and Test SDK Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Commands to build the SDK, run tests, and manually test your plugin using an example script. ```bash # Build the SDK pnpm run build # Run tests (if any) pnpm test # Test your plugin manually node examples/your-plugin-example.ts ``` -------------------------------- ### Build and Test Plugin Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md Commands to build the SDK, run tests, and execute an example to verify plugin functionality. ```bash pnpm run build pnpm test node examples/your-plugin-example.ts ``` -------------------------------- ### Install yalc Globally Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/DEVELOPMENT.md Install yalc globally using npm. This command should be run once if yalc is not already installed. ```bash npm install -g yalc ``` -------------------------------- ### Install Dependencies Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Install project dependencies using your preferred package manager (pnpm, npm, or yarn). ```bash pnpm install # or npm install # or yarn install ``` -------------------------------- ### Complete Scroll Tracking Plugin Implementation Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md This TypeScript example demonstrates a complete scroll tracking plugin, including environment support checks, event capturing with debouncing, setup, and teardown logic. It logs information and errors using the SDK's logger. ```typescript // src/plugins/ScrollPlugin.ts import { BasePlugin } from "./BasePlugin"; import type { TelemetryEvent } from "../types"; export class ScrollPlugin extends BasePlugin { private scrollHandler: (() => void) | null = null; private scrollTimeout: NodeJS.Timeout | null = null; protected isSupported(): boolean { return typeof window !== "undefined"; } private captureScroll = () => { try { // Debounce scroll events if (this.scrollTimeout) { clearTimeout(this.scrollTimeout); } this.scrollTimeout = setTimeout(() => { const evt: TelemetryEvent = { eventType: "interaction", eventName: "scroll", payload: { scrollY: window.scrollY, scrollX: window.scrollX, viewportHeight: window.innerHeight, documentHeight: document.documentElement.scrollHeight, scrollPercentage: (window.scrollY / (document.documentElement.scrollHeight - window.innerHeight)) * 100, }, timestamp: new Date().toISOString(), }; this.logger.debug("Scroll event captured", { scrollY: window.scrollY, scrollPercentage: evt.payload.scrollPercentage, }); this.safeCapture(evt); }, 100); // Debounce for 100ms } catch (error) { this.logger.error("Failed to capture scroll event", { error: error instanceof Error ? error.message : String(error), }); } }; protected setup(): void { if (!this.isSupported()) { this.logger.warn("ScrollPlugin not supported in this environment"); this.isEnabled = false; return; } try { this.scrollHandler = this.captureScroll.bind(this); window.addEventListener("scroll", this.scrollHandler, { passive: true }); this.logger.info("ScrollPlugin setup complete"); } catch (error) { this.logger.error("Failed to setup ScrollPlugin", { error: error instanceof Error ? error.message : String(error), }); this.isEnabled = false; } } teardown(): void { try { if (this.scrollHandler) { window.removeEventListener("scroll", this.scrollHandler); this.scrollHandler = null; } if (this.scrollTimeout) { clearTimeout(this.scrollTimeout); this.scrollTimeout = null; } this.logger.info("ScrollPlugin teardown complete"); } catch (error) { this.logger.error("Failed to teardown ScrollPlugin", { error: error instanceof Error ? error.message : String(error), }); } } } ``` -------------------------------- ### Build the SDK Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/DEVELOPMENT.md Navigate to the telemetry-sdk directory and build the project using pnpm, npm, or yarn. Ensure all dependencies are installed before building. ```bash cd /Users/jayeshsadhwani/projects/telemetry-sdk pnpm install # or npm install / yarn install pnpm run build # or npm run build / yarn build ``` -------------------------------- ### Clone Repository Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Clone your forked repository locally to start making changes. ```bash git clone https://github.com/your-username/telemetry-sdk.git cd telemetry-sdk ``` -------------------------------- ### Quick Start Plugin Template Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md A basic template for creating a new plugin. Replace `YourPluginName` with your actual plugin name and fill in the initialization and cleanup logic. ```typescript import { BasePlugin } from "./BasePlugin"; import type { TelemetryEvent } from "../types"; export class YourPluginName extends BasePlugin { protected isSupported(): boolean { return typeof window !== "undefined"; } protected setup(): void { if (!this.isSupported()) { this.logger.warn("YourPluginName not supported"); this.isEnabled = false; return; } try { // Your initialization code here this.logger.info("YourPluginName setup complete"); } catch (error) { this.logger.error("Failed to setup YourPluginName", { error }); this.isEnabled = false; } } teardown(): void { try { // Your cleanup code here this.logger.info("YourPluginName teardown complete"); } catch (error) { this.logger.error("Failed to teardown YourPluginName", { error }); } } } ``` -------------------------------- ### Add SDK to Consumer App Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/DEVELOPMENT.md In the consumer application's directory, add the SDK using yalc. This command links the local SDK to the app. Ensure dependencies are installed afterward. ```bash cd /Users/jayeshsadhwani/projects/crossword-next yalc add @hyperlook/telemetry-sdk pnpm install # or npm install / yarn install ``` -------------------------------- ### Create Plugin File Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md Defines the main plugin logic and event capture for a new plugin. Ensure to implement `isSupported`, `setup`, and `teardown` methods. ```typescript import { BasePlugin } from "./BasePlugin"; import type { TelemetryEvent } from "../types"; export class YourPluginName extends BasePlugin { protected isSupported(): boolean { return typeof window !== "undefined"; } protected setup(): void { /* Initialize your plugin */ } teardown(): void { /* Clean up resources */ } } ``` -------------------------------- ### Initialize Telemetry in Vanilla JS/TS Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/README.md Guide for using the Telemetry SDK in plain JavaScript or TypeScript projects. This snippet shows basic initialization and optional user identification. Replace 'your-api-key' with your actual API key. ```typescript import { initTelemetry } from "@hyperlook/telemetry-sdk"; const telemetry = initTelemetry({ hyperlookApiKey: "your-api-key", // Replace with your actual API key }); // Optional: Identify a user telemetry.identify("user-123", { name: "John Doe", email: "john@example.com", }); ``` -------------------------------- ### Implement Required Plugin Methods Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md Provides the basic structure for essential plugin methods: `isSupported` to check environment compatibility, `setup` for initialization, and `teardown` for cleanup. ```typescript protected isSupported(): boolean { // Check if plugin works in current environment return typeof window !== "undefined"; } protected setup(): void { // Initialize plugin (event listeners, timers, etc.) // Called when plugin is enabled } teardown(): void { // Clean up resources (remove listeners, clear timers) // Called when plugin is disabled or SDK shuts down } ``` -------------------------------- ### Extend BasePlugin for Custom Scroll Depth Tracking Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt Implement a custom plugin by extending BasePlugin. Ensure isSupported() checks for the environment and setup() adds event listeners. Use this.safeCapture() to emit events. ```typescript import { BasePlugin, initTelemetry, type TelemetryEvent, } from "@hyperlook/telemetry-sdk"; class ScrollDepthPlugin extends BasePlugin { private handler: (() => void) | null = null; private maxDepth = 0; public isSupported(): boolean { return typeof window !== "undefined"; } protected setup(): void { this.handler = () => { const depth = Math.round( ((window.scrollY + window.innerHeight) / document.body.scrollHeight) * 100 ); if (depth > this.maxDepth) { this.maxDepth = depth; const evt: TelemetryEvent = { eventType: "engagement", eventName: "scroll_depth", payload: { depthPercent: depth, url: window.location.href }, timestamp: new Date().toISOString(), }; this.safeCapture(evt); } }; window.addEventListener("scroll", this.handler, { passive: true }); this.logger.info("ScrollDepthPlugin setup complete"); } teardown(): void { if (this.handler) { window.removeEventListener("scroll", this.handler); this.handler = null; } this.logger.info("ScrollDepthPlugin teardown complete"); } } // Register and use const telemetry = initTelemetry({ hyperlookApiKey: "hlk_live_abc123" }); const scrollPlugin = new ScrollDepthPlugin(); telemetry.register(scrollPlugin); ``` -------------------------------- ### Build SDK Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Build the SDK for production or distribution. ```bash pnpm run build # or npm run build # or yarn build ``` -------------------------------- ### Get Current Session ID Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/README.md Retrieves the unique identifier for the current user session. This is useful for correlating events within a single session. ```typescript const sessionId = telemetry.getSessionId(); console.log("Current session:", sessionId); ``` -------------------------------- ### Get Current User ID Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/README.md Returns the currently identified user ID, if one has been set. Returns `undefined` if no user has been identified yet. ```typescript const userId = telemetry.getUserId(); console.log("Current user:", userId); ``` -------------------------------- ### Publish SDK to Local yalc Store Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/DEVELOPMENT.md Publish the built SDK to your local yalc store. The --push flag automatically updates all linked projects. ```bash yalc publish --push ``` -------------------------------- ### Initialize Telemetry in Next.js Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/README.md Set up the TelemetryProvider component in your Next.js application to initialize the SDK. Ensure you replace 'your-api-key' with your actual API key. This provider should wrap your main application content. ```tsx "use client"; import { useEffect } from "react"; import { initTelemetry } from "@hyperlook/telemetry-sdk"; export default function TelemetryProvider() { useEffect(() => { const telemetry = initTelemetry({ hyperlookApiKey: "your-api-key", // Replace with your actual API key }); return () => { telemetry.destroy(); }; }, []); return null; } ``` ```tsx import TelemetryProvider from "@/components/TelemetryProvider"; export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( {children} ); } ``` -------------------------------- ### Update Initialization Logging for New Plugin Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Includes the status of your plugin in the SDK's initialization log messages for easier debugging. ```typescript this.logger.info("TelemetryManager initialized", { endpoint: HYPERLOOK_URL, batchSize: config.batchSize ?? 50, flushInterval: this.flushInterval, maxRetries: config.maxRetries ?? 3, samplingRate: config.samplingRate ?? 1.0, enablePageViews: config.enablePageViews, enableClicks: config.enableClicks, enableLogs: config.enableLogs, enableNetwork: config.enableNetwork, enablePerformance: config.enablePerformance, enableYourPlugin: config.enableYourPlugin, // Add this line enableCustomEvents: config.enableCustomEvents, exporters: exportersToEnable, }); ``` -------------------------------- ### Add Plugin to Configuration Table Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Documents the new configuration option for your plugin in the README's configuration table. ```markdown | `enableYourPlugin` | `boolean` | `false` | Enable your plugin description | ``` -------------------------------- ### Add Plugin Documentation Section Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Provides a dedicated section in the README to describe your plugin's functionality. ```markdown ### YourPluginName Brief description of what your plugin does and what events it captures. ``` -------------------------------- ### Enable and Configure Session Replay Plugin Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt Initialize the telemetry SDK with the session replay plugin enabled. Configure recording parameters like `maxEvents`, `maxDuration`, and masking options for sensitive data. ```typescript import { initTelemetry } from "@hyperlook/telemetry-sdk"; const telemetry = initTelemetry({ hyperlookApiKey: "hlk_live_abc123", enableSessionReplay: true, sessionReplay: { maxEvents: 2000, maxDuration: 10 * 60 * 1000, // 10 minutes maskAllInputs: true, // Mask all form inputs maskTextSelector: ".pii", // Also mask elements with class .pii blockClass: "no-record", // Elements with this class are not recorded inlineStylesheet: true, recordCanvas: false, slimDOMOptions: { script: true, comment: true, }, }, }); // Session replay events are captured and exported automatically. // Session ID is available for correlation: console.log("Replay session:", telemetry.getSessionId()); ``` -------------------------------- ### Initialize Telemetry Manager Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt The primary entry point for the SDK. Constructs and returns a `TelemetryManager` instance, registers plugins, processes early events, and attaches lifecycle handlers for event flushing. ```APIDOC ## `initTelemetry(config?)` ### Description The primary entry point for the SDK. Constructs and returns a `TelemetryManager` instance, registers all enabled plugins, processes any events captured before initialization (early queue), and automatically attaches `beforeunload`/`pagehide`/`visibilitychange` handlers in browsers or `SIGTERM`/`SIGINT`/`exit` handlers in Node.js to flush events before shutdown. ### Method `initTelemetry(config?: TelemetryConfig): TelemetryManager` ### Parameters #### Query Parameters - **config** (TelemetryConfig) - Optional - Configuration object for the telemetry manager. - **hyperlookApiKey** (string) - Required for Hyperlook exporter. - **batchSize** (number) - Optional - Send when this many events accumulate (default: 50). - **flushInterval** (number) - Optional - Also flush every X milliseconds (default: 30000). - **maxRetries** (number) - Optional - Maximum number of retries for event delivery. - **retryDelay** (number) - Optional - Base delay in milliseconds for exponential backoff (default: 1000). - **maxRetryDelay** (number) - Optional - Maximum delay in milliseconds for exponential backoff. - **samplingRate** (number) - Optional - Capture X% of events (e.g., 0.5 for 50%). - **enablePageViews** (boolean) - Optional - Enable page view tracking (default: true). - **enableClicks** (boolean) - Optional - Enable click tracking (default: true). - **enableLogs** (boolean) - Optional - Enable console log tracking (default: true). - **enableNetwork** (boolean) - Optional - Enable network request tracking (default: true). - **enablePerformance** (boolean) - Optional - Enable performance metrics tracking (default: true). - **enableErrors** (boolean) - Optional - Enable JavaScript error tracking (default: true). - **enableCustomEvents** (boolean) - Optional - Enable custom event tracking (default: true). - **enableSessionReplay** (boolean) - Optional - Enable session replay tracking (default: false). - **logging** (object) - Optional - Logger configuration. - **level** (string) - Optional - Logging level (e.g., 'DEBUG', 'INFO', 'WARN', 'ERROR'). - **enableConsole** (boolean) - Optional - Enable console output for logs (default: true). - **enableTimestamp** (boolean) - Optional - Include timestamps in logs (default: true). - **prefix** (string) - Optional - Prefix for log messages. ### Request Example ```typescript import { initTelemetry } from "@hyperlook/telemetry-sdk"; const telemetry = initTelemetry({ hyperlookApiKey: "hlk_live_abc123", // Required for Hyperlook exporter // Batching batchSize: 50, // Send when 50 events accumulate (default) flushInterval: 30000, // Also flush every 30 s (default) // Reliability maxRetries: 3, retryDelay: 1000, // Base delay for exponential backoff maxRetryDelay: 30000, // Sampling (useful in high-traffic apps) samplingRate: 0.5, // Capture 50 % of events // Plugins (all default true except customEvents / sessionReplay) enablePageViews: true, enableClicks: true, enableLogs: true, enableNetwork: true, enablePerformance: true, enableErrors: true, enableCustomEvents: true, enableSessionReplay: false, // Logger logging: { level: "DEBUG", enableConsole: true, enableTimestamp: true, prefix: "[MyApp]", }, }); console.log("Session:", telemetry.getSessionId()); // Session: 3f7a1b2c-... ``` ``` -------------------------------- ### Rebuild and Re-publish SDK Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/DEVELOPMENT.md During development, make changes in the SDK, rebuild it, and then re-publish to yalc using the --push flag to update all linked applications. ```bash pnpm run build yalc publish --push ``` -------------------------------- ### Run Tests Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Execute the project's test suite to ensure code integrity. ```bash pnpm test # or npm test # or yarn test ``` -------------------------------- ### Publish Package to NPM Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/NPM_GUIDE.md After bumping the version, use this command to publish the new version to the npm registry as a public package. ```sh pnpm publish --access public ``` -------------------------------- ### Import SDK in App Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/DEVELOPMENT.md Import and use the telemetry SDK in your application as you normally would. This assumes the SDK has been successfully added via yalc. ```javascript import { initTelemetry } from "@hyperlook/telemetry-sdk"; ``` -------------------------------- ### Initialize Telemetry with Circuit Breaker Configuration Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt Configure the telemetry SDK with custom circuit breaker settings. Adjust `circuitBreakerMaxFailures` and `circuitBreakerFailureThreshold` to control when the circuit opens. ```typescript import { initTelemetry } from "@hyperlook/telemetry-sdk"; const telemetry = initTelemetry({ hyperlookApiKey: "hlk_live_abc123", circuitBreakerMaxFailures: 5, circuitBreakerTimeout: 30_000, // 30 s before half-open probe circuitBreakerFailureThreshold: 0.4, // Open at 40 % failure rate }); const cb = telemetry.getCircuitBreakerState(); console.log(cb); ``` -------------------------------- ### Create and Set a Custom Global Logger Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt Replace the default SDK logger with a custom instance using createLogger() and setLogger(). This allows integration with existing application logging frameworks. ```typescript import { createLogger, setLogger, getLogger } from "@hyperlook/telemetry-sdk"; // Create a custom logger with a DEBUG level and custom formatter const logger = createLogger({ level: "DEBUG", enableConsole: true, enableTimestamp: true, prefix: "[Telemetry]", formatter: (level, message, meta) => JSON.stringify({ ts: Date.now(), level, message, ...meta }), }); // Install as the global SDK logger before calling initTelemetry setLogger(logger); // Confirm replacement const active = getLogger(); active.info("Logger replaced", { ready: true }); // {"ts":1715000000000,"level":2,"message":"Logger replaced","ready":true} import { initTelemetry } from "@hyperlook/telemetry-sdk"; const telemetry = initTelemetry({ hyperlookApiKey: "hlk_live_abc123" }); ``` -------------------------------- ### Use yalc Push for Updates Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/DEVELOPMENT.md Use `yalc push` in the SDK directory to update all linked applications after making changes and rebuilding the SDK. This is an alternative to `yalc publish --push`. ```bash yalc push ``` -------------------------------- ### Set Default Configuration for New Plugin Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Initializes the default configuration for your plugin, setting its enable flag to false by default. ```typescript export const initialTelemetryConfig: TelemetryConfig = { endpoint: "https://api.your-domain.com/telemetry", hyperlookApiKey: "your-hyperlook-api-key-here", exporters: [ExporterType.HYPERLOOK], enablePageViews: true, batchSize: 5, enableClicks: true, enableLogs: true, enableNetwork: true, enablePerformance: true, enableYourPlugin: false, // Add this line (usually false by default) enableCustomEvents: false, flushInterval: 10000, maxRetries: 3, retryDelay: 1000, samplingRate: 1.0, }; ``` -------------------------------- ### Advanced Telemetry Configuration Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/README.md Demonstrates comprehensive configuration options for the Telemetry SDK, including event batching, retries, sampling, plugin enablement, and logging settings. This allows fine-tuning the SDK's behavior for specific application needs. ```typescript import { initTelemetry } from "@hyperlook/telemetry-sdk"; const telemetry = initTelemetry({ hyperlookApiKey: "your-api-key", // Replace with your Hyperlook API key // Event batching configuration batchSize: 50, // Number of events to batch before sending flushInterval: 30000, // Flush interval in milliseconds (30 seconds) // Retry configuration maxRetries: 3, // Maximum number of retry attempts retryDelay: 1000, // Delay between retries in milliseconds // Sampling configuration samplingRate: 0.1, // Only capture 10% of events (0.0 to 1.0) // Plugin configuration enablePageViews: true, // Track page view events (page_hit) enableClicks: true, // Track user clicks enableLogs: true, // Track console logs enableNetwork: true, // Track HTTP requests enablePerformance: true, // Track performance metrics enableCustomEvents: true, // Enable custom events plugin // Logging configuration logging: { level: "INFO", // Log level: ERROR, WARN, INFO, DEBUG, SILENT enableConsole: true, // Enable console logging enableTimestamp: true, // Include timestamps in logs prefix: "[MyApp]", // Custom log prefix }, }); ``` -------------------------------- ### Create New Plugin File Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Define the main plugin logic and event capture functionality in a new TypeScript file. ```typescript import { BasePlugin } from "./BasePlugin"; import type { TelemetryEvent } from "../types"; export class YourPluginName extends BasePlugin { // Plugin-specific properties private hasInitialized = false; // Check if the plugin is supported in the current environment protected isSupported(): boolean { return typeof window !== "undefined" && typeof document !== "undefined"; } // Main event capture logic private captureEvent = () => { try { if (this.hasInitialized) { return; } this.hasInitialized = true; const evt: TelemetryEvent = { eventType: "your_event_type", eventName: "your_event_name", payload: { // Your event data here timestamp: new Date().toISOString(), }, timestamp: new Date().toISOString(), }; this.logger.debug("Your event captured", { // Log relevant data }); this.safeCapture(evt); } catch (error) { this.logger.error("Failed to capture your event", { error: error instanceof Error ? error.message : String(error), }); } }; // Plugin initialization - called when the plugin is enabled protected setup(): void { if (!this.isSupported()) { this.logger.warn("YourPluginName not supported in this environment"); this.isEnabled = false; return; } try { // Set up event listeners, timers, observers, etc. // Example: window.addEventListener("your_event", this.captureEvent); this.logger.info("YourPluginName setup complete"); } catch (error) { this.logger.error("Failed to setup YourPluginName", { error: error instanceof Error ? error.message : String(error), }); this.isEnabled = false; } } // Plugin cleanup - called when the plugin is disabled or SDK shuts down teardown(): void { try { // Clean up event listeners, timers, observers, etc. // Example: window.removeEventListener("your_event", this.captureEvent); this.logger.info("YourPluginName teardown complete"); } catch (error) { this.logger.error("Failed to teardown YourPluginName", { error: error instanceof Error ? error.message : String(error), }); } } } ``` -------------------------------- ### Initialize Telemetry in Next.js Client Component Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt This client component initializes the telemetry SDK once per session. It configures various data collection options and identifies the user if a userId is available in localStorage. Ensure NEXT_PUBLIC_HYPERLOOK_KEY is set in your environment variables. ```tsx // components/TelemetryProvider.tsx "use client"; import { useEffect } from "react"; import { initTelemetry } from "@hyperlook/telemetry-sdk"; export default function TelemetryProvider() { useEffect(() => { const telemetry = initTelemetry({ hyperlookApiKey: process.env.NEXT_PUBLIC_HYPERLOOK_KEY!, enablePageViews: true, // Captures SPA navigation via History API patch enableClicks: true, enableNetwork: true, enablePerformance: true, enableCustomEvents: true, samplingRate: 1.0, }); // Identify once the user session is known const userId = localStorage.getItem("userId"); if (userId) { telemetry.identify(userId, { source: "localStorage" }); } return () => { telemetry.destroy(); }; }, []); return null; } // app/layout.tsx import TelemetryProvider from "@/components/TelemetryProvider"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` -------------------------------- ### Safely Capture Events in Plugin Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Best practice for event capture within a plugin, using `this.safeCapture()` to handle errors gracefully. ```markdown - **Always use `this.safeCapture()`** - Handles errors gracefully and prevents crashes - **Include meaningful payload data** - Make events useful for analytics - **Use consistent event naming** - Follow the pattern: `event_type` and `event_name` ``` -------------------------------- ### Implement Event Capture Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md Demonstrates how to capture telemetry events using `this.safeCapture()`. Always wrap event capture logic in a try-catch block and use `safeCapture` to prevent errors from crashing the SDK. ```typescript private captureEvent = () => { try { const evt: TelemetryEvent = { eventType: "your_type", eventName: "your_name", payload: { /* your data */ }, timestamp: new Date().toISOString(), }; this.safeCapture(evt); // Always use safeCapture! } catch (error) { this.logger.error("Failed to capture event", { error }); } }; ``` -------------------------------- ### Update Initialization Logging Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md Log the configuration status of your plugin during TelemetryManager initialization for debugging purposes. ```typescript this.logger.info("TelemetryManager initialized", { enableYourPlugin: config.enableYourPlugin, // Add this line // ... other config }); ``` -------------------------------- ### Export Plugin from Main SDK Index Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Make the plugin accessible to SDK users by exporting it from the main SDK index file. ```typescript // Add import import { YourPluginName } from "./plugins/YourPluginName"; // Add to exports export { TelemetryManager, BasePlugin, ClickPlugin, LogPlugin, NetworkPlugin, PerformancePlugin, CustomEventsPlugin, PageViewPlugin, YourPluginName, // Add this line HTTPExporter, getLogger, setLogger, createLogger, }; ``` -------------------------------- ### Configure HTTP Exporter with Custom Endpoint and Timeouts Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt Initialize the telemetry SDK using the HTTP exporter to send events to a custom endpoint. Configure connection and request timeouts, along with retry parameters. ```typescript import { initTelemetry, HTTPExporter } from "@hyperlook/telemetry-sdk"; import { ExporterType } from "@hyperlook/telemetry-sdk"; // Use a custom endpoint instead of Hyperlook const telemetry = initTelemetry({ exporters: [ExporterType.HTTP], endpoint: "https://ingest.mycompany.com/v1/events", connectionTimeout: 5_000, // Fail fast on connection (5 s) requestTimeout: 20_000, // Wait up to 20 s for response maxRetries: 5, retryDelay: 500, }); // The HTTPExporter can also be instantiated directly for custom pipelines const exporter = new HTTPExporter(5_000, 20_000); await exporter.export( [ { eventType: "page", eventName: "page_hit", payload: { url: "https://app.example.com/dashboard", title: "Dashboard" }, timestamp: new Date().toISOString(), }, ], "https://ingest.mycompany.com/v1/events" ); ``` -------------------------------- ### Initialize Telemetry Manager Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt Initializes the TelemetryManager with configuration options for API keys, batching, reliability, sampling, plugin enablement, and logging. Use this as the primary entry point for the SDK. ```typescript import { initTelemetry } from "@hyperlook/telemetry-sdk"; const telemetry = initTelemetry({ hyperlookApiKey: "hlk_live_abc123", // Required for Hyperlook exporter // Batching batchSize: 50, // Send when 50 events accumulate (default) flushInterval: 30000, // Also flush every 30 s (default) // Reliability maxRetries: 3, retryDelay: 1000, // Base delay for exponential backoff maxRetryDelay: 30000, // Sampling (useful in high-traffic apps) samplingRate: 0.5, // Capture 50 % of events // Plugins (all default true except customEvents / sessionReplay) enablePageViews: true, enableClicks: true, enableLogs: true, enableNetwork: true, enablePerformance: true, enableErrors: true, enableCustomEvents: true, enableSessionReplay: false, // Logger logging: { level: "DEBUG", enableConsole: true, enableTimestamp: true, prefix: "[MyApp]", }, }); console.log("Session:", telemetry.getSessionId()); // Session: 3f7a1b2c-... ``` -------------------------------- ### SessionReplayPlugin Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt Enables recording of DOM mutations, user interactions, and network activity for session replay. Offers options for masking sensitive data, setting recording limits, and configuring slim DOM output. ```APIDOC ## `SessionReplayPlugin` ### Description Enabled via `enableSessionReplay: true`. Uses `rrweb` to record full DOM mutations, user interactions, and network activity. Emits `session_replay_start`, `session_replay_batch` (one per rrweb event), and `session_replay_end` events. Recording stops automatically at `maxEvents` (default 1 000) or `maxDuration` (default 5 min). Sensitive content can be masked using CSS selectors or the `maskAllInputs` / `maskTextInputs` flags. ### Configuration ```typescript import { initTelemetry } from "@hyperlook/telemetry-sdk"; const telemetry = initTelemetry({ hyperlookApiKey: "hlk_live_abc123", enableSessionReplay: true, sessionReplay: { maxEvents: 2000, maxDuration: 10 * 60 * 1000, // 10 minutes maskAllInputs: true, // Mask all form inputs maskTextSelector: ".pii", // Also mask elements with class .pii blockClass: "no-record", // Elements with this class are not recorded inlineStylesheet: true, recordCanvas: false, slimDOMOptions: { script: true, comment: true, }, }, }); // Session replay events are captured and exported automatically. // Session ID is available for correlation: console.log("Replay session:", telemetry.getSessionId()); ``` ``` -------------------------------- ### Add Plugin Configuration Option Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md Define an optional configuration property for your plugin in the main telemetry configuration type. ```typescript export type TelemetryConfig = { enableYourPlugin?: boolean; // Add this line // ... other options }; ``` -------------------------------- ### Export Plugin from Plugins Index Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Make the newly created plugin available for import by exporting it from the plugins index file. ```typescript export { BasePlugin } from "./BasePlugin"; export { ClickPlugin } from "./ClickPlugin"; export { CustomEventsPlugin } from "./CustomEventsPlugin"; export { ErrorPlugin } from "./ErrorPlugin"; export { LogPlugin } from "./LogPlugin"; export { NetworkPlugin } from "./NetworkPlugin"; export { PerformancePlugin } from "./PerformancePlugin"; export { PageViewPlugin } from "./PageViewPlugin"; export { YourPluginName } from "./YourPluginName"; // Add this line ``` -------------------------------- ### Export Plugin from Main SDK Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md Make your plugin accessible to users of the telemetry SDK by adding it to the main export. ```typescript import { YourPluginName } from "./plugins/YourPluginName"; export { YourPluginName }; // Add to exports ``` -------------------------------- ### Export Plugin for Import Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md Make your newly created plugin available for import in other parts of the SDK. ```typescript export { YourPluginName } from "./YourPluginName"; // Add this line ``` -------------------------------- ### Register Plugin in PluginManager Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md Configure the PluginManager to auto-initialize your plugin when its corresponding configuration option is enabled. ```typescript import { YourPluginName } from "../plugins"; // Add import const pluginConfigs = [ { enabled: config.enableYourPlugin, // Add this block plugin: YourPluginName, name: "YourPluginName", }, // ... other plugins ]; ``` -------------------------------- ### Register New Plugin in PluginManager Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Adds your plugin to the list of configurations within the PluginManager, ensuring it's initialized when enabled. ```typescript // Add import import { ClickPlugin, LogPlugin, NetworkPlugin, PerformancePlugin, CustomEventsPlugin, PageViewPlugin, YourPluginName, // Add this line } from "../plugins"; // Add to plugin configurations array const pluginConfigs = [ { enabled: config.enablePageViews ?? true, plugin: PageViewPlugin, name: "PageViewPlugin", }, { enabled: config.enableClicks, plugin: ClickPlugin, name: "ClickPlugin", }, { enabled: config.enableLogs, plugin: LogPlugin, name: "LogPlugin", }, { enabled: config.enableNetwork, plugin: NetworkPlugin, name: "NetworkPlugin", }, { enabled: config.enablePerformance, plugin: PerformancePlugin, name: "PerformancePlugin", }, { enabled: config.enableYourPlugin, // Add this block plugin: YourPluginName, name: "YourPluginName", }, { enabled: config.enableCustomEvents, plugin: CustomEventsPlugin, name: "CustomEventsPlugin", isCustomEvents: true, }, ]; ``` -------------------------------- ### Graceful and Emergency SDK Shutdown Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt `shutdown()` performs a graceful teardown, including a final flush. `destroy()` is an emergency variant that skips the flush and immediately releases resources. ```typescript import { initTelemetry } from "@hyperlook/telemetry-sdk"; const telemetry = initTelemetry({ hyperlookApiKey: "hlk_live_abc123" }); // Graceful (Node.js service shutdown) process.on("SIGTERM", async () => { const timeout = setTimeout(() => telemetry.destroy(), 10_000); try { await telemetry.shutdown(); clearTimeout(timeout); console.log("Telemetry flushed — exiting."); process.exit(0); } catch { telemetry.destroy(); process.exit(1); } }); // Check state before acting if (!telemetry.isShutdown()) { telemetry.capture({ eventType: "app", eventName: "heartbeat", payload: {}, timestamp: new Date().toISOString() }); } ``` -------------------------------- ### Error Handling in Plugin Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Best practices for error handling within a plugin, including using try-catch blocks and logging errors. ```markdown - **Wrap event capture in try-catch** - Prevent plugin failures from affecting the SDK - **Log errors appropriately** - Use `this.logger.error()` for debugging - **Graceful degradation** - Disable plugin if setup fails ``` -------------------------------- ### telemetry.flush Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt Immediately exports all buffered events. It can optionally use `navigator.sendBeacon` for guaranteed delivery during page unload. ```APIDOC ## `telemetry.flush(useBeacon?)` ### Description Immediately exports all buffered events. When `useBeacon` is `true` (or when the manager is in `SHUTTING_DOWN` / `SHUTDOWN` state) it uses `navigator.sendBeacon` to guarantee delivery during page unload. If the export fails and is retryable, the batch is returned to the internal buffer. ### Parameters - `useBeacon` (boolean) - Optional. If true, uses `navigator.sendBeacon` for delivery. ### Example ```typescript await telemetry.flush(); window.addEventListener("beforeunload", () => { telemetry.flush(true).catch(() => telemetry.destroy()); }); ``` ``` -------------------------------- ### Flush Telemetry Data Immediately Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt Use `telemetry.flush()` to export buffered events immediately. Set `useBeacon` to `true` for guaranteed delivery during page unload via `navigator.sendBeacon`. ```typescript import { initTelemetry } from "@hyperlook/telemetry-sdk"; const telemetry = initTelemetry({ hyperlookApiKey: "hlk_live_abc123" }); // Trigger an immediate flush (e.g., after a critical user action) await telemetry.flush(); // Flush using sendBeacon — safe to call during beforeunload window.addEventListener("beforeunload", () => { telemetry.flush(true).catch(() => telemetry.destroy()); }); ``` -------------------------------- ### Set Default Plugin Configuration Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/PLUGIN_GUIDE.md Provide a default value for your plugin's configuration option, typically `false` to disable it by default. ```typescript export const initialTelemetryConfig: TelemetryConfig = { enableYourPlugin: false, // Add this line (usually false by default) // ... other defaults }; ``` -------------------------------- ### Bump Package Version Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/NPM_GUIDE.md Use this command to increment the version of your package (patch, minor, or major). Replace `patch` with `minor` or `major` as needed. This command also updates the version, builds the package, commits changes, tags the release, and pushes to GitHub. ```sh pnpm version patch ``` -------------------------------- ### Capture Custom Events with Telemetry SDK Source: https://context7.com/drdroidlab/telemetry-sdk/llms.txt Use `captureCustomEvent` for convenience or `captureEvent` with a pre-built `TelemetryEvent` object. Inputs are validated and sanitized, with reserved event types blocked. ```typescript import { initTelemetry } from "@hyperlook/telemetry-sdk"; const telemetry = initTelemetry({ hyperlookApiKey: "hlk_live_abc123", enableCustomEvents: true, }); const customPlugin = telemetry.getCustomEventsPlugin(); if (customPlugin) { // Variant A: convenience method customPlugin.captureCustomEvent("ecommerce", "product_viewed", { productId: "prod_512", productName: "Noise-Cancelling Headphones", category: "Electronics", price: 299.99, currency: "USD", inStock: true, }); // Variant B: pre-built event object customPlugin.captureEvent({ eventType: "feature_usage", eventName: "export_triggered", payload: { format: "CSV", rowCount: 1200, triggeredBy: "schedule" }, timestamp: new Date().toISOString(), }); } ``` -------------------------------- ### Capture Custom Event via Plugin Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/README.md When `enableCustomEvents` is true, you can access the custom events plugin to capture specific events with detailed payloads. Check if the plugin is available before use. ```typescript const customPlugin = telemetry.getCustomEventsPlugin(); if (customPlugin) { // Capture a custom event with type, name, and payload customPlugin.captureCustomEvent("ecommerce", "product_viewed", { productId: "prod_123", productName: "Wireless Headphones", category: "Electronics", price: 99.99, currency: "USD", }); } ``` -------------------------------- ### Custom Events Plugin Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/README.md Methods for capturing custom events when the `enableCustomEvents` option is set to true. ```APIDOC ## captureCustomEvent(eventType: string, eventName: string, payload: Record): void ### Description Captures a custom event with a specified type, name, and payload. ### Method `captureCustomEvent` (accessed via `getCustomEventsPlugin()`) ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - **eventType** (string) - The type of the custom event. - **eventName** (string) - The name of the custom event. - **payload** (Record) - An object containing the event payload. ### Request Example ```typescript const customPlugin = telemetry.getCustomEventsPlugin(); if (customPlugin) { customPlugin.captureCustomEvent("ecommerce", "product_viewed", { productId: "prod_123", productName: "Wireless Headphones", category: "Electronics", price: 99.99, currency: "USD", }); } ``` ### Response #### Success Response (void) - This method does not return a value. ``` -------------------------------- ### Define Telemetry Configuration Type Source: https://github.com/drdroidlab/telemetry-sdk/blob/main/CONTRIBUTING.md Extends the TelemetryConfig type to include a new option for enabling your plugin. ```typescript export type TelemetryConfig = { endpoint?: string; hyperlookApiKey?: string; exporters?: ExporterType[]; enablePageViews?: boolean; enableClicks?: boolean; enableLogs?: boolean; enableNetwork?: boolean; enablePerformance?: boolean; enableYourPlugin?: boolean; // Add this line batchSize?: number; flushInterval?: number; maxRetries?: number; retryDelay?: number; samplingRate?: number; logging?: LoggerConfig; sessionId?: string; userId?: string; enableCustomEvents?: boolean; }; ```