Files
gravl/backend/README.md
clawd e09017d2e0 feat(08-01): Health monitoring & logging infrastructure
- Set up Winston structured logging with console and file outputs
- Create GET /api/health endpoint with uptime, database status, response times
- Add request logging middleware (method, path, statusCode, duration)
- Create health monitoring module with database connectivity checks
- Log all HTTP requests with timing information
- Log auth events (login, register) and data modifications
- Replace console.log/error with structured logger calls
- Update backend README with logging configuration documentation
- Add tests for health endpoint and logging middleware
- Logs directory: logs/combined.log and logs/error.log

Deliverables met:
✓ Structured logging (Winston) integrated
✓ Enhanced health endpoint with uptime & database info
✓ Request logging middleware attached to all routes
✓ Comprehensive logging documentation in README.md
✓ Tests passing for health and logging functionality
✓ All critical operations logged with context
2026-03-03 21:28:46 +01:00

8.2 KiB
Raw Permalink Blame History

Gravl Backend

Backend service for the Gravl exercise and fitness tracking platform.

Overview

The Gravl backend is a Node.js/Express application that provides:

  • REST API for exercise data management
  • User authentication and authorization
  • Integration with frontend via HTTP
  • Structured logging for monitoring and debugging
  • Health check endpoint with system metrics for deployment monitoring

Local Development

Prerequisites

  • Node.js 18+
  • npm or yarn
  • Docker & Docker Compose (for local container development)

Installation

cd backend
npm install

Running Locally

Development mode (with hot reload):

npm run dev

The server starts on http://localhost:3001

Production mode:

npm run build
npm start

Environment Variables

Create a .env file in the backend directory:

NODE_ENV=development
PORT=3001
DATABASE_URL=postgresql://user:password@localhost:5432/gravl

See .env.example (if available) for all supported variables.


Logging & Monitoring

Structured Logging (Winston)

The backend uses Winston for structured logging with multiple transports:

Console Output (Development):

  • Human-readable format with timestamps and color coding
  • Logs all INFO, WARN, ERROR, and DEBUG messages

File Output:

  • logs/combined.log — All application logs
  • logs/error.log — Error-level logs only
  • Max file size: 5MB with 5 file rotation

Log Levels:

  • debug — Development debugging info
  • info — General information events
  • warn — Warning conditions
  • error — Error conditions

Example Log Format:

2026-03-03 18:21:00 [info] User registered { userId: 42, email: user@example.com }
2026-03-03 18:21:15 [info] HTTP Request { method: 'GET', path: '/api/health', statusCode: 200, duration: '12ms' }

Request Logging Middleware

All HTTP requests are automatically logged with:

  • HTTP method and path
  • Response status code
  • Request duration (milliseconds)
  • Client IP address
  • User-Agent

Example:

[info] HTTP Request { method: 'POST', path: '/api/logs', statusCode: 200, duration: '45ms' }

Accessing Logs

Local Development:

npm run dev  # Logs print to console in real-time
tail -f logs/combined.log  # Follow all logs
tail -f logs/error.log     # Follow errors only

Docker Container:

docker logs -f gravl-backend           # Real-time logs
docker logs --tail 100 gravl-backend   # Last 100 lines

API Endpoints

Health Check (Monitoring & Deployment)

GET /api/health

Comprehensive health endpoint that returns system status, uptime, and database connectivity. Used by deployment scripts to verify backend is operational.

Response (Healthy):

{
  "status": "healthy",
  "uptime": 3600,
  "timestamp": "2026-03-03T18:21:00.000Z",
  "database": {
    "connected": true,
    "responseTime": "15ms"
  }
}

Response (Degraded):

{
  "status": "degraded",
  "uptime": 3600,
  "timestamp": "2026-03-03T18:21:00.000Z",
  "database": {
    "connected": false,
    "error": "Connection timeout"
  }
}

Status Values:

  • healthy — All systems operational (HTTP 200)
  • degraded — Some systems degraded but functional (HTTP 200)
  • unhealthy — Critical systems down (HTTP 503)

