feat: add cache monitoring scripts and enhance JiraAnalyticsCache

- Introduced `cache-monitor.ts` for real-time cache monitoring, providing stats and actions for managing Jira analytics cache.
- Updated `package.json` with new cache-related scripts for easy access.
- Enhanced `JiraAnalyticsCacheService` to support TTL for cache entries, automatic cleanup of expired entries, and improved logging for cache operations.
- Added methods for calculating time until expiry and formatting TTL for better visibility.
This commit is contained in:
Julien Froidefond
2025-09-26 11:42:18 +02:00
parent 350dbe6479
commit bd7ede412e
3 changed files with 273 additions and 20 deletions

137
scripts/cache-monitor.ts Normal file
View File

@@ -0,0 +1,137 @@
#!/usr/bin/env tsx
/**
* Script de monitoring du cache Jira Analytics
* Usage: npm run cache:monitor
*/
import { jiraAnalyticsCache } from '../src/services/integrations/jira/analytics-cache';
import * as readline from 'readline';
function displayCacheStats() {
console.log('\n📊 === STATISTIQUES DU CACHE JIRA ANALYTICS ===');
const stats = jiraAnalyticsCache.getStats();
console.log(`\n📈 Total des entrées: ${stats.totalEntries}`);
if (stats.projects.length === 0) {
console.log('📭 Aucune donnée en cache');
return;
}
console.log('\n📋 Projets en cache:');
stats.projects.forEach(project => {
const status = project.isExpired ? '❌ EXPIRÉ' : '✅ VALIDE';
console.log(`${project.projectKey}:`);
console.log(` - Âge: ${project.age}`);
console.log(` - TTL: ${project.ttl}`);
console.log(` - Expire dans: ${project.expiresIn}`);
console.log(` - Taille: ${Math.round(project.size / 1024)}KB`);
console.log(` - Statut: ${status}`);
console.log('');
});
}
function displayCacheActions() {
console.log('\n🔧 === ACTIONS DISPONIBLES ===');
console.log('1. Afficher les statistiques');
console.log('2. Forcer le nettoyage');
console.log('3. Invalider tout le cache');
console.log('4. Surveiller en temps réel (Ctrl+C pour arrêter)');
console.log('5. Quitter');
}
async function monitorRealtime() {
console.log('\n👀 Surveillance en temps réel (Ctrl+C pour arrêter)...');
const interval = setInterval(() => {
console.clear();
displayCacheStats();
console.log('\n⏰ Mise à jour toutes les 5 secondes...');
}, 5000);
// Gérer l'arrêt propre
process.on('SIGINT', () => {
clearInterval(interval);
console.log('\n\n👋 Surveillance arrêtée');
process.exit(0);
});
}
async function main() {
console.log('🚀 Cache Monitor Jira Analytics');
const args = process.argv.slice(2);
const command = args[0];
switch (command) {
case 'stats':
displayCacheStats();
break;
case 'cleanup':
console.log('\n🧹 Nettoyage forcé du cache...');
const cleaned = jiraAnalyticsCache.forceCleanup();
console.log(`${cleaned} entrées supprimées`);
break;
case 'clear':
console.log('\n🗑 Invalidation de tout le cache...');
jiraAnalyticsCache.invalidateAll();
console.log('✅ Cache vidé');
break;
case 'monitor':
await monitorRealtime();
break;
default:
displayCacheStats();
displayCacheActions();
// Interface interactive simple
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const askAction = () => {
rl.question('\nChoisissez une action (1-5): ', async (answer: string) => {
switch (answer.trim()) {
case '1':
displayCacheStats();
askAction();
break;
case '2':
const cleaned = jiraAnalyticsCache.forceCleanup();
console.log(`${cleaned} entrées supprimées`);
askAction();
break;
case '3':
jiraAnalyticsCache.invalidateAll();
console.log('✅ Cache vidé');
askAction();
break;
case '4':
rl.close();
await monitorRealtime();
break;
case '5':
console.log('👋 Au revoir !');
rl.close();
process.exit(0);
break;
default:
console.log('❌ Action invalide');
askAction();
}
});
};
askAction();
}
}
// Exécution du script
main().catch(console.error);