هذا الالتزام موجود في:
2026-07-26 19:57:48 +03:00
التزام a6e65f3f37
29 ملفات معدلة مع 3538 إضافات و0 حذوفات

عرض الملف

@@ -0,0 +1,8 @@
.git
.gitignore
.env
.env.*
README.md
Dockerfile
.dockerignore
dashboard

عرض الملف

@@ -0,0 +1,34 @@
# Build stage
FROM golang:1.26-alpine AS builder
WORKDIR /app
# Copy dependency files first to leverage Docker cache
COPY go.mod ./
# Copy source code
COPY . .
# Build the application
RUN go build -o server .
# Runtime stage
FROM alpine:3.20
# Create a non-root user
RUN adduser -D appuser
WORKDIR /app
# Copy the compiled binary
COPY --from=builder /app/server .
# Run as non-root user
USER appuser
# Document the application port
EXPOSE 8080
# Start the application
CMD ["./server"]

عرض الملف

@@ -0,0 +1,3 @@
module q1-deploy-monitor
go 1.26.5

عرض الملف

@@ -0,0 +1,95 @@
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"sync/atomic"
)
// Stores the total number of API requests.
var requestCount uint64
func main() {
// Register API endpoints
http.HandleFunc("/", requestCounter(helloHandler))
http.HandleFunc("/health", requestCounter(healthHandler))
http.HandleFunc("/metrics", metricsHandler)
// Start server on port 8080
fmt.Println("Server is running on port 8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
// Middleware that counts API requests.
// The /metrics endpoint is not wrapped with this middleware,
// so requests to /metrics are not included in the counter.
func requestCounter(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
atomic.AddUint64(&requestCount, 1)
next(w, r)
}
}
// Adds CORS headers to allow the dashboard to access the API.
func enableCORS(w http.ResponseWriter) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
}
// Root endpoint
func helloHandler(w http.ResponseWriter, r *http.Request) {
enableCORS(w)
// Handle browser CORS preflight requests
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusNoContent)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{
"message": "Hello, World!",
})
}
// Health check endpoint
func healthHandler(w http.ResponseWriter, r *http.Request) {
enableCORS(w)
// Handle browser CORS preflight requests
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusNoContent)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{
"status": "healthy",
})
}
// Metrics endpoint
// This endpoint does NOT increment the request counter.
func metricsHandler(w http.ResponseWriter, r *http.Request) {
enableCORS(w)
// Handle browser CORS preflight requests
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusNoContent)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]uint64{
"requests": atomic.LoadUint64(&requestCount),
})
}