Add CI/CD pipeline, architecture documentation, and monitoring application

- Created a GitHub Actions workflow for CI/CD to deploy to Ghyamah, including testing, building, and pushing Docker images.
- Added architecture design document for handling 15,000 requests per second, detailing system components, capacity planning, and cold start strategies.
- Introduced a Python-based uptime/latency/SSL monitor with a static dashboard, utilizing standard libraries only.
- Included Dockerfile and entrypoint script for the monitoring application, ensuring it runs as a non-root user and handles process management.
- Added a .dockerignore file to exclude unnecessary files from the Docker build context.
- Created an HTML dashboard for visualizing monitoring metrics, including uptime, latency, and SSL certificate status.
هذا الالتزام موجود في:
2026-07-27 23:08:39 +03:00
الأصل c3368b9124
التزام 439a31ba93
16 ملفات معدلة مع 1753 إضافات و0 حذوفات

6
Q1/.dockerignore Normal file
عرض الملف

@@ -0,0 +1,6 @@
data/
*.pyc
__pycache__/
.git
.gitignore
README.md

13
Q1/Dockerfile Normal file
عرض الملف

@@ -0,0 +1,13 @@
FROM node:20-alpine3.16
WORKDIR /app
COPY --chown=node:node server.js .
RUN npm init -y && npm install express cors
USER node
EXPOSE 3000
CMD ["node" , "server.js"]

60
Q1/index.html Normal file
عرض الملف

@@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>لوحة مراقبة الـ API</title>
<style>
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #f4f7f6; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }
.dashboard { background: white; padding: 30px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); text-align: center; width: 400px; }
h2 { color: #333; margin-bottom: 20px; }
.metric { background: #eef2f5; margin: 10px 0; padding: 15px; border-radius: 8px; font-size: 1.2em; display: flex; justify-content: space-between; }
.metric span { font-weight: bold; color: #0056b3; }
.status-dot { display: inline-block; width: 12px; height: 12px; border-radius: 50%; background: gray; margin-left: 8px; }
.online { background: #28a745; }
.offline { background: #dc3545; }
</style>
</head>
<body>
<div class="dashboard">
<h2>مراقبة النظام <span id="statusDot" class="status-dot"></span></h2>
<div class="metric">
الحالة: <span id="statusText">جاري التحميل...</span>
</div>
<div class="metric">
زمن الاستجابة: <span id="responseTime">0 ms</span>
</div>
<div class="metric">
عدد الطلبات الإجمالي: <span id="requestCount">0</span>
</div>
</div>
<script>
const API_URL = "";
async function fetchMetrics() {
try {
const res = await fetch(API_URL);
const data = await res.json();
document.getElementById('statusText').innerText = data.status;
document.getElementById('statusText').style.color = '#28a745';
document.getElementById('statusDot').className = 'status-dot online';
document.getElementById('responseTime').innerText = data.response_time_ms + ' ms';
document.getElementById('requestCount').innerText = data.request_count;
} catch (error) {
document.getElementById('statusText').innerText = 'انقطاع الاتصال (Offline)';
document.getElementById('statusText').style.color = '#dc3545';
document.getElementById('statusDot').className = 'status-dot offline';
document.getElementById('responseTime').innerText = '-';
}
}
setInterval(fetchMetrics, 5000);
fetchMetrics();
</script>
</body>
</html>

28
Q1/monitor.sh Executable file
عرض الملف

@@ -0,0 +1,28 @@
#!/bin/bash
API_URL=$1
echo "Starting monitor script..."
echo "API URL: $API_URL"
echo "------------------------------------------------"
while true; do
HTTP_STATUS=$(curl -o /dev/null -s -w "%{http_code}" -m 5 "$API_URL")
if [ "$HTTP_STATUS" -eq 200 ]; then
response=$(curl -s -m 5 "$API_URL")
status=$(echo "$response" | jq -r '.status' 2>/dev/null)
if [ -n "$status" ] && [ "$status" != "null" ]; then
echo "Status: $status | Response Time: ${response_time}ms"
else
echo "HTTP 200 OK, but invalid JSON format received."
fi
elif [ "$HTTP_STATUS" -eq 000 ]; then
echo "Application is Offline or unreachable (Timeout)."
else
echo "Application is unhealthy. HTTP Status: $HTTP_STATUS"
fi
sleep 30
done

35
Q1/server.js Normal file
عرض الملف

@@ -0,0 +1,35 @@
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
let requestCount = 0;
let lastResponseTime = 0;
app.use((req, res, next) => {
requestCount++;
const start = Date.now();
res.on('finish', () => {
lastResponseTime = Date.now() - start;
});
next();
});
app.get('/health', (req, res) => {
res.json({
status: 'Online',
uptime_seconds: process.uptime(),
request_count: requestCount,
response_time_ms: lastResponseTime
});
});
app.get('/', (req, res) => {
res.send('Welcome to the Backend API!');
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`API is running on port ${PORT}`);
});