mindboost-rnbo-test-project/plugins/logger.server.ts

135 lines
4.2 KiB
TypeScript

import * as fs from 'fs'
import { createGzip } from 'zlib'
import { pino, transport } from 'pino'
import { createTransport } from 'nodemailer'
import { config } from 'dotenv'
export default defineNuxtPlugin(() => {
useNuxtApp().$logger.log('[logger.server.ts] Plugin geladen!')
// Format the Date in log file name
const getCurrentDate = () => {
const now = new Date()
const year = now.getFullYear()
const month = String(now.getMonth() + 1).padStart(2, '0') // Monat von 0-11
const day = String(now.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
config()
// Standardwerte für Konfiguration
const maxFiles = parseInt(process.env.LOG_MAX_FILES || '10') // Maximale Anzahl von Log-Dateien
const logDirectory = process.env.LOG_DIRECTORY || './logs' // Verzeichnis für Log-Dateien
const alertThreshold = parseInt(process.env.LOG_ALERT_THRESHOLD || '5') // Warnschwelle für Log-Dateien
const alertEmail =
process.env.LOG_ALERT_EMAIL || 'robert.rapp@mindboost.team' // E-Mail-Adresse für Warnungen
const checkInterval = parseInt(
process.env.LOG_CHECK_INTERVAL || (30 * 60 * 1000).toString()
) // Überwachungsintervall
const currentDate = getCurrentDate() // Format: 2023-11-27
// Sicherstellen, dass das Log-Verzeichnis existiert
if (!fs.existsSync(logDirectory)) {
fs.mkdirSync(logDirectory, { recursive: true })
}
// Transport für Pino
const pinotransport = transport({
target: 'pino/file',
options: {
destination: `${logDirectory}/app-${currentDate}.log`,
mkdir: true,
rotate: {
interval: '1d', // Log-Rotation täglich
size: '10M' // Maximalgröße für einzelne Logs
}
}
})
// Logger erstellen
const logger = pino(pinotransport)
// Funktion zur E-Mail-Benachrichtigung
async function sendAlertEmail (fileCount: number) {
const transporter = createTransport({
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT || '465'),
secure: process.env.SMTP_SECURE === 'true', // TLS/SSL basierend auf ENV
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS
}
})
const message = {
from: process.env.SMTP_USER || 'app@mindboost.team',
to: alertEmail,
subject: 'Warnung: Hohe Anzahl von Log-Dateien',
text: `Es wurden heute bereits ${fileCount} Log-Dateien erstellt. Schau es dir bitte mal an.`
}
try {
await transporter.sendMail(message)
logger.info('Warn-E-Mail wurde erfolgreich gesendet.')
} catch (error) {
logger.error('Fehler beim Senden der Warn-E-Mail:', error)
}
}
// Funktion zur Überwachung der Log-Dateien
function monitorLogs () {
fs.readdir(logDirectory, (err, files) => {
if (err) {
logger.error('Fehler beim Lesen des Log-Verzeichnisses:', err)
return
}
const logFiles = files.filter(file => file.endsWith('.log'))
logger.info(`Aktuelle Anzahl von Log-Dateien: ${logFiles.length}`)
if (logFiles.length >= alertThreshold) {
sendAlertEmail(logFiles.length)
}
if (logFiles.length > maxFiles) {
zipOldLogs(logFiles)
}
})
}
// Funktion zum Zippen alter Logs
function zipOldLogs (logFiles: string[]) {
const filesToZip = logFiles.slice(0, logFiles.length - maxFiles)
filesToZip.forEach((file) => {
const inputPath = `${logDirectory}/${file}`
const outputPath = `${inputPath}.gz`
const gzip = createGzip()
const source = fs.createReadStream(inputPath)
const destination = fs.createWriteStream(outputPath)
source
.pipe(gzip)
.pipe(destination)
.on('finish', () => {
fs.unlinkSync(inputPath) // Originaldatei löschen
logger.info(`Log-Datei wurde erfolgreich gezippt: ${outputPath}`)
})
.on('error', (err) => {
logger.error(`Fehler beim Zippen der Log-Datei ${file}:`, err)
})
})
}
// Log-Rotation überwachen
pinotransport.on('drain', () => {
logger.info('Neue Log-Datei wurde erstellt oder rotiert.')
monitorLogs()
})
// Überwachung alle 30 Minuten ausführen
setInterval(monitorLogs, checkInterval)
return {
provide: {
logger
}
}
})