/* * @project: TERA * @version: Development (beta) * @license: MIT (not for evil) * @copyright: Yuriy Ivanov (Vtools) 2017-2019 [progr76@gmail.com] * Web: https://terafoundation.org * Twitter: https://twitter.com/terafoundation * Telegram: https://t.me/terafoundation */ require("./constant.js"); var fs = require('fs'); require("./log-strict.js"); var file_name_info = global.GetDataPath("info.log"); var file_name_infoPrev = global.GetDataPath("info-prev.log"); global.CheckSizeLogFile(file_name_info, file_name_infoPrev); var file_name_log = global.GetDataPath("log.log"); var file_name_logPrev = global.GetDataPath("log-prev.log"); global.CheckSizeLogFile(file_name_log, file_name_logPrev); var file_name_log_web = global.GetDataPath("web.log"); var file_name_log_webPrev = global.GetDataPath("web-prev.log"); global.CheckSizeLogFile(file_name_log_web, file_name_log_webPrev); var file_name_error = global.GetDataPath("err.log"); var file_name_errorPrev = global.GetDataPath("err-prev.log"); global.CheckSizeLogFile(file_name_error, file_name_errorPrev); var file_name_error_tx = global.GetDataPath("err-tx.log"); var file_name_error_txPrev = global.GetDataPath("err-tx-prev.log"); global.CheckSizeLogFile(file_name_error_tx, file_name_error_txPrev); global.ToLog = function(Str, Level) { if (Level === undefined) Level = 1; if (Level && Level > global.LOG_LEVEL) return; if (global.ALL_LOG_TO_CLIENT) ToLogClient(Str, undefined, undefined); else ToLogFile(file_name_log, Str); }; global.WEB_LOG = 0; global.ToLogWeb = function(Str) { if (global.WEB_LOG) { SaveToLogFileSync(file_name_log_web, Str); } }; global.SmallAddr = function(Str) { return Str.substr(0, 5); }; global.ToErrorTrace = function(Str) { global.ToError("" + Str + ":" + new Error().stack); }; global.ToLogTrace = function(Str) { global.ToErrorTrace(Str); }; global.ToInfo = function(Str) { ToLogFile(file_name_info, Str, 1); }; global.ToError = function(Str) { ToLogFile(file_name_error, Str); }; global.ToErrorTx = function(Str) { SaveToLogFileSync(file_name_error_tx, Str); global.ToLog(Str); }; function ToLogFile(file_name, Str, bNoFile?) { if (Str instanceof Error) { Str = Str.message + "\n" + Str.stack; } if (!global.START_SERVER) Str = global.PROCESS_NAME + ": " + Str; if (global.PROCESS_NAME !== "MAIN" && process.send) { process.send({ cmd: "log", message: Str }); return; } else { console.log("" + global.START_PORT_NUMBER + ": " + global.GetStrOnlyTime() + ": " + Str); } if (bNoFile) return; SaveToLogFileSync(file_name, Str); }; global.ArrLogClient = []; function ToLogClient(Str, StrKey, bFinal) { if (!Str) return; ToLogFile(file_name_log, Str); if (!StrKey) StrKey = ""; global.ArrLogClient.push({ text: global.GetStrOnlyTime() + " " + Str, key: StrKey, final: bFinal, }); if (global.ArrLogClient.length > 13) global.ArrLogClient.shift(); }; global.ToLogClient = ToLogClient; global.ToLogClient0 = ToLogClient; var StartStatTime; var CONTEXT_STATS = { Total: {}, Interval: [] }; var CONTEXT_ERRORS = { Total: {}, Interval: [] }; var CurStatIndex = 0; global.PrepareStatEverySecond = function() { CurStatIndex++; var index = GetCurrentStatIndex(); CopyStatInterval(CONTEXT_STATS, index); CopyStatInterval(CONTEXT_ERRORS, index); }; global.TO_ERROR_LOG = function(Module, ErrNum, Str, type, data1, data2) { if (Str instanceof Error) { Str = Str.message + "\n"; } if (type === "rinfo") Str += " from: " + data1.address + ':' + data1.port; else if (type === "node") Str += " from: " + data1.ip + ':' + data1.port; var Key = Module + ":" + ErrNum; global.ToError(" ==ERROR== " + Key + " " + Str); AddToStatContext(CONTEXT_ERRORS, Key); global.ADD_TO_STAT("ERRORS"); }; function GetCurrentStatIndex() { var DefMaxStatPeriod = global.MAX_STAT_PERIOD * 2 + 2; return CurStatIndex % DefMaxStatPeriod; }; global.HASH_RATE = 0; global.ADD_HASH_RATE = function(Count) { Count = Count / 1000000; global.HASH_RATE += Count; global.ADD_TO_STAT("HASHRATE", Count); }; global.GET_STAT = function(Key) { var Val = CONTEXT_STATS.Total[Key]; if (!Val) Val = 0; return Val; }; global.ADD_TO_STAT_TIME = function(Name, startTime, bDetail) { if (global.STAT_MODE) { if (bDetail && global.STAT_MODE !== 2) return; var Time = process.hrtime(startTime); var deltaTime = Time[0] * 1000 + Time[1] / 1e6; global.ADD_TO_STAT(Name, deltaTime); } }; global.ADD_TO_STAT = function(Key, Count, bDetail) { if (global.STAT_MODE) { if (bDetail && global.STAT_MODE !== 2) return; AddToStatContext(CONTEXT_STATS, Key, Count); } }; global.GET_STATDIAGRAMS = function(Keys) { var now = global.GetCurrentTime(); var index = GetCurrentStatIndex(); if (!Keys || !Keys.length) return []; var Data = []; for (var i = 0; i < Keys.length; i++) { var name = Keys[i]; var Value = GetDiagramData(CONTEXT_STATS, name); Data.push({ name: name, maxindex: index, arr: Value, starttime: (StartStatTime - 0), steptime: 1 }); } var MinLength = undefined; for (var i = 0; i < Data.length; i++) { var arr = Data[i].arr; if (arr.length > 0 && (MinLength === undefined || arr.length < MinLength)) MinLength = arr.length; } var MaxSizeArr = 500; for (var i = 0; i < Data.length; i++) { var ItemServer = Data[i]; var arr = ItemServer.arr; if (MinLength && arr.length > MinLength) { arr = arr.slice(arr.length - MinLength); } if (MinLength) if (",POWER_MY_WIN,POWER_BLOCKCHAIN,".indexOf("," + ItemServer.name + ",") >= 0) { arr = global.SERVER.GetStatBlockchain(ItemServer.name, MinLength); } var AvgValue = 0; for (var j = 0; j < arr.length; j++) { if (arr[j]) AvgValue += arr[j]; } if (arr.length > 0) AvgValue = AvgValue / arr.length; var StepTime = 1; if (ItemServer.name.substr(0, 4) === "MAX:") { while (arr.length >= MaxSizeArr) { arr = ResizeArrMax(arr); StepTime = StepTime * 2; } } else { while (arr.length >= MaxSizeArr) { arr = ResizeArrAvg(arr); StepTime = StepTime * 2; } } ItemServer.AvgValue = AvgValue; ItemServer.steptime = StepTime; ItemServer.arr = arr.slice(1); } return Data; }; global.GET_STATS = function(Key) { var now = global.GetCurrentTime(); var index = GetCurrentStatIndex(); var stats = { Counter: CONTEXT_STATS.Total, Counter10S: CalcInterval(CONTEXT_STATS, index, 10), Counter10M: CalcInterval(CONTEXT_STATS, index, 10 * 60), }; var errors = { Counter: CONTEXT_ERRORS.Total, Counter10S: CalcInterval(CONTEXT_ERRORS, index, 10), Counter10M: CalcInterval(CONTEXT_ERRORS, index, 10 * 60), }; var Period = (now - StartStatTime) / 1000; return { stats: stats, errors: errors, period: Period, Confirmation: [] }; }; global.StartCommonStat = function() { for (var key in CONTEXT_STATS.Total) return; global.ClearCommonStat(); }; global.ClearCommonStat = function() { CurStatIndex = 0; StartStatTime = undefined; CONTEXT_STATS = { Total: {}, Interval: [] }; CONTEXT_ERRORS = { Total: {}, Interval: [] }; global.HASH_RATE = 0; global.SERVER.ClearStat(); }; function ResizeArrMax(arr) { var arr2 = []; var Count2 = Math.trunc(arr.length / 2); for (var i = 0; i < Count2; i++) { arr2[i] = Math.max(arr[i * 2], arr[i * 2 + 1]); } return arr2; }; function ResizeArrAvg(arr) { var arr2 = []; var Count2 = Math.trunc(arr.length / 2); for (var i = 0; i < Count2; i++) { arr2[i] = (arr[i * 2] + arr[i * 2 + 1]) / 2; } return arr2; }; function ResizeArr(arr) { var arr2 = []; var Count2 = Math.trunc(arr.length / 2); for (var i = 0; i < Count2; i++) { arr2[i] = arr[i * 2]; } return arr2; }; global.ResizeArrAvg = ResizeArrAvg; global.ResizeArrMax = ResizeArrMax; function GetDiagramData(Context, Key) { var DefMaxStatPeriod = global.MAX_STAT_PERIOD * 2 + 2; var IsMax; if (Key.substr(0, 4) === "MAX:") IsMax = true; else IsMax = false; var delta = global.MAX_STAT_PERIOD; var index2 = GetCurrentStatIndex(); var index1 = (index2 - delta + DefMaxStatPeriod) % DefMaxStatPeriod; var Total = Context.Total; var Counter1; var arr = []; var PrevValue = undefined; for (var i = index1; i < index1 + delta; i++) { var index3 = i % DefMaxStatPeriod; Counter1 = Context.Interval[index3]; if (Counter1) { var Value = Counter1[Key]; if (Value !== undefined) { if (!IsMax) { if (PrevValue !== undefined) { arr.push(Value - PrevValue); } else { arr.push(Value); } PrevValue = Value; } else { arr.push(Value); } } else { arr.push(0); } } } return arr; }; function CalcInterval(Context, index2, delta) { var DefMaxStatPeriod = global.MAX_STAT_PERIOD * 2 + 2; var Res = {}; var index1 = (index2 - delta + DefMaxStatPeriod) % DefMaxStatPeriod; var Total = Context.Total; var Counter1; for (var i = index1; i < index1 + delta; i++) { var index3 = i % DefMaxStatPeriod; Counter1 = Context.Interval[index3]; if (Counter1) break; } if (Counter1) for (var Key in Total) { if (Key.substr(0, 4) === "MAX:") Res[Key] = 0; else { if (Counter1[Key] === undefined) Res[Key] = Total[Key]; else Res[Key] = Total[Key] - Counter1[Key]; } } return Res; }; function AddToStatContext(Context, Key, AddValue?) { if (AddValue === undefined) AddValue = 1; var Val = Context.Total[Key]; if (!Val) Val = 0; if (Key.substr(0, 4) === "MAX:") Val = Math.max(Val, AddValue); else Val = Val + AddValue; Context.Total[Key] = Val; if (!StartStatTime) StartStatTime = global.GetCurrentTime(0); }; function CopyStatInterval(Context, index) { var Counter = Context.Interval[index]; if (!Counter) { Counter = {}; Context.Interval[index] = Counter; } var Total = Context.Total; for (var Key in Total) { Counter[Key] = Total[Key]; if (Key.substr(0, 4) === "MAX:") Total[Key] = 0; } }; if (global.DEBUG_MODE) global.TO_DEBUG_LOG = function(Str, type, data1, data2) { if (!global.DEBUG_MODE) return; if (type === "rinfo") Str += " from: " + data1.address + ':' + data1.port + ' - ' + data2.length; global.ToLog(Str); }; else global.TO_DEBUG_LOG = function(Str, type, data1, data2) { }; function SaveToLogFileAsync(fname, Str) { fs.open(fname, "a", undefined, function(err, file_handle) { if (!err) { var StrLog = global.GetStrTime() + " : " + Str + "\r\n"; fs.write(file_handle, StrLog, null, 'utf8', function(err, written) { if (!err) { fs.close(file_handle, function(err) { if (err) console.log(err); }); } else { console.log("Ошибка записи в лог-файл ошибок!"); } }); } else { console.log("Ошибка открытия лог-файла ошибок"); } }); }; function SaveToLogFileSync(fname, Str) { try { var StrLog = global.GetStrTime() + " : " + Str + "\r\n"; var file_handle = fs.openSync(fname, "a"); fs.writeSync(file_handle, StrLog, null, 'utf8'); fs.closeSync(file_handle); } catch (err) { console.log(err.message); } }; global.GetStrOnlyTime = function(now) { if (!global.GetCurrentTime) return ":::"; if (!now) now = global.GetCurrentTime(); var Str = "" + now.getHours().toStringZ(2); Str = Str + ":" + now.getMinutes().toStringZ(2); Str = Str + ":" + now.getSeconds().toStringZ(2); Str = Str + "." + now.getMilliseconds().toStringZ(3); return Str; }; global.GetStrTime = function(now) { if (!global.GetCurrentTime) return ":::"; if (!now) now = global.GetCurrentTime(); var Str = "" + now.getDate().toStringZ(2); Str = Str + "." + (1 + now.getMonth()).toStringZ(2); Str = Str + "." + now.getFullYear(); Str = Str + " " + now.getHours().toStringZ(2); Str = Str + ":" + now.getMinutes().toStringZ(2); Str = Str + ":" + now.getSeconds().toStringZ(2); Str = Str + "." + now.getMilliseconds().toStringZ(3); return Str; };