@iobroker/js-controller-common-db
Version:
The Library contains the common utils for the ioBroker controller which can be used by db classes too, as they do not rely on the db (circular dependencies).
365 lines (364 loc) • 15.1 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var logger_exports = {};
__export(logger_exports, {
logger: () => logger
});
module.exports = __toCommonJS(logger_exports);
var import_winston = __toESM(require("winston"), 1);
var import_winston_daily_rotate_file = __toESM(require("winston-daily-rotate-file"), 1);
var import_node_fs = __toESM(require("node:fs"), 1);
var import_node_path = __toESM(require("node:path"), 1);
var import_node_os = __toESM(require("node:os"), 1);
var tools = __toESM(require("../../lib/common/tools.js"), 1);
var import_winston_transport = __toESM(require("winston-transport"), 1);
var import_triple_beam = require("triple-beam");
var import_deep_clone = __toESM(require("deep-clone"), 1);
var url = __toESM(require("node:url"), 1);
var import_node_module = require("node:module");
const import_meta = {};
const thisDir = url.fileURLToPath(new URL(".", import_meta.url || `file://${__filename}`));
const require2 = (0, import_node_module.createRequire)(import_meta.url || `file://${__filename}`);
const hostname = tools.getHostName();
let SysLog;
try {
SysLog = require2("winston-syslog").Syslog;
} catch {
}
let Seq;
try {
Seq = require2("@datalust/winston-seq").SeqTransport;
} catch {
}
const IoSysLog = SysLog && class extends SysLog {
constructor(options) {
super(options);
}
log(info, callback) {
const ioInfo = info;
if (ioInfo[import_triple_beam.LEVEL] === "warn") {
ioInfo[import_triple_beam.LEVEL] = "warning";
}
if (ioInfo[import_triple_beam.LEVEL] === "info") {
ioInfo[import_triple_beam.LEVEL] = "notice";
}
if (ioInfo[import_triple_beam.LEVEL] === "debug") {
ioInfo[import_triple_beam.LEVEL] = "info";
}
if (ioInfo[import_triple_beam.LEVEL] === "silly") {
ioInfo[import_triple_beam.LEVEL] = "debug";
}
super.log?.(ioInfo, callback);
}
};
const IoSeq = Seq && class extends Seq {
log(info, callback) {
const ioInfo = (0, import_deep_clone.default)(info);
ioInfo.props = ioInfo.props || {};
const level = (ioInfo.level || "").toLowerCase();
if (level.includes("error")) {
ioInfo.level = "Error";
} else if (level.includes("warn")) {
ioInfo.level = "Warning";
} else if (level.includes("info")) {
ioInfo.level = "Information";
} else if (level.includes("debug")) {
ioInfo.level = "Debug";
} else if (level.includes("silly")) {
ioInfo.level = "Verbose";
} else {
ioInfo.level = "Information";
}
ioInfo.props.Hostname = tools.getHostName();
if (ioInfo.message) {
const msgParts = ioInfo.message.match(/^([^.]+\.[0-9]+) \(([^)]+)\) (.*)$/s);
if (msgParts) {
ioInfo.props.Source = msgParts[1];
ioInfo.props.Pid = msgParts[2];
} else {
ioInfo.props.Source = "js-controller";
}
}
super.log(ioInfo, callback);
}
};
class NotifierTransport extends import_winston_transport.default {
name;
constructor(opts) {
super(opts);
this.name = "NT";
}
log(info, callback) {
const msg = {
severity: info[import_triple_beam.LEVEL],
ts: new Date(info.timestamp).getTime(),
message: info.message
};
setImmediate(() => this.emit("logged", msg));
callback();
}
}
function logger(level, files, noStdout, prefix) {
const options = {
transports: []
};
if (typeof files === "string") {
files = [files];
}
const formatter = (info) => `${timestamp(info.timestamp)} - ${info.level}: ${info.message}`;
files = files || [];
const isNpm = !thisDir.replace(/\\/g, "/").toLowerCase().includes(`${tools.appName.toLowerCase()}.js-controller/packages/`);
if (tools.isObject(level)) {
const userOptions = (0, import_deep_clone.default)(level);
level = userOptions.level;
prefix = userOptions.prefix || "";
noStdout = userOptions.noStdout;
const winstonFormats = [];
winstonFormats.push(import_winston.default.format.timestamp({ format: timestamp }));
if (userOptions.json === void 0 || userOptions.json) {
winstonFormats.push(import_winston.default.format.json());
}
if (prefix) {
winstonFormats.push(import_winston.default.format.label({ label: prefix }));
}
if (userOptions.colorize === void 0 || userOptions.colorize) {
winstonFormats.push(import_winston.default.format.colorize());
}
options.format = import_winston.default.format.combine.apply(null, winstonFormats);
if (userOptions.prefix !== void 0) {
delete userOptions.prefix;
}
if (userOptions.transport) {
let fName = 0;
const isWindows = import_node_os.default.platform().startsWith("win");
for (const transport of Object.values(userOptions.transport)) {
transport._defaultConfigLoglevel = transport.level;
transport.level = transport.level || level;
if (transport.type === "file" && transport.enabled !== false) {
transport.filename = transport.filename || `log/${tools.appName}`;
if (!transport.fileext && transport.filename.indexOf(".log") === -1) {
transport.fileext = ".log";
}
if (!fName) {
transport.systemLog = true;
}
transport.handleExceptions = false;
transport.name = fName ? `dailyRotateFile${fName}` : tools.appName;
fName++;
transport.filename = transport.filename.replace(/\\/g, "/");
if (transport.filename.match(/^\w:\/|^\//)) {
transport.filename = import_node_path.default.normalize(transport.filename);
} else {
transport.filename = import_node_path.default.normalize(`${tools.getControllerDir()}${isNpm ? "/../../" : "/"}${transport.filename}`);
}
transport.auditFile = `${transport.filename}-audit.json`;
transport.createSymlink = transport.createSymlink !== void 0 ? transport.createSymlink : !isWindows;
transport.symlinkName = transport.symlinkName !== void 0 ? transport.symlinkName : import_node_path.default.basename(`${transport.filename}.current.log`);
transport.filename += `.%DATE%${transport.fileext || ""}`;
transport.silent = transport.silent !== void 0 ? transport.silent : false;
transport.localTime = transport.localTime !== void 0 ? transport.localTime : userOptions.localTime === void 0 ? true : userOptions.localTime;
transport.datePattern = "YYYY-MM-DD";
transport.format = import_winston.default.format.combine(import_winston.default.format.printf(formatter));
transport.zippedArchive = isWindows ? false : transport.zippedArchive !== void 0 ? transport.zippedArchive : true;
if (transport.maxFiles === null && userOptions.maxDays) {
transport.maxFiles = `${userOptions.maxDays}d`;
}
try {
const _log = new import_winston_daily_rotate_file.default(transport);
_log.on("error", (err) => {
console.error(`Error on log file rotation: ${err.message}`);
});
options.transports.push(_log);
} catch (e) {
if (e.code === "EACCES") {
e.code = "EACCES_LOG";
}
throw e;
}
} else if (transport.type === "syslog" && transport.enabled !== false) {
if (!IoSysLog) {
console.error("Syslog configured, but not installed! Ignore");
continue;
}
transport.localhost = transport.localhost || hostname;
transport.format = import_winston.default.format.combine(import_winston.default.format.printf(formatter));
if (transport.sysLogType) {
transport.type = transport.sysLogType;
delete transport.sysLogType;
} else {
delete transport.type;
}
try {
options.transports.push(new IoSysLog(transport));
} catch (e) {
console.error(`Cannot activate Syslog: ${e.message}`);
}
} else if (transport.type === "http" && transport.enabled !== false) {
transport.host = transport.host || "localhost";
try {
options.transports.push(new import_winston.default.transports.Http(transport));
} catch (e) {
console.error(`Cannot activate HTTP: ${e.message}`);
}
} else if (transport.type === "stream" && transport.enabled !== false) {
transport.host = transport.host || "localhost";
try {
if (typeof transport.stream === "string") {
transport.stream = import_node_fs.default.createWriteStream(transport.stream);
transport.stream.on("error", (err) => {
console.error(`Error in Stream: ${err.message}`);
});
}
options.transports.push(new import_winston.default.transports.Stream(transport));
} catch (e) {
console.error(`Cannot activate Stream: ${e.message}`);
}
} else if (transport.type === "seq" && transport.enabled !== false) {
if (!IoSeq) {
console.error("Seq configured, but not installed! Ignore");
continue;
}
if (transport.serverUrl) {
try {
transport.onError = (e) => {
console.log(`SEQ error: ${e.message}`);
};
const seqLogger = new IoSeq(transport);
options.transports.push(seqLogger);
} catch (e) {
console.error(`Cannot activate SEQ: ${e.message}`);
}
} else {
console.error("Cannot activate SEQ: No serverUrl specified");
}
}
}
}
} else {
for (let i = 0; i < files.length; i++) {
const opt = {
name: i ? `dailyRotateFile${i}` : tools.appName,
filename: import_node_path.default.normalize(isNpm ? `${thisDir}/../../../log/${files[i]}` : `${thisDir}/../log/${files[i]}`),
extension: ".log",
datePattern: "YYYY-MM-DD",
level,
silent: false,
localTime: true,
handleExceptions: false
};
options.transports.push(new import_winston_daily_rotate_file.default(opt));
}
}
if (!noStdout) {
options.transports.push(new import_winston.default.transports.Console({
level,
silent: false,
format: import_winston.default.format.combine(import_winston.default.format.printf(formatter))
}));
}
options.transports.push(new NotifierTransport({
level,
silent: false
}));
const log = import_winston.default.createLogger(options);
log.getFileName = function() {
let transport = this.transports.find((t) => t.transport && t.transport.dirname || t.dirname);
if (transport) {
transport = transport.transport ? transport.transport : transport;
return `${transport.dirname}/${transport.filename.replace("%DATE%", getDate())}`;
}
return "";
};
log.on("error", (error) => {
console.log(`Logger error: ${error.message}`);
});
log.activateDateChecker = function(isEnabled, daysCount) {
if (!isEnabled && this._fileChecker) {
clearInterval(this._fileChecker);
} else if (isEnabled && !this._fileChecker) {
if (!daysCount) {
daysCount = 3;
}
this._fileChecker = setInterval(() => {
this.transports.forEach((transport) => {
if (transport.name !== "dailyRotateFile" || !transport.options || transport.options.name !== tools.appName) {
return;
}
if (transport && import_node_fs.default.existsSync(transport.dirname)) {
let files2;
try {
files2 = import_node_fs.default.readdirSync(transport.dirname);
} catch (e) {
console.error(`host.${hostname} Cannot read log directory: ${e.message}`);
return;
}
const forXdays = new Date();
forXdays.setDate(forXdays.getDate() - daysCount - 1);
for (let i = 0; i < files2.length; i++) {
const match = files2[i].match(/.+\.(\d+-\d+-\d+)/);
if (match) {
const date = new Date(match[1]);
if (date < forXdays) {
try {
this.log({
level: "info",
message: `host.${hostname} Delete log file ${files2[i]}`
});
console.log(`host.${hostname} Delete log file ${files2[i]}`);
import_node_fs.default.unlinkSync(`${transport.dirname}/${files2[i]}`);
} catch (e) {
this.log({
level: import_node_os.default.platform().startsWith("win") ? "info" : "error",
message: `host.${hostname} Cannot delete file "${import_node_path.default.normalize(
`${transport.dirname}/${files2[i]}`
)}": ${e}`
});
console.log(`host.${hostname} Cannot delete file "${import_node_path.default.normalize(
`${transport.dirname}/${files2[i]}`
)}": ${e.message}`);
}
}
}
}
}
});
}, 36e5);
}
};
return log;
}
function getDate() {
const ts = new Date();
return `${ts.getFullYear()}-${(ts.getMonth() + 1).toString().padStart(2, "0")}-${ts.getDate().toString().padStart(2, "0")}`;
}
function timestamp(date) {
const ts = date ? new Date(date) : new Date();
return `${ts.getFullYear()}-${(ts.getMonth() + 1).toString().padStart(2, "0")}-${ts.getDate().toString().padStart(2, "0")} ${ts.getHours().toString().padStart(2, "0")}:${ts.getMinutes().toString().padStart(2, "0")}:${ts.getSeconds().toString().padStart(2, "0")}.${ts.getMilliseconds().toString().padStart(3, "0")} `;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
logger
});
//# sourceMappingURL=logger.js.map
;