74 · Monitoring & Alerting

Expose a /health endpoint, configure ANS error-rate alerts, and use cf app / cf logs for incident triage.

Episode 74 — Monitoring & Alerting

What you'll learn

Why this matters

You won't be watching the logs 24/7. When something breaks in production you need an alert in Slack or email within minutes, not days. Proper monitoring also tells you when your app is approaching memory limits or when a specific endpoint is suddenly slow — before a user files a ticket.

Monitoring tools on BTP

Tool Best for
BTP Cockpit (app overview) CPU / memory / instance count at a glance
cf app / cf logs First-level triage from CLI
SAP Application Logging (Kibana) Log-level query and error search
SAP Alert Notification Service Event-driven alerts to email/Slack/PagerDuty
SAP Cloud ALM Cross-landscape health dashboard (enterprise)
Custom /health endpoint External uptime monitors (UptimeRobot, Pingdom)

Exposing a /health endpoint in CAP

// srv/server.js
const cds = require('@sap/cds');

cds.on('bootstrap', async app => {
  app.get('/health', async (req, res) => {
    try {
      // Ping the database
      const db = await cds.connect.to('db');
      await db.run('SELECT 1 FROM dummy');

      res.status(200).json({
        status: 'UP',
        timestamp: new Date().toISOString(),
        version: process.env.npm_package_version
      });
    } catch (err) {
      res.status(503).json({
        status: 'DOWN',
        error: err.message
      });
    }
  });
});

The /health endpoint bypasses XSUAA (no @requires) so external uptime monitors can call it without authentication. Ensure it does not expose sensitive information — just UP/DOWN and a timestamp.

Configuring SAP Alert Notification Service

See Episode 60 for full setup. For monitoring-specific alerts:

// Alert on high error rate in a 5-minute window
// (implemented as a periodic check job — Episode 65)
const ans = await cds.connect.to('AlertNotificationService');

const errorCount = await db.run(
  `SELECT COUNT(*) AS n FROM ErrorLog WHERE ts > NOW() - INTERVAL '5' MINUTE`
);

if (errorCount.n > 50) {
  await ans.post('/producer/v1/resource-events', {
    eventType:    'HighErrorRate',
    eventTimestamp: Date.now(),
    severity:     'CRITICAL',
    resource: {
      resourceName: 'my-cap-app',
      resourceType: 'Application'
    },
    body: {
      state:   'PROBLEM',
      details: `${errorCount.n} errors in the last 5 minutes`
    }
  });
}

Using cf app for live metrics

# Current memory, CPU, instances, status
cf app my-cap-app-srv

# Example output:
# Instances running: 2/2
# Memory usage: 312M / 512M
# CPU:  3.1% / 3.8%
# Disk: 423M / 1G

# Recent CF platform events (restarts, crashes)
cf events my-cap-app-srv

# Stream live logs (combine with grep for errors)
cf logs my-cap-app-srv | grep -i error

Setting memory and scaling thresholds

In manifest.yml or MTA:

memory: 512M
disk_quota: 1G
instances: 2

Autoscale with the CF App Autoscaler (if entitled):

# autoscaler-policy.json
{
  "instance_min_count": 2,
  "instance_max_count": 5,
  "scaling_rules": [
    { "metric_type": "memoryused", "threshold": 400, "operator": ">=", "adjustment": "+1" },
    { "metric_type": "memoryused", "threshold": 200, "operator": "<",  "adjustment": "-1" }
  ]
}

Incident triage checklist

When an alert fires:
1. cf app my-cap-app-srv — is the app running? How many instances are UP?
2. cf logs my-cap-app-srv --recent — look for ERROR lines around the incident time
3. Kibana: filter level: ERROR AND @timestamp: [now-30m TO now]
4. cf events my-cap-app-srv — any recent crashes or restarts?
5. BTP Cockpit → HANA Cloud → Monitor — is the DB healthy?
6. If memory usage > 90% → cf scale my-cap-app-srv -m 1G to buy time
7. If stuck deploy → cf mta-ops → abort / resume

Common mistakes

Mistake Fix
No /health endpoint Uptime monitors have nothing to poll
/health endpoint behind auth External monitors can't reach it — no @requires
Not setting instances: 2 minimum One crash = total downtime
Alerting on every error Alert on error RATE — individual errors are noise
Not logging the correlationId You can't trace a specific user complaint in Kibana

Checkpoint ✓

You can expose a /health endpoint that pings the database, configure ANS alerts on error rate, use cf app, cf logs, and cf events for triage, and follow a structured incident checklist from alert to resolution.

Sign in for progress tracking & Q&A →