Response Fields:

  • status — Overall health status
  • uptime — Seconds since application started
  • timestamp — ISO 8601 timestamp of check
  • database.connected — Boolean database connectivity status
  • database.responseTime — Database query response time
  • database.error — Error message if connection failed (optional)

Testing

npm test              # Run all tests
npm run test:watch   # Run tests in watch mode

Health & Logging Tests

The test suite includes:

  • Health endpoint status validation
  • Uptime tracking accuracy
  • Database connectivity checking
  • Request logging middleware functionality
  • Error handling for database failures

Docker

Building the Image

docker build -t gravl-backend:latest .

Running in Container

docker run -p 3001:3001 \
  -e NODE_ENV=production \
  -e DATABASE_URL=postgresql://... \
  gravl-backend:latest

Viewing logs from container:

docker logs -f gravl-backend

With Docker Compose

See the root docker-compose.yml for multi-container setup.


Deployment

Automated Deployment

The backend is deployed using scripts in the root scripts/ directory:

  • scripts/deploy.sh — Pulls latest code, builds fresh Docker image, starts container with health checks
  • scripts/build-check.sh — Verifies deployed container matches local git HEAD

How to Deploy

cd /workspace/gravl
scripts/deploy.sh

Checking Deployment Status

cd /workspace/gravl
scripts/build-check.sh

For complete deployment documentation, see: docs/DEPLOYMENT.md

That guide includes:

  • Prerequisites and setup
  • How to run deploy.sh
  • How to check build status
  • Troubleshooting (health check failures, stale containers, etc.)
  • Recovery procedures (rollbacks, cleanup)

Health Check Configuration

The backend exposes a comprehensive health check endpoint at GET /api/health. The deployment script (scripts/deploy.sh) waits up to 60 seconds for this endpoint to return HTTP 200.

In your backend code:

// Auto-integrated in src/index.js
app.get('/api/health', async (req, res) => {
  const health = await getHealthStatus(pool);
  const statusCode = health.status === 'healthy' ? 200 : 503;
  res.status(statusCode).json(health);
});

Deployment timeout: 60 seconds (12 retries × 5 seconds)

  • If this endpoint takes >5 seconds to respond, deployment will timeout
  • Health check is lightweight and includes database connectivity test

Project Structure

backend/
├── src/
│   ├── index.js                # Server entry point
│   ├── utils/
│   │   ├── logger.js           # Winston logger configuration
│   │   └── health.js           # Health monitoring utilities
│   ├── middleware/
│   │   └── requestLogger.js    # HTTP request logging middleware
│   ├── routes/                 # API endpoints
│   ├── controllers/            # Business logic
│   ├── models/                 # Data models (if using ORM)
│   └── services/               # External integrations
├── test/                       # Test files
├── logs/                       # Log files (created at runtime)
├── Dockerfile                  # Container image definition
├── package.json                # Dependencies
└── README.md                   # This file

Troubleshooting

Health Check Endpoint Not Responding

Symptom: Deployment fails with "Health check failed after 60s"

Causes & Fixes:

  1. Port 3001 is already in use

    lsof -i :3001
    # Kill the conflicting process or use a different port
    
  2. Backend code has a syntax error

    npm run dev  # Look for error messages in logs
    tail -f logs/error.log
    
  3. Database connection is failing

    • Backend is stuck trying to connect to DB
    • Check DB_HOST, DB_PORT, DB_USER, DB_PASSWORD in .env
    • Ensure database is running and accessible
  4. Logs directory not writable

    mkdir -p logs
    chmod 755 logs
    

See docs/DEPLOYMENT.md for more deployment troubleshooting.

Checking Logs for Errors

Console (Development):

npm run dev  # Full logs with colors

Log Files:

tail -50 logs/combined.log  # Last 50 lines of all logs
tail -50 logs/error.log     # Last 50 lines of errors only
grep "ERROR" logs/combined.log  # Find all error messages

Docker:

docker logs gravl-backend | grep ERROR

Contributing

See the root project README or CONTRIBUTING.md for guidelines on:


License

[Specify your license here]


Last updated: 2026-03-03 Phase 08-01: Health Monitoring & Logging Infrastructure