• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Server Monitoring Best Practices: Keeping Your PHP App and MongoDB Clusters Alive on Linode

Server Monitoring Best Practices: Keeping Your PHP App and MongoDB Clusters Alive on Linode

Proactive Health Checks for PHP Applications

Maintaining the health of a PHP application goes beyond simply checking if the web server is responding. We need to ensure the application itself is functioning correctly, processing requests efficiently, and not leaking resources. This involves a multi-layered approach, starting with basic HTTP checks and extending to application-specific metrics.

HTTP Endpoint Health Checks

A fundamental check is to ensure your web server (e.g., Nginx or Apache) is serving your PHP application. This can be done by periodically fetching a dedicated health check endpoint. This endpoint should perform minimal, quick checks like database connectivity and essential configuration validation.

For example, create a healthcheck.php file in your application’s public directory:

<?php
header('Content-Type: application/json');

$response = ['status' => 'ok', 'timestamp' => time()];

// Basic check: Database connectivity (example using PDO)
try {
    // Replace with your actual database connection details
    $db = new PDO('mysql:host=localhost;dbname=your_db', 'user', 'password', [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_TIMEOUT => 2 // 2-second timeout
    ]);
    $db->query('SELECT 1'); // Simple query to test connection
} catch (PDOException $e) {
    http_response_code(503); // Service Unavailable
    $response = ['status' => 'error', 'message' => 'Database connection failed: ' . $e->getMessage()];
    echo json_encode($response);
    exit;
}

// Add other critical checks here (e.g., cache connectivity, essential service availability)

echo json_encode($response);
?>

You can then use a tool like curl or a dedicated monitoring agent to poll this endpoint. For instance, using curl in a cron job:

#!/bin/bash

HEALTHCHECK_URL="http://your-app-domain.com/healthcheck.php"
EXPECTED_STATUS_CODE=200
EXPECTED_JSON_KEY="status"
EXPECTED_JSON_VALUE="ok"
LOG_FILE="/var/log/php_healthcheck.log"

echo "$(date '+%Y-%m-%d %H:%M:%S') - Checking health of $HEALTHCHECK_URL" >> $LOG_FILE

HTTP_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" "$HEALTHCHECK_URL")

