You can connect monitoring tools like Sentry, LogRocket, and custom health check endpoints to Replit apps by adding their SDK packages through npm or pip, storing API keys in Replit Secrets, and initializing the monitoring code at app startup. Sentry captures server-side errors automatically, LogRocket records frontend user sessions, and custom health check endpoints let external uptime monitors verify your app is running. All monitoring credentials must be added to both workspace Secrets and deployment configuration.
Adding Error Tracking, Session Recording, and Health Monitoring to Replit Apps
Replit's Console and Shell show basic output and errors, but production apps need deeper visibility into what goes wrong and when. This tutorial walks through integrating three types of monitoring: Sentry for automatic error capture and alerting, LogRocket for frontend session replay and debugging, and custom health check endpoints for uptime monitoring services. You will store all monitoring credentials securely using Replit Secrets and configure each tool to work in both development and deployed environments.
Prerequisites
- A Replit account with a deployed or ready-to-deploy web application
- A Sentry account (free tier available at sentry.io)
- Basic familiarity with npm package installation
- Understanding of how Replit Secrets work for storing API keys
Step-by-step guide
Create accounts and get API keys for monitoring services
Create accounts and get API keys for monitoring services
Before integrating any monitoring tool, create accounts on the services you plan to use. For Sentry, sign up at sentry.io and create a new project for Node.js or your language of choice. Copy the DSN (Data Source Name) string from the project settings. For LogRocket, sign up at logrocket.com and create a new project to get your App ID. Store both values in Replit Secrets immediately rather than pasting them into code.
Expected result: You have a Sentry DSN string and a LogRocket App ID ready to store in Replit Secrets.
Store monitoring credentials in Replit Secrets
Store monitoring credentials in Replit Secrets
Open the Secrets tool from the left sidebar Tools dock. Add each monitoring credential as an App Secret. Create SENTRY_DSN with your Sentry DSN string as the value, and LOGROCKET_APP_ID with your LogRocket App ID. These values are encrypted with AES-256 and never appear in your source code. Remember to also add these same secrets in the Deployments pane configuration before publishing, because workspace secrets do not transfer to deployments automatically.
Expected result: SENTRY_DSN and LOGROCKET_APP_ID appear in your App Secrets list, encrypted and ready for use in code.
Install and configure Sentry for server-side error tracking
Install and configure Sentry for server-side error tracking
Open the Shell terminal and install the Sentry SDK for your language. For Node.js, run npm install @sentry/node. Initialize Sentry as early as possible in your application entry point, before any other imports that might throw errors. Sentry automatically captures unhandled exceptions and unhandled promise rejections. You can also capture specific errors manually with Sentry.captureException. In production, Sentry groups similar errors, tracks frequency, and sends email or Slack alerts.
1// src/server.js - Initialize Sentry before other imports2import * as Sentry from '@sentry/node';34Sentry.init({5 dsn: process.env.SENTRY_DSN,6 environment: process.env.REPLIT_DEPLOYMENT === '1'7 ? 'production'8 : 'development',9 tracesSampleRate: 0.2, // Sample 20% of transactions10});1112import express from 'express';1314const app = express();1516// Sentry request handler must be first middleware17app.use(Sentry.Handlers.requestHandler());1819// Your routes here20app.get('/api/data', (req, res) => {21 // If this throws, Sentry captures it automatically22 res.json({ status: 'ok' });23});2425// Sentry error handler must be before other error handlers26app.use(Sentry.Handlers.errorHandler());2728app.listen(3000, '0.0.0.0');Expected result: Sentry captures errors automatically. Test by throwing an error in a route and verifying it appears in your Sentry dashboard.
Add LogRocket for frontend session recording
Add LogRocket for frontend session recording
For React frontend apps, install LogRocket from the Shell with npm install logrocket. Initialize it in your main React entry file before rendering the app. LogRocket records user sessions including clicks, scrolls, network requests, and console output. You can replay these sessions in the LogRocket dashboard to see exactly what the user experienced when an error occurred. Since LogRocket runs in the browser, the App ID is exposed in client-side code, but this is safe because LogRocket App IDs are designed to be public.
1// src/main.tsx - Initialize LogRocket for frontend2import React from 'react';3import ReactDOM from 'react-dom/client';4import LogRocket from 'logrocket';5import App from './App';6import './index.css';78// Initialize LogRocket only in production9if (import.meta.env.PROD) {10 const appId = import.meta.env.VITE_LOGROCKET_APP_ID;11 if (appId) {12 LogRocket.init(appId);13 }14}1516ReactDOM.createRoot(document.getElementById('root')!).render(17 <React.StrictMode>18 <App />19 </React.StrictMode>20);Expected result: LogRocket records user sessions in production. Visit your deployed app and check the LogRocket dashboard for session replays.
Build a custom health check endpoint
Build a custom health check endpoint
External uptime monitoring services like UptimeRobot, Pingdom, or Better Uptime need an HTTP endpoint to check periodically. Create a dedicated health check route that returns a 200 status when the app is healthy. Include useful metadata like uptime, memory usage, and database connectivity status. This endpoint also serves as Replit's deployment health check, which must respond within 5 seconds. Keep it lightweight with no heavy database queries or external API calls.
1import pg from 'pg';23const pool = new pg.Pool({4 connectionString: process.env.DATABASE_URL,5});67app.get('/health', async (req, res) => {8 const health = {9 status: 'ok',10 uptime: process.uptime(),11 timestamp: new Date().toISOString(),12 memory: {13 heapUsed: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),14 heapTotal: Math.round(process.memoryUsage().heapTotal / 1024 / 1024),15 },16 database: 'unknown',17 };1819 try {20 await pool.query('SELECT 1');21 health.database = 'connected';22 } catch {23 health.database = 'disconnected';24 health.status = 'degraded';25 }2627 const statusCode = health.status === 'ok' ? 200 : 503;28 res.status(statusCode).json(health);29});Expected result: The /health endpoint returns a JSON response with status, uptime, memory, and database connectivity in under 5 seconds.
Add custom structured logging for production debugging
Add custom structured logging for production debugging
Replit Console shows standard output, but structured JSON logging makes it much easier to search and filter logs in production. Replace console.log with a simple logger that outputs JSON with timestamps, log levels, and contextual data. This format works with log aggregation tools if you send logs to an external service. For most Replit projects, Console output combined with Sentry error tracking is sufficient, but structured logs help when debugging complex issues that do not throw errors.
1// src/logger.js - Simple structured logger2function createLogger(service) {3 const log = (level, message, data = {}) => {4 const entry = {5 timestamp: new Date().toISOString(),6 level,7 service,8 message,9 ...data,10 };11 console.log(JSON.stringify(entry));12 };1314 return {15 info: (msg, data) => log('info', msg, data),16 warn: (msg, data) => log('warn', msg, data),17 error: (msg, data) => log('error', msg, data),18 };19}2021export default createLogger;2223// Usage:24// import createLogger from './logger.js';25// const logger = createLogger('api');26// logger.info('Request received', { path: '/api/data', method: 'GET' });Expected result: Log entries appear as structured JSON in the Console, making them easy to search and parse.
Complete working example
1// src/server.js2// Express server with Sentry, health check, and structured logging34import * as Sentry from '@sentry/node';5import express from 'express';6import pg from 'pg';7import createLogger from './logger.js';89// Initialize Sentry first10Sentry.init({11 dsn: process.env.SENTRY_DSN,12 environment: process.env.REPLIT_DEPLOYMENT === '1'13 ? 'production'14 : 'development',15 tracesSampleRate: 0.2,16});1718const app = express();19const logger = createLogger('server');20const pool = new pg.Pool({21 connectionString: process.env.DATABASE_URL,22});2324app.use(Sentry.Handlers.requestHandler());25app.use(express.json());2627// Health check endpoint28app.get('/health', async (req, res) => {29 const health = {30 status: 'ok',31 uptime: process.uptime(),32 timestamp: new Date().toISOString(),33 memory: {34 heapMB: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),35 },36 database: 'unknown',37 };38 try {39 await pool.query('SELECT 1');40 health.database = 'connected';41 } catch {42 health.database = 'disconnected';43 health.status = 'degraded';44 }45 res.status(health.status === 'ok' ? 200 : 503).json(health);46});4748// Example API route49app.get('/api/data', async (req, res) => {50 logger.info('Data requested', { query: req.query });51 try {52 const result = await pool.query('SELECT * FROM items LIMIT 50');53 res.json(result.rows);54 } catch (error) {55 logger.error('Database query failed', { error: error.message });56 Sentry.captureException(error);57 res.status(500).json({ error: 'Internal server error' });58 }59});6061app.use(Sentry.Handlers.errorHandler());6263const PORT = process.env.PORT || 3000;64app.listen(PORT, '0.0.0.0', () => {65 logger.info('Server started', { port: PORT });66});Common mistakes when connecting monitoring tools to Replit
Why it's a problem: Initializing Sentry after other imports instead of at the top of the entry file
How to avoid: Sentry must be initialized before other modules load so it can instrument them properly. Move Sentry.init() to the very first lines of your entry file.
Why it's a problem: Putting the Sentry error handler before route definitions
How to avoid: Sentry.Handlers.errorHandler() must come after all route definitions but before any custom error handlers. Place it as the last middleware.
Why it's a problem: Not adding monitoring secrets to the deployment configuration
How to avoid: Workspace secrets do not transfer to deployments. Add SENTRY_DSN and other monitoring keys in the Deployments pane before publishing.
Why it's a problem: Making the health check endpoint perform heavy database queries
How to avoid: Use a simple SELECT 1 query to test connectivity. Heavy queries in the health check can cause 5-second timeout failures and false downtime alerts.
Why it's a problem: Recording all sessions with LogRocket in development
How to avoid: Wrap LogRocket.init() in a production check. Recording development sessions wastes your LogRocket quota and clutters the dashboard.
Best practices
- Initialize Sentry before any other imports so it captures errors from all modules
- Store all monitoring API keys and DSNs in Replit Secrets, never in source code
- Add monitoring secrets to both workspace Secrets and the deployment configuration
- Set tracesSampleRate to 0.1 or 0.2 in production to stay within free tier quotas
- Keep the health check endpoint lightweight with no heavy computations or slow queries
- Use structured JSON logging so log entries are searchable and parseable
- Initialize LogRocket only in production to avoid recording development sessions
- Test error tracking by intentionally throwing an error and verifying it appears in Sentry
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I have a Node.js Express app deployed on Replit. I want to add Sentry for error tracking, a health check endpoint for uptime monitoring, and structured JSON logging. Show me how to set up each one with proper Replit Secrets configuration.
Add Sentry error tracking to my Express app. Initialize it at the top of the entry file using the SENTRY_DSN from Replit Secrets. Add request and error handler middleware. Create a /health endpoint that checks database connectivity and returns JSON with status, uptime, and memory usage. Add a structured JSON logger.
Frequently asked questions
Sentry offers a free Developer tier with 5,000 errors per month, one user, and basic alerting. This is sufficient for most small to medium Replit projects.
Yes. Workspace secrets do not transfer to deployments automatically. Add SENTRY_DSN and any other monitoring keys in the Deployments pane before publishing.
Modern monitoring SDKs have minimal performance impact. Sentry captures errors asynchronously, and LogRocket runs in the browser without affecting server performance. Keep tracesSampleRate low to minimize overhead.
Yes. Any monitoring service that provides an npm or pip SDK works on Replit. Install the SDK, store the API key in Secrets, and initialize it in your app. The setup pattern is the same.
Register your /health endpoint with a free uptime monitoring service like UptimeRobot or Better Uptime. These services ping your endpoint at regular intervals and send email or SMS alerts when it stops responding.
Client-side JavaScript logs appear in the Preview pane DevTools, not in the Replit Console. Open DevTools in the preview panel by right-clicking and selecting Inspect.
Yes. Use an HTTP transport in your logger to send structured JSON log entries to services like Logtail, Papertrail, or Datadog. Store the API endpoint and key in Replit Secrets.
Return a JSON object with at minimum a status field and an HTTP 200 status code when healthy. Include uptime, memory usage, and database connectivity status for richer monitoring data. Return 503 when degraded.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation