Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom metric framework and cluster API metrics #1341

Merged
merged 17 commits into from
Nov 10, 2023
51 changes: 50 additions & 1 deletion app/apollo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const { models, connectDb } = require('./models');
const promClient = require('prom-client');
const createMetricsPlugin = require('apollo-metrics');
const apolloMetricsPlugin = createMetricsPlugin(promClient.register);
const { customMetricsClient } = require('../customMetricsClient'); // Add custom metrics plugin
const apolloMaintenancePlugin = require('./maintenance/maintenanceModePlugin.js');
const { GraphqlPubSub } = require('./subscription');

Expand Down Expand Up @@ -140,7 +141,55 @@ const createApolloServer = (schema) => {
initLogger.info(customPlugins, 'Apollo server custom plugin are loaded.');
const server = new ApolloServer({
introspection: true, // set to true as long as user has valid token
plugins: customPlugins,
plugins: [
customPlugins,
{
// Detect custom metrics as they occur
requestDidStart(context) {
// Capture the start time when the request starts
const startTime = Date.now();

// Track if API operation has errored since didEncounterErrors() could trigger after didResolveOperation()
let gaugeIncremented = false;

// Parse API operation name
const match = context.request.query.match(/\{\s*(\w+)/);
const operationName = match ? match[1] : 'Query name not found ';
const operationNameDuration = operationName + 'Duration';
const operationNameGauge = operationName + 'Gauge';

// Increment my_api_calls_total when operation detected
customMetricsClient.incrementApiCall();

return {
didResolveOperation() {
// Record API operation duration metrics
const durationInSeconds = (Date.now() - startTime) / 1000;
if (customMetricsClient[operationNameDuration]) {
customMetricsClient[operationNameDuration].observe(durationInSeconds);
}

// Record API operation success and failure gauge metrics
if (customMetricsClient[operationNameGauge]) {
customMetricsClient[operationNameGauge].inc({ status: 'success' });
gaugeIncremented = true;
}
},

didEncounterErrors() {
// Record API operation success and failure gauge metrics
if (customMetricsClient[operationNameGauge]) {
customMetricsClient[operationNameGauge].inc({ status: 'failure' });
// Decrease gauge success count if error found later in request process
if (gaugeIncremented == true) {
customMetricsClient[operationNameGauge].dec({ status: 'success' });
}
}
},
};
},
},
],
schema,
allowBatchedHttpRequests: (process.env.GRAPHQL_DISABLE_BATCHING ? false : true),
formatError: error => {
Expand Down
Loading