181 lines
6.1 KiB
JavaScript
181 lines
6.1 KiB
JavaScript
const BaseService = require('./BaseService');
|
|
const cron = require('node-cron');
|
|
const os = require('os');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const ip = require('ip');
|
|
const si = require('systeminformation');
|
|
const fetch = require('node-fetch');
|
|
const packageJson = require('../package.json');
|
|
|
|
class ReportManagerService extends BaseService {
|
|
constructor() {
|
|
// Configuration par défaut
|
|
const defaultConfig = {
|
|
enabled: 'off',
|
|
endpoint: 'https://cdn-apollon-p198-61m1.dinawo.fr/api/report/receive',
|
|
cronSchedule: '0 0 * * *' // Par défaut, une fois par jour à minuit
|
|
};
|
|
|
|
super('reportManager', defaultConfig);
|
|
this.job = null;
|
|
}
|
|
|
|
async _startImplementation() {
|
|
if (this.job) {
|
|
return;
|
|
}
|
|
|
|
// Valider le cron schedule
|
|
const schedule = this.config.cronSchedule || this.defaultConfig.cronSchedule;
|
|
if (!cron.validate(schedule)) {
|
|
throw new Error(`Schedule cron invalide: ${schedule}`);
|
|
}
|
|
|
|
this.job = cron.schedule(schedule, () => this.generateAndSendReport());
|
|
this.logger.info(`Service de rapport programmé avec le planning: ${schedule}`);
|
|
}
|
|
|
|
async _stopImplementation() {
|
|
if (this.job) {
|
|
this.job.stop();
|
|
this.job = null;
|
|
}
|
|
}
|
|
|
|
formatUptime(uptime) {
|
|
const days = Math.floor(uptime / (24 * 60 * 60));
|
|
uptime %= (24 * 60 * 60);
|
|
const hours = Math.floor(uptime / (60 * 60));
|
|
uptime %= (60 * 60);
|
|
const minutes = Math.floor(uptime / 60);
|
|
return `${days}d ${hours}h ${minutes}m`;
|
|
}
|
|
|
|
async getInternalErrors() {
|
|
const date = new Date();
|
|
date.setDate(date.getDate() - 1);
|
|
const previousDate = date.toISOString().split('T')[0];
|
|
const logFile = path.join(__dirname, '..', 'logs', `log-${previousDate}.log`);
|
|
|
|
try {
|
|
const logs = fs.readFileSync(logFile, 'utf-8');
|
|
return logs.split('\n').filter(line => /\[38;5;9mInternal-Error/.test(line));
|
|
} catch (err) {
|
|
this.logger.error('Erreur lors de la lecture des logs:', err);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
async generateReport() {
|
|
try {
|
|
const internalErrors = await this.getInternalErrors();
|
|
|
|
if (internalErrors.length === 0) {
|
|
this.logger.info('Pas d\'erreurs internes dans les logs d\'hier. Pas de rapport généré.');
|
|
return null;
|
|
}
|
|
|
|
const loadavg = os.loadavg().map(load => (load / os.cpus().length) * 100);
|
|
|
|
const osInfo = {
|
|
type: os.type(),
|
|
platform: os.platform(),
|
|
arch: os.arch(),
|
|
release: os.release(),
|
|
uptime: this.formatUptime(os.uptime()),
|
|
loadavg: loadavg
|
|
};
|
|
|
|
const networkInterfaces = os.networkInterfaces();
|
|
const diskUsage = await si.fsSize();
|
|
const cpuTemperature = await si.cpuTemperature();
|
|
const userInfo = os.userInfo();
|
|
|
|
const systemInfo = {
|
|
memoryInfo: ((os.totalmem() - os.freemem()) / os.totalmem() * 100).toFixed(2),
|
|
cpuInfo: (os.cpus().length / os.cpus().length * 100).toFixed(2),
|
|
diskInfo: diskUsage.map(disk => ({
|
|
fs: disk.fs,
|
|
type: disk.type,
|
|
size: disk.size,
|
|
used: disk.used,
|
|
available: disk.available,
|
|
use: disk.use
|
|
})),
|
|
ipAddress: ip.address(),
|
|
cdnVersion: packageJson.version,
|
|
osInfo: osInfo,
|
|
userInfo: {
|
|
username: userInfo.username,
|
|
homedir: userInfo.homedir,
|
|
shell: userInfo.shell
|
|
},
|
|
errors: internalErrors,
|
|
networkInterfaces: networkInterfaces,
|
|
serverUptime: os.uptime(),
|
|
systemLoad: loadavg,
|
|
cpuTemperature: cpuTemperature
|
|
};
|
|
|
|
const reportDate = new Date();
|
|
reportDate.setDate(reportDate.getDate() - 1);
|
|
const reportFileName = `report_${reportDate.toISOString().split('T')[0]}_${ip.address()}.json`;
|
|
|
|
// Sauvegarder le rapport localement
|
|
const reportDir = path.join(__dirname, '..', 'report');
|
|
if (!fs.existsSync(reportDir)) {
|
|
fs.mkdirSync(reportDir, { recursive: true });
|
|
}
|
|
|
|
fs.writeFileSync(
|
|
path.join(reportDir, reportFileName),
|
|
JSON.stringify(systemInfo, null, 2)
|
|
);
|
|
|
|
return systemInfo;
|
|
} catch (error) {
|
|
this.logger.error('Erreur lors de la génération du rapport:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async generateAndSendReport() {
|
|
try {
|
|
const report = await this.generateReport();
|
|
|
|
if (!report) {
|
|
return;
|
|
}
|
|
|
|
this.logger.info("Envoi du rapport...");
|
|
|
|
const response = await fetch(this.config.endpoint, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(report)
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Erreur HTTP! statut: ${response.status}`);
|
|
}
|
|
|
|
const responseData = await response.json();
|
|
this.logger.info('Rapport envoyé avec succès. Réponse:', responseData);
|
|
|
|
return responseData;
|
|
} catch (error) {
|
|
this.logger.error('Échec de l\'envoi du rapport:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Méthode pour forcer l'envoi d'un rapport immédiatement
|
|
async forceSendReport() {
|
|
return this.generateAndSendReport();
|
|
}
|
|
}
|
|
|
|
module.exports = new ReportManagerService(); |