@harperfast/harper 5.0.7 → 5.0.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.
Files changed (62) hide show
  1. package/bin/status.js +2 -2
  2. package/bin/stop.js +5 -6
  3. package/components/OptionsWatcher.ts +9 -1
  4. package/dataLayer/harperBridge/TableSizeObject.ts +35 -0
  5. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.ts +24 -0
  6. package/dist/bin/status.js +2 -2
  7. package/dist/bin/status.js.map +1 -1
  8. package/dist/bin/stop.js +5 -5
  9. package/dist/bin/stop.js.map +1 -1
  10. package/dist/components/OptionsWatcher.js +8 -1
  11. package/dist/components/OptionsWatcher.js.map +1 -1
  12. package/dist/dataLayer/harperBridge/TableSizeObject.d.ts +20 -0
  13. package/dist/dataLayer/harperBridge/TableSizeObject.js +32 -0
  14. package/dist/dataLayer/harperBridge/TableSizeObject.js.map +1 -0
  15. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.d.ts +6 -6
  16. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +18 -19
  17. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js.map +1 -1
  18. package/dist/resources/DatabaseTransaction.js +6 -1
  19. package/dist/resources/DatabaseTransaction.js.map +1 -1
  20. package/dist/resources/RecordEncoder.js +10 -1
  21. package/dist/resources/RecordEncoder.js.map +1 -1
  22. package/dist/resources/Table.js +13 -2
  23. package/dist/resources/Table.js.map +1 -1
  24. package/dist/resources/databases.js +2 -1
  25. package/dist/resources/databases.js.map +1 -1
  26. package/dist/resources/graphql.d.ts +3 -8
  27. package/dist/resources/graphql.js +180 -173
  28. package/dist/resources/graphql.js.map +1 -1
  29. package/dist/security/jsLoader.js +16 -2
  30. package/dist/security/jsLoader.js.map +1 -1
  31. package/dist/security/keys.js +1 -1
  32. package/dist/security/keys.js.map +1 -1
  33. package/dist/server/DurableSubscriptionsSession.js +2 -0
  34. package/dist/server/DurableSubscriptionsSession.js.map +1 -1
  35. package/dist/server/serverHelpers/serverUtilities.js +2 -2
  36. package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
  37. package/dist/utility/environment/systemInformation.d.ts +178 -49
  38. package/dist/utility/environment/systemInformation.js +359 -219
  39. package/dist/utility/environment/systemInformation.js.map +1 -1
  40. package/dist/utility/operation_authorization.js +2 -2
  41. package/dist/utility/operation_authorization.js.map +1 -1
  42. package/package.json +2 -2
  43. package/resources/DatabaseTransaction.ts +8 -3
  44. package/resources/RecordEncoder.ts +9 -1
  45. package/resources/Table.ts +13 -2
  46. package/resources/databases.ts +2 -1
  47. package/resources/graphql.ts +13 -5
  48. package/security/jsLoader.ts +14 -2
  49. package/security/keys.js +1 -1
  50. package/server/DurableSubscriptionsSession.ts +1 -0
  51. package/server/serverHelpers/serverUtilities.ts +2 -5
  52. package/studio/web/assets/{index-C0And10y.js → index-BftP-yQ8.js} +2 -2
  53. package/studio/web/assets/{index-C0And10y.js.map → index-BftP-yQ8.js.map} +1 -1
  54. package/studio/web/index.html +1 -1
  55. package/utility/environment/systemInformation.ts +698 -0
  56. package/utility/operation_authorization.js +2 -5
  57. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +0 -25
  58. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +0 -34
  59. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.d.ts +0 -21
  60. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +0 -24
  61. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js.map +0 -1
  62. package/utility/environment/systemInformation.js +0 -355