if [ "$HTTP_RESPONSE" != "$EXPECTED_STATUS_CODE" ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: Unexpected HTTP status code: $HTTP_RESPONSE" >> $LOG_FILE
    # Trigger alert here (e.g., send email, Slack notification)
    exit 1
fi

# Further check JSON response
JSON_RESPONSE=$(curl -s "$HEALTHCHECK_URL")
if ! echo "$JSON_RESPONSE" | grep -q "\"$EXPECTED_JSON_KEY\":\"$EXPECTED_JSON_VALUE\""; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: Unexpected JSON response: $JSON_RESPONSE" >> $LOG_FILE
    # Trigger alert here
    exit 1
fi

echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: Application health check passed." >> $LOG_FILE
exit 0

This script should be scheduled via cron to run at regular intervals (e.g., every minute).

Application Performance Monitoring (APM) Integration

For deeper insights, integrate an Application Performance Monitoring (APM) tool. Tools like New Relic, Datadog, or even open-source solutions like Prometheus with the PHP-FPM exporter can provide invaluable metrics on request latency, error rates, transaction traces, and resource utilization (CPU, memory) specific to your PHP processes.

Key PHP Metrics to Monitor:

  • Request Latency: Average and percentile (p95, p99) response times for key transactions.
  • Error Rate: Percentage of requests resulting in PHP errors (e.g., E_ERROR, E_WARNING, E_NOTICE) or HTTP 5xx errors.
  • Throughput: Requests per minute (RPM).
  • PHP-FPM Pool Metrics: Active processes, idle processes, queue length, slow requests.
  • Memory Usage: Peak memory usage per request and overall PHP process memory.
  • CPU Usage: CPU time consumed by PHP processes.

Configure your APM agent to collect these metrics and set up alerts for anomalies. For example, an alert for a sustained increase in average request latency or a spike in error rates is crucial.

MongoDB Cluster Health and Performance Monitoring

MongoDB clusters, especially replica sets and sharded clusters, require diligent monitoring to ensure data availability, consistency, and optimal performance. Linode’s managed MongoDB offerings simplify some aspects, but understanding the underlying metrics is vital for advanced troubleshooting and capacity planning.

Replica Set Health

The health of a replica set is paramount. Key indicators include the state of each member, replication lag, and oplog window.

Use the rs.status() command in the MongoDB shell to get a comprehensive overview:

mongo --host mongodb0.example.net --port 27017 --username admin --password 'your_password' --authenticationDatabase admin

rs.status()

Key fields to scrutinize in rs.status() output:

  • members[].stateStr: Should ideally be ‘PRIMARY’, ‘SECONDARY’, or ‘ARBITER’. Any other state (e.g., ‘STARTUP’, ‘RECOVERING’, ‘DOWN’, ‘ROLLBACK’) indicates a problem.
  • members[].health: Should be 1 (healthy). 0 indicates an unhealthy member.
  • members[].replicationLagSecs: The replication lag in seconds for secondary members. A consistently high or increasing lag is a major concern.
  • oplog.logLengthSecs: The total length of the oplog in seconds.
  • oplog.time: The timestamp of the last entry in the oplog.
  • oplog.tாய்ச்ச: The oplog window, calculated as oplog.logLengthSecs – (current time – oplog.time). A small oplog window can lead to secondaries falling behind if writes are heavy.

Automate the polling of these metrics. You can script this using the MongoDB shell or a driver (e.g., Python’s pymongo) and send the data to your monitoring system (e.g., Prometheus, InfluxDB).

Example Python script snippet using pymongo:

from pymongo import MongoClient
from datetime import datetime, timezone
import time

# Replace with your MongoDB connection string
client = MongoClient('mongodb://admin:[email protected]:27017/?authSource=admin')
db = client.admin

try:
    rs_status = db.command('replSetGetStatus')
    current_time_ms = int(time.time() * 1000)

    for member in rs_status['members']:
        member_id = member['_id']
        state_str = member['stateStr']
        health = member['health']
        optime_ms = member['optimeDate'].timegm() * 1000 # Convert datetime to milliseconds since epoch

        # Calculate lag for secondaries
        replication_lag_sec = 0
        if state_str == 'SECONDARY':
            replication_lag_sec = (current_time_ms - optime_ms) / 1000.0

        print(f"Member: {member_id}, State: {state_str}, Health: {health}, Lag: {replication_lag_sec:.2f}s")

        # Send metrics to your monitoring system (e.g., Prometheus Pushgateway, InfluxDB)
        # Example: push_metric('mongodb_member_health', {'member': member_id, 'state': state_str}, health)
        # Example: push_metric('mongodb_member_replication_lag_seconds', {'member': member_id}, replication_lag_sec)

    # Oplog window calculation
    oplog_stats = rs_status['oplog']
    oplog_length_sec = oplog_stats['logLengthSecs']
    oplog_last_time_ms = oplog_stats['time'].timegm() * 1000
    oplog_window_sec = oplog_length_sec - ((current_time_ms - oplog_last_time_ms) / 1000.0)

    print(f"Oplog Length: {oplog_length_sec}s, Oplog Window: {oplog_window_sec:.2f}s")
    # Example: push_metric('mongodb_oplog_window_seconds', {}, oplog_window_sec)

except Exception as e:
    print(f"Error fetching replica set status: {e}")

client.close()

Performance Metrics

Beyond replica set status, monitor core performance indicators:

  • Query Performance: Slow queries (use the slowms setting and monitor the slow query log), query execution times, and index usage.
  • Read/Write Operations: Operations per second (reads, writes), insert/update/delete latency.
  • Network Traffic: Inbound and outbound network bandwidth.
  • Disk I/O: Read/write operations per second, latency, and queue depth.
  • Memory Usage: Resident set size (RSS), virtual memory size (VMS), cache hit rates (e.g., WiredTiger cache).
  • CPU Usage: System and user CPU time consumed by MongoDB processes.
  • Connections: Number of active connections, connection pool usage.

Tools like mongostat and mongotop provide real-time insights, but for historical trending and alerting, integrate with a time-series database and dashboarding tool. Linode’s Cloud Manager may offer some basic metrics, but for production environments, a dedicated solution is recommended.

# Real-time statistics
mongostat --host mongodb0.example.net --port 27017 --username admin --password 'your_password' --authenticationDatabase admin --discover --interval 5

# Real-time top-like view of collections
mongotop --host mongodb0.example.net --port 27017 --username admin --password 'your_password' --authenticationDatabase admin --discover --interval 10

For automated collection, consider using the MongoDB Atlas monitoring tools (if applicable) or setting up the MongoDB Exporter for Prometheus. This exporter can scrape metrics from your MongoDB instances and expose them in a Prometheus-compatible format.

System-Level Monitoring on Linode

Don’t forget the foundational layer: the Linode instances themselves. Comprehensive system monitoring ensures that the underlying infrastructure is healthy and not a bottleneck.

Key Linode Instance Metrics

  • CPU Utilization: Overall CPU load and per-core usage. High sustained CPU can indicate inefficient application code or insufficient resources.
  • Memory Usage: RAM usage, swap usage. Excessive swapping is a strong indicator of memory pressure.
  • Disk I/O: Read/write operations, disk latency, and disk space utilization. Running out of disk space is a critical failure point.
  • Network Traffic: Inbound/outbound bandwidth, packet loss, network errors.
  • Process Monitoring: Ensure critical processes (PHP-FPM, Nginx/Apache, MongoDB daemons) are running and not consuming excessive resources.

Linode provides basic monitoring through its Cloud Manager. For more advanced, granular, and centralized monitoring, deploy agents like:

  • Node Exporter (Prometheus): Collects a wide range of hardware and OS metrics.
  • Telegraf (InfluxDB): A plugin-driven server agent that can collect metrics and send them to various outputs, including InfluxDB.
  • Datadog Agent / New Relic Infrastructure Agent: Commercial agents that integrate deeply with their respective platforms.

Configure these agents to collect the metrics listed above and forward them to your central monitoring system. Set up alerts for thresholds like CPU > 90% for 5 minutes, Memory Usage > 85%, Disk Space < 10% free, or critical processes being down.

Log Aggregation and Analysis

Centralized logging is indispensable for debugging and identifying root causes of issues. Collect logs from your web server (Nginx/Apache), PHP-FPM, MongoDB, and application logs into a single, searchable location.

Tools like:

  • ELK Stack (Elasticsearch, Logstash, Kibana): A powerful open-source solution.
  • Loki (Grafana): A log aggregation system inspired by Prometheus, designed for cost efficiency and ease of operation.
  • Datadog Logs / Splunk: Commercial log management platforms.

can be used. Configure your servers to forward logs using agents like Filebeat (for ELK), Promtail (for Loki), or the respective agents for commercial solutions. Ensure your application logs are structured (e.g., JSON) to facilitate easier parsing and searching.

Example Log Rotation and Forwarding (using Filebeat for ELK):

# /etc/filebeat/filebeat.yml

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/nginx/*.log
    - /var/log/php-fpm/*.log
    - /var/log/mongodb/mongod.log
    - /var/log/your_app/*.log # Assuming your app logs here

processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~

output.elasticsearch:
  hosts: ["your-elasticsearch-host:9200"]
  # username: "elastic"
  # password: "changeme"

# Or for Logstash:
# output.logstash:
#   hosts: ["your-logstash-host:5044"]

Regularly review logs for recurring errors, unusual patterns, or security-related events. Set up alerts based on specific log messages (e.g., critical errors, repeated failed login attempts).

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Leveraging Laravel Octane and Docker Swarm for High-Performance, Scalable WordPress Headless Deployments
  • Migrating Legacy WordPress to Headless with Laravel: A Performance and Security Deep Dive
  • Leveraging PHP 8’s JIT Compiler and Vector APIs for Extreme Web Application Performance
  • Leveraging PHP 8 JIT and AWS Lambda for High-Performance, Serverless WordPress REST API Backends
  • Beyond the Basics: Leveraging PHP 8.3’s JIT Compiler and Fibers for High-Concurrency Laravel Applications

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (664)
  • Desktop Applications (14)
  • DevOps (11)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (6)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (873)
  • PHP (15)
  • PHP Development (49)
  • Plugins & Themes (244)
  • Programming Languages (10)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (650)
  • SEO & Growth (492)
  • Server (118)
  • Softwares (1)
  • Ubuntu (9)
  • Uncategorized (20)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (26)
  • WordPress Plugin Development (728)
  • WordPress Theme Development (357)

Recent Posts

  • Leveraging Laravel Octane and Docker Swarm for High-Performance, Scalable WordPress Headless Deployments
  • Migrating Legacy WordPress to Headless with Laravel: A Performance and Security Deep Dive
  • Leveraging PHP 8's JIT Compiler and Vector APIs for Extreme Web Application Performance

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (873)
  • WordPress Plugin Development (728)
  • Debugging & Troubleshooting (664)
  • Security & Compliance (650)
  • SEO & Growth (492)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala