rrdtool.ts
Version:
RRDTool High Level library for Node.js written in TypeScript
106 lines (105 loc) • 4.07 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const debug = require("debug")("rrdtool:proc");
const child_process_1 = __importDefault(require("child_process"));
const util_1 = require("./util");
const exec = async (args) => new Promise((resolve, reject) => {
debug(["rrdtool"].concat(args).join(" "));
const stdout = [];
const stderr = [];
const p = child_process_1.default.spawn("rrdtool", args, { env: { LANG: "C" } });
p.stdout.on("data", chunk => stdout.push(chunk));
p.stderr.on("data", chunk => stderr.push(chunk));
p.on("close", code => {
if (code !== 0) {
const str = Buffer.concat(stderr).toString();
const err = new Error(str.replace(/^ERROR: /, ""));
return reject(err);
}
return resolve(Buffer.concat(stdout).toString());
});
});
const create = async (filename, definitions, o) => {
const opts = [];
// rrdtool dosen't allow inserting a value onto
// the start date. Decrese it by one so we can do that.
if (o === null || o === void 0 ? void 0 : o.start)
opts.push(`--start ${o.start - 1}`);
if (o === null || o === void 0 ? void 0 : o.step)
opts.push(`--step ${o.step}`);
if (!(o === null || o === void 0 ? void 0 : o.overwrite))
opts.push("--no-overwrite");
if (o === null || o === void 0 ? void 0 : o.templateFile)
opts.push(`--template ${o.templateFile}`);
if (o === null || o === void 0 ? void 0 : o.sourceFile)
opts.push(`--source ${o.sourceFile}`);
exec(["create", filename, ...opts, ...definitions]);
};
const dump = async (filename) => {
// XXX: output file and --header?
return exec(["dump", filename]);
};
const fetch = async (filename, cf, o) => {
const opts = [];
// rrdtool counts timestamp very strange, hence the -1
if (o === null || o === void 0 ? void 0 : o.start)
opts.push(`--start ${o.start - 1}`);
if (o === null || o === void 0 ? void 0 : o.end)
opts.push(`--end ${o.end - 1}`);
if (o === null || o === void 0 ? void 0 : o.resolution)
opts.push(`--resolution ${o.resolution}`);
if (o === null || o === void 0 ? void 0 : o.alignStart)
opts.push("--align-start");
const data = await exec(["fetch", filename, cf, ...opts]);
const rows = data.trim().split("\n");
const header = rows[0].trim().split(/ +/);
const parseRow = (row) => {
const [t, d] = row.split(":");
return {
ts: Number(t),
values: d.trim().split(/ +/).reduce((p, c, i) => {
const n = Number(c);
if (!Number.isNaN(n)) {
p[header[i]] = n;
}
return p;
}, {}),
};
};
return rows.slice(2).map(parseRow);
};
const info = async (filename) => {
// XXX: --noflush?
const str = await exec(["info", filename]);
return (0, util_1.parseInfo)(str);
};
const last = async (filename) => {
return Number(await exec(["last", filename]));
};
// XXX: lastUpdate
const update = async (filename, values, o) => {
const template = [];
const data = [(o === null || o === void 0 ? void 0 : o.timestamp) || "N"]; // XXX: "N" if no timestamp?
for (const key of Object.keys(values)) {
const v = values[key];
if (v === undefined)
continue;
data.push(v);
template.push(key);
}
const opts = ["--template", template.join(":")];
if (o === null || o === void 0 ? void 0 : o.skipPastUpdates)
opts.push(`--skip-past-updates`);
exec([(o === null || o === void 0 ? void 0 : o.verbose) ? "updatev" : "update", filename, ...opts, data.join(":")]);
};
exports.default = {
create,
dump,
fetch,
info,
last,
update,
};