@@ -1,25 +1,87 @@
1
- 'use strict';
2
- const fs = require('fs-extra');
3
- const path = require('path');
4
- const si = require('systeminformation');
5
- const log = require('../logging/harper_logger.js');
6
- const terms = require("../hdbTerms.js");
7
- const lmdbGetTableSize = require('../../dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js');
8
- const schemaDescribe = require('../../dataLayer/schemaDescribe.js');
9
- const { getThreadInfo } = require('../../server/threads/manageThreads.js');
10
- const env = require('./environmentManager.js');
11
- env.initSync();
12
- const { databases } = require("../../resources/databases.js");
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.SystemInformationResponse = exports.SystemInformationRequest = void 0;
40
+ exports.getTimeInfo = getTimeInfo;
41
+ exports.getCPUInfo = getCPUInfo;
42
+ exports.getMemoryInfo = getMemoryInfo;
43
+ exports.getHDBProcessInfo = getHDBProcessInfo;
44
+ exports.getDiskInfo = getDiskInfo;
45
+ exports.getNetworkInfo = getNetworkInfo;
46
+ exports.getSystemInformation = getSystemInformation;
47
+ exports.getTableSize = getTableSize;
48
+ exports.getMetrics = getMetrics;
49
+ exports.systemInformation = systemInformation;
50
+ const promises_1 = require("node:fs/promises");
51
+ const node_path_1 = __importDefault(require("node:path"));
52
+ const systeminformation_1 = __importDefault(require("systeminformation"));
53
+ const harper_logger_js_1 = __importDefault(require("../logging/harper_logger.js"));
54
+ const hdbTerms = __importStar(require("../hdbTerms.js"));
55
+ const lmdbGetTableSize_ts_1 = require("../../dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js");
56
+ const manageThreads_js_1 = require("../../server/threads/manageThreads.js");
57
+ const environmentManager_js_1 = __importDefault(require("./environmentManager.js"));
58
+ const databases_ts_1 = require("../../resources/databases.js");
59
+ const TableSizeObject_ts_1 = require("../../dataLayer/harperBridge/TableSizeObject.js");
60
+ const rocksdb_js_1 = require("@harperfast/rocksdb-js");
61
+ environmentManager_js_1.default.initSync();
13
62
  //this will hold the system_information which is static to improve performance
14
63
  let systemInformationCache = undefined;
15
64
  class SystemInformationRequest {
65
+ operator;
66
+ attributes;
16
67
  constructor(attributes) {
17
- this.operator = terms.OPERATIONS_ENUM.SYSTEM_INFORMATION;
68
+ this.operator = hdbTerms.OPERATIONS_ENUM.SYSTEM_INFORMATION;
18
69
  this.attributes = attributes;
19
70
  }
20
71
  }
