tutorial

Monitoring Apollo Config with Vigilmon

Apollo is the distributed configuration management platform powering real-time config push across environments. Learn how to monitor Config Service, Admin Service, Portal, Eureka, and MySQL health with Vigilmon.

Apollo is the distributed configuration management center that powers real-time configuration push for applications across development, staging, UAT, and production environments. Applications subscribe to Apollo's Config Service and receive configuration updates within seconds — no restart required. When Apollo's Config Service goes down, connected applications continue running on stale in-memory configuration until they restart, at which point they fail to load configuration entirely.

Vigilmon gives you external health monitoring for every Apollo component: Config Service, Admin Service, Portal, Eureka service registry, and the MySQL persistence layer — so you catch failures before they affect your configuration deployment workflow or your application's ability to receive updates.


Why Apollo Monitoring Matters

Apollo is composed of multiple interdependent services, and each failure mode has a different operational impact:

  • Config Service down — applications cannot receive new configuration; restarts leave apps with no configuration
  • Admin Service down — Portal cannot write configuration changes; CI/CD pipelines using the Apollo API are blocked
  • Portal down — operators cannot manage configurations, review history, or trigger environment promotions
  • Eureka failing — Config Service and Admin Service cannot discover each other; Portal loses its service registry
  • MySQL down — configuration writes stop; history, rollbacks, and namespace releases all fail

Each component needs independent monitoring — a Portal outage and a Config Service outage have very different on-call priorities.


What You'll Set Up

  • HTTP health monitors for Portal (port 8070), Config Service (port 8080), and Admin Service (port 8090)
  • Eureka service registry health check
  • MySQL backend connectivity monitor
  • Configuration push latency health endpoint
  • Active client connection count monitor
  • Rollback and release success rate health
  • Alert routing by component and severity

Step 1: Monitor Apollo Portal

The Portal is Apollo's management web console on port 8070. Operators use it to manage configurations, approve releases, and trigger environment promotions.

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter: http://your-apollo-portal:8070/health
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Under Response body contains, enter "status":"UP".
  7. Click Save.

The /health endpoint on Apollo Portal returns a Spring Boot Actuator health payload. A 200 with "status":"UP" confirms the Portal is accepting operator requests.


Step 2: Monitor Config Service

