When you run multiple video sites across different servers, monitoring is essential. Here's how I built a lightweight monitoring dashboard for TrendVidStream and its sister sites.
What to Monitor
For a multi-site video platform, the critical metrics are:
- Site availability - Is each site responding?
- Content freshness - When was the last successful fetch?
- Database health - SQLite integrity and size
- API quota - YouTube API usage
- Cache hit rates - Are caches working?
- Performance - PageSpeed scores over time
Health Check Endpoint
Each site exposes a /health endpoint:
<?php
// health.php
header('Content-Type: application/json');
header('Cache-Control: no-cache');
$db = new PDO('sqlite:' . __DIR__ . '/data/app.db');
// Check database
$dbOk = false;
try {
$result = $db->query('PRAGMA integrity_check')->fetchColumn();
$dbOk = ($result === 'ok');
} catch (Exception $e) {
$dbOk = false;
}
// Get last fetch time
$lastFetch = $db->query(
"SELECT MAX(fetched_at) FROM videos"
)->fetchColumn();
// Get video counts per region
$regions = $db->query(
"SELECT region, COUNT(*) as count FROM videos GROUP BY region"
)->fetchAll(PDO::FETCH_KEY_PAIR);
// Database file size
$dbSize = filesize(__DIR__ . '/data/app.db');
// Cache stats
$cacheDir = __DIR__ . '/data/cache';
$cacheFiles = glob($cacheDir . '/*.cache');
$cacheSize = array_sum(array_map('filesize', $cacheFiles ?: []));
$status = [
'status' => $dbOk ? 'healthy' : 'degraded',
'timestamp' => date('c'),
'php_version' => PHP_VERSION,
'sapi' => php_sapi_name(),
'database' => [
'ok' => $dbOk,
'size_mb' => round($dbSize / 1024 / 1024, 2),
'last_fetch' => $lastFetch,
'freshness_hours' => $lastFetch
? round((time() - strtotime($lastFetch)) / 3600, 1)
: null,
],
'regions' => $regions,
'cache' => [
'files' => count($cacheFiles ?: []),
'size_mb' => round($cacheSize / 1024 / 1024, 2),
],
'opcache' => function_exists('opcache_get_status')
? opcache_get_status(false)
: null,
];
http_response_code($dbOk ? 200 : 503);
echo json_encode($status, JSON_PRETTY_PRINT);
Dashboard Collector
A script that checks all sites periodically:
<?php
// monitor.php - Run from a monitoring server or local machine
$sites = [
'dwv' => 'https://dailywatch.video/health',
'tvh' => 'https://topvideohub.com/health',
'tvs' => 'https://trendvidstream.com/health',
'vvv' => 'https://viralvidvault.com/health',
];
$results = [];
foreach ($sites as $alias => $url) {
$start = microtime(true);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTPHEADER => ['Accept: application/json'],
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$elapsed = round((microtime(true) - $start) * 1000);
curl_close($ch);
$data = json_decode($response, true);
$results[$alias] = [
'reachable' => $httpCode === 200,
'status' => $data['status'] ?? 'unreachable',
'response_ms' => $elapsed,
'last_fetch' => $data['database']['last_fetch'] ?? null,
'freshness_hours' => $data['database']['freshness_hours'] ?? null,
'db_size_mb' => $data['database']['size_mb'] ?? null,
'regions' => $data['regions'] ?? [],
'total_videos' => array_sum($data['regions'] ?? []),
];
}
// Display dashboard
echo "\n=== Multi-Site Video Platform Monitor ===";
echo "\n" . date('Y-m-d H:i:s') . "\n";
echo str_repeat('=', 60) . "\n\n";
foreach ($results as $alias => $r) {
$status = $r['reachable'] ? "OK" : "DOWN";
$fresh = $r['freshness_hours'] !== null
? "{$r['freshness_hours']}h ago"
: "unknown";
printf(
"%-5s | %-8s | %4dms | %5d videos | Last fetch: %s | DB: %sMB\n",
strtoupper($alias),
$status,
$r['response_ms'],
$r['total_videos'],
$fresh,
$r['db_size_mb'] ?? '?'
);
}
// Alert if any site is down or stale
$alerts = [];
foreach ($results as $alias => $r) {
if (!$r['reachable']) {
$alerts[] = "ALERT: {$alias} is unreachable";
}
if ($r['freshness_hours'] !== null && $r['freshness_hours'] > 12) {
$alerts[] = "ALERT: {$alias} last fetch was {$r['freshness_hours']} hours ago";
}
}
if (!empty($alerts)) {
echo "\n" . str_repeat('!', 60) . "\n";
foreach ($alerts as $alert) {
echo "$alert\n";
}
}
PageSpeed Monitoring
<?php
class PageSpeedMonitor
{
private string $apiKey;
public function __construct(string $apiKey)
{
$this->apiKey = $apiKey;
}
public function audit(string $url, string $strategy = 'mobile'): array
{
$apiUrl = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?'
. http_build_query([
'url' => $url,
'strategy' => $strategy,
'key' => $this->apiKey,
'category' => 'performance',
]);
$response = json_decode(file_get_contents($apiUrl), true);
$audit = $response['lighthouseResult'] ?? [];
return [
'score' => ($audit['categories']['performance']['score'] ?? 0) * 100,
'lcp' => $audit['audits']['largest-contentful-paint']['numericValue'] ?? 0,
'cls' => $audit['audits']['cumulative-layout-shift']['numericValue'] ?? 0,
'inp' => $audit['audits']['experimental-interaction-to-next-paint']['numericValue'] ?? 0,
];
}
}
// Monitor all sites
$monitor = new PageSpeedMonitor(getenv('PAGESPEED_API_KEY'));
$pages = [
'https://trendvidstream.com/',
'https://trendvidstream.com/category/music',
'https://trendvidstream.com/category/gaming',
];
foreach ($pages as $url) {
$result = $monitor->audit($url);
printf(
"%s\n Score: %d | LCP: %dms | CLS: %.3f\n",
$url,
$result['score'],
$result['lcp'],
$result['cls']
);
}
Cron-Based Monitoring
# Check health every 30 minutes
*/30 * * * * php /path/to/monitor.php >> /var/log/monitor.log 2>&1
# PageSpeed audit twice daily
0 6,18 * * * php /path/to/pagespeed_audit.php >> /var/log/pagespeed.log 2>&1
This monitoring system keeps all 4 TrendVidStream sites healthy. The health endpoint pattern is reusable for any PHP application with SQLite.
Key principle: monitor what matters (availability, freshness, performance), alert on what is actionable, and keep the monitoring infrastructure simpler than what it monitors.
Top comments (0)