72
+ exports.SystemInformationRequest = SystemInformationRequest;
21
73
  class SystemInformationResponse {
22
- constructor(system, time, cpu, memory, disk, network, harperdbProcesses) {
74
+ system;
75
+ time;
76
+ cpu;
77
+ memory;
78
+ disk;
79
+ network;
80
+ harperdb_processes;
81
+ table_size;
82
+ metrics;
83
+ threads;
84
+ constructor(system, time, cpu, memory, disk, network, harperdbProcesses, tableSize, metrics, threads) {
23
85
  this.system = system;
24
86
  this.time = time;
25
87
  this.cpu = cpu;
@@ -27,139 +89,150 @@ class SystemInformationResponse {
27
89
  this.disk = disk;
28
90
  this.network = network;
29
91
  this.harperdb_processes = harperdbProcesses;
92
+ this.table_size = tableSize;
93
+ this.metrics = metrics;
94
+ this.threads = threads;
30
95
  }
31
96
  }
32
- module.exports = {
33
- getHDBProcessInfo,
34
- getNetworkInfo,
35
- getDiskInfo,
36
- getMemoryInfo,
37
- getCPUInfo,
38
- getTimeInfo,
39
- getSystemInformation,
40
- systemInformation,
41
- getTableSize,
42
- getMetrics,
43
- SystemInformationRequest,
44
- };
97
+ exports.SystemInformationResponse = SystemInformationResponse;
45
98
  /**
46
- * executes the time function to return the time info for the system
47
- * @returns {si.Systeminformation.TimeData}
99
+ * Returns the current local time, uptime, timezone, and timezone name.
48
100
  */
49
101
  function getTimeInfo() {
50
- return si.time();
102
+ return systeminformation_1.default.time();
51
103
  }
52
104
  /**
53
- * executes cpu related functions
54
- * @returns {Promise<{}|Pick<si.Systeminformation.CpuData, "manufacturer" | "brand" | "vendor" | "speed" | "cores" | "physicalCores" | "processors">>}
105
+ * Detects CPU information such as manufacturer, brand, vendor, speed, cores, physical cores, and
106
+ * processors.
55
107
  */
56
108
  async function getCPUInfo() {
57
109
  try {
58
- // eslint-disable-next-line no-unused-vars
59
- let { family, model, stepping, revision, voltage, speedmin, speedmax, governor, socket, cache, ...cpuInfo } = await si.cpu();
60
- cpuInfo.cpu_speed = await si.cpuCurrentSpeed();
61
- let {
62
- // eslint-disable-next-line no-unused-vars
63
- rawCurrentload, cpus, ...cpuCurrentLoad } = await si.currentLoad();
64
- cpuCurrentLoad.cpus = [];
65
- cpus.forEach((cpuData) => {
66
- // eslint-disable-next-line no-unused-vars
67
- let { rawLoad, rawLoadIdle, rawLoadIrq, rawLoadNice, rawLoadSystem, rawLoadUser, ...cpuLoad } = cpuData;
68
- cpuCurrentLoad.cpus.push(cpuLoad);
69
- });
70
- cpuInfo.current_load = cpuCurrentLoad;
71
- return cpuInfo;
110
+ const [cpu, cpu_speed, loadInfo] = await Promise.all([systeminformation_1.default.cpu(), systeminformation_1.default.cpuCurrentSpeed(), systeminformation_1.default.currentLoad()]);
111
+ const { manufacturer, brand, vendor, speed, cores, physicalCores, performanceCores, efficiencyCores, processors, flags, virtualization, } = cpu;
112
+ const { avgLoad, cpus, currentLoad, currentLoadUser, currentLoadSystem, currentLoadNice, currentLoadIdle, currentLoadIrq, } = loadInfo;
113
+ return {
114
+ manufacturer,
115
+ brand,
116
+ vendor,
117
+ speed,
118
+ cores,
119
+ physicalCores,
120
+ performanceCores,
121
+ efficiencyCores,
122
+ processors,
123
+ flags,
124
+ virtualization,
125
+ cpu_speed,
126
+ current_load: {
127
+ avgLoad,
128
+ cpus: cpus.map(({ load, loadUser, loadSystem, loadNice, loadIdle, loadIrq }) => ({
129
+ load,
130
+ loadUser,
131
+ loadSystem,
132
+ loadNice,
133
+ loadIdle,
134
+ loadIrq,
135
+ })),
136
+ currentLoad,
137
+ currentLoadUser,
138
+ currentLoadSystem,
139
+ currentLoadNice,
140
+ currentLoadIdle,
141
+ currentLoadIrq,
142
+ },
143
+ };
72
144
  }
73
145
  catch (e) {
74
- log.error(`error in getCPUInfo: ${e}`);
75
- return {};
146
+ harper_logger_js_1.default.error(`error in getCPUInfo: ${e}`);
147
+ return null;
76
148
  }
77
149
  }
78
150
  /**
79
- * fetches information related memory
80
- * @returns {Promise<{}|Pick<si.Systeminformation.MemData, "total" | "free" | "used" | "active" | "available" | "swaptotal" | "swapused" | "swapfree">>}
151
+ * Detect system and Node.js memory usage.
81
152
  */
82
153
  async function getMemoryInfo() {
83
154
  try {
84
- // eslint-disable-next-line no-unused-vars
85
- let { buffers, cached, slab, buffcache, ...memInfo } = await si.mem();
86
- return Object.assign(memInfo, process.memoryUsage());
155
+ const { total, free, used, active, available, reclaimable, swaptotal, swapused, swapfree, writeback, dirty } = await systeminformation_1.default.mem();
156
+ return {
157
+ total,
158
+ free,
159
+ used,
160
+ active,
161
+ available,
162
+ reclaimable,
163
+ swaptotal,
164
+ swapused,
165
+ swapfree,
166
+ writeback,
167
+ dirty,
168
+ ...process.memoryUsage(),
169
+ };
87
170
  }
88
171
  catch (e) {
89
- log.error(`error in getMemoryInfo: ${e}`);
90
- return {};
172
+ harper_logger_js_1.default.error(`error in getMemoryInfo: ${e}`);
173
+ return null;
174
+ }
175
+ }
176
+ async function getHdbPid() {
177
+ try {
178
+ return Number.parseInt(await (0, promises_1.readFile)(node_path_1.default.join(environmentManager_js_1.default.get(hdbTerms.CONFIG_PARAMS.ROOTPATH), hdbTerms.HDB_PID_FILE), 'utf8'));
179
+ }
180
+ catch (err) {
181
+ if (err.code === hdbTerms.NODE_ERROR_CODES.ENOENT) {
182
+ harper_logger_js_1.default.warn(`Unable to locate 'hdb.pid' file, try stopping and starting Harper. This could be because Harper is not running.`);
183
+ }
184
+ else {
185
+ throw err;
186
+ }
91
187
  }
92
188
  }
93
189
  /**
94
- * searches for & returns the processes for hdb core
190
+ * Detects the Harper process PID and returns the process info.
95
191
  * @returns {Promise<{core: []}>}
96
192
  */
97
193
  async function getHDBProcessInfo() {
98
- let harperdbProcesses = {
194
+ const harperdbProcesses = {
99
195
  core: [],
100
196
  };
101
197
  try {
102
- let processes = await si.processes();
103
- let hdbPid;
104
- try {
105
- hdbPid = Number.parseInt(await fs.readFile(path.join(env.get(terms.CONFIG_PARAMS.ROOTPATH), terms.HDB_PID_FILE), 'utf8'));
198
+ const [processes, hdbPid] = await Promise.all([systeminformation_1.default.processes(), getHdbPid()]);
199
+ const proc = processes.list.find((p) => p.pid === hdbPid);
200
+ if (proc) {
201
+ harperdbProcesses.core.push(proc);
106
202
  }
107
- catch (err) {
108
- if (err.code === terms.NODE_ERROR_CODES.ENOENT) {
109
- log.warn(`Unable to locate 'hdb.pid' file, try stopping and starting Harper. This could be because Harper is not running.`);
110
- }
111
- else {
112
- throw err;
113
- }
114
- }
115
- processes.list.forEach((p) => {
116
- if (p.pid === hdbPid) {
117
- harperdbProcesses.core.push(p);
118
- }
119
- });
120
- for (const hdbP of harperdbProcesses.core) {
121
- for (const p of processes.list) {
122
- if (p.pid === hdbP.parentPid && (p.name === 'PM2' || p.command === 'PM2')) {
123
- hdbP.parent = 'PM2';
124
- }
125
- }
126
- }
127
- return harperdbProcesses;
128
203
  }
129
204
  catch (e) {
130
- log.error(`error in getHDBProcessInfo: ${e}`);
131
- return harperdbProcesses;
205
+ harper_logger_js_1.default.error(`error in getHDBProcessInfo: ${e}`);
132
206
  }
207
+ return harperdbProcesses;
133
208
  }
134
209
  /**
135
- * gets disk related info & stats
136
- * @returns {Promise<{}>}
210
+ * Retrieves disk related info & stats
211
+ * @returns {Promise<DiskInfo>}
137
212
  */
138
213
  async function getDiskInfo() {
139
- let disk = {};
214
+ const disk = {};
140
215
  try {
141
- if (!env.get(terms.CONFIG_PARAMS.OPERATIONSAPI_SYSINFO_DISK))
216
+ if (!environmentManager_js_1.default.get(hdbTerms.CONFIG_PARAMS.OPERATIONSAPI_SYSINFO_DISK))
142
217
  return disk;
143
- // eslint-disable-next-line no-unused-vars
144
- let { rIO_sec, wIO_sec, tIO_sec, ms, ...diskIo } = await si.disksIO();
145
- disk.io = diskIo;
146
- // eslint-disable-next-line no-unused-vars
147
- let { rxSec, txSec, wxSec, ...fsStats } = await si.fsStats();
148
- disk.read_write = fsStats;
149
- disk.size = await si.fsSize();
150
- return disk;
218
+ const [disksIO, fsStats, fsSize] = await Promise.all([systeminformation_1.default.disksIO(), systeminformation_1.default.fsStats(), systeminformation_1.default.fsSize()]);
219
+ const { rIO, wIO, tIO } = disksIO;
220
+ disk.io = { rIO, wIO, tIO };
221
+ const { rx, tx, wx } = fsStats;
222
+ disk.read_write = { rx, tx, wx };
223
+ disk.size = fsSize;
151
224
  }
152
225
  catch (e) {
153
- log.error(`error in getDiskInfo: ${e}`);
154
- return disk;
226
+ harper_logger_js_1.default.error(`error in getDiskInfo: ${e}`);
155
227
  }
228
+ return disk;
156
229
  }
157
230
  /**
158
- * gets networking & connection information & stats
231
+ * Detects networking connection information & stats
159
232
  * @returns {Promise<{interfaces: [], default_interface: null, stats: [], latency: {}, connections: []}>}
160
233
  */
161
234
  async function getNetworkInfo() {
162
- let network = {
235
+ const network = {
163
236
  default_interface: null,
164
237
  latency: {},
165
238
  interfaces: [],
@@ -167,160 +240,227 @@ async function getNetworkInfo() {
167
240
  connections: [],
168
241
  };
169
242
  try {
170
- if (!env.get(terms.CONFIG_PARAMS.OPERATIONSAPI_SYSINFO_NETWORK))
243
+ if (!environmentManager_js_1.default.get(hdbTerms.CONFIG_PARAMS.OPERATIONSAPI_SYSINFO_NETWORK))
171
244
  return network;
172
- network.default_interface = await si.networkInterfaceDefault();
173
- network.latency = await si.inetChecksite('google.com');
174
- let nInterfaces = await si.networkInterfaces();
175
- nInterfaces.forEach((_interface) => {
176
- // eslint-disable-next-line no-unused-vars
177
- let { internal, virtual, mtu, dhcp, dnsSuffix, ieee8021xAuth, ieee8021xState, carrierChanges, ...networkInt } = _interface;
178
- network.interfaces.push(networkInt);
179
- });
180
- let stats = await si.networkStats();
181
- stats.forEach((nStat) => {
182
- // eslint-disable-next-line no-unused-vars
183
- let { rxSec, txSec, ms, ...stat } = nStat;
184
- network.stats.push(stat);
185
- });
186
- return network;
245
+ const [defaultInterface, latency, nInterfaces, stats] = await Promise.all([
246
+ systeminformation_1.default.networkInterfaceDefault(),
247
+ systeminformation_1.default.inetChecksite('https://google.com').catch(() => ({})),
248
+ systeminformation_1.default.networkInterfaces(),
249
+ systeminformation_1.default.networkStats(),
250
+ ]);
251
+ network.default_interface = defaultInterface || null;
252
+ network.latency = latency;
253
+ for (const nInterface of nInterfaces) {
254
+ const { iface, ifaceName, default: isDefault, ip4, ip4subnet, ip6, ip6subnet, mac, operstate, type, duplex, speed, } = nInterface;
255
+ network.interfaces.push({
256
+ iface,
257
+ ifaceName,
258
+ default: isDefault,
259
+ ip4,
260
+ ip4subnet,
261
+ ip6,
262
+ ip6subnet,
263
+ mac,
264
+ operstate,
265
+ type,
266
+ duplex,
267
+ speed,
268
+ });
269
+ }
270
+ for (const nStat of stats) {
271
+ const { iface, operstate, rx_bytes, rx_dropped, rx_errors, tx_bytes, tx_dropped, tx_errors } = nStat;
272
+ network.stats.push({ iface, operstate, rx_bytes, rx_dropped, rx_errors, tx_bytes, tx_dropped, tx_errors });
273
+ }
187
274
  }
188
275
  catch (e) {
189
- log.error(`error in getNetworkInfo: ${e}`);
190
- return network;
276
+ harper_logger_js_1.default.error(`error in getNetworkInfo: ${e}`);
191
277
  }
278
+ return network;
192
279
  }
193
280
  /**
194
- * gets system information
195
- * @returns {Promise<Pick<si.Systeminformation.OsData, "platform" | "distro" | "release" | "codename" | "kernel" | "arch" | "hostname">|{}>}
281
+ * Detect operating system and Node.js runtime information.
282
+ * @returns {Promise<SystemInfo>}
196
283
  */
197
284
  async function getSystemInformation() {
198
285
  if (systemInformationCache !== undefined) {
199
286
  return systemInformationCache;
200
287
  }
201
- let system_info = {};
288
+ let systemInfo = {};
202
289
  try {
203
- // eslint-disable-next-line no-unused-vars
204
- let { codepage, logofile, serial, build, servicepack, uefi, ...sysInfo } = await si.osInfo();
205
- system_info = sysInfo;
206
- let versions = await si.versions('node, npm');
207
- system_info.node_version = versions.node;
208
- system_info.npm_version = versions.npm;
209
- systemInformationCache = system_info;
210
- return systemInformationCache;
290
+ const [osInfo, versions] = await Promise.all([systeminformation_1.default.osInfo(), systeminformation_1.default.versions('node, npm')]);
291
+ const { platform, distro, release, codename, kernel, arch, hostname, fqdn } = osInfo;
292
+ const { node, npm } = versions;
293
+ systemInfo = {
294
+ platform,
295
+ distro,
296
+ release,
297
+ codename,
298
+ kernel,
299
+ arch,
300
+ hostname,
301
+ fqdn,
302
+ node_version: node,
303
+ npm_version: npm,
304
+ };
305
+ systemInformationCache = systemInfo;
211
306
  }
212
307
  catch (e) {
213
- log.error(`error in getSystemInformation: ${e}`);
214
- return system_info;
308
+ harper_logger_js_1.default.error(`error in getSystemInformation: ${e}`);
215
309
  }
310
+ return systemInfo;
216
311
  }
217
- async function getTableSize() {
218
- //get details for all tables
219
- let tableSizes = [];
220
- let allSchemas = await schemaDescribe.describeAll();
221
- for (const tables of Object.values(allSchemas)) {
222
- for (const tableData of Object.values(tables)) {
223
- tableSizes.push(await lmdbGetTableSize(tableData));
312
+ function rocksdbGetTableSize(table) {
313
+ const rocksdb = table.primaryStore;
314
+ const stats = rocksdb.getStats();
315
+ const transactionLogSize = rocksdb
316
+ .listLogs()
317
+ .reduce((sum, logName) => sum + rocksdb.useLog(logName).getLogFileSize(), 0);
318
+ return new TableSizeObject_ts_1.TableSizeObject(table.databaseName, table.tableName, stats['rocksdb.estimate-live-data-size'] ?? 0, stats['rocksdb.estimate-num-keys'] ?? 0, transactionLogSize
319
+ // transactionLogRecordCount - currently not supported by `rocksdb-js`
320
+ );
321
+ }
322
+ /**
323
+ * Retrieves table size information.
324
+ * @returns {TableSizeObject[]}
325
+ */
326
+ function getTableSize() {
327
+ const results = [];
328
+ const databases = (0, databases_ts_1.getDatabases)();
329
+ for (const db of Object.values(databases)) {
330
+ for (const table of Object.values(db)) {
331
+ if (table.primaryStore.rootStore instanceof rocksdb_js_1.RocksDatabase) {
332
+ results.push(rocksdbGetTableSize(table));
333
+ }
334
+ else {
335
+ results.push((0, lmdbGetTableSize_ts_1.lmdbGetTableSize)(table));
336
+ }
224
337
  }
225
338
  }
226
- return tableSizes;
339
+ return results;
227
340
  }
341
+ const rocksDBDatabaseLevelStats = new Set([
342
+ 'blockCacheCapacity',
343
+ 'blockCacheDataHit',
344
+ 'blockCacheDataMiss',
345
+ 'blockCacheFilterHit',
346
+ 'blockCacheFilterMiss',
347
+ 'blockCacheHit',
348
+ 'blockCacheIndexHit',
349
+ 'blockCacheIndexMiss',
350
+ 'blockCacheMiss',
351
+ 'blockCachePinnedUsage',
352
+ 'blockCacheUsage',
353
+ 'bytesRead',
354
+ 'bytesWritten',
355
+ 'dbFlushMicros',
356
+ 'dbGetMicros',
357
+ 'dbSeekMicros',
358
+ 'dbWriteMicros',
359
+ 'noFileErrors',
360
+ 'numberKeysRead',
361
+ 'numberKeysWritten',
362
+ 'numberReseeksIteration',
363
+ 'numRunningFlushes',
364
+ 'oldestSnapshotTime',
365
+ 'stallMicros',
366
+ 'txnOverheadMutexOldCommitMap',
367
+ 'txnOverheadMutexPrepare',
368
+ 'txnOverheadMutexSnapshot',
369
+ ]);
370
+ // Strips the "rocksdb." prefix and converts kebab-case to camelCase
371
+ function toRocksDBCamelCase(key) {
372
+ return key.replace(/^rocksdb\./, '').replace(/[-.]([a-z])/g, (_, c) => c.toUpperCase());
373
+ }
374
+ function getRocksDBStats(table, dbStats) {
375
+ const stats = table.primaryStore.getStats();
376
+ const tableStats = (dbStats.tables[table.tableName] = {});
377
+ for (const [key, value] of Object.entries(stats)) {
378
+ const name = toRocksDBCamelCase(key);
379
+ if (rocksDBDatabaseLevelStats.has(name)) {
380
+ dbStats[name] = value;
381
+ }
382
+ else {
383
+ tableStats[name] = value;
384
+ }
385
+ }
386
+ }
387
+ function getLMDBStats(table, dbStats) {
388
+ if (!dbStats.readers) {
389
+ const { root: _root, ...stats } = table.primaryStore.rootStore.getStats();
390
+ Object.assign(dbStats, stats);
391
+ dbStats.readers = table.primaryStore.rootStore
392
+ .readerList()
393
+ .split(/\n\s+/)
394
+ .slice(1)
395
+ .map((line) => {
396
+ const [pid, thread, txnid] = line.trim().split(' ');
397
+ return { pid, thread, txnid };
398
+ });
399
+ if (table.auditStore) {
400
+ const { treeDepth, treeBranchPageCount, treeLeafPageCount, entryCount, overflowPages } = table.auditStore.getStats();
401
+ dbStats.audit = { treeDepth, treeBranchPageCount, treeLeafPageCount, entryCount, overflowPages };
402
+ }
403
+ }
404
+ const { entryCount, overflowPages, treeBranchPageCount, treeDepth, treeLeafPageCount } = table.primaryStore.getStats();
405
+ dbStats.tables[table.tableName] = { entryCount, overflowPages, treeBranchPageCount, treeDepth, treeLeafPageCount };
406
+ }
407
+ /**
408
+ * Get RocksDB or LMDB metrics for all databases and tables.
409
+ * @returns {Promise<DatabaseMetrics>}
410
+ */
228
411
  async function getMetrics() {
229
- let schemaStats = {};
230
- for (let schemaName in databases) {
231
- let dbStats = (schemaStats[schemaName] = {});
232
- let tableStats = (dbStats.tables = {});
233
- for (let tableName in databases[schemaName]) {
412
+ const databaseStats = {};
413
+ const databases = (0, databases_ts_1.getDatabases)();
414
+ for (const [dbName, db] of Object.entries(databases)) {
415
+ const dbStats = { tables: {} };
416
+ databaseStats[dbName] = dbStats;
417
+ for (const [tableName, table] of Object.entries(db)) {
234
418
  try {
235
- let table = databases[schemaName][tableName];
236
- if (!dbStats.readers) {
237
- Object.assign(dbStats, table.primaryStore.rootStore.getStats());
238
- delete dbStats.root;
239
- dbStats.readers = table.primaryStore.rootStore
240
- .readerList()
241
- .split(/\n\s+/)
242
- .slice(1)
243
- .map((line) => {
244
- const [pid, thread, txnid] = line.trim().split(' ');
245
- return { pid, thread, txnid };
246
- });
247
- if (table.auditStore) {
248
- const { treeDepth, treeBranchPageCount, treeLeafPageCount, entryCount, overflowPages } = table.auditStore.getStats();
249
- dbStats.audit = { treeDepth, treeBranchPageCount, treeLeafPageCount, entryCount, overflowPages };
250
- }
419
+ if (table.primaryStore.rootStore instanceof rocksdb_js_1.RocksDatabase) {
420
+ getRocksDBStats(table, dbStats);
251
421
  }
252
- let tableFullStats = table.primaryStore.getStats();
253
- let tablePrunedStats = {};
254
- for (let storeKey of ['treeDepth', 'treeBranchPageCount', 'treeLeafPageCount', 'entryCount', 'overflowPages']) {
255
- tablePrunedStats[storeKey] = tableFullStats[storeKey];
422
+ else {
423
+ getLMDBStats(table, dbStats);
256
424
  }
257
- tableStats[tableName] = tablePrunedStats;
258
425
  }
259
426
  catch (error) {
260
- // if a schema no longer exists, don't want to throw an error
261
- log.notify(`Error getting stats for table ${tableName}: ${error}`);
427
+ // if a database no longer exists, don't want to throw an error
428
+ harper_logger_js_1.default.notify(`Error getting stats for table ${tableName}: ${error}`);
262
429
  }
263
430
  }
264
431
  }
265
- return schemaStats;
432
+ return databaseStats;
266
433
  }
434
+ const attributeMap = {
435
+ system: getSystemInformation,
436
+ time: getTimeInfo,
437
+ cpu: getCPUInfo,
438
+ memory: getMemoryInfo,
439
+ disk: getDiskInfo,
440
+ network: getNetworkInfo,
441
+ harperdb_processes: getHDBProcessInfo,
442
+ table_size: getTableSize,
443
+ metrics: getMetrics,
444
+ threads: manageThreads_js_1.getThreadInfo,
445
+ };
267
446
  /**
268
- *
447
+ * Retrieves system information for the requested attributes.
269
448
  * @param {SystemInformationRequest} systemInfoReq
270
449
  * @returns {Promise<SystemInformationResponse>}
271
450
  */
272
451
  async function systemInformation(systemInfoReq) {
273
- let response = new SystemInformationResponse();
274
- if (!Array.isArray(systemInfoReq.attributes) || systemInfoReq.attributes.length === 0) {
275
- response.system = await getSystemInformation();
276
- response.time = getTimeInfo();
277
- response.cpu = await getCPUInfo();
278
- response.memory = await getMemoryInfo();
279
- response.disk = await getDiskInfo();
280
- response.network = await getNetworkInfo();
281
- response.harperdb_processes = await getHDBProcessInfo();
282
- response.table_size = await getTableSize();
283
- response.metrics = await getMetrics();
284
- response.threads = await getThreadInfo();
285
- return response;
286
- }
287
- for (let attr of systemInfoReq.attributes) {
288
- switch (attr) {
289
- case 'system':
290
- response.system = await getSystemInformation();
291
- break;
292
- case 'time':
293
- response.time = getTimeInfo();
294
- break;
295
- case 'cpu':
296
- response.cpu = await getCPUInfo();
297
- break;
298
- case 'memory':
299
- response.memory = await getMemoryInfo();
300
- break;
301
- case 'disk':
302
- response.disk = await getDiskInfo();
303
- break;
304
- case 'network':
305
- response.network = await getNetworkInfo();
306
- break;
307
- case 'harperdb_processes':
308
- response.harperdb_processes = await getHDBProcessInfo();
309
- break;
310
- case 'table_size':
311
- response.table_size = await getTableSize();
312
- break;
313
- case 'database_metrics':
314
- case 'metrics':
315
- response.metrics = await getMetrics();
316
- break;
317
- case 'threads':
318
- response.threads = await getThreadInfo();
319
- break;
320
- default:
321
- break;
452
+ const attributes = Array.isArray(systemInfoReq.attributes) && systemInfoReq.attributes.length > 0
453
+ ? systemInfoReq.attributes
454
+ : Object.keys(attributeMap);
455
+ const response = new SystemInformationResponse();
456
+ await Promise.all(attributes
457
+ .filter((attr) => attr in attributeMap)
458
+ .map(async (attr) => {
459
+ if (attr === 'database_metrics') {
460
+ attr = 'metrics';
322
461
  }
323
- }
462
+ response[attr] = await attributeMap[attr]();
463
+ }));
324
464
  return response;
325
465
  }
326
466
  //# sourceMappingURL=systemInformation.js.map