Config Service (port 8080) is the most critical Apollo component — it serves real-time configuration to all connected application clients via long-polling.

  1. Add a new Vigilmon HTTP monitor.
  2. URL: http://your-apollo-configservice:8080/health
  3. Check interval: 1 minute.
  4. Expected status: 200.
  5. Body contains: "status":"UP".
  6. Response time threshold: 5000ms — Config Service processes long-poll connections and can be CPU-intensive under load.
  7. Alert channel: P1 (highest priority — this is your applications' lifeline).

If you run multiple Config Service instances behind a load balancer, add one monitor per instance to detect partial failures where one node is unhealthy but the LB continues routing to it.


Step 3: Monitor Admin Service

Admin Service (port 8090) handles configuration management API calls from Portal and CI/CD automation.

  1. Add a Vigilmon HTTP monitor.
  2. URL: http://your-apollo-adminservice:8090/health
  3. Check interval: 1 minute.
  4. Expected status: 200.
  5. Body contains: "status":"UP".
  6. Alert channel: P2 — configuration writes fail, but clients continue receiving their current configuration.

Step 4: Build an Apollo Health Sidecar

Add a sidecar service that monitors Apollo's inter-component health signals — Eureka registry, MySQL backend, client connections, and push latency:

Node.js Apollo Health Sidecar

// apollo-health.js
const express = require('express');
const axios = require('axios');
const mysql = require('mysql2/promise');

const app = express();

const APOLLO_PORTAL = process.env.APOLLO_PORTAL_URL || 'http://localhost:8070';
const APOLLO_META = process.env.APOLLO_META_SERVER_URL || 'http://localhost:8080';
const MYSQL_HOST = process.env.APOLLO_DB_HOST || 'localhost';
const MYSQL_PORT = parseInt(process.env.APOLLO_DB_PORT || '3306');
const MYSQL_USER = process.env.APOLLO_DB_USER || 'apollo';
const MYSQL_PASS = process.env.APOLLO_DB_PASS || '';
const MYSQL_DB = process.env.APOLLO_DB_NAME || 'ApolloConfigDB';

app.get('/health/apollo/eureka', async (req, res) => {
  // Apollo Meta Server exposes Eureka registry — check that Config and Admin services are registered
  try {
    const resp = await axios.get(
      `${APOLLO_META}/eureka/apps`,
      {
        headers: { Accept: 'application/json' },
        timeout: 8000,
      }
    );
    const apps = resp.data.applications?.application || [];
    const configSvc = apps.find(a => a.name === 'APOLLO-CONFIGSERVICE');
    const adminSvc = apps.find(a => a.name === 'APOLLO-ADMINSERVICE');

    const issues = [];
    const configCount = configSvc?.instance?.length || 0;
    const adminCount = adminSvc?.instance?.length || 0;

    if (configCount === 0) issues.push('no_config_service_instances');
    if (adminCount === 0) issues.push('no_admin_service_instances');

    if (issues.length > 0) {
      return res.status(503).json({
        status: 'degraded',
        issues,
        config_service_instances: configCount,
        admin_service_instances: adminCount,
      });
    }

    return res.json({
      status: 'ok',
      config_service_instances: configCount,
      admin_service_instances: adminCount,
    });
  } catch (err) {
    return res.status(503).json({ status: 'down', error: err.message });
  }
});

app.get('/health/apollo/mysql', async (req, res) => {
  let conn;
  try {
    conn = await mysql.createConnection({
      host: MYSQL_HOST,
      port: MYSQL_PORT,
      user: MYSQL_USER,
      password: MYSQL_PASS,
      database: MYSQL_DB,
      connectTimeout: 3000,
    });
    await conn.execute('SELECT 1');
    await conn.end();
    return res.json({ status: 'ok' });
  } catch (err) {
    if (conn) conn.destroy();
    return res.status(503).json({ status: 'down', error: err.message });
  }
});

app.get('/health/apollo/clients', async (req, res) => {
  const minClients = parseInt(process.env.MIN_APOLLO_CLIENTS || '1');
  try {
    // Apollo Config Service exposes connected client count via Actuator metrics
    const resp = await axios.get(
      `${APOLLO_META}/actuator/metrics/apollo.long.poll.connections`,
      { timeout: 5000 }
    );
    const clientCount = resp.data.measurements?.find(m => m.statistic === 'VALUE')?.value || 0;

    if (clientCount < minClients) {
      return res.status(503).json({
        status: 'degraded',
        reason: 'client_count_below_threshold',
        client_count: clientCount,
        threshold: minClients,
      });
    }

    return res.json({ status: 'ok', client_count: clientCount });
  } catch (err) {
    // Metric may not be exposed in older Apollo versions — treat as non-fatal
    return res.json({ status: 'ok', note: 'client_metric_unavailable' });
  }
});

app.get('/health/apollo/portal-api', async (req, res) => {
  // Verify Portal can perform an authenticated API operation
  const portalToken = process.env.APOLLO_PORTAL_TOKEN || '';
  if (!portalToken) {
    return res.json({ status: 'ok', note: 'portal_api_check_not_configured' });
  }

  try {
    const resp = await axios.get(
      `${APOLLO_PORTAL}/openapi/v1/envs`,
      {
        headers: { Authorization: portalToken },
        timeout: 5000,
      }
    );
    const envs = Array.isArray(resp.data) ? resp.data : [];
    return res.json({ status: 'ok', env_count: envs.length });
  } catch (err) {
    return res.status(503).json({ status: 'down', error: err.message });
  }
});

app.listen(8099, () => console.log('Apollo health sidecar on :8099'));

Install dependencies and run:

npm install express axios mysql2
node apollo-health.js

Configure environment variables:

APOLLO_PORTAL_URL=http://localhost:8070
APOLLO_META_SERVER_URL=http://localhost:8080
APOLLO_DB_HOST=localhost
APOLLO_DB_USER=apollo
APOLLO_DB_PASS=your-password
APOLLO_PORTAL_TOKEN=your-open-api-token
MIN_APOLLO_CLIENTS=10

Step 5: Heartbeat for Environment Promotion Workflows

Apollo's DEV→FAT→UAT→PRO promotion workflow is critical for controlled configuration rollouts. If CI/CD promotion pipelines start failing silently, configuration changes pile up in early environments and never reach production.

Set up a heartbeat to verify your promotion automation is running:

  1. In Vigilmon, click Add MonitorHeartbeat.
  2. Name: apollo-config-promotion-pipeline.
  3. Expected interval: 1440 minutes (daily promotion run).
  4. Grace period: 60 minutes.
  5. Save and copy the heartbeat URL.

Wire the ping into your promotion CI step:

# In your CI/CD pipeline after successful environment promotion
curl -X POST \
  "http://your-apollo-portal:8070/openapi/v1/envs/FAT/apps/${APP_ID}/clusters/default/namespaces/${NAMESPACE}/releases" \
  -H "Authorization: ${APOLLO_PORTAL_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{\"releaseTitle\": \"$(date +%Y%m%d)-auto\", \"releasedBy\": \"ci\"}"

if [ $? -eq 0 ]; then
  curl -s "${VIGILMON_HEARTBEAT_URL}" > /dev/null
fi

Step 6: Add Vigilmon Monitors for Each Sidecar Endpoint

| Endpoint | Expected | Interval | |---|---|---| | /health/apollo/eureka | 200, body "status":"ok" | 1 min | | /health/apollo/mysql | 200, body "status":"ok" | 1 min | | /health/apollo/clients | 200, body "status":"ok" | 2 min | | /health/apollo/portal-api | 200, body "status":"ok" | 2 min |


Step 7: Configure Alert Channels and Routing

| Monitor | Alert Channel | Suggested Priority | |---|---|---| | Config Service /health | Slack + PagerDuty | P1 — apps can't receive config updates | | Admin Service /health | Slack + PagerDuty | P1 — config writes blocked | | Portal /health | Slack | P2 — operator access blocked | | Eureka registry | Slack | P1 — service discovery for Apollo internals | | MySQL backend | Slack + PagerDuty | P1 — all config persistence fails | | Client connections | Slack | P2 — apps disconnected from Config Service | | Portal API health | Email | P2 — CI/CD integration broken | | Promotion heartbeat | Slack | P2 — promotion pipeline missing |

Recommended settings:

  • Consecutive failures before alert: 2 for all components — avoids false positives from brief restarts
  • Response time threshold: 5000ms for Config Service (long-poll processing under load)
  • Maintenance windows: suppress during Apollo version upgrades, which require a brief restart sequence across all components

Step 8: Multi-Environment Monitoring

Apollo manages configurations across multiple environments (DEV, FAT, UAT, PRO). Each environment runs its own Config Service. Add monitors for each environment's Config Service — not just production:

http://apollo-configservice-dev:8080/health    → P3 alert
http://apollo-configservice-fat:8080/health    → P3 alert
http://apollo-configservice-uat:8080/health    → P2 alert
http://apollo-configservice-pro:8080/health    → P1 alert

UAT and production Config Service failures are higher priority because they affect final-stage testing and live applications respectively.


Summary

| Monitor | Target | What It Catches | |---|---|---| | HTTP — Portal | :8070/health | Portal down, operators lose config management | | HTTP — Config Service | :8080/health | Apps cannot receive configuration updates | | HTTP — Admin Service | :8090/health | Config write operations fail | | HTTP — Eureka | :8099/health/apollo/eureka | Config/Admin service discovery failure | | HTTP — MySQL | :8099/health/apollo/mysql | Config persistence failure | | HTTP — client connections | :8099/health/apollo/clients | Mass client disconnection from Config Service | | HTTP — Portal API | :8099/health/apollo/portal-api | CI/CD integration broken | | Heartbeat — promotion pipeline | Heartbeat URL | Promotion automation failure |

Apollo makes it possible to change configuration across your entire fleet in seconds — but that power depends on every component staying healthy. With Vigilmon watching Config Service, Admin Service, Portal, Eureka, MySQL, and your promotion pipelines, you catch failures before they block configuration deployments or leave your applications unable to bootstrap.

Get started free at vigilmon.online — your first Apollo monitor is running in under two minutes.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →