File size: 2,686 Bytes
4321cf6
0aa7f4c
2abd104
 
0aa7f4c
4321cf6
 
 
 
 
 
 
 
0aa7f4c
4321cf6
 
 
 
 
0aa7f4c
 
 
 
 
2abd104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4321cf6
2abd104
 
4321cf6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
process.env.TZ = "Europe/Istanbul";
const log4js = require("log4js");
const util = require("util");

log4js.configure({
    appenders: {
        console: { type: "console" },
    },
    categories: {
        default: {
            appenders: ["console"],
            level: "info"
        }
    },
    layouts: {
        customLayout: {
            type: 'pattern',
            pattern: '%d{hh:mm:ss} %-5p %c - %m',
        }
    }
});

const logger = log4js.getLogger();

// --- WEB PANEL İÇİN BELLEK İÇİ LOG TAMPONU ---
// log4js'in kendisi "son X dakikanın logları" diye bir şey sunmuyor, o yüzden
// her log çağrısını (console'a yazmaya ek olarak) burada da saklıyoruz.
// Varsayılan tutma süresi 30 dakika; bu sürenin dışındaki kayıtlar otomatik atılır.
const LOG_RETENTION_MS = 30 * 60 * 1000;
const MAX_BUFFER_SIZE = 5000; // Aşırı log patlaması durumunda RAM'i sınırlamak için güvenlik tavanı

let logBuffer = [];

function pruneOldLogs() {
    const cutoff = Date.now() - LOG_RETENTION_MS;
    while (logBuffer.length && logBuffer[0].time < cutoff) {
        logBuffer.shift();
    }
    if (logBuffer.length > MAX_BUFFER_SIZE) {
        logBuffer.splice(0, logBuffer.length - MAX_BUFFER_SIZE);
    }
}

function formatArgs(args) {
    try {
        return args
            .map((a) => (typeof a === "string" ? a : util.inspect(a, { depth: 2 })))
            .join(" ");
    } catch (e) {
        return "[loglanamayan mesaj]";
    }
}

function pushToBuffer(level, args) {
    try {
        logBuffer.push({
            time: Date.now(),
            level,
            message: formatArgs(args)
        });
        pruneOldLogs();
    } catch (e) {
        // Log tamponuna yazarken bile bir hata olursa asıl process'i etkilemesin
    }
}

// logger.info / warn / error / debug / trace / fatal çağrılarını, orijinal
// davranışlarını bozmadan, aynı zamanda tampona da yazacak şekilde sarmalıyoruz.
["trace", "debug", "info", "warn", "error", "fatal"].forEach((level) => {
    if (typeof logger[level] !== "function") return;
    const original = logger[level].bind(logger);
    logger[level] = (...args) => {
        pushToBuffer(level, args);
        return original(...args);
    };
});

// Web panelden çağrılacak: HER ZAMAN son 30 dakikanın loglarını döner.
// Kasıtlı olarak parametre almıyor — süre dışarıdan (istekle) değiştirilemesin,
// tampon zaten her yazımda 30 dk'dan eskisini otomatik siliyor (RAM güvenliği).
function getRecentLogs() {
    const cutoff = Date.now() - LOG_RETENTION_MS;
    return logBuffer.filter((l) => l.time >= cutoff);
}

module.exports = {
    logger,
    getRecentLogs
}