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.
- Log in to vigilmon.online and click Add Monitor.
- Set Type to
HTTP / HTTPS. - Enter:
http://your-apollo-portal:8070/health - Set Check interval to
1 minute. - Set Expected HTTP status to
200. - Under Response body contains, enter
"status":"UP". - 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.
- Add a new Vigilmon HTTP monitor.
- URL:
http://your-apollo-configservice:8080/health - Check interval:
1 minute. - Expected status:
200. - Body contains:
"status":"UP". - Response time threshold:
5000ms— Config Service processes long-poll connections and can be CPU-intensive under load. - 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.
- Add a Vigilmon HTTP monitor.
- URL:
http://your-apollo-adminservice:8090/health - Check interval:
1 minute. - Expected status:
200. - Body contains:
"status":"UP". - 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:
- In Vigilmon, click Add Monitor → Heartbeat.
- Name:
apollo-config-promotion-pipeline. - Expected interval:
1440minutes (daily promotion run). - Grace period:
60minutes. - 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:
2for all components — avoids false positives from brief restarts - Response time threshold:
5000msfor 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.