Skip to Content
UptimeBeacon 1.0 is released 🎉

Examples

This page provides practical examples of using Sentinel Guard in various scenarios and environments.

Basic Examples

Simple Application Monitoring

import { SentinelGuard } from "@uptimebeacon/sentinel-guard"; const sentinel = new SentinelGuard({ apiKey: process.env.SENTINEL_API_KEY!, baseUrl: process.env.SENTINEL_API_URL!, monitorApiKey: process.env.SENTINEL_MONITOR_API_KEY!, }); // Start monitoring sentinel.startMonitoring({ interval: 30000, maxConsecutiveErrors: 5, }); console.log("Application monitoring started"); // Graceful shutdown process.on("SIGINT", () => { sentinel.stopMonitoring(); process.exit(0); });

Manual Heartbeat

import { SentinelGuard } from "@uptimebeacon/sentinel-guard"; const sentinel = new SentinelGuard({ apiKey: process.env.SENTINEL_API_KEY!, baseUrl: process.env.SENTINEL_API_URL!, monitorApiKey: process.env.SENTINEL_MONITOR_API_KEY!, }); async function sendCustomHeartbeat() { try { const response = await sentinel.sendHeartbeat({ status: "ONLINE", metadata: { service: "user-service", version: "2.1.0", environment: process.env.NODE_ENV, uptime: process.uptime(), }, }); if (response.success) { console.log("Heartbeat sent successfully"); } else { console.error("Heartbeat failed"); } } catch (error) { console.error("Error sending heartbeat:", error); } } // Send heartbeat every 60 seconds setInterval(sendCustomHeartbeat, 60000);

Web Framework Integration

Express.js Application

import express from "express"; import { SentinelGuard } from "@uptimebeacon/sentinel-guard"; const app = express(); const PORT = process.env.PORT || 3000; // Initialize monitoring const sentinel = new SentinelGuard({ apiKey: process.env.SENTINEL_API_KEY!, baseUrl: process.env.SENTINEL_API_URL!, monitorApiKey: process.env.SENTINEL_MONITOR_API_KEY!, }); // Middleware for health checks app.use((req, res, next) => { // Track request timing const start = Date.now(); res.on("finish", () => { const duration = Date.now() - start; console.log(`${req.method} ${req.path} - ${duration}ms`); }); next(); }); // Health check endpoint app.get("/health", (req, res) => { const isMonitoring = sentinel.isMonitoringActive(); const errorCount = sentinel.getErrorCount(); res.json({ status: "healthy", monitoring: isMonitoring, errors: errorCount, uptime: process.uptime(), timestamp: new Date().toISOString(), }); }); // Start server app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); // Start monitoring after server is ready sentinel.startMonitoring({ interval: 45000, maxConsecutiveErrors: 3, }); console.log("Server monitoring started"); }); // Graceful shutdown process.on("SIGTERM", () => { console.log("Received SIGTERM, shutting down gracefully"); sentinel.stopMonitoring(); process.exit(0); });

Fastify Application

import Fastify from "fastify"; import { SentinelGuard } from "@uptimebeacon/sentinel-guard"; const fastify = Fastify({ logger: true }); const sentinel = new SentinelGuard({ apiKey: process.env.SENTINEL_API_KEY!, baseUrl: process.env.SENTINEL_API_URL!, monitorApiKey: process.env.SENTINEL_MONITOR_API_KEY!, }); // Health check route fastify.get("/health", async (request, reply) => { return { status: "healthy", monitoring: sentinel.isMonitoringActive(), errors: sentinel.getErrorCount(), uptime: process.uptime(), }; }); // Start server const start = async () => { try { await fastify.listen({ port: 3000 }); sentinel.startMonitoring({ interval: 30000, maxConsecutiveErrors: 5, }); console.log("Fastify server and monitoring started"); } catch (err) { fastify.log.error(err); process.exit(1); } }; start();

Database Integration

Prisma Integration

import { PrismaClient } from "@prisma/client"; import { SentinelGuard } from "@uptimebeacon/sentinel-guard"; const prisma = new PrismaClient(); const sentinel = new SentinelGuard({ apiKey: process.env.SENTINEL_API_KEY!, baseUrl: process.env.SENTINEL_API_URL!, monitorApiKey: process.env.SENTINEL_MONITOR_API_KEY!, }); // Set up database monitoring sentinel.setPrismaClient(prisma); // Start monitoring with database latency tracking sentinel.startMonitoring({ interval: 30000, maxConsecutiveErrors: 5, }); // Example API endpoint with database operation async function getUserById(id: string) { try { const user = await prisma.user.findUnique({ where: { id }, }); // Send heartbeat with operation status await sentinel.sendHeartbeat({ status: "ONLINE", metadata: { operation: "getUserById", userId: id, found: !!user, }, }); return user; } catch (error) { // Send error heartbeat await sentinel.sendHeartbeat({ status: "ERROR", metadata: { operation: "getUserById", error: error.message, }, }); throw error; } } // Cleanup on shutdown process.on("SIGINT", async () => { await prisma.$disconnect(); sentinel.stopMonitoring(); process.exit(0); });

Redis Integration

import { createClient } from "redis"; import { SentinelGuard } from "@uptimebeacon/sentinel-guard"; const redis = createClient({ url: process.env.REDIS_URL, }); const sentinel = new SentinelGuard({ apiKey: process.env.SENTINEL_API_KEY!, baseUrl: process.env.SENTINEL_API_URL!, monitorApiKey: process.env.SENTINEL_MONITOR_API_KEY!, }); async function initializeServices() { // Connect to Redis await redis.connect(); console.log("Redis connected"); // Set up Redis monitoring sentinel.setRedisClient(redis); // Start monitoring sentinel.startMonitoring({ interval: 30000, maxConsecutiveErrors: 5, }); console.log("Services initialized with monitoring"); } // Example cache operation with monitoring async function getCachedData(key: string) { try { const data = await redis.get(key); await sentinel.sendHeartbeat({ status: "ONLINE", metadata: { operation: "cache_get", key, hit: !!data, }, }); return data; } catch (error) { await sentinel.sendHeartbeat({ status: "ERROR", metadata: { operation: "cache_get", error: error.message, }, }); throw error; } } initializeServices();

Full Database Stack

import { PrismaClient } from "@prisma/client"; import { createClient } from "redis"; import { SentinelGuard } from "@uptimebeacon/sentinel-guard"; const prisma = new PrismaClient(); const redis = createClient({ url: process.env.REDIS_URL }); const sentinel = new SentinelGuard({ apiKey: process.env.SENTINEL_API_KEY!, baseUrl: process.env.SENTINEL_API_URL!, monitorApiKey: process.env.SENTINEL_MONITOR_API_KEY!, }); class DatabaseService { async initialize() { await redis.connect(); console.log("Database services connected"); // Configure monitoring for both databases sentinel.setPrismaClient(prisma); sentinel.setRedisClient(redis); sentinel.startMonitoring({ interval: 30000, maxConsecutiveErrors: 3, }); } async getUserWithCache(id: string) { const cacheKey = `user:${id}`; try { // Try cache first const cached = await redis.get(cacheKey); if (cached) { await sentinel.sendHeartbeat({ status: "ONLINE", metadata: { operation: "getUserWithCache", source: "cache", userId: id, }, }); return JSON.parse(cached); } // Fallback to database const user = await prisma.user.findUnique({ where: { id }, }); if (user) { // Cache the result await redis.setex(cacheKey, 300, JSON.stringify(user)); } await sentinel.sendHeartbeat({ status: "ONLINE", metadata: { operation: "getUserWithCache", source: "database", userId: id, found: !!user, }, }); return user; } catch (error) { await sentinel.sendHeartbeat({ status: "ERROR", metadata: { operation: "getUserWithCache", error: error.message, }, }); throw error; } } async cleanup() { await prisma.$disconnect(); await redis.disconnect(); sentinel.stopMonitoring(); } } const dbService = new DatabaseService(); dbService.initialize();

Error Handling

Comprehensive Error Handling

import { SentinelGuard, NetworkError, AuthenticationError, RateLimitError, SentinelGuardError, } from "@uptimebeacon/sentinel-guard"; const sentinel = new SentinelGuard({ apiKey: process.env.SENTINEL_API_KEY!, baseUrl: process.env.SENTINEL_API_URL!, monitorApiKey: process.env.SENTINEL_MONITOR_API_KEY!, retryConfig: { maxRetries: 5, baseDelay: 2000, backoffMultiplier: 2, }, }); async function robustHeartbeat(status: string, metadata?: any) { try { const response = await sentinel.sendHeartbeat({ status: status as any, metadata, }); return response; } catch (error) { if (error instanceof AuthenticationError) { console.error("Authentication failed:", error.message); // Handle authentication issues process.exit(1); } else if (error instanceof NetworkError) { console.error("Network error:", error.message); // Network issues - might be temporary setTimeout(() => robustHeartbeat(status, metadata), 10000); } else if (error instanceof RateLimitError) { console.error("Rate limit exceeded:", error.message); // Back off and retry later setTimeout(() => robustHeartbeat(status, metadata), 60000); } else if (error instanceof SentinelGuardError) { console.error("Sentinel Guard error:", error.message); } else { console.error("Unknown error:", error); } throw error; } } // Monitor error rates let errorCount = 0; let successCount = 0; setInterval(async () => { try { await robustHeartbeat("ONLINE", { errorRate: errorCount / (errorCount + successCount), totalRequests: errorCount + successCount, }); successCount++; } catch (error) { errorCount++; } }, 30000);

Retry Logic Example

import { SentinelGuard } from "@uptimebeacon/sentinel-guard"; const sentinel = new SentinelGuard({ apiKey: process.env.SENTINEL_API_KEY!, baseUrl: process.env.SENTINEL_API_URL!, monitorApiKey: process.env.SENTINEL_MONITOR_API_KEY!, }); class RetryableService { private maxRetries = 3; private retryDelay = 1000; async sendHeartbeatWithRetry(data: any, attempt = 1): Promise<any> { try { return await sentinel.sendHeartbeat(data); } catch (error) { if (attempt < this.maxRetries) { console.log(`Heartbeat failed (attempt ${attempt}), retrying...`); await new Promise((resolve) => setTimeout(resolve, this.retryDelay * attempt), ); return this.sendHeartbeatWithRetry(data, attempt + 1); } throw error; } } } const service = new RetryableService();

Advanced Use Cases

Microservices Architecture

import { SentinelGuard } from "@uptimebeacon/sentinel-guard"; class MicroserviceMonitor { private sentinel: SentinelGuard; private serviceName: string; private serviceVersion: string; constructor(serviceName: string, serviceVersion: string) { this.serviceName = serviceName; this.serviceVersion = serviceVersion; this.sentinel = new SentinelGuard({ apiKey: process.env.SENTINEL_API_KEY!, baseUrl: process.env.SENTINEL_API_URL!, monitorApiKey: process.env.SENTINEL_MONITOR_API_KEY!, }); } async startMonitoring() { this.sentinel.startMonitoring({ interval: 30000, maxConsecutiveErrors: 5, }); // Send initial heartbeat with service info await this.sentinel.sendHeartbeat({ status: "ONLINE", metadata: { service: this.serviceName, version: this.serviceVersion, environment: process.env.NODE_ENV, instance: process.env.INSTANCE_ID, startup: new Date().toISOString(), }, }); } async reportOperation(operation: string, success: boolean, duration: number) { await this.sentinel.sendHeartbeat({ status: success ? "ONLINE" : "ERROR", metadata: { service: this.serviceName, operation, success, duration, timestamp: new Date().toISOString(), }, }); } async reportHealthCheck(checks: Record<string, boolean>) { const allHealthy = Object.values(checks).every(Boolean); await this.sentinel.sendHeartbeat({ status: allHealthy ? "ONLINE" : "ERROR", metadata: { service: this.serviceName, healthChecks: checks, overallHealth: allHealthy, }, }); } } // Usage const monitor = new MicroserviceMonitor("user-service", "1.2.3"); monitor.startMonitoring();

Background Job Processing

import { SentinelGuard } from "@uptimebeacon/sentinel-guard"; class JobProcessor { private sentinel: SentinelGuard; private activeJobs = new Map<string, Date>(); constructor() { this.sentinel = new SentinelGuard({ apiKey: process.env.SENTINEL_API_KEY!, baseUrl: process.env.SENTINEL_API_URL!, monitorApiKey: process.env.SENTINEL_MONITOR_API_KEY!, }); this.sentinel.startMonitoring({ interval: 60000, // Check every minute maxConsecutiveErrors: 3, }); } async processJob(jobId: string, jobData: any) { const startTime = new Date(); this.activeJobs.set(jobId, startTime); try { // Simulate job processing await this.doWork(jobData); const duration = Date.now() - startTime.getTime(); await this.sentinel.sendHeartbeat({ status: "ONLINE", metadata: { jobId, duration, status: "completed", activeJobs: this.activeJobs.size, }, }); this.activeJobs.delete(jobId); } catch (error) { await this.sentinel.sendHeartbeat({ status: "ERROR", metadata: { jobId, error: error.message, status: "failed", activeJobs: this.activeJobs.size, }, }); this.activeJobs.delete(jobId); throw error; } } private async doWork(data: any) { // Simulate work await new Promise((resolve) => setTimeout(resolve, 1000)); } async reportQueueStatus(queueSize: number) { await this.sentinel.sendHeartbeat({ status: queueSize > 100 ? "HIGH_LATENCY" : "ONLINE", metadata: { queueSize, activeJobs: this.activeJobs.size, processingRate: this.calculateProcessingRate(), }, }); } private calculateProcessingRate(): number { // Calculate jobs processed per minute return 0; // Simplified } }

Scheduled Tasks

import { SentinelGuard } from "@uptimebeacon/sentinel-guard"; import cron from "node-cron"; class ScheduledTaskMonitor { private sentinel: SentinelGuard; constructor() { this.sentinel = new SentinelGuard({ apiKey: process.env.SENTINEL_API_KEY!, baseUrl: process.env.SENTINEL_API_URL!, monitorApiKey: process.env.SENTINEL_MONITOR_API_KEY!, }); this.sentinel.startMonitoring({ interval: 120000, // 2 minutes maxConsecutiveErrors: 2, }); } setupTasks() { // Daily backup task cron.schedule("0 2 * * *", async () => { await this.runTask("daily-backup", this.performBackup); }); // Hourly cleanup task cron.schedule("0 * * * *", async () => { await this.runTask("hourly-cleanup", this.performCleanup); }); // Health check every 5 minutes cron.schedule("*/5 * * * *", async () => { await this.runTask("health-check", this.performHealthCheck); }); } private async runTask(taskName: string, taskFn: () => Promise<void>) { const startTime = Date.now(); try { await taskFn(); const duration = Date.now() - startTime; await this.sentinel.sendHeartbeat({ status: "ONLINE", metadata: { task: taskName, duration, status: "completed", timestamp: new Date().toISOString(), }, }); } catch (error) { await this.sentinel.sendHeartbeat({ status: "ERROR", metadata: { task: taskName, error: error.message, status: "failed", timestamp: new Date().toISOString(), }, }); } } private async performBackup() { // Backup logic console.log("Performing backup..."); } private async performCleanup() { // Cleanup logic console.log("Performing cleanup..."); } private async performHealthCheck() { // Health check logic console.log("Performing health check..."); } } const taskMonitor = new ScheduledTaskMonitor(); taskMonitor.setupTasks();

Docker Integration

Docker Compose Example

version: "3.8" services: app: build: . environment: - SENTINEL_API_KEY=${SENTINEL_API_KEY} - SENTINEL_API_URL=${SENTINEL_API_URL} - SENTINEL_MONITOR_API_KEY=${SENTINEL_MONITOR_API_KEY} - NODE_ENV=production depends_on: - postgres - redis ports: - "3000:3000" postgres: image: postgres:15 environment: - POSTGRES_DB=myapp - POSTGRES_USER=user - POSTGRES_PASSWORD=password redis: image: redis:7-alpine ports: - "6379:6379"

Dockerfile with Monitoring

FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . # Build the application RUN npm run build # Health check endpoint HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD curl -f http://localhost:3000/health || exit 1 EXPOSE 3000 CMD ["npm", "start"]

Next Steps