GraphQL Performance Monitoring
Query Performance Monitoring with Apollo Engine
The GraphQL stack in keystone-alpha is powered by Apollo Server, which comes with performance monitoring built in via the Apollo Engine.
Apollo Engine provides a free service up to 25 million monthly requests, including:
- Query logging
- Error logging
- Query performance monitoring
- Query performance tracing
- Schema version history
Apollo Engine Query Trace Example
Setting up Apollo Engine
Apollo Engine Account
Sign up for an Apollo Engine account.
Follow the prompts to create a new service. On the second step, you will see a screen such as:
Ignore the npx apollo service:push command for now,
we'll need to upload the schema a slightly different way to account for any
Access Control you may have setup.
Config
Create the .env file as suggested:
ENGINE_API_KEY=service:tests:C-ddserkuj5-BU-2345jf
(👆 that's not a real key!)
Create a file apollo.config.js:
module.exports = {
  service: {
    localSchemaFile: './schema.graphql',
  },
};
Push Schema To Apollo Engine
We will use the keystone.dumpSchema() command to create a schema we can upload
to Apollo Engine.
Somewhere in your main Keystone application code you will be calling
keystone.createList(), followed by a call to new WebServer(keystone, { ... }).
We will now add some extra commands between these two calls:
keystone.createList('Foo', {
  /* ... */
});
// ---- Schema dumping ----
if (typeof process.env.DUMP_SCHEMA === 'string') {
  const schemaName = 'public'; //this is the default keystonejs schema name
  keystone.dumpSchema(process.env.DUMP_SCHEMA, schemaName);
  console.log(`Schema dumped to: ${path.resolve(process.env.DUMP_SCHEMA)}`);
  process.exit(0);
}
// ---- End Schema dumping ----
const server = new WebServer(keystone, {
  /* ... */
});
Next, start the KeystoneJS server but include a DUMP_SCHEMA environment variable.
This will output the KeystoneJS schema to the given path
(ready for us to upload to Apollo Engine!):
DUMP_SCHEMA=./schema.graphql node index.js
Note ./schema.graphql is the same path we set in apollo.config.js
schema.graphql should look something like:
scalar Upload
scalar DateTime
input GroupRelateToOneInput {
  # ...
}
# ... And so on
Now we can push our generated schema to Apollo Engine with the command:
npx apollo service:push
(Note: For performance and security reasons,
you may wish to add apollo to your devDependencies,
and add the command above to your package.json without the npx prefix)
Wait for Apollo Engine to show the newly uploaded service:
Successfully pushed schema to Apollo Engine
Send stats to Apollo Engine
Ensure your application is reading .env environment variables on boot.
We recommend the dotenv library for this:
node -r dotenv/config index.js
(Note: you do not need the DUMP_SCHEMA environment variable when starting the
server - it is only used for exporting an updated schema and should not be set
when trying to start the KeystoneJS GraphQL API)
Apollo Server will read the ENGINE_API_KEY env var and start sending GraphQL
stats to Apollo Engine.
Within seconds of triggering GraphQL requests, they will begin to show in Apollo Engine:
Apollo Engine > Metrics > Slow Query > Trace > Inspect
Tweaking stats sent to Apollo Engine
The WebServer config option can accept an apollo key for setting different
options, one of which can be used to configure the Apollo Engine connection:
const server = new WebServer(keystone, {
  /* ... */
  apollo: {
    engine: {
      privateVariables: ['password'],
    },
  },
});
See the Apollo Server docs for more options.