@clickup/pg-microsharding
Version:
Microshards support for PostgreSQL
169 lines • 5.7 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.stdlog = exports.stderr = exports.stdout = exports.TMP_DIR = void 0;
exports.progress = progress;
exports.print = print;
exports.log = log;
const fs_1 = require("fs");
const stream_1 = require("stream");
const util_1 = require("util");
const chalk_1 = __importDefault(require("chalk"));
const log_update_1 = __importDefault(require("log-update"));
const dateToStr_1 = require("./dateToStr");
const prependDate_1 = require("./prependDate");
const stripPassword_1 = require("./stripPassword");
/** The directory to write the data and log files to. */
exports.TMP_DIR = `/tmp/pg-microsharding.${process.getuid()}`;
(0, fs_1.mkdirSync)(exports.TMP_DIR, { recursive: true, mode: 0o700 });
/**
* A helper class to easier mock output in unit tests.
*/
class StdWritable extends stream_1.PassThrough {
constructor(std) {
var _a, _b;
super();
this.std = std;
this.pipe(this.std);
if (!this.columns && parseInt((_a = process.env["COLUMNS"]) !== null && _a !== void 0 ? _a : "")) {
this.columns = parseInt(process.env["COLUMNS"]);
}
if (!this.rows && parseInt((_b = process.env["ROWS"]) !== null && _b !== void 0 ? _b : "")) {
this.rows = parseInt(process.env["ROWS"]);
}
}
get rows() {
return this.std.rows;
}
get columns() {
return this.std.columns;
}
set rows(rows) {
this.std.rows = rows;
}
set columns(columns) {
this.std.columns = columns;
}
}
/**
* A helper class to write messages to a log file.
*/
class FileLogWritable extends stream_1.Transform {
constructor() {
super({
transform: (chunk, _encoding, callback) => callback(null, (0, util_1.stripVTControlCharacters)(String(chunk))),
});
// Swallow the data, until pipeToNewLogFile() is called.
this.pipe(new FileLogWritable.Writable({ write: (_, __, callback) => callback() }));
}
pipeToNewLogFile(key) {
const fileName = `${exports.TMP_DIR}/${(0, dateToStr_1.dateToStr)(new Date())}.${key}.log`;
const file = (0, fs_1.createWriteStream)(fileName, { flags: "a" });
this.pipe(file);
return async () => new Promise((resolve) => {
this.unpipe(file);
file.end(resolve);
});
}
}
/** Use instead of process.stdout. */
exports.stdout = new StdWritable(process.stdout);
/** Use instead of process.stderr. */
exports.stderr = new StdWritable(process.stderr);
/** The messages are also logged to this stream. By default, they are swallowed.
* The caller may pipe it to a file if needed.*/
exports.stdlog = new FileLogWritable();
// A log-update engine. We use stderr, to not pollute the output when --json
// flag is used for instance.
const progressObj = log_update_1.default.create(exports.stderr, { showCursor: true });
// Last unique lines written with progress().
const progressLoggedLines = new Set();
/**
* Logs erasable (or persistent) progress message prepended with the timestamp.
* The unique lines of the message are also written to the file log.
*/
function progress(...lines) {
progress.unlogged(...lines);
const linesToLog = lines.filter((line) => !progressLoggedLines.has(line) && line.trim());
if (linesToLog.length > 0) {
exports.stdlog.write((0, stripPassword_1.stripPassword)((0, prependDate_1.prependDate)(linesToLog)) + "\n");
}
progressLoggedLines.clear();
for (const line of lines) {
progressLoggedLines.add(line);
}
}
/**
* Same as progress(), but does not write to the file log.
*/
progress.unlogged = (...lines) => {
progressObj((0, stripPassword_1.stripPassword)((0, prependDate_1.prependDate)(lines)));
};
/**
* Clears the progress.
*/
progress.clear = () => {
progressObj.clear();
progressLoggedLines.clear();
};
/**
* Persists the progress on screen.
*/
progress.done = () => {
progressObj.done();
progressLoggedLines.clear();
};
/**
* Clears the progress and prints the raw message to console and to log file.
*/
function print(msg) {
progress.done();
const str = (0, stripPassword_1.stripPassword)(msg) + "\n";
exports.stdout.write(str);
exports.stdlog.write(str);
}
/**
* Same as print(), but uses bold font.
*/
print.section = (msg) => {
print(chalk_1.default.bold(msg));
};
/**
* Same as print(), but prepends the current date and time. The message is also
* written to the log file.
*/
function log(...lines) {
print((0, prependDate_1.prependDate)(lines));
}
/**
* Same as log() (i.e. with date/time prepended), but in red.
*/
log.warning = (...lines) => {
print(chalk_1.default.yellow((0, prependDate_1.prependDate)(lines)));
};
/**
* Same as log() (i.e. with date/time prepended), but in red.
*/
log.error = (...lines) => {
print(chalk_1.default.red((0, prependDate_1.prependDate)(lines)));
};
/**
* Logs details about the upcoming runShell() execution.
*/
log.shellCmd = ({ comment, cmd, input, isError = false, }) => {
var _a;
if (!comment.match(/[!?.:]$/)) {
comment += "...";
}
log(chalk_1.default[isError ? "red" : "greenBright"](chalk_1.default.bold(comment)));
if (cmd) {
log(chalk_1.default.gray(`$ ${cmd}`));
}
input = (_a = input === null || input === void 0 ? void 0 : input.trim()) !== null && _a !== void 0 ? _a : null;
if (input) {
log(chalk_1.default.gray(input.trim()));
}
};
//# sourceMappingURL=logging.js.map