mirror of
https://github.com/MCSManager/MCSManager.git
synced 2025-02-17 15:59:41 +08:00
重构 日志广播与历史记录
This commit is contained in:
parent
b479ec70b7
commit
2a7e73a2a3
@ -1,72 +1,90 @@
|
||||
"use strict";
|
||||
// 日志历史储存
|
||||
|
||||
const MAX_HISTORY_SIZE = 1000;
|
||||
const DELETE_ALTER_INIT_SIZE = 600;
|
||||
const fs = require('fs');
|
||||
const fsExtra = require('fs-extra');
|
||||
|
||||
const MAX_HISTORY_SIZE = 1024 * 1024 * 1;
|
||||
const BASE_RECORD_DIR = './server/tmp_log_history/';
|
||||
const FILE_CODE = "utf8";
|
||||
|
||||
class LogHistory {
|
||||
constructor(id) {
|
||||
this.id = id;
|
||||
this.readPoints = {};
|
||||
this.log = new Array();
|
||||
this.path = BASE_RECORD_DIR + id + '.log';
|
||||
if (!fsExtra.existsSync(BASE_RECORD_DIR)) {
|
||||
fsExtra.mkdirs(BASE_RECORD_DIR);
|
||||
}
|
||||
}
|
||||
|
||||
writeLine(text = "") {
|
||||
if (text.length == 0) return;
|
||||
if (this.log.length > MAX_HISTORY_SIZE) {
|
||||
this.log.splice(0, DELETE_ALTER_INIT_SIZE);
|
||||
}
|
||||
let addLineLength = 0;
|
||||
text = text.replace(/\r/igm, "");
|
||||
if (text.indexOf('\n') != -1) {
|
||||
let arr = text.split('\n');
|
||||
for (let v of arr) {
|
||||
if (v) {
|
||||
this.log.push(v);
|
||||
addLineLength++;
|
||||
if (fs.existsSync(this.path))
|
||||
fs.appendFile(this.path, text, FILE_CODE, (err) => {
|
||||
if (err) MCSERVER.log('实例', this.id, '日志历史记录文件写入错误:', err.message);
|
||||
let fsstat = fs.statSync(this.path);
|
||||
let size = fsstat.size;
|
||||
if (size > MAX_HISTORY_SIZE) {
|
||||
fs.unlinkSync(this.path);
|
||||
}
|
||||
});
|
||||
else
|
||||
fs.writeFile(this.path, text, (err) => {
|
||||
if (err) MCSERVER.log('实例', this.id, '日志历史记录文件创建错误:', err.message);
|
||||
});
|
||||
}
|
||||
|
||||
readLine(demander = "", size = 1024, callback = () => { }) {
|
||||
if (!this.readPoints[demander]) {
|
||||
this.readPoints[demander] = 0;
|
||||
}
|
||||
const demanderPoint = this.readPoints[demander];
|
||||
const buffer = Buffer.alloc(size);
|
||||
fs.open(this.path, 'r', (err, fd) => {
|
||||
if (err) {
|
||||
MCSERVER.log('实例', this.id, '日志历史记录文件打开错误:', err.message);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
this.log.push(text);
|
||||
addLineLength++;
|
||||
}
|
||||
for (let k in this.readPoints) {
|
||||
this.readPoints[k] += addLineLength;
|
||||
}
|
||||
fs.read(fd, buffer, 0, size, demanderPoint, (err, bytesRead, buffer) => {
|
||||
if (err) {
|
||||
MCSERVER.log('实例', this.id, '日志历史记录文件读取错误:', err.message);
|
||||
return;
|
||||
};
|
||||
const logText = buffer.slice(0, bytesRead).toString();
|
||||
this.readPoints[demander] += size;
|
||||
callback && callback(logText);
|
||||
// 关闭文件
|
||||
fs.close(fd, () => { });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
readLine(demander = "", size = 10) {
|
||||
readLineReverse(demander = "", size = 1024, notadd = false, callback = () => { }) {
|
||||
if (!this.readPoints[demander]) {
|
||||
this.readPoints[demander] = 0;
|
||||
}
|
||||
let demanderPoint = this.readPoints[demander];
|
||||
let text = "";
|
||||
let logarr = this.log;
|
||||
let i;
|
||||
for (i = demanderPoint; i <= demanderPoint + size; i++) {
|
||||
let point = logarr.length - i - 1;
|
||||
if (point < 0) break;
|
||||
let v = logarr[point] + '\n';
|
||||
if (logarr[point] && logarr[point].trim().length > 0) text += v;
|
||||
}
|
||||
this.readPoints[demander] = demanderPoint + size;
|
||||
return text;
|
||||
}
|
||||
|
||||
readLineReverse(demander = "", size = 10, notadd = false) {
|
||||
if (!this.readPoints[demander]) {
|
||||
this.readPoints[demander] = 0;
|
||||
}
|
||||
let demanderPoint = this.readPoints[demander];
|
||||
let text = "";
|
||||
let logarr = this.log;
|
||||
let i;
|
||||
for (i = (logarr.length - 1 - size - demanderPoint); i < logarr.length - demanderPoint; i++) {
|
||||
let v = logarr[i] + '\n';
|
||||
if (logarr[i] && logarr[i].trim().length > 0) text += v;
|
||||
}
|
||||
const demanderPoint = this.readPoints[demander];
|
||||
const buffer = Buffer.alloc(size);
|
||||
fs.open(this.path, 'r', (err, fd) => {
|
||||
if (err) {
|
||||
MCSERVER.log('实例', this.id, '日志历史记录文件打开错误:', err.message);
|
||||
return;
|
||||
}
|
||||
fs.read(fd, buffer, 0, size, demanderPoint, (err, bytesRead, buffer) => {
|
||||
if (err) {
|
||||
MCSERVER.log('实例', this.id, '日志历史记录文件读取错误:', err.message);
|
||||
return;
|
||||
};
|
||||
const logText = buffer.slice(0, bytesRead).toString();
|
||||
this.readPoints[demander] += size;
|
||||
callback && callback(logText);
|
||||
// 关闭文件
|
||||
fs.close(fd, () => { });
|
||||
});
|
||||
});
|
||||
if (!notadd) this.readPoints[demander] = demanderPoint + size;
|
||||
return text;
|
||||
}
|
||||
|
||||
setPoint(demander, v) {
|
||||
|
@ -96,7 +96,8 @@
|
||||
<div class="PanelTitle">实时终端控制台</div>
|
||||
<div class="PanelBody">
|
||||
<!-- 终端 -->
|
||||
<div id="WebTerminal" class="WebTerminalScreen"></div>
|
||||
<div id="WebTerminal" class="WebTerminalScreen" style="display: block;"></div>
|
||||
<div id="LogHistoryTerminal" class="WebTerminalScreen" style="display: block;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -112,29 +112,41 @@ WebSocketObserver().listener('server/console/remove', (data) => {
|
||||
});
|
||||
|
||||
|
||||
//缓冲区定时发送频率,默认限制两秒刷新缓冲区
|
||||
let consoleBuffer = {};
|
||||
// 缓冲区定时发送频率,默认限制两秒刷新缓冲区
|
||||
const consoleBuffer = {};
|
||||
setInterval(() => {
|
||||
for (const serverName in consoleBuffer) {
|
||||
let data = consoleBuffer[serverName];
|
||||
// 记录日志历史记录
|
||||
const logHistory = serverModel.ServerManager().getServer(serverName).logHistory;
|
||||
if (logHistory) logHistory.writeLine(data)
|
||||
|
||||
// 发送前端的标准,前端只识别 \r\n ,不可是\n
|
||||
data = data.replace(/\n/gim, '\r\n');
|
||||
data = data.replace(/\r\r\n/gim, '\r\n');
|
||||
//刷新每个服务器的缓冲数据
|
||||
selectWebsocket(serverName, (socket) => {
|
||||
socket.send({
|
||||
ws: socket.ws,
|
||||
resK: 'server/console/ws',
|
||||
resV: {},
|
||||
body: data
|
||||
try {
|
||||
let data = consoleBuffer[serverName];
|
||||
const server = serverModel.ServerManager().getServer(serverName);
|
||||
// 此实例可能已经失去联系,可能被删除,可能被改名
|
||||
if (!server || !data) {
|
||||
consoleBuffer[serverName] = undefined;
|
||||
delete consoleBuffer[serverName];
|
||||
continue;
|
||||
}
|
||||
const logHistory = server.logHistory;
|
||||
if (logHistory) logHistory.writeLine(data)
|
||||
// 发送前端的标准,前端只识别 \r\n ,不可是\n
|
||||
data = data.replace(/\n/gim, '\r\n');
|
||||
data = data.replace(/\r\r\n/gim, '\r\n');
|
||||
//刷新每个服务器的缓冲数据
|
||||
selectWebsocket(serverName, (socket) => {
|
||||
socket.send({
|
||||
ws: socket.ws,
|
||||
resK: 'server/console/ws',
|
||||
resV: {},
|
||||
body: data
|
||||
});
|
||||
});
|
||||
});
|
||||
// 释放内存
|
||||
consoleBuffer[serverName] = "";
|
||||
// 释放内存并删除键
|
||||
consoleBuffer[serverName] = undefined;
|
||||
delete consoleBuffer[serverName];
|
||||
} catch (error) {
|
||||
MCSERVER.log('实例', serverName, '日志周期性广播任务错误:');
|
||||
console.log(error);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}, MCSERVER.localProperty.console_send_times);
|
||||
//控制台标准输出流
|
||||
|
@ -5,6 +5,7 @@ const permssion = require('../../../helper/Permission');
|
||||
const serverModel = require('../../../model/ServerModel');
|
||||
const response = require('../../../helper/Response');
|
||||
|
||||
const HISTORY_SIZE_LINE = 1024;
|
||||
|
||||
// 正序历史记录路由
|
||||
WebSocketObserver().listener('server/console/history', (data) => {
|
||||
@ -18,14 +19,16 @@ WebSocketObserver().listener('server/console/history', (data) => {
|
||||
response.wsSend(data.ws, 'server/console/history', 'terminalBack', "[控制面板]: 暂无任何历史记录.\r\n");
|
||||
return;
|
||||
}
|
||||
let sendText = logHistory.readLine(userName, 30);
|
||||
if (sendText) {
|
||||
sendText = sendText.replace(/\n/gim, '\r\n');
|
||||
sendText = sendText.replace(/\r\r\n/gim, '\r\n');
|
||||
response.wsSend(data.ws, 'server/console/history', 'terminalBack', sendText);
|
||||
} else {
|
||||
response.wsSend(data.ws, 'server/console/history', 'terminalBack', "[控制面板]: 无法再读取更多的服务端日志.\r\n");
|
||||
}
|
||||
logHistory.readLine(userName, HISTORY_SIZE_LINE, (sendText) => {
|
||||
if (sendText) {
|
||||
sendText = sendText.replace(/\n/gim, '\r\n');
|
||||
sendText = sendText.replace(/\r\r\n/gim, '\r\n');
|
||||
response.wsSend(data.ws, 'server/console/history', 'terminalBack', sendText);
|
||||
} else {
|
||||
response.wsSend(data.ws, 'server/console/history', 'terminalBack', "[控制面板]: 无法再读取更多的服务端日志.\r\n");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@ -40,12 +43,14 @@ WebSocketObserver().listener('server/console/history_reverse', (data) => {
|
||||
const logHistory = serverModel.ServerManager().getServer(serverName).logHistory;
|
||||
if (!logHistory)
|
||||
return;
|
||||
let sendText = logHistory.readLineReverse(userName, 50, true);
|
||||
if (sendText) {
|
||||
sendText = sendText.replace(/\n/gim, '\r\n');
|
||||
sendText = sendText.replace(/\r\r\n/gim, '\r\n');
|
||||
response.wsSend(data.ws, 'server/console/history', 'terminalBack', sendText);
|
||||
}
|
||||
logHistory.readLineReverse(userName, HISTORY_SIZE_LINE, true, (sendText) => {
|
||||
if (sendText) {
|
||||
sendText = sendText.replace(/\n/gim, '\r\n');
|
||||
sendText = sendText.replace(/\r\r\n/gim, '\r\n');
|
||||
response.wsSend(data.ws, 'server/console/history', 'terminalBack', sendText);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user