Files
CDN-APP-INSIDER/services/reportService.js
Dinawo 51d11a6c36
Some checks failed
continuous-integration/drone/push Build is failing
Update v1.1.0-beta.1
2024-12-21 18:16:25 +01:00

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();