@harperfast/harper 5.0.6 → 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.
- package/bin/status.js +2 -2
- package/bin/stop.js +5 -6
- package/components/OptionsWatcher.ts +9 -1
- package/dataLayer/harperBridge/TableSizeObject.ts +35 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.ts +24 -0
- package/dist/bin/status.js +2 -2
- package/dist/bin/status.js.map +1 -1
- package/dist/bin/stop.js +5 -5
- package/dist/bin/stop.js.map +1 -1
- package/dist/components/OptionsWatcher.js +8 -1
- package/dist/components/OptionsWatcher.js.map +1 -1
- package/dist/dataLayer/harperBridge/TableSizeObject.d.ts +20 -0
- package/dist/dataLayer/harperBridge/TableSizeObject.js +32 -0
- package/dist/dataLayer/harperBridge/TableSizeObject.js.map +1 -0
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.d.ts +6 -6
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +18 -19
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js.map +1 -1
- package/dist/resources/DatabaseTransaction.js +6 -1
- package/dist/resources/DatabaseTransaction.js.map +1 -1
- package/dist/resources/RecordEncoder.js +10 -1
- package/dist/resources/RecordEncoder.js.map +1 -1
- package/dist/resources/Table.js +13 -2
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/databases.js +2 -1
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/graphql.d.ts +3 -8
- package/dist/resources/graphql.js +180 -173
- package/dist/resources/graphql.js.map +1 -1
- package/dist/security/jsLoader.js +16 -2
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/security/keys.js +1 -1
- package/dist/security/keys.js.map +1 -1
- package/dist/server/DurableSubscriptionsSession.js +2 -0
- package/dist/server/DurableSubscriptionsSession.js.map +1 -1
- package/dist/server/serverHelpers/serverUtilities.js +2 -2
- package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
- package/dist/utility/environment/systemInformation.d.ts +178 -49
- package/dist/utility/environment/systemInformation.js +359 -219
- package/dist/utility/environment/systemInformation.js.map +1 -1
- package/dist/utility/operation_authorization.js +2 -2
- package/dist/utility/operation_authorization.js.map +1 -1
- package/package.json +2 -2
- package/resources/DatabaseTransaction.ts +8 -3
- package/resources/RecordEncoder.ts +9 -1
- package/resources/Table.ts +13 -2
- package/resources/databases.ts +2 -1
- package/resources/graphql.ts +13 -5
- package/security/jsLoader.ts +14 -2
- package/security/keys.js +1 -1
- package/server/DurableSubscriptionsSession.ts +1 -0
- package/server/serverHelpers/serverUtilities.ts +2 -5
- package/studio/web/assets/{index-qbLPhOzw.js → index-BftP-yQ8.js} +2 -2
- package/studio/web/assets/{index-qbLPhOzw.js.map → index-BftP-yQ8.js.map} +1 -1
- package/studio/web/index.html +1 -1
- package/utility/environment/systemInformation.ts +698 -0
- package/utility/operation_authorization.js +2 -5
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +0 -25
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +0 -34
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.d.ts +0 -21
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +0 -24
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js.map +0 -1
- package/utility/environment/systemInformation.js +0 -355
|
@@ -1,25 +1,87 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
47
|
-
* @returns {si.Systeminformation.TimeData}
|
|
99
|
+
* Returns the current local time, uptime, timezone, and timezone name.
|
|
48
100
|
*/
|
|
49
101
|
function getTimeInfo() {
|
|
50
|
-
return
|
|
102
|
+
return systeminformation_1.default.time();
|
|
51
103
|
}
|
|
52
104
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
75
|
-
return
|
|
146
|
+
harper_logger_js_1.default.error(`error in getCPUInfo: ${e}`);
|
|
147
|
+
return null;
|
|
76
148
|
}
|
|
77
149
|
}
|
|
78
150
|
/**
|
|
79
|
-
*
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
190
|
+
* Detects the Harper process PID and returns the process info.
|
|
95
191
|
* @returns {Promise<{core: []}>}
|
|
96
192
|
*/
|
|
97
193
|
async function getHDBProcessInfo() {
|
|
98
|
-
|
|
194
|
+
const harperdbProcesses = {
|
|
99
195
|
core: [],
|
|
100
196
|
};
|
|
101
197
|
try {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
131
|
-
return harperdbProcesses;
|
|
205
|
+
harper_logger_js_1.default.error(`error in getHDBProcessInfo: ${e}`);
|
|
132
206
|
}
|
|
207
|
+
return harperdbProcesses;
|
|
133
208
|
}
|
|
134
209
|
/**
|
|
135
|
-
*
|
|
136
|
-
* @returns {Promise<
|
|
210
|
+
* Retrieves disk related info & stats
|
|
211
|
+
* @returns {Promise<DiskInfo>}
|
|
137
212
|
*/
|
|
138
213
|
async function getDiskInfo() {
|
|
139
|
-
|
|
214
|
+
const disk = {};
|
|
140
215
|
try {
|
|
141
|
-
if (!
|
|
216
|
+
if (!environmentManager_js_1.default.get(hdbTerms.CONFIG_PARAMS.OPERATIONSAPI_SYSINFO_DISK))
|
|
142
217
|
return disk;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
disk.io =
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
disk.
|
|
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
|
-
|
|
154
|
-
return disk;
|
|
226
|
+
harper_logger_js_1.default.error(`error in getDiskInfo: ${e}`);
|
|
155
227
|
}
|
|
228
|
+
return disk;
|
|
156
229
|
}
|
|
157
230
|
/**
|
|
158
|
-
*
|
|
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
|
-
|
|
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 (!
|
|
243
|
+
if (!environmentManager_js_1.default.get(hdbTerms.CONFIG_PARAMS.OPERATIONSAPI_SYSINFO_NETWORK))
|
|
171
244
|
return network;
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
-
|
|
190
|
-
return network;
|
|
276
|
+
harper_logger_js_1.default.error(`error in getNetworkInfo: ${e}`);
|
|
191
277
|
}
|
|
278
|
+
return network;
|
|
192
279
|
}
|
|
193
280
|
/**
|
|
194
|
-
*
|
|
195
|
-
* @returns {Promise<
|
|
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
|
|
288
|
+
let systemInfo = {};
|
|
202
289
|
try {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
214
|
-
return system_info;
|
|
308
|
+
harper_logger_js_1.default.error(`error in getSystemInformation: ${e}`);
|
|
215
309
|
}
|
|
310
|
+
return systemInfo;
|
|
216
311
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
|
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
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
|
|
236
|
-
|
|
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
|
-
|
|
253
|
-
|
|
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
|
|
261
|
-
|
|
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
|
|
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
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
|