dbgate-api 6.6.0 → 6.6.1
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/package.json +6 -6
- package/src/auth/authProvider.js +1 -1
- package/src/controllers/archive.js +1 -1
- package/src/controllers/auth.js +1 -1
- package/src/controllers/cloud.js +1 -1
- package/src/controllers/connections.js +4 -4
- package/src/controllers/databaseConnections.js +11 -11
- package/src/controllers/files.js +24 -4
- package/src/controllers/runners.js +7 -6
- package/src/controllers/scheduler.js +1 -1
- package/src/controllers/serverConnections.js +4 -4
- package/src/controllers/sessions.js +4 -4
- package/src/controllers/uploads.js +2 -2
- package/src/currentVersion.js +2 -2
- package/src/index.js +35 -5
- package/src/main.js +59 -20
- package/src/proc/databaseConnectionProcess.js +21 -12
- package/src/proc/serverConnectionProcess.js +6 -6
- package/src/proc/sessionProcess.js +2 -2
- package/src/proc/sshForwardProcess.js +1 -1
- package/src/shell/archiveWriter.js +1 -1
- package/src/shell/copyStream.js +1 -1
- package/src/shell/executeQuery.js +3 -3
- package/src/shell/importDatabase.js +3 -3
- package/src/shell/jsonLinesReader.js +1 -1
- package/src/shell/jsonLinesWriter.js +1 -1
- package/src/shell/jsonReader.js +1 -1
- package/src/shell/jsonWriter.js +1 -1
- package/src/shell/loadDatabase.js +2 -2
- package/src/shell/modifyJsonLinesReader.js +1 -1
- package/src/shell/queryReader.js +1 -1
- package/src/shell/requirePlugin.js +6 -1
- package/src/shell/runScript.js +1 -1
- package/src/shell/sqlDataWriter.js +1 -1
- package/src/shell/tableReader.js +3 -3
- package/src/shell/tableWriter.js +1 -1
- package/src/shell/unzipDirectory.js +4 -4
- package/src/shell/zipDirectory.js +3 -3
- package/src/shell/zipJsonLinesData.js +3 -3
- package/src/utility/DatastoreProxy.js +3 -3
- package/src/utility/JsonLinesDatastore.js +4 -2
- package/src/utility/appLogStore.js +119 -0
- package/src/utility/childProcessChecker.js +1 -1
- package/src/utility/cloudIntf.js +5 -5
- package/src/utility/connectUtility.js +1 -1
- package/src/utility/directories.js +2 -2
- package/src/utility/extractSingleFileFromZip.js +3 -3
- package/src/utility/loadModelTransform.js +1 -1
- package/src/utility/sshTunnel.js +7 -7
- package/src/utility/sshTunnelProxy.js +1 -1
- package/src/utility/useController.js +3 -3
|
@@ -6,7 +6,6 @@ const {
|
|
|
6
6
|
extractIntSettingsValue,
|
|
7
7
|
getLogger,
|
|
8
8
|
isCompositeDbName,
|
|
9
|
-
dbNameLogCategory,
|
|
10
9
|
extractErrorMessage,
|
|
11
10
|
extractErrorLogData,
|
|
12
11
|
ScriptWriterEval,
|
|
@@ -45,6 +44,14 @@ function getStatusCounter() {
|
|
|
45
44
|
return statusCounter;
|
|
46
45
|
}
|
|
47
46
|
|
|
47
|
+
function getLogInfo() {
|
|
48
|
+
return {
|
|
49
|
+
database: dbhan ? dbhan.database : undefined,
|
|
50
|
+
conid: dbhan ? dbhan.conid : undefined,
|
|
51
|
+
engine: storedConnection ? storedConnection.engine : undefined,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
48
55
|
async function checkedAsyncCall(promise) {
|
|
49
56
|
try {
|
|
50
57
|
const res = await promise;
|
|
@@ -131,10 +138,10 @@ async function readVersion() {
|
|
|
131
138
|
const driver = requireEngineDriver(storedConnection);
|
|
132
139
|
try {
|
|
133
140
|
const version = await driver.getVersion(dbhan);
|
|
134
|
-
logger.debug(`Got server version: ${version.version}`);
|
|
141
|
+
logger.debug(getLogInfo(), `DBGM-00037 Got server version: ${version.version}`);
|
|
135
142
|
serverVersion = version;
|
|
136
143
|
} catch (err) {
|
|
137
|
-
logger.error(extractErrorLogData(err), 'Error getting DB server version');
|
|
144
|
+
logger.error(extractErrorLogData(err, getLogInfo()), 'DBGM-00149 Error getting DB server version');
|
|
138
145
|
serverVersion = { version: 'Unknown' };
|
|
139
146
|
}
|
|
140
147
|
process.send({ msgtype: 'version', version: serverVersion });
|
|
@@ -148,9 +155,8 @@ async function handleConnect({ connection, structure, globalSettings }) {
|
|
|
148
155
|
const driver = requireEngineDriver(storedConnection);
|
|
149
156
|
dbhan = await checkedAsyncCall(connectUtility(driver, storedConnection, 'app'));
|
|
150
157
|
logger.debug(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}, 'DB: ${dbNameLogCategory(dbhan.database)} }`
|
|
158
|
+
getLogInfo(),
|
|
159
|
+
`DBGM-00038 Connected to database, separate schemas: ${storedConnection.useSeparateSchemas ? 'YES' : 'NO'}`
|
|
154
160
|
);
|
|
155
161
|
dbhan.feedback = feedback => setStatus({ feedback });
|
|
156
162
|
await checkedAsyncCall(readVersion());
|
|
@@ -257,13 +263,16 @@ async function handleDriverDataCore(msgid, callMethod, { logName }) {
|
|
|
257
263
|
const result = await callMethod(driver);
|
|
258
264
|
process.send({ msgtype: 'response', msgid, result: serializeJsTypesForJsonStringify(result) });
|
|
259
265
|
} catch (err) {
|
|
260
|
-
logger.error(
|
|
266
|
+
logger.error(
|
|
267
|
+
extractErrorLogData(err, { logName, ...getLogInfo() }),
|
|
268
|
+
`DBGM-00150 Error when handling message ${logName}`
|
|
269
|
+
);
|
|
261
270
|
process.send({ msgtype: 'response', msgid, errorMessage: extractErrorMessage(err, 'Error executing DB data') });
|
|
262
271
|
}
|
|
263
272
|
}
|
|
264
273
|
|
|
265
274
|
async function handleSchemaList({ msgid }) {
|
|
266
|
-
logger.debug('Loading schema list');
|
|
275
|
+
logger.debug(getLogInfo(), 'DBGM-00039 Loading schema list');
|
|
267
276
|
return handleDriverDataCore(msgid, driver => driver.listSchemas(dbhan), { logName: 'listSchemas' });
|
|
268
277
|
}
|
|
269
278
|
|
|
@@ -351,7 +360,7 @@ async function handleSqlPreview({ msgid, objects, options }) {
|
|
|
351
360
|
process.send({ msgtype: 'response', msgid, sql: dmp.s, isTruncated: generator.isTruncated });
|
|
352
361
|
if (generator.isUnhandledException) {
|
|
353
362
|
setTimeout(async () => {
|
|
354
|
-
logger.error('Exiting because of unhandled exception');
|
|
363
|
+
logger.error(getLogInfo(), 'DBGM-00151 Exiting because of unhandled exception');
|
|
355
364
|
await driver.close(dbhan);
|
|
356
365
|
process.exit(0);
|
|
357
366
|
}, 500);
|
|
@@ -485,7 +494,7 @@ function start() {
|
|
|
485
494
|
setInterval(async () => {
|
|
486
495
|
const time = new Date().getTime();
|
|
487
496
|
if (time - lastPing > 40 * 1000) {
|
|
488
|
-
logger.info('Database connection not alive, exiting');
|
|
497
|
+
logger.info(getLogInfo(), 'DBGM-00040 Database connection not alive, exiting');
|
|
489
498
|
const driver = requireEngineDriver(storedConnection);
|
|
490
499
|
await driver.close(dbhan);
|
|
491
500
|
process.exit(0);
|
|
@@ -497,10 +506,10 @@ function start() {
|
|
|
497
506
|
try {
|
|
498
507
|
await handleMessage(message);
|
|
499
508
|
} catch (err) {
|
|
500
|
-
logger.error(extractErrorLogData(err), 'Error in DB connection');
|
|
509
|
+
logger.error(extractErrorLogData(err, getLogInfo()), 'DBGM-00041 Error in DB connection');
|
|
501
510
|
process.send({
|
|
502
511
|
msgtype: 'error',
|
|
503
|
-
error: extractErrorMessage(err, 'Error processing message'),
|
|
512
|
+
error: extractErrorMessage(err, 'DBGM-00042 Error processing message'),
|
|
504
513
|
msgid: message?.msgid,
|
|
505
514
|
});
|
|
506
515
|
}
|
|
@@ -39,7 +39,7 @@ async function handleRefresh() {
|
|
|
39
39
|
name: 'error',
|
|
40
40
|
message: err.message,
|
|
41
41
|
});
|
|
42
|
-
logger.error(extractErrorLogData(err), 'Error refreshing server databases');
|
|
42
|
+
logger.error(extractErrorLogData(err), 'DBGM-00152 Error refreshing server databases');
|
|
43
43
|
setTimeout(() => process.exit(1), 1000);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -50,7 +50,7 @@ async function readVersion() {
|
|
|
50
50
|
try {
|
|
51
51
|
version = await driver.getVersion(dbhan);
|
|
52
52
|
} catch (err) {
|
|
53
|
-
logger.error(extractErrorLogData(err), 'Error getting DB server version');
|
|
53
|
+
logger.error(extractErrorLogData(err), 'DBGM-00153 Error getting DB server version');
|
|
54
54
|
version = { version: 'Unknown' };
|
|
55
55
|
}
|
|
56
56
|
process.send({ msgtype: 'version', version });
|
|
@@ -90,7 +90,7 @@ async function handleConnect(connection) {
|
|
|
90
90
|
name: 'error',
|
|
91
91
|
message: err.message,
|
|
92
92
|
});
|
|
93
|
-
logger.error(extractErrorLogData(err), 'Error connecting to server');
|
|
93
|
+
logger.error(extractErrorLogData(err), 'DBGM-00154 Error connecting to server');
|
|
94
94
|
setTimeout(() => process.exit(1), 1000);
|
|
95
95
|
}
|
|
96
96
|
|
|
@@ -120,7 +120,7 @@ async function handleDatabaseOp(op, { msgid, name }) {
|
|
|
120
120
|
} else {
|
|
121
121
|
const dmp = driver.createDumper();
|
|
122
122
|
dmp[op](name);
|
|
123
|
-
logger.info({ sql: dmp.s }, 'Running script');
|
|
123
|
+
logger.info({ sql: dmp.s }, 'DBGM-00043 Running script');
|
|
124
124
|
await driver.query(dbhan, dmp.s, { discardResult: true });
|
|
125
125
|
}
|
|
126
126
|
await handleRefresh();
|
|
@@ -170,7 +170,7 @@ function start() {
|
|
|
170
170
|
setInterval(async () => {
|
|
171
171
|
const time = new Date().getTime();
|
|
172
172
|
if (time - lastPing > 40 * 1000) {
|
|
173
|
-
logger.info('Server connection not alive, exiting');
|
|
173
|
+
logger.info('DBGM-00044 Server connection not alive, exiting');
|
|
174
174
|
const driver = requireEngineDriver(storedConnection);
|
|
175
175
|
if (dbhan) {
|
|
176
176
|
await driver.close(dbhan);
|
|
@@ -188,7 +188,7 @@ function start() {
|
|
|
188
188
|
name: 'error',
|
|
189
189
|
message: err.message,
|
|
190
190
|
});
|
|
191
|
-
logger.error(extractErrorLogData(err), `Error processing message ${message?.['msgtype']}`);
|
|
191
|
+
logger.error(extractErrorLogData(err), `DBGM-00155 Error processing message ${message?.['msgtype']}`);
|
|
192
192
|
}
|
|
193
193
|
});
|
|
194
194
|
}
|
|
@@ -230,7 +230,7 @@ function start() {
|
|
|
230
230
|
setInterval(async () => {
|
|
231
231
|
const time = new Date().getTime();
|
|
232
232
|
if (time - lastPing > 25 * 1000) {
|
|
233
|
-
logger.info('Session not alive, exiting');
|
|
233
|
+
logger.info('DBGM-00045 Session not alive, exiting');
|
|
234
234
|
const driver = requireEngineDriver(storedConnection);
|
|
235
235
|
await driver.close(dbhan);
|
|
236
236
|
process.exit(0);
|
|
@@ -250,7 +250,7 @@ function start() {
|
|
|
250
250
|
!currentProfiler &&
|
|
251
251
|
executingScripts == 0
|
|
252
252
|
) {
|
|
253
|
-
logger.info('Session not active, exiting');
|
|
253
|
+
logger.info('DBGM-00046 Session not active, exiting');
|
|
254
254
|
const driver = requireEngineDriver(storedConnection);
|
|
255
255
|
await driver.close(dbhan);
|
|
256
256
|
process.exit(0);
|
|
@@ -41,7 +41,7 @@ async function handleStart({ connection, tunnelConfig }) {
|
|
|
41
41
|
tunnelConfig,
|
|
42
42
|
});
|
|
43
43
|
} catch (err) {
|
|
44
|
-
logger.error(extractErrorLogData(err), 'Error creating SSH tunnel connection:');
|
|
44
|
+
logger.error(extractErrorLogData(err), 'DBGM-00156 Error creating SSH tunnel connection:');
|
|
45
45
|
|
|
46
46
|
process.send({
|
|
47
47
|
msgtype: 'error',
|
|
@@ -10,7 +10,7 @@ const logger = getLogger();
|
|
|
10
10
|
function archiveWriter({ folderName, fileName }) {
|
|
11
11
|
const dir = resolveArchiveFolder(folderName);
|
|
12
12
|
if (!fs.existsSync(dir)) {
|
|
13
|
-
logger.info(`Creating directory ${dir}`);
|
|
13
|
+
logger.info(`DBGM-00047 Creating directory ${dir}`);
|
|
14
14
|
fs.mkdirSync(dir);
|
|
15
15
|
}
|
|
16
16
|
const jsonlFile = path.join(dir, `${fileName}.jsonl`);
|
package/src/shell/copyStream.js
CHANGED
|
@@ -83,7 +83,7 @@ async function copyStream(input, output, options) {
|
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
logger.error(extractErrorLogData(err, { progressName }), 'Import/export job failed');
|
|
86
|
+
logger.error(extractErrorLogData(err, { progressName }), 'DBGM-00157 Import/export job failed');
|
|
87
87
|
// throw err;
|
|
88
88
|
}
|
|
89
89
|
}
|
|
@@ -28,20 +28,20 @@ async function executeQuery({
|
|
|
28
28
|
useTransaction,
|
|
29
29
|
}) {
|
|
30
30
|
if (!logScriptItems && !skipLogging) {
|
|
31
|
-
logger.info({ sql: getLimitedQuery(sql) }, `Execute query`);
|
|
31
|
+
logger.info({ sql: getLimitedQuery(sql) }, `DBGM-00048 Execute query`);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
if (!driver) driver = requireEngineDriver(connection);
|
|
35
35
|
const dbhan = systemConnection || (await connectUtility(driver, connection, 'script'));
|
|
36
36
|
|
|
37
37
|
if (sqlFile) {
|
|
38
|
-
logger.debug(`Loading SQL file ${sqlFile}`);
|
|
38
|
+
logger.debug(`DBGM-00049 Loading SQL file ${sqlFile}`);
|
|
39
39
|
sql = await fs.readFile(sqlFile, { encoding: 'utf-8' });
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
try {
|
|
43
43
|
if (!skipLogging) {
|
|
44
|
-
logger.debug(`Running SQL query, length: ${sql.length}`);
|
|
44
|
+
logger.debug(`DBGM-00050 Running SQL query, length: ${sql.length}`);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
await driver.script(dbhan, sql, { logScriptItems, useTransaction });
|
|
@@ -45,14 +45,14 @@ class ImportStream extends stream.Transform {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
async function importDatabase({ connection = undefined, systemConnection = undefined, driver = undefined, inputFile }) {
|
|
48
|
-
logger.info(`Importing database`);
|
|
48
|
+
logger.info(`DBGM-00051 Importing database`);
|
|
49
49
|
|
|
50
50
|
if (!driver) driver = requireEngineDriver(connection);
|
|
51
51
|
const dbhan = systemConnection || (await connectUtility(driver, connection, 'write'));
|
|
52
52
|
try {
|
|
53
|
-
logger.info(`Input file: ${inputFile}`);
|
|
53
|
+
logger.info(`DBGM-00052 Input file: ${inputFile}`);
|
|
54
54
|
const downloadedFile = await download(inputFile);
|
|
55
|
-
logger.info(`Downloaded file: ${downloadedFile}`);
|
|
55
|
+
logger.info(`DBGM-00053 Downloaded file: ${downloadedFile}`);
|
|
56
56
|
|
|
57
57
|
const fileStream = fs.createReadStream(downloadedFile, 'utf-8');
|
|
58
58
|
const splittedStream = splitQueryStream(fileStream, {
|
|
@@ -42,7 +42,7 @@ class ParseStream extends stream.Transform {
|
|
|
42
42
|
* @returns {Promise<readerType>} - reader object
|
|
43
43
|
*/
|
|
44
44
|
async function jsonLinesReader({ fileName, encoding = 'utf-8', limitRows = undefined }) {
|
|
45
|
-
logger.info(`Reading file ${fileName}`);
|
|
45
|
+
logger.info(`DBGM-00054 Reading file ${fileName}`);
|
|
46
46
|
|
|
47
47
|
const downloadedFile = await download(fileName);
|
|
48
48
|
|
|
@@ -33,7 +33,7 @@ class StringifyStream extends stream.Transform {
|
|
|
33
33
|
* @returns {Promise<writerType>} - writer object
|
|
34
34
|
*/
|
|
35
35
|
async function jsonLinesWriter({ fileName, encoding = 'utf-8', header = true }) {
|
|
36
|
-
logger.info(`Writing file ${fileName}`);
|
|
36
|
+
logger.info(`DBGM-00055 Writing file ${fileName}`);
|
|
37
37
|
const stringify = new StringifyStream({ header });
|
|
38
38
|
const fileStream = fs.createWriteStream(fileName, encoding);
|
|
39
39
|
return [stringify, fileStream];
|
package/src/shell/jsonReader.js
CHANGED
|
@@ -63,7 +63,7 @@ async function jsonReader({
|
|
|
63
63
|
encoding = 'utf-8',
|
|
64
64
|
limitRows = undefined,
|
|
65
65
|
}) {
|
|
66
|
-
logger.info(`Reading file ${fileName}`);
|
|
66
|
+
logger.info(`DBGM-00056 Reading file ${fileName}`);
|
|
67
67
|
|
|
68
68
|
const downloadedFile = await download(fileName);
|
|
69
69
|
const fileStream = fs.createReadStream(
|
package/src/shell/jsonWriter.js
CHANGED
|
@@ -96,7 +96,7 @@ class StringifyStream extends stream.Transform {
|
|
|
96
96
|
* @returns {Promise<writerType>} - writer object
|
|
97
97
|
*/
|
|
98
98
|
async function jsonWriter({ fileName, jsonStyle, keyField = '_key', rootField, encoding = 'utf-8' }) {
|
|
99
|
-
logger.info(`Writing file ${fileName}`);
|
|
99
|
+
logger.info(`DBGM-00057 Writing file ${fileName}`);
|
|
100
100
|
const stringify = new StringifyStream({ jsonStyle, keyField, rootField });
|
|
101
101
|
const fileStream = fs.createWriteStream(fileName, encoding);
|
|
102
102
|
return [stringify, fileStream];
|
|
@@ -6,13 +6,13 @@ const exportDbModel = require('../utility/exportDbModel');
|
|
|
6
6
|
const logger = getLogger('analyseDb');
|
|
7
7
|
|
|
8
8
|
async function loadDatabase({ connection = undefined, systemConnection = undefined, driver = undefined, outputDir }) {
|
|
9
|
-
logger.debug(`Analysing database`);
|
|
9
|
+
logger.debug(`DBGM-00058 Analysing database`);
|
|
10
10
|
|
|
11
11
|
if (!driver) driver = requireEngineDriver(connection);
|
|
12
12
|
const dbhan = systemConnection || (await connectUtility(driver, connection, 'read', { forceRowsAsObjects: true }));
|
|
13
13
|
try {
|
|
14
14
|
const dbInfo = await driver.analyseFull(dbhan);
|
|
15
|
-
logger.debug(`Analyse finished`);
|
|
15
|
+
logger.debug(`DBGM-00059 Analyse finished`);
|
|
16
16
|
|
|
17
17
|
await exportDbModel(dbInfo, outputDir);
|
|
18
18
|
} finally {
|
|
@@ -132,7 +132,7 @@ async function modifyJsonLinesReader({
|
|
|
132
132
|
mergeKey = null,
|
|
133
133
|
mergeMode = 'merge',
|
|
134
134
|
}) {
|
|
135
|
-
logger.info(`Reading file ${fileName} with change set`);
|
|
135
|
+
logger.info(`DBGM-00060 Reading file ${fileName} with change set`);
|
|
136
136
|
|
|
137
137
|
const fileStream = fs.createReadStream(
|
|
138
138
|
fileName,
|
package/src/shell/queryReader.js
CHANGED
|
@@ -29,7 +29,7 @@ async function queryReader({
|
|
|
29
29
|
// if (!sql && !json) {
|
|
30
30
|
// throw new Error('One of sql or json must be set');
|
|
31
31
|
// }
|
|
32
|
-
logger.info({ sql: query || sql }, `Reading query`);
|
|
32
|
+
logger.info({ sql: query || sql }, `DBGM-00061 Reading query`);
|
|
33
33
|
// else console.log(`Reading query ${JSON.stringify(json)}`);
|
|
34
34
|
|
|
35
35
|
if (!driver) {
|
|
@@ -4,6 +4,7 @@ const { pluginsdir, packagedPluginsDir, getPluginBackendPath } = require('../uti
|
|
|
4
4
|
const platformInfo = require('../utility/platformInfo');
|
|
5
5
|
const authProxy = require('../utility/authProxy');
|
|
6
6
|
const { getLogger } = require('dbgate-tools');
|
|
7
|
+
//
|
|
7
8
|
const logger = getLogger('requirePlugin');
|
|
8
9
|
|
|
9
10
|
const loadedPlugins = {};
|
|
@@ -12,6 +13,10 @@ const dbgateEnv = {
|
|
|
12
13
|
dbgateApi: null,
|
|
13
14
|
platformInfo,
|
|
14
15
|
authProxy,
|
|
16
|
+
isProApp: () =>{
|
|
17
|
+
const { isProApp } = require('../utility/checkLicense');
|
|
18
|
+
return isProApp();
|
|
19
|
+
}
|
|
15
20
|
};
|
|
16
21
|
function requirePlugin(packageName, requiredPlugin = null) {
|
|
17
22
|
if (!packageName) throw new Error('Missing packageName in plugin');
|
|
@@ -20,7 +25,7 @@ function requirePlugin(packageName, requiredPlugin = null) {
|
|
|
20
25
|
if (requiredPlugin == null) {
|
|
21
26
|
let module;
|
|
22
27
|
const modulePath = getPluginBackendPath(packageName);
|
|
23
|
-
logger.info(`Loading module ${packageName} from ${modulePath}`);
|
|
28
|
+
logger.info(`DBGM-00062 Loading module ${packageName} from ${modulePath}`);
|
|
24
29
|
try {
|
|
25
30
|
// @ts-ignore
|
|
26
31
|
module = __non_webpack_require__(modulePath);
|
package/src/shell/runScript.js
CHANGED
|
@@ -11,7 +11,7 @@ async function runScript(func) {
|
|
|
11
11
|
await func();
|
|
12
12
|
process.exit(0);
|
|
13
13
|
} catch (err) {
|
|
14
|
-
logger.error(extractErrorLogData(err), `Error running script`);
|
|
14
|
+
logger.error(extractErrorLogData(err), `DBGM-00158 Error running script`);
|
|
15
15
|
process.exit(1);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -41,7 +41,7 @@ class SqlizeStream extends stream.Transform {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
async function sqlDataWriter({ fileName, dataName, driver, encoding = 'utf-8' }) {
|
|
44
|
-
logger.info(`Writing file ${fileName}`);
|
|
44
|
+
logger.info(`DBGM-00063 Writing file ${fileName}`);
|
|
45
45
|
const stringify = new SqlizeStream({ fileName, dataName });
|
|
46
46
|
const fileStream = fs.createWriteStream(fileName, encoding);
|
|
47
47
|
return [stringify, fileStream];
|
package/src/shell/tableReader.js
CHANGED
|
@@ -23,7 +23,7 @@ async function tableReader({ connection, systemConnection, pureName, schemaName,
|
|
|
23
23
|
|
|
24
24
|
if (driver.databaseEngineTypes.includes('document')) {
|
|
25
25
|
// @ts-ignore
|
|
26
|
-
logger.info(`Reading collection ${fullNameToString(fullName)}`);
|
|
26
|
+
logger.info(`DBGM-00064 Reading collection ${fullNameToString(fullName)}`);
|
|
27
27
|
// @ts-ignore
|
|
28
28
|
return await driver.readQuery(dbhan, JSON.stringify(fullName));
|
|
29
29
|
}
|
|
@@ -32,14 +32,14 @@ async function tableReader({ connection, systemConnection, pureName, schemaName,
|
|
|
32
32
|
const query = `select * from ${quoteFullName(driver.dialect, fullName)}`;
|
|
33
33
|
if (table) {
|
|
34
34
|
// @ts-ignore
|
|
35
|
-
logger.info(`Reading table ${fullNameToString(table)}`);
|
|
35
|
+
logger.info(`DBGM-00065 Reading table ${fullNameToString(table)}`);
|
|
36
36
|
// @ts-ignore
|
|
37
37
|
return await driver.readQuery(dbhan, query, table);
|
|
38
38
|
}
|
|
39
39
|
const view = await driver.analyseSingleObject(dbhan, fullName, 'views');
|
|
40
40
|
if (view) {
|
|
41
41
|
// @ts-ignore
|
|
42
|
-
logger.info(`Reading view ${fullNameToString(view)}`);
|
|
42
|
+
logger.info(`DBGM-00066 Reading view ${fullNameToString(view)}`);
|
|
43
43
|
// @ts-ignore
|
|
44
44
|
return await driver.readQuery(dbhan, query, view);
|
|
45
45
|
}
|
package/src/shell/tableWriter.js
CHANGED
|
@@ -20,7 +20,7 @@ const logger = getLogger('tableWriter');
|
|
|
20
20
|
* @returns {Promise<writerType>} - writer object
|
|
21
21
|
*/
|
|
22
22
|
async function tableWriter({ connection, schemaName, pureName, driver, systemConnection, ...options }) {
|
|
23
|
-
logger.info(`Writing table ${fullNameToString({ schemaName, pureName })}`);
|
|
23
|
+
logger.info(`DBGM-00067 Writing table ${fullNameToString({ schemaName, pureName })}`);
|
|
24
24
|
|
|
25
25
|
if (!driver) {
|
|
26
26
|
driver = requireEngineDriver(connection);
|
|
@@ -52,14 +52,14 @@ function unzipDirectory(zipPath, outputDirectory) {
|
|
|
52
52
|
readStream.on('end', () => zipFile.readEntry());
|
|
53
53
|
|
|
54
54
|
writeStream.on('finish', () => {
|
|
55
|
-
logger.info(`Extracted "${entry.fileName}" → "${destPath}".`);
|
|
55
|
+
logger.info(`DBGM-00068 Extracted "${entry.fileName}" → "${destPath}".`);
|
|
56
56
|
res();
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
writeStream.on('error', writeErr => {
|
|
60
60
|
logger.error(
|
|
61
61
|
extractErrorLogData(writeErr),
|
|
62
|
-
`Error extracting "${entry.fileName}" from "${zipPath}".`
|
|
62
|
+
`DBGM-00069 Error extracting "${entry.fileName}" from "${zipPath}".`
|
|
63
63
|
);
|
|
64
64
|
rej(writeErr);
|
|
65
65
|
});
|
|
@@ -74,14 +74,14 @@ function unzipDirectory(zipPath, outputDirectory) {
|
|
|
74
74
|
zipFile.on('end', () => {
|
|
75
75
|
Promise.all(pending)
|
|
76
76
|
.then(() => {
|
|
77
|
-
logger.info(`Archive "${zipPath}" fully extracted to "${outputDirectory}".`);
|
|
77
|
+
logger.info(`DBGM-00070 Archive "${zipPath}" fully extracted to "${outputDirectory}".`);
|
|
78
78
|
resolve(true);
|
|
79
79
|
})
|
|
80
80
|
.catch(reject);
|
|
81
81
|
});
|
|
82
82
|
|
|
83
83
|
zipFile.on('error', err => {
|
|
84
|
-
logger.error(extractErrorLogData(err), `ZIP file error in ${zipPath}.`);
|
|
84
|
+
logger.error(extractErrorLogData(err), `DBGM-00071 ZIP file error in ${zipPath}.`);
|
|
85
85
|
reject(err);
|
|
86
86
|
});
|
|
87
87
|
});
|
|
@@ -16,16 +16,16 @@ function zipDirectory(inputDirectory, outputFile) {
|
|
|
16
16
|
|
|
17
17
|
// Listen for all archive data to be written
|
|
18
18
|
output.on('close', () => {
|
|
19
|
-
logger.info(`ZIP file created (${archive.pointer()} total bytes)`);
|
|
19
|
+
logger.info(`DBGM-00072 ZIP file created (${archive.pointer()} total bytes)`);
|
|
20
20
|
resolve();
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
archive.on('warning', err => {
|
|
24
|
-
logger.warn(extractErrorLogData(err), `Warning while creating ZIP: ${err.message}`);
|
|
24
|
+
logger.warn(extractErrorLogData(err), `DBGM-00073 Warning while creating ZIP: ${err.message}`);
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
archive.on('error', err => {
|
|
28
|
-
logger.error(extractErrorLogData(err), `Error while creating ZIP: ${err.message}`);
|
|
28
|
+
logger.error(extractErrorLogData(err), `DBGM-00074 Error while creating ZIP: ${err.message}`);
|
|
29
29
|
reject(err);
|
|
30
30
|
});
|
|
31
31
|
|
|
@@ -17,16 +17,16 @@ function zipDirectory(jsonDb, outputFile) {
|
|
|
17
17
|
|
|
18
18
|
// Listen for all archive data to be written
|
|
19
19
|
output.on('close', () => {
|
|
20
|
-
logger.info(`ZIP file created (${archive.pointer()} total bytes)`);
|
|
20
|
+
logger.info(`DBGM-00075 ZIP file created (${archive.pointer()} total bytes)`);
|
|
21
21
|
resolve();
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
archive.on('warning', err => {
|
|
25
|
-
logger.warn(extractErrorLogData(err), `Warning while creating ZIP: ${err.message}`);
|
|
25
|
+
logger.warn(extractErrorLogData(err), `DBGM-00076 Warning while creating ZIP: ${err.message}`);
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
archive.on('error', err => {
|
|
29
|
-
logger.error(extractErrorLogData(err), `Error while creating ZIP: ${err.message}`);
|
|
29
|
+
logger.error(extractErrorLogData(err), `DBGM-00077 Error while creating ZIP: ${err.message}`);
|
|
30
30
|
reject(err);
|
|
31
31
|
});
|
|
32
32
|
|
|
@@ -61,7 +61,7 @@ class DatastoreProxy {
|
|
|
61
61
|
this.subprocess = null;
|
|
62
62
|
});
|
|
63
63
|
this.subprocess.on('error', err => {
|
|
64
|
-
logger.error(extractErrorLogData(err), 'Error in data store subprocess');
|
|
64
|
+
logger.error(extractErrorLogData(err), 'DBGM-00167 Error in data store subprocess');
|
|
65
65
|
this.subprocess = null;
|
|
66
66
|
});
|
|
67
67
|
this.subprocess.send({ msgtype: 'open', file: this.file });
|
|
@@ -77,7 +77,7 @@ class DatastoreProxy {
|
|
|
77
77
|
try {
|
|
78
78
|
this.subprocess.send({ msgtype: 'read', msgid, offset, limit });
|
|
79
79
|
} catch (err) {
|
|
80
|
-
logger.error(extractErrorLogData(err), 'Error getting rows');
|
|
80
|
+
logger.error(extractErrorLogData(err), 'DBGM-00168 Error getting rows');
|
|
81
81
|
this.subprocess = null;
|
|
82
82
|
}
|
|
83
83
|
});
|
|
@@ -91,7 +91,7 @@ class DatastoreProxy {
|
|
|
91
91
|
try {
|
|
92
92
|
this.subprocess.send({ msgtype: 'notify', msgid });
|
|
93
93
|
} catch (err) {
|
|
94
|
-
logger.error(extractErrorLogData(err), 'Error notifying subprocess');
|
|
94
|
+
logger.error(extractErrorLogData(err), 'DBGM-00169 Error notifying subprocess');
|
|
95
95
|
this.subprocess = null;
|
|
96
96
|
}
|
|
97
97
|
});
|
|
@@ -7,7 +7,6 @@ const AsyncLock = require('async-lock');
|
|
|
7
7
|
const lock = new AsyncLock();
|
|
8
8
|
const stableStringify = require('json-stable-stringify');
|
|
9
9
|
const { evaluateCondition } = require('dbgate-sqltree');
|
|
10
|
-
const requirePluginFunction = require('./requirePluginFunction');
|
|
11
10
|
const esort = require('external-sorting');
|
|
12
11
|
const { jsldir } = require('./directories');
|
|
13
12
|
const LineReader = require('./LineReader');
|
|
@@ -23,7 +22,10 @@ class JsonLinesDatastore {
|
|
|
23
22
|
this.notifyChangedCallback = null;
|
|
24
23
|
this.currentFilter = null;
|
|
25
24
|
this.currentSort = null;
|
|
26
|
-
|
|
25
|
+
if (formatterFunction) {
|
|
26
|
+
const requirePluginFunction = require('./requirePluginFunction');
|
|
27
|
+
this.rowFormatter = requirePluginFunction(formatterFunction);
|
|
28
|
+
}
|
|
27
29
|
this.sortedFiles = {};
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { logsdir } = require('./directories');
|
|
4
|
+
const { format, addDays, startOfDay } = require('date-fns');
|
|
5
|
+
const LineReader = require('./LineReader');
|
|
6
|
+
const socket = require('./socket');
|
|
7
|
+
const _ = require('lodash');
|
|
8
|
+
|
|
9
|
+
async function getLogFiles(timeFrom, timeTo) {
|
|
10
|
+
const dir = logsdir();
|
|
11
|
+
const files = await fs.readdir(dir);
|
|
12
|
+
const startPrefix = format(timeFrom, 'yyyy-MM-dd');
|
|
13
|
+
const endPrefix = format(addDays(timeTo, 1), 'yyyy-MM-dd');
|
|
14
|
+
const logFiles = files
|
|
15
|
+
.filter(file => file.endsWith('.ndjson'))
|
|
16
|
+
.filter(file => file >= startPrefix && file < endPrefix);
|
|
17
|
+
return logFiles.sort().map(x => path.join(dir, x));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const RECENT_LOG_LIMIT = 1000;
|
|
21
|
+
|
|
22
|
+
let recentLogs = null;
|
|
23
|
+
const beforeRecentLogs = [];
|
|
24
|
+
|
|
25
|
+
function adjustRecentLogs() {
|
|
26
|
+
if (recentLogs.length > RECENT_LOG_LIMIT) {
|
|
27
|
+
recentLogs.splice(0, recentLogs.length - RECENT_LOG_LIMIT);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function prepareEntryForExport(entry, lastEntry) {
|
|
32
|
+
return {
|
|
33
|
+
date: format(new Date(entry.time), 'yyyy-MM-dd'),
|
|
34
|
+
time: format(new Date(entry.time), 'HH:mm:ss'),
|
|
35
|
+
dtime: lastEntry ? entry.time - lastEntry.time : 0,
|
|
36
|
+
msgcode: entry.msgcode || '',
|
|
37
|
+
message: entry.msg || '',
|
|
38
|
+
..._.omit(entry, ['time', 'msg', 'msgcode']),
|
|
39
|
+
conid: entry.conid || '',
|
|
40
|
+
database: entry.database || '',
|
|
41
|
+
engine: entry.engine || '',
|
|
42
|
+
ts: entry.time,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function copyAppLogsIntoFile(timeFrom, timeTo, fileName, prepareForExport) {
|
|
47
|
+
const writeStream = fs.createWriteStream(fileName);
|
|
48
|
+
|
|
49
|
+
let lastEntry = null;
|
|
50
|
+
for (const file of await getLogFiles(timeFrom, timeTo)) {
|
|
51
|
+
const readStream = fs.createReadStream(file);
|
|
52
|
+
const reader = new LineReader(readStream);
|
|
53
|
+
do {
|
|
54
|
+
const line = await reader.readLine();
|
|
55
|
+
if (line == null) break;
|
|
56
|
+
try {
|
|
57
|
+
const logEntry = JSON.parse(line);
|
|
58
|
+
if (logEntry.time >= timeFrom && logEntry.time <= timeTo) {
|
|
59
|
+
writeStream.write(
|
|
60
|
+
JSON.stringify(prepareForExport ? prepareEntryForExport(logEntry, lastEntry) : logEntry) + '\n'
|
|
61
|
+
);
|
|
62
|
+
lastEntry = logEntry;
|
|
63
|
+
}
|
|
64
|
+
} catch (e) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
} while (true);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function initializeRecentLogProvider() {
|
|
72
|
+
const logs = [];
|
|
73
|
+
for (const file of await getLogFiles(startOfDay(new Date()), new Date())) {
|
|
74
|
+
const fileStream = fs.createReadStream(file);
|
|
75
|
+
const reader = new LineReader(fileStream);
|
|
76
|
+
do {
|
|
77
|
+
const line = await reader.readLine();
|
|
78
|
+
if (line == null) break;
|
|
79
|
+
try {
|
|
80
|
+
const logEntry = JSON.parse(line);
|
|
81
|
+
logs.push(logEntry);
|
|
82
|
+
if (logs.length > RECENT_LOG_LIMIT) {
|
|
83
|
+
logs.shift();
|
|
84
|
+
}
|
|
85
|
+
} catch (e) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
} while (true);
|
|
89
|
+
}
|
|
90
|
+
recentLogs = logs;
|
|
91
|
+
recentLogs.push(...beforeRecentLogs);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let counter = 0;
|
|
95
|
+
function pushToRecentLogs(msg) {
|
|
96
|
+
const finalMsg = {
|
|
97
|
+
...msg,
|
|
98
|
+
counter,
|
|
99
|
+
};
|
|
100
|
+
counter += 1;
|
|
101
|
+
if (recentLogs) {
|
|
102
|
+
recentLogs.push(finalMsg);
|
|
103
|
+
adjustRecentLogs();
|
|
104
|
+
socket.emit('applog-event', finalMsg);
|
|
105
|
+
} else {
|
|
106
|
+
beforeRecentLogs.push(finalMsg);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function getRecentAppLogRecords() {
|
|
111
|
+
return recentLogs ?? beforeRecentLogs;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
module.exports = {
|
|
115
|
+
initializeRecentLogProvider,
|
|
116
|
+
getRecentAppLogRecords,
|
|
117
|
+
pushToRecentLogs,
|
|
118
|
+
copyAppLogsIntoFile,
|
|
119
|
+
};
|
|
@@ -12,7 +12,7 @@ function childProcessChecker() {
|
|
|
12
12
|
// This will come once parent dies.
|
|
13
13
|
// One way can be to check for error code ERR_IPC_CHANNEL_CLOSED
|
|
14
14
|
// and call process.exit()
|
|
15
|
-
logger.error(extractErrorLogData(err), 'parent died');
|
|
15
|
+
logger.error(extractErrorLogData(err), 'DBGM-00163 parent died');
|
|
16
16
|
process.exit(1);
|
|
17
17
|
}
|
|
18
18
|
}, 1000);
|