# How to connect monitoring tools to Replit

- Tool: Replit
- Difficulty: Beginner
- Time required: 15 minutes
- Compatibility: All Replit plans (monitoring tools work on Starter, Core, and Pro)
- Last updated: March 2026

## TL;DR

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.

## Before you start

- 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

### 1. 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.

### 2. 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.

### 3. 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.

```
// src/server.js - Initialize Sentry before other imports
import * as Sentry from '@sentry/node';

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.REPLIT_DEPLOYMENT === '1'
    ? 'production'
    : 'development',
  tracesSampleRate: 0.2, // Sample 20% of transactions
});

import express from 'express';

const app = express();

// Sentry request handler must be first middleware
app.use(Sentry.Handlers.requestHandler());

// Your routes here
app.get('/api/data', (req, res) => {
  // If this throws, Sentry captures it automatically
  res.json({ status: 'ok' });
});

// Sentry error handler must be before other error handlers
app.use(Sentry.Handlers.errorHandler());

app.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.

### 4. 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.

```
// src/main.tsx - Initialize LogRocket for frontend
import React from 'react';
import ReactDOM from 'react-dom/client';
import LogRocket from 'logrocket';
import App from './App';
import './index.css';

// Initialize LogRocket only in production
if (import.meta.env.PROD) {
  const appId = import.meta.env.VITE_LOGROCKET_APP_ID;
  if (appId) {
    LogRocket.init(appId);
  }
}

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
```

**Expected result:** LogRocket records user sessions in production. Visit your deployed app and check the LogRocket dashboard for session replays.

### 5. 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.

```
import pg from 'pg';

const pool = new pg.Pool({
  connectionString: process.env.DATABASE_URL,
});

app.get('/health', async (req, res) => {
  const health = {
    status: 'ok',
    uptime: process.uptime(),
    timestamp: new Date().toISOString(),
    memory: {
      heapUsed: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
      heapTotal: Math.round(process.memoryUsage().heapTotal / 1024 / 1024),
    },
    database: 'unknown',
  };

  try {
    await pool.query('SELECT 1');
    health.database = 'connected';
  } catch {
    health.database = 'disconnected';
    health.status = 'degraded';
  }

  const statusCode = health.status === 'ok' ? 200 : 503;
  res.status(statusCode).json(health);
});
```

**Expected result:** The /health endpoint returns a JSON response with status, uptime, memory, and database connectivity in under 5 seconds.

### 6. 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.

```
// src/logger.js - Simple structured logger
function createLogger(service) {
  const log = (level, message, data = {}) => {
    const entry = {
      timestamp: new Date().toISOString(),
      level,
      service,
      message,
      ...data,
    };
    console.log(JSON.stringify(entry));
  };

  return {
    info: (msg, data) => log('info', msg, data),
    warn: (msg, data) => log('warn', msg, data),
    error: (msg, data) => log('error', msg, data),
  };
}

export default createLogger;

// Usage:
// import createLogger from './logger.js';
// const logger = createLogger('api');
// 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 code example

File: `src/server.js`

```javascript
// src/server.js
// Express server with Sentry, health check, and structured logging

import * as Sentry from '@sentry/node';
import express from 'express';
import pg from 'pg';
import createLogger from './logger.js';

// Initialize Sentry first
Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.REPLIT_DEPLOYMENT === '1'
    ? 'production'
    : 'development',
  tracesSampleRate: 0.2,
});

const app = express();
const logger = createLogger('server');
const pool = new pg.Pool({
  connectionString: process.env.DATABASE_URL,
});

app.use(Sentry.Handlers.requestHandler());
app.use(express.json());

// Health check endpoint
app.get('/health', async (req, res) => {
  const health = {
    status: 'ok',
    uptime: process.uptime(),
    timestamp: new Date().toISOString(),
    memory: {
      heapMB: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
    },
    database: 'unknown',
  };
  try {
    await pool.query('SELECT 1');
    health.database = 'connected';
  } catch {
    health.database = 'disconnected';
    health.status = 'degraded';
  }
  res.status(health.status === 'ok' ? 200 : 503).json(health);
});

// Example API route
app.get('/api/data', async (req, res) => {
  logger.info('Data requested', { query: req.query });
  try {
    const result = await pool.query('SELECT * FROM items LIMIT 50');
    res.json(result.rows);
  } catch (error) {
    logger.error('Database query failed', { error: error.message });
    Sentry.captureException(error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

app.use(Sentry.Handlers.errorHandler());

const PORT = process.env.PORT || 3000;
app.listen(PORT, '0.0.0.0', () => {
  logger.info('Server started', { port: PORT });
});
```

## Common mistakes

- **Initializing Sentry after other imports instead of at the top of the entry file** — undefined Fix: 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.
- **Putting the Sentry error handler before route definitions** — undefined Fix: Sentry.Handlers.errorHandler() must come after all route definitions but before any custom error handlers. Place it as the last middleware.
- **Not adding monitoring secrets to the deployment configuration** — undefined Fix: Workspace secrets do not transfer to deployments. Add SENTRY_DSN and other monitoring keys in the Deployments pane before publishing.
- **Making the health check endpoint perform heavy database queries** — undefined Fix: 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.
- **Recording all sessions with LogRocket in development** — undefined Fix: 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

## Frequently asked questions

### Is Sentry free to use with Replit?

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.

### Do I need to add monitoring secrets to the deployment configuration?

Yes. Workspace secrets do not transfer to deployments automatically. Add SENTRY_DSN and any other monitoring keys in the Deployments pane before publishing.

### Will monitoring tools slow down my Replit app?

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.

### Can I use Datadog or New Relic instead of Sentry?

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.

### How do I get alerts when my Replit app goes down?

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.

### Where do client-side console.log messages appear?

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.

### Can I send logs to an external log aggregation service?

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.

### What should my health check endpoint return?

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.

---

Source: https://www.rapidevelopers.com/replit-tutorial/how-to-integrate-third-party-monitoring-tools-with-replit-hosted-applications
© RapidDev — https://www.rapidevelopers.com/replit-tutorial/how-to-integrate-third-party-monitoring-tools-with-replit-hosted-applications
