@conduitplatform/module-tools 0.17.0-alpha.7 → 0.17.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.mdx CHANGED
@@ -6,6 +6,19 @@ This library provides a framework to build micro-services in NodeJS that can be
6
6
 
7
7
  - run npm build
8
8
 
9
+ ## Logging
10
+
11
+ Modules log to stdout. When `LOKI_URL` is set, the same logs are also shipped to Loki. File logging is on unless `LOG_TO_FILE=false`.
12
+
13
+ | Variable | Default | Description |
14
+ | -------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
15
+ | `LOG_TO_FILE` | unset (on) | Set to `false` to skip file logs. Any other value, or leaving it unset, writes them. |
16
+ | `LOG_FILE_DIR` | `{tmpdir}/conduit-logs` | Directory for `combined-YYYY-MM-DD.log` and `errors-YYYY-MM-DD.log`. It is created when missing. |
17
+ | `LOG_RETENTION_DAYS` | `3` | Days of log files to keep. Older files are deleted. Non-positive or non-integer values use the default. |
18
+ | `LOG_FILE_MAX_SIZE` | `20m` | Max size of each file before a same-day size roll. Accepts `k`, `m`, or `g` suffixes, or a positive byte count. Invalid values use the default. |
19
+
20
+ Files roll once per day and are not gzipped. Metadata in file lines is single-line JSON.
21
+
9
22
  ## Features ✔️
10
23
 
11
24
  - Service registration & discovery
package/dist/index.cjs CHANGED
@@ -1283,9 +1283,84 @@ async function setupLoki(module2, instance) {
1283
1283
  }
1284
1284
  }
1285
1285
 
1286
- // src/utilities/initializeSdk.ts
1287
- var import_winston2 = __toESM(require("winston"), 1);
1286
+ // src/logging/fileTransports.ts
1287
+ var import_fs = __toESM(require("fs"), 1);
1288
+ var import_os = __toESM(require("os"), 1);
1288
1289
  var import_path2 = __toESM(require("path"), 1);
1290
+ var import_winston2 = __toESM(require("winston"), 1);
1291
+ var import_winston_daily_rotate_file = __toESM(require("winston-daily-rotate-file"), 1);
1292
+ var DEFAULT_RETENTION_DAYS = 3;
1293
+ var DEFAULT_MAX_SIZE = "20m";
1294
+ var SIZE_STRING = /^(?:0\.)?\d+[kmg]$/i;
1295
+ function positiveIntFromEnv(raw, fallback) {
1296
+ if (raw === void 0) return fallback;
1297
+ const trimmed = raw.trim();
1298
+ if (!/^[0-9]+$/.test(trimmed)) return fallback;
1299
+ const value = Number(trimmed);
1300
+ if (!Number.isSafeInteger(value) || value <= 0) return fallback;
1301
+ return value;
1302
+ }
1303
+ function logFileMaxSize() {
1304
+ const raw = process.env.LOG_FILE_MAX_SIZE?.trim();
1305
+ if (!raw) return DEFAULT_MAX_SIZE;
1306
+ if (SIZE_STRING.test(raw)) return raw.toLowerCase();
1307
+ if (/^[0-9]+$/.test(raw)) {
1308
+ const bytes = Number(raw);
1309
+ if (Number.isSafeInteger(bytes) && bytes > 0) return bytes;
1310
+ }
1311
+ return DEFAULT_MAX_SIZE;
1312
+ }
1313
+ function formatMeta(meta) {
1314
+ if (Array.isArray(meta)) {
1315
+ if (meta.length === 0) return "";
1316
+ return meta.map((item) => JSON.stringify(item)).join(" ");
1317
+ }
1318
+ if (meta !== null && typeof meta === "object") {
1319
+ if (Object.keys(meta).length === 0) return "";
1320
+ return JSON.stringify(meta);
1321
+ }
1322
+ return "";
1323
+ }
1324
+ function createFileFormat() {
1325
+ return import_winston2.default.format.combine(
1326
+ import_winston2.default.format.errors({ stack: true }),
1327
+ import_winston2.default.format.timestamp({
1328
+ format: "YYYY-MM-DD HH:mm:ss"
1329
+ }),
1330
+ import_winston2.default.format.printf((info) => {
1331
+ const metaText = formatMeta(info.meta);
1332
+ const line = `[${info.timestamp}] [${info.level.toUpperCase()}]: ${info.message}`;
1333
+ if (info.stack) {
1334
+ return `${line} ${info.stack}`;
1335
+ }
1336
+ return metaText ? `${line} ${metaText}` : line;
1337
+ })
1338
+ );
1339
+ }
1340
+ function rotateTransport(logDir, name, level) {
1341
+ return new import_winston_daily_rotate_file.default({
1342
+ dirname: logDir,
1343
+ filename: `${name}-%DATE%.log`,
1344
+ datePattern: "YYYY-MM-DD",
1345
+ level,
1346
+ maxFiles: `${positiveIntFromEnv(process.env.LOG_RETENTION_DAYS, DEFAULT_RETENTION_DAYS)}d`,
1347
+ maxSize: logFileMaxSize(),
1348
+ zippedArchive: false,
1349
+ auditFile: import_path2.default.join(logDir, `.${name}-audit.json`),
1350
+ format: createFileFormat()
1351
+ });
1352
+ }
1353
+ function createFileLogTransports() {
1354
+ if (process.env.LOG_TO_FILE?.trim() === "false") {
1355
+ return [];
1356
+ }
1357
+ const logDir = process.env.LOG_FILE_DIR?.trim() || import_path2.default.join(import_os.default.tmpdir(), "conduit-logs");
1358
+ import_fs.default.mkdirSync(logDir, { recursive: true });
1359
+ return [
1360
+ rotateTransport(logDir, "combined", "info"),
1361
+ rotateTransport(logDir, "errors", "error")
1362
+ ];
1363
+ }
1289
1364
 
1290
1365
  // src/metrics/index.ts
1291
1366
  var import_prom_client = require("prom-client");
@@ -1674,17 +1749,9 @@ function clientMiddleware() {
1674
1749
  var initializeSdk = (coreUrl, moduleName, watchModules = true, serviceHealthStatusGetter = () => import_grpc_sdk13.HealthCheckStatus.SERVING) => {
1675
1750
  let logger;
1676
1751
  try {
1677
- logger = new ConduitLogger([
1678
- new import_winston2.default.transports.File({
1679
- filename: import_path2.default.join(__dirname, ".logs/combined.log"),
1680
- level: "info"
1681
- }),
1682
- new import_winston2.default.transports.File({
1683
- filename: import_path2.default.join(__dirname, ".logs/errors.log"),
1684
- level: "error"
1685
- })
1686
- ]);
1687
- } catch (e) {
1752
+ const fileTransports = createFileLogTransports();
1753
+ logger = fileTransports.length > 0 ? new ConduitLogger(fileTransports) : new ConduitLogger();
1754
+ } catch {
1688
1755
  logger = new ConduitLogger();
1689
1756
  }
1690
1757
  const grpcSdk = new import_grpc_sdk13.ConduitGrpcSdk(