syntex-logger
Version:
A Basic Logging System
404 lines (328 loc) • 8.1 kB
JavaScript
let LanguageSwitcher = require('./language_manager');
const fs = require('fs'), path = require('path');
var logger;
const originalStderrWrite = process.stderr.write.bind(process.stderr);
process.stderr.write = (chunk, encoding, callback) => {
var reference, scriptPath, message = chunk;
if(typeof chunk == 'string')
{
if(chunk.includes('[') && chunk.includes('] '))
{
message = chunk.substring(chunk.split('] ')[0].length + 2);
}
if(typeof message == 'string' && message.includes('at '))
{
var p = message.split('at ')[1];
if(p.includes('\n'))
{
p = p.split('\n')[0];
}
if(p.includes('(') && p.includes(':'))
{
scriptPath = p.split('(')[1].split(':')[0];
}
var s = (p.match(/\//g) || []).length;
if(s > 0 && p.includes(':'))
{
p = p.split('/')[s];
reference = { script : p.split(':')[0], row : p.split(':')[1] };
}
}
}
if(logger != null && scriptPath != null && reference != null && scriptPath.includes(path.resolve(__dirname, '../..') + '/'))
{
logger.log('error', 'bridge', 'Bridge', message, '( [' + reference.script + '] %error[1]% [' + reference.row + '] )');
chunk = '';
}
return originalStderrWrite(chunk, encoding, callback);
};
module.exports = class Logger
{
constructor(platform)
{
logger = this;
this.query = [];
this.LanguageSwitcher = new LanguageSwitcher(platform.language || 'en');
this.options = platform.config.log;
if(platform.pluginName != null)
{
this.pluginName = platform.pluginName;
}
else
{
this.log('warn', 'bridge', 'Bridge', '%missing_plugin_name%!');
}
}
setLogDirectory(logDirectory)
{
if(logDirectory != null)
{
this.logDirectory = logDirectory;
setTimeout(() => this._removeExpired(), 60000);
this.expiredInterval = setInterval(() => this._removeExpired(), 3600 * 1000);
}
}
log(level, id, letters)
{
var messages = [ ...arguments ];
messages.splice(0, 3);
if(this.options == null || this.options[level] == null || this.options[level] == true)
{
var color = '';
if(level == 'success')
{
color = '\x1b[92m';
}
else if(level == 'update')
{
color = '\x1b[96m';
}
else if(level == 'read')
{
color = '\x1b[36m';
}
else if(level == 'info')
{
color = '\x1b[93m';
}
else if(level == 'warn')
{
color = '\x1b[93m';
}
else if(level == 'debug')
{
color = '\x1b[35m';
}
else
{
color = '\x1b[31m';
}
for(const i in messages)
{
if(typeof messages[i] == 'string')
{
messages[i] = this.manageLanguage(messages[i]);
}
}
if(level == 'error')
{
console.log('[' + this.pluginName + '] ' + color + '[' + level.toUpperCase() + ']\x1b[0m', messages[0]);
for(var i = 1; i < messages.length; i++)
{
console.log(messages[i]);
}
}
else
{
console.log('[' + this.pluginName + '] ' + color + '[' + level.toUpperCase() + ']\x1b[0m', ...messages);
}
this._saveLog(level[0].toUpperCase() + level.substring(1), id, letters, Math.round(new Date().getTime() / 1000), messages);
}
}
err(error)
{
if(error instanceof Object && error.message != null && error.stack != null)
{
var reference, stack = error.stack.split('\n');
stack.splice(0, 1);
stack = stack.join('\n');
if(error.stack.includes('at '))
{
var p = error.stack.split('at ')[1];
if(p.includes('\n'))
{
p = p.split('\n')[0];
}
var s = (p.match(/\//g) || []).length;
if(s > 0 && p.includes(':'))
{
p = p.split('/')[s];
reference = { script : p.split(':')[0], row : p.split(':')[1] };
}
}
if(reference != null)
{
this.log('error', 'bridge', 'Bridge', '%error[0]%: ' + error.message + ' ( [' + reference.script + '] %error[1]% [' + reference.row + '] )', stack);
}
else
{
this.log('error', 'bridge', 'Bridge', '%error[0]%: ' + error.message, stack);
}
}
else
{
this.log('error', 'bridge', 'Bridge', error);
}
}
debug(message)
{
this.log('debug', 'bridge', 'Bridge', message);
}
load(pluginName, group)
{
return new Promise((resolve) => {
if(this.logDirectory != null && pluginName != null)
{
fs.readFile(path.join(this.logDirectory, pluginName + '.txt'), (err, data) => {
if(data && !err)
{
data = data.toString();
data = data.replace(/"/g, "'");
var parts = data.split('#\n');
parts.pop();
if(group != null)
{
var search = [];
for(const part of parts)
{
if(part.split('[')[2] != null && part.split('[')[2].split(']')[0] == group)
{
search.push(part);
}
}
resolve(search.reverse());
}
else
{
resolve(parts.reverse());
}
}
else
{
resolve(null);
}
});
}
else
{
resolve(null);
}
});
}
manageLanguage(message)
{
var converted = message;
if(this.LanguageSwitcher != null && message != null)
{
if(message.includes('%'))
{
for(var i = 0; i < (message.match(/%/g) || []).length; i += 2)
{
var param = message.split('%')[i + 1].split('%')[0];
var found = false;
for(let phrase in this.LanguageSwitcher.language)
{
var replacement = this.LanguageSwitcher.language[phrase];
var search = param;
if(param.includes('[') && param.includes(']'))
{
replacement = replacement[param.split('[')[1].split(']')[0]];
search = param.split('[')[0];
}
if(phrase == search)
{
converted = converted.replace('%' + param + '%', replacement);
found = true;
}
}
if(!found)
{
i--;
}
}
}
}
return converted;
}
_saveLog(level, id, letters, time, messages)
{
if(this.logDirectory != null && this.pluginName != null)
{
var data = '[' + time + '][' + id + '][' + letters + '][' + level + '] ';
try
{
for(const i in messages)
{
if(i != 0)
{
data += '\n';
}
if(typeof messages[i] != 'string')
{
data += JSON.stringify(messages[i]);
}
else
{
data += messages[i];
}
}
data += '#\n';
if(!this.removeExpired)
{
fs.appendFileSync(path.join(this.logDirectory, this.pluginName + '.txt'), data, 'utf8');
}
else
{
this.query.push(data);
}
}
catch(e)
{
console.log(e);
}
}
}
_removeExpired()
{
if(this.logDirectory != null && this.pluginName != null)
{
this.removeExpired = true;
fs.readFile(path.join(this.logDirectory, this.pluginName + '.txt'), (err, data) => {
if(data && !err)
{
var newData = '';
data = data.toString();
var parts = data.split('#\n');
for(const part of parts)
{
if(part != '')
{
var time = part.split('[')[1].split(']')[0];
if(new Date() - new Date(time * 1000) < 86400000)
{
newData += part + '#\n';
}
}
}
if(newData != '')
{
fs.writeFile(path.join(this.logDirectory, this.pluginName + '.txt'), newData, (err) => {
if(err)
{
logger.log('error', 'bridge', 'Bridge', path.join(this.logDirectory, this.pluginName + '.txt') + ' %update_error%');
}
this._clearQuery();
});
}
else
{
this._clearQuery();
}
}
else
{
this._clearQuery();
}
});
}
}
_clearQuery()
{
this.removeExpired = false;
for(const query of this.query)
{
fs.appendFileSync(path.join(this.logDirectory, this.pluginName + '.txt'), query, 'utf8');
}
this.query = [];
}
}