Committed and Pushed by ButtonClick
This commit is contained in:
165
programs/log.js
Executable file
165
programs/log.js
Executable file
@@ -0,0 +1,165 @@
|
||||
// programs/log.js
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// --- configuration ---
|
||||
const LOG_DIR = path.join(__dirname, '..', 'logs');
|
||||
fs.mkdirSync(LOG_DIR, { recursive: true });
|
||||
|
||||
function getLogFilePath(d = new Date()) {
|
||||
const yyyy = d.getFullYear();
|
||||
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
||||
const dd = String(d.getDate()).padStart(2, '0');
|
||||
return path.join(LOG_DIR, `${yyyy}_${mm}_${dd}.txt`);
|
||||
}
|
||||
|
||||
function write(obj) {
|
||||
const line = JSON.stringify(obj) + '\n';
|
||||
fs.appendFile(getLogFilePath(), line, (err) => {
|
||||
if (err) console.error('[log] write error:', err);
|
||||
});
|
||||
}
|
||||
|
||||
// --- common extractors ---
|
||||
function commonFromReq(req) {
|
||||
try {
|
||||
const xff = req?.headers?.['x-forwarded-for'];
|
||||
const xRealIp = req?.headers?.['x-real-ip'];
|
||||
const ipFromXff = xff ? xff.split(',')[0].trim() : null;
|
||||
const ip =
|
||||
ipFromXff ||
|
||||
xRealIp ||
|
||||
req?.ip ||
|
||||
req?.socket?.remoteAddress ||
|
||||
null;
|
||||
|
||||
const tls =
|
||||
req?.socket?.encrypted
|
||||
? {
|
||||
protocol:
|
||||
typeof req.socket.getProtocol === 'function'
|
||||
? req.socket.getProtocol()
|
||||
: null,
|
||||
cipher:
|
||||
typeof req.socket.getCipher === 'function'
|
||||
? (req.socket.getCipher() || {}).name
|
||||
: null,
|
||||
}
|
||||
: null;
|
||||
|
||||
// MAC is not available across routed networks
|
||||
const mac = null;
|
||||
|
||||
return {
|
||||
ip,
|
||||
ips: Array.isArray(req?.ips) ? req.ips : [],
|
||||
xff: xff || null,
|
||||
remoteAddress: req?.socket?.remoteAddress || null,
|
||||
remoteFamily: req?.socket?.remoteFamily || null,
|
||||
userAgent: req?.headers?.['user-agent'] || null,
|
||||
acceptLanguage: req?.headers?.['accept-language'] || null,
|
||||
secChUa: req?.headers?.['sec-ch-ua'] || null,
|
||||
secChUaPlatform: req?.headers?.['sec-ch-ua-platform'] || null,
|
||||
secChUaMobile: req?.headers?.['sec-ch-ua-mobile'] || null,
|
||||
referer: req?.headers?.['referer'] || null,
|
||||
tls,
|
||||
mac,
|
||||
};
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function commonFromSocket(socket) {
|
||||
return {
|
||||
remoteAddress: socket?.remoteAddress || null,
|
||||
remoteFamily: socket?.remoteFamily || null,
|
||||
};
|
||||
}
|
||||
|
||||
// --- specific log functions ---
|
||||
function logHttpRequest(req) {
|
||||
write({
|
||||
ts: new Date().toISOString(),
|
||||
type: 'http',
|
||||
method: req?.method || null,
|
||||
url: (req?.originalUrl ?? req?.url) || null,
|
||||
...commonFromReq(req),
|
||||
});
|
||||
}
|
||||
|
||||
function logTcpConnection(socket) {
|
||||
write({
|
||||
ts: new Date().toISOString(),
|
||||
type: 'tcp',
|
||||
...commonFromSocket(socket),
|
||||
});
|
||||
}
|
||||
|
||||
function logHttpUpgrade(req) {
|
||||
write({
|
||||
ts: new Date().toISOString(),
|
||||
type: 'http-upgrade',
|
||||
url: req?.url || null,
|
||||
...commonFromReq(req),
|
||||
});
|
||||
}
|
||||
|
||||
function logWssConnected(req) {
|
||||
write({
|
||||
ts: new Date().toISOString(),
|
||||
type: 'wss',
|
||||
url: req?.url || null,
|
||||
...commonFromReq(req),
|
||||
});
|
||||
}
|
||||
|
||||
function logWssClosed(req, code, reason) {
|
||||
write({
|
||||
ts: new Date().toISOString(),
|
||||
type: 'wss-close',
|
||||
url: req?.url || null,
|
||||
code: typeof code === 'number' ? code : null,
|
||||
reason: reason ? reason.toString() : null,
|
||||
...commonFromReq(req),
|
||||
});
|
||||
}
|
||||
|
||||
function logSnapshot(python, response){
|
||||
write({
|
||||
ts: new Date().toISOString(),
|
||||
type: 'snapshot',
|
||||
command: python.toString(),
|
||||
wsResponse: response.toString()
|
||||
})
|
||||
}
|
||||
|
||||
// --- generic hooks you requested ---
|
||||
function connected(context = {}) {
|
||||
write({
|
||||
ts: new Date().toISOString(),
|
||||
type: 'connected',
|
||||
...context,
|
||||
});
|
||||
}
|
||||
|
||||
function connectionLost(context = {}) {
|
||||
write({
|
||||
ts: new Date().toISOString(),
|
||||
type: 'connection-lost',
|
||||
...context,
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
logHttpRequest,
|
||||
logTcpConnection,
|
||||
logHttpUpgrade,
|
||||
logWssConnected,
|
||||
logSnapshot,
|
||||
logWssClosed,
|
||||
connected,
|
||||
connectionLost,
|
||||
};
|
||||
Reference in New Issue
Block a user