0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-01 02:41:39 -05:00

Removed the metrics server from Ghost (#21629)

no issue

- Since we decided to use the pushgateway instead of running a metrics
server, this removes the metrics server and its e2e tests
- We may reintroduce it later, but for now this is a simpler setup
This commit is contained in:
Chris Raible 2024-11-14 19:39:12 -08:00 committed by GitHub
parent 3728a4eaea
commit 015b881bc1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 0 additions and 150 deletions

View file

@ -266,29 +266,6 @@ function initPrometheusClient({config}) {
return null;
}
/**
* Starts the standalone metrics server and registers a cleanup task to stop it when the ghost server shuts down
* @param {object} ghostServer
*/
async function initMetricsServer({prometheusClient, ghostServer, config}) {
debug('Begin: initMetricsServer');
if (ghostServer && config.get('prometheus:metrics_server:enabled')) {
const {MetricsServer} = require('@tryghost/prometheus-metrics');
const serverConfig = {
host: config.get('prometheus:metrics_server:host') || '127.0.0.1',
port: config.get('prometheus:metrics_server:port') || 9416
};
const handler = prometheusClient.handleMetricsRequest.bind(prometheusClient);
const metricsServer = new MetricsServer({serverConfig, handler});
await metricsServer.start();
// Ensure the metrics server is cleaned up when the ghost server is shut down
ghostServer.registerCleanupTask(async () => {
await metricsServer.shutdown();
});
}
debug('End: initMetricsServer');
}
/**
* Dynamic routing is generated from the routes.yaml file
* When Ghost's DB and core are loaded, we can access this file and call routing.routingManager.start
@ -634,9 +611,6 @@ async function bootGhost({backend = true, frontend = true, server = true} = {})
// Step 7 - Init our background services, we don't wait for this to finish
initBackgroundServices({config});
// Step 8 - Init our metrics server, we don't wait for this to finish
initMetricsServer({prometheusClient, ghostServer, config});
// If we pass the env var, kill Ghost
if (process.env.GHOST_CI_SHUTDOWN_AFTER_BOOT) {
process.exit(0);

View file

@ -1,124 +0,0 @@
const assert = require('node:assert/strict');
const testUtils = require('../../utils');
const request = require('supertest');
const parsePrometheusTextFormat = require('parse-prometheus-text-format');
const configUtils = require('../../utils/configUtils');
describe('Metrics Server', function () {
before(function () {
configUtils.set('prometheus:enabled', true);
configUtils.set('prometheus:metrics_server:enabled', true);
configUtils.set('prometheus:metrics_server:host', '127.0.0.1');
configUtils.set('prometheus:metrics_server:port', 9417);
});
it('should start up when Ghost boots and stop when Ghost stops', async function () {
// Ensure the metrics server is running after Ghost boots
await testUtils.startGhost({forceStart: true});
await request('http://127.0.0.1:9417').get('/metrics').expect(200);
// Stop Ghost and ensure the metrics server is no longer running
await testUtils.stopGhost();
// Requesting the metrics endpoint should throw an error
let error;
try {
await request('http://127.0.0.1:9417').get('/metrics');
} catch (err) {
error = err;
}
assert.ok(error);
});
it('should not start if enabled is false', async function () {
configUtils.set('prometheus:metrics_server:enabled', false);
await testUtils.startGhost({forceStart: true});
// Requesting the metrics endpoint should throw an error
let error;
try {
await request('http://127.0.0.1:9417').get('/metrics');
} catch (err) {
error = err;
}
assert.ok(error);
await testUtils.stopGhost();
});
describe('metrics and format', function () {
let metricsResponse;
let metricsText;
before(async function () {
configUtils.set('prometheus:metrics_server:enabled', true);
await testUtils.startGhost({forceStart: true});
metricsResponse = await request('http://127.0.0.1:9417').get('/metrics');
metricsText = metricsResponse.text;
await testUtils.stopGhost();
});
it('should export the metrics in the right format', async function () {
const metricsJson = parsePrometheusTextFormat(metricsText);
assert.ok(metricsJson);
});
it('should use the right prefix for all metrics', async function () {
const metricsJson = parsePrometheusTextFormat(metricsText);
const metricNames = metricsJson.map(metric => metric.name);
metricNames.forEach((metricName) => {
assert.match(metricName, /^ghost_/);
});
});
it('should have help text for all metrics', async function () {
const metricsJson = parsePrometheusTextFormat(metricsText);
metricsJson.forEach((metric) => {
assert.ok(metric.help);
});
});
it('should have type for all metrics', async function () {
const metricsJson = parsePrometheusTextFormat(metricsText);
metricsJson.forEach((metric) => {
assert.ok(metric.type);
});
});
it('should have all the right metrics', async function () {
// Ensures we have all the metrics we expect exported
// This could be a snapshot test in the future, but for now just check the names of the metrics
// Add new metrics to this list as they are added
const expectedMetrics = [
'ghost_process_cpu_user_seconds_total',
'ghost_process_cpu_system_seconds_total',
'ghost_process_cpu_seconds_total',
'ghost_process_start_time_seconds',
'ghost_process_resident_memory_bytes',
'ghost_nodejs_eventloop_lag_seconds',
'ghost_nodejs_eventloop_lag_min_seconds',
'ghost_nodejs_eventloop_lag_max_seconds',
'ghost_nodejs_eventloop_lag_mean_seconds',
'ghost_nodejs_eventloop_lag_stddev_seconds',
'ghost_nodejs_eventloop_lag_p50_seconds',
'ghost_nodejs_eventloop_lag_p90_seconds',
'ghost_nodejs_eventloop_lag_p99_seconds',
'ghost_nodejs_active_resources',
'ghost_nodejs_active_resources_total',
'ghost_nodejs_active_handles',
'ghost_nodejs_active_handles_total',
'ghost_nodejs_active_requests',
'ghost_nodejs_active_requests_total',
'ghost_nodejs_heap_size_total_bytes',
'ghost_nodejs_heap_size_used_bytes',
'ghost_nodejs_external_memory_bytes',
'ghost_nodejs_heap_space_size_total_bytes',
'ghost_nodejs_heap_space_size_used_bytes',
'ghost_nodejs_heap_space_size_available_bytes',
'ghost_nodejs_version_info',
'ghost_nodejs_gc_duration_seconds'
];
const metricsJson = parsePrometheusTextFormat(metricsText);
const metricNames = metricsJson.map(metric => metric.name);
for (const metricName of expectedMetrics) {
assert.ok(metricNames.includes(metricName));
}
});
});
});