Creating a Custom Monitor Plugin ​
This recipe walks through creating a custom monitor plugin for Launchpad's process monitoring system. Monitor plugins let you hook into process lifecycle events and add custom functionality to your process management.
Overview ​
Monitor plugins in Launchpad:
- React to process lifecycle events (start, stop, errors, etc.)
- Can modify or enhance monitoring behavior
- Have access to the monitor instance and its utilities
- Run in the order they are defined in your config
Basic Plugin Structure ​
Here's a minimal plugin example:
typescript
const myPlugin = {
name: 'my-monitor-plugin',
hooks: {
afterAppStart: async (ctx) => {
// Your logic here
}
}
}
Step-by-Step Example ​
Let's create a plugin that logs app restarts and sends notifications:
typescript
const restartNotifierPlugin = {
name: 'restart-notifier',
hooks: {
// Runs after an app starts
afterAppStart: async ({ monitor, logger }) => {
const apps = monitor.getApps();
for (const app of apps) {
if (app.restarts > 0) {
logger.warn(
`App ${app.name} has restarted ${app.restarts} times`
);
// Add your notification logic here
}
}
},
// Runs when an app encounters an error
onAppError: async ({ app, error, logger }) => {
logger.error(
`Error in ${app.name}: ${error.message}`
);
}
}
}
Add it to your Launchpad config:
typescript
import { defineConfig } from '@bluecadet/launchpad-cli';
export default defineConfig({
monitor: {
apps: [ /* your apps */ ],
plugins: [
restartNotifierPlugin
]
}
});
Available Hooks ​
Monitor plugins can use these hooks:
beforeConnect
/afterConnect
: PM2 connection lifecyclebeforeDisconnect
/afterDisconnect
: PM2 disconnection lifecyclebeforeAppStart
/afterAppStart
: App start lifecyclebeforeAppStop
/afterAppStop
: App stop lifecycleonAppError
: App errorsonAppLog
/onAppErrorLog
: App loggingbeforeShutdown
: System shutdown
TIP
Choose hooks based on what events you need to monitor. Most monitoring logic will use the app lifecycle hooks.
Working with the Context ​
Each hook receives a context object with useful utilities:
typescript
const myPlugin = {
name: 'my-plugin',
hooks: {
afterAppStart: async (ctx) => {
const {
monitor, // Access monitor instance
logger, // Plugin-specific logging
app // The current app (in app-specific hooks)
} = ctx;
// Example: Log app status
logger.info(`App ${app.name} is running`);
}
}
}
Best Practices ​
- Name your plugin clearly: Use a descriptive, unique name
- Handle errors gracefully: Use try/catch blocks
- Log important events: Use the provided logger
- Clean up resources: Handle cleanup in shutdown hooks
- Keep it focused: One responsibility per plugin
typescript
const bestPracticePlugin = {
name: 'best-practice-plugin',
hooks: {
afterAppStart: async ({ app, logger }) => {
try {
logger.info(`Monitoring app: ${app.name}`);
// Your logic here...
} catch (error) {
logger.error('Plugin failed:', error);
throw error; // Re-throw to notify Launchpad
}
},
beforeShutdown: async ({ logger }) => {
// Clean up resources
logger.info('Cleaning up...');
}
}
}
Going Further ​
- See Monitor Plugin Reference for complete API details
- Check Monitor Reference for monitor documentation
- Explore example plugins for real-world usage
NOTE
Remember to test your plugins thoroughly, especially error handling and cleanup logic.