@oas-tools/oas-telemetry 0.2.1 → 0.2.2
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/dist/exporters/InMemoryDbExporter.cjs +19 -0
- package/dist/index.cjs +59 -17
- package/dist/ui.cjs +34 -16
- package/package.json +13 -7
- package/src/exporters/InMemoryDbExporter.js +28 -8
- package/src/index.js +87 -29
- package/src/ui.js +903 -887
|
@@ -7,6 +7,12 @@ exports.InMemoryExporter = void 0;
|
|
|
7
7
|
var _core = require("@opentelemetry/core");
|
|
8
8
|
var _nedb = _interopRequireDefault(require("nedb"));
|
|
9
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
11
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
12
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
13
|
+
let dbglog = () => {};
|
|
14
|
+
if (process.env.OTDEBUG == "true") dbglog = console.log;
|
|
15
|
+
|
|
10
16
|
//import in memory database
|
|
11
17
|
|
|
12
18
|
class InMemoryExporter {
|
|
@@ -24,6 +30,13 @@ class InMemoryExporter {
|
|
|
24
30
|
|
|
25
31
|
// Insert spans into the in-memory database
|
|
26
32
|
this._spans.insert(cleanSpans, (err, newDoc) => {
|
|
33
|
+
InMemoryExporter.plugins.forEach((p, i) => {
|
|
34
|
+
cleanSpans.forEach(t => {
|
|
35
|
+
dbglog(`Sending trace <${t._id}> to plugin (Plugin #${i}) <${p.name}>`);
|
|
36
|
+
dbglog(`Trace: \n<${JSON.stringify(t, null, 2)}`);
|
|
37
|
+
p.newTrace(t);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
27
40
|
if (err) {
|
|
28
41
|
console.error(err);
|
|
29
42
|
return;
|
|
@@ -64,8 +77,14 @@ class InMemoryExporter {
|
|
|
64
77
|
getFinishedSpans() {
|
|
65
78
|
return this._spans;
|
|
66
79
|
}
|
|
80
|
+
activatePlugin(plugin) {
|
|
81
|
+
dbglog(`Activating plugin <${plugin.getName()}>...`);
|
|
82
|
+
InMemoryExporter.plugins.push(plugin);
|
|
83
|
+
dbglog(`Plugin <${plugin.getName()}> active (Total active plugins: ${InMemoryExporter.plugins.length})`);
|
|
84
|
+
}
|
|
67
85
|
}
|
|
68
86
|
exports.InMemoryExporter = InMemoryExporter;
|
|
87
|
+
_defineProperty(InMemoryExporter, "plugins", []);
|
|
69
88
|
function removeCircularRefs(obj) {
|
|
70
89
|
const seen = new WeakMap(); // Used to keep track of visited objects
|
|
71
90
|
|
package/dist/index.cjs
CHANGED
|
@@ -11,9 +11,16 @@ var _fs = require("fs");
|
|
|
11
11
|
var _path = _interopRequireDefault(require("path"));
|
|
12
12
|
var _jsYaml = _interopRequireDefault(require("js-yaml"));
|
|
13
13
|
var _ui = _interopRequireDefault(require("./ui.cjs"));
|
|
14
|
+
var _axios = _interopRequireDefault(require("axios"));
|
|
14
15
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
16
|
// telemetryMiddleware.js
|
|
16
17
|
|
|
18
|
+
let dbglog = () => {};
|
|
19
|
+
if (process.env.OTDEBUG == "true") dbglog = console.log;
|
|
20
|
+
let plugins = [];
|
|
21
|
+
let telemetryStatus = {
|
|
22
|
+
active: true
|
|
23
|
+
};
|
|
17
24
|
let baseURL = '/telemetry';
|
|
18
25
|
let telemetryConfig = {
|
|
19
26
|
exporter: _telemetry.inMemoryExporter,
|
|
@@ -21,19 +28,18 @@ let telemetryConfig = {
|
|
|
21
28
|
};
|
|
22
29
|
function oasTelemetry(tlConfig) {
|
|
23
30
|
if (tlConfig) {
|
|
24
|
-
|
|
31
|
+
dbglog('Telemetry config provided');
|
|
25
32
|
telemetryConfig = tlConfig;
|
|
26
33
|
if (telemetryConfig.exporter == undefined) telemetryConfig.exporter = _telemetry.inMemoryExporter;
|
|
27
34
|
}
|
|
28
|
-
if (telemetryConfig.spec)
|
|
29
|
-
if (telemetryConfig.specFileName != "")
|
|
30
|
-
console.
|
|
35
|
+
if (telemetryConfig.spec) dbglog(`Spec content provided`);else {
|
|
36
|
+
if (telemetryConfig.specFileName != "") dbglog(`Spec file used for telemetry: ${telemetryConfig.specFileName}`);else {
|
|
37
|
+
console.error("No spec available !");
|
|
31
38
|
}
|
|
32
39
|
}
|
|
33
40
|
const router = (0, _express.Router)();
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
if (telemetryConfig.baseURL) baseURL = telemetryConfig.baseURL;
|
|
42
|
+
router.use((0, _express.json)());
|
|
37
43
|
router.get(baseURL, mainPage);
|
|
38
44
|
router.get(baseURL + "/detail/*", detailPage);
|
|
39
45
|
router.get(baseURL + "/spec", specLoader);
|
|
@@ -45,6 +51,8 @@ function oasTelemetry(tlConfig) {
|
|
|
45
51
|
router.get(baseURL + "/list", listTelemetry);
|
|
46
52
|
router.post(baseURL + "/find", findTelemetry);
|
|
47
53
|
router.get(baseURL + "/heapStats", heapStats);
|
|
54
|
+
router.get(baseURL + "/plugins", listPlugins);
|
|
55
|
+
router.post(baseURL + "/plugins", registerPlugin);
|
|
48
56
|
return router;
|
|
49
57
|
}
|
|
50
58
|
const apiPage = (req, res) => {
|
|
@@ -138,6 +146,17 @@ const listTelemetry = (req, res) => {
|
|
|
138
146
|
});
|
|
139
147
|
});
|
|
140
148
|
};
|
|
149
|
+
const heapStats = (req, res) => {
|
|
150
|
+
var heapStats = _v.default.getHeapStatistics();
|
|
151
|
+
|
|
152
|
+
// Round stats to MB
|
|
153
|
+
var roundedHeapStats = Object.getOwnPropertyNames(heapStats).reduce(function (map, stat) {
|
|
154
|
+
map[stat] = Math.round(heapStats[stat] / 1024 / 1024 * 1000) / 1000;
|
|
155
|
+
return map;
|
|
156
|
+
}, {});
|
|
157
|
+
roundedHeapStats['units'] = 'MB';
|
|
158
|
+
res.send(roundedHeapStats);
|
|
159
|
+
};
|
|
141
160
|
const findTelemetry = (req, res) => {
|
|
142
161
|
const spansDB = telemetryConfig.exporter.getFinishedSpans();
|
|
143
162
|
const body = req.body;
|
|
@@ -174,15 +193,38 @@ const findTelemetry = (req, res) => {
|
|
|
174
193
|
});
|
|
175
194
|
}
|
|
176
195
|
};
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
|
|
196
|
+
const listPlugins = (req, res) => {
|
|
197
|
+
res.send(plugins.map(p => {
|
|
198
|
+
return {
|
|
199
|
+
id: p.id,
|
|
200
|
+
url: p.url,
|
|
201
|
+
active: p.active
|
|
202
|
+
};
|
|
203
|
+
}));
|
|
204
|
+
};
|
|
205
|
+
const registerPlugin = (req, res) => {
|
|
206
|
+
let pluginResource = req.body;
|
|
207
|
+
dbglog(`Plugin Registration Request: = ${JSON.stringify(req.body, null, 2)}...`);
|
|
208
|
+
dbglog(`Getting plugin at ${pluginResource.url}...`);
|
|
209
|
+
_axios.default.get(pluginResource.url).then(response => {
|
|
210
|
+
dbglog(`Plugin fetched.`);
|
|
211
|
+
const pluginCode = response.data;
|
|
212
|
+
dbglog("Plugin size: " + pluginCode.length);
|
|
213
|
+
var plugin;
|
|
214
|
+
eval(pluginCode);
|
|
215
|
+
plugin.load(pluginResource.config);
|
|
216
|
+
if (plugin.isConfigured()) {
|
|
217
|
+
dbglog(`Loaded plugin <${plugin.getName()}>`);
|
|
218
|
+
pluginResource.plugin = plugin;
|
|
219
|
+
pluginResource.name = plugin.getName();
|
|
220
|
+
pluginResource.active = true;
|
|
221
|
+
plugins.push(pluginResource);
|
|
222
|
+
_telemetry.inMemoryExporter.activatePlugin(pluginResource.plugin);
|
|
223
|
+
res.status(201).send(`Plugin registered`);
|
|
224
|
+
} else {
|
|
225
|
+
console.error(`Plugin <${plugin.getName()}> can not be configured`);
|
|
226
|
+
res.status(400).send(`Plugin configuration problem`);
|
|
227
|
+
}
|
|
228
|
+
}).catch(err => console.error("registerPlugin:" + err));
|
|
187
229
|
};
|
|
188
230
|
module.exports = exports.default;
|
package/dist/ui.cjs
CHANGED
|
@@ -6,8 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = ui;
|
|
7
7
|
function ui() {
|
|
8
8
|
return {
|
|
9
|
-
main:
|
|
10
|
-
<!DOCTYPE html>
|
|
9
|
+
main: `<!DOCTYPE html>
|
|
11
10
|
<html lang="en">
|
|
12
11
|
|
|
13
12
|
<head>
|
|
@@ -124,14 +123,16 @@ function ui() {
|
|
|
124
123
|
if (c != "") {
|
|
125
124
|
pathRegExpStr += "/";
|
|
126
125
|
if (c.charAt(0) == "{" && c.charAt(c.length - 1) == "}") {
|
|
127
|
-
|
|
126
|
+
// Ensure it matches at least one character (.+)
|
|
127
|
+
pathRegExpStr += "(.+)";
|
|
128
128
|
} else {
|
|
129
129
|
pathRegExpStr += c;
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
});
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
|
|
134
|
+
// Allow an optional trailing slash
|
|
135
|
+
pathRegExpStr += "/?\$";
|
|
135
136
|
|
|
136
137
|
return pathRegExpStr;
|
|
137
138
|
}
|
|
@@ -380,8 +381,7 @@ function ui() {
|
|
|
380
381
|
</body>
|
|
381
382
|
|
|
382
383
|
</html>`,
|
|
383
|
-
detail:
|
|
384
|
-
<!DOCTYPE html>
|
|
384
|
+
detail: `<!DOCTYPE html>
|
|
385
385
|
<html lang="en">
|
|
386
386
|
|
|
387
387
|
<head>
|
|
@@ -584,14 +584,16 @@ function ui() {
|
|
|
584
584
|
if (c != "") {
|
|
585
585
|
pathRegExpStr += "/";
|
|
586
586
|
if (c.charAt(0) == "{" && c.charAt(c.length - 1) == "}") {
|
|
587
|
-
|
|
587
|
+
// Ensure it matches at least one character (.+)
|
|
588
|
+
pathRegExpStr += "(.+)";
|
|
588
589
|
} else {
|
|
589
590
|
pathRegExpStr += c;
|
|
590
591
|
}
|
|
591
592
|
}
|
|
592
593
|
});
|
|
593
594
|
|
|
594
|
-
|
|
595
|
+
// Allow an optional trailing slash
|
|
596
|
+
pathRegExpStr += "/?\$";
|
|
595
597
|
|
|
596
598
|
return pathRegExpStr;
|
|
597
599
|
}
|
|
@@ -600,7 +602,24 @@ function ui() {
|
|
|
600
602
|
try {
|
|
601
603
|
log(\`Fetchig traces for <\${path}> - \${method} - \${status},.. \`);
|
|
602
604
|
|
|
603
|
-
const
|
|
605
|
+
const body = {
|
|
606
|
+
"flags": { "containsRegex": true },
|
|
607
|
+
"config": { "regexIds": ["attributes.http.target"] },
|
|
608
|
+
"search": {
|
|
609
|
+
"attributes.http.target": getPathRegEx(path),
|
|
610
|
+
"attributes.http.method": method.toUpperCase(),
|
|
611
|
+
"attributes.http.status_code": parseInt(status)
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
log("body: " + JSON.stringify(body, null, 2));
|
|
615
|
+
//response is to the post at /telemetry/find
|
|
616
|
+
const response = await fetch("/telemetry/find", {
|
|
617
|
+
method: "POST",
|
|
618
|
+
headers: {
|
|
619
|
+
"Content-Type": "application/json"
|
|
620
|
+
},
|
|
621
|
+
body: JSON.stringify(body)
|
|
622
|
+
});
|
|
604
623
|
|
|
605
624
|
if (!response.ok) {
|
|
606
625
|
throw new Error("ERROR getting the Traces.");
|
|
@@ -608,13 +627,12 @@ function ui() {
|
|
|
608
627
|
|
|
609
628
|
const responseJSON = await response.json();
|
|
610
629
|
const traces = responseJSON.spans;
|
|
611
|
-
const filteredTraces = traces; //filter made in server side
|
|
612
|
-
log(\`Feched \${traces.length} traces.\`);
|
|
613
|
-
//log(\`First trace: \${JSON.stringify(traces[0],null,2)}\`);
|
|
614
630
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
631
|
+
log(\`Fetched \${traces.length} traces.\`);
|
|
632
|
+
|
|
633
|
+
if (traces.length != traceCount) {
|
|
634
|
+
loadTraces(traces);
|
|
635
|
+
traceCount = traces.length;
|
|
618
636
|
}
|
|
619
637
|
|
|
620
638
|
setTimeout(fetchTracesByParsing, 1000, path, method, status);
|
package/package.json
CHANGED
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oas-tools/oas-telemetry",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "This package exports an
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "This package exports an Express middleware that traces requests and responses of an Express application using OpenTelemetry.",
|
|
5
5
|
"author": "Manuel Otero",
|
|
6
6
|
"contributors": [
|
|
7
|
-
"Alejandro Santisteban",
|
|
7
|
+
"Alejandro Santisteban",
|
|
8
|
+
"Pablo Fernandez"
|
|
8
9
|
],
|
|
9
10
|
"license": "Apache-2.0",
|
|
10
11
|
"type": "module",
|
|
11
12
|
"scripts": {
|
|
13
|
+
"devImportUi": "node dev/ui/importUiToHtml.js",
|
|
14
|
+
"devExportUi": "node dev/ui/exportHtmlToUi.js",
|
|
12
15
|
"build": "babel src -d dist --out-file-extension .cjs",
|
|
16
|
+
"devUi": "nodemon --watch dev/ui --ext html --exec \"npm run devExportUi && npm run build && node test/functional/otTestServer.cjs\"",
|
|
13
17
|
"publish": "npm run build && npm publish",
|
|
14
18
|
"testPerformance": "npm i && cd test/performance/ && ./test.sh",
|
|
15
19
|
"pretest": "npm run build",
|
|
16
|
-
"test": "npm run testCJS && npm run testMJS",
|
|
17
|
-
"testCJS": "npm run preTestCJS && npm run launchTestCJS && npm run postTestCJS",
|
|
20
|
+
"test": "npm run testCJS && npm run testMJS",
|
|
21
|
+
"testCJS": "npm run preTestCJS && npm run launchTestCJS && npm run postTestCJS",
|
|
18
22
|
"preTestCJS": "node test/functional/otTestServer.cjs &",
|
|
19
23
|
"launchTestCJS": "npx -y wait-on http://localhost:3000/api/v1/pets && npm run sendRequests && sleep 4 && npm run checkRequestsLog",
|
|
20
24
|
"postTestCJS": "kill `ps -uax | grep \"node test/functional/otTestServer\" | grep -v \"grep\" | grep -v \"sh\" | awk '{print $2}'`",
|
|
21
|
-
"testMJS": "npm run preTestMJS && npm run launchTestMJS && npm run postTestMJS",
|
|
25
|
+
"testMJS": "npm run preTestMJS && npm run launchTestMJS && npm run postTestMJS",
|
|
22
26
|
"preTestMJS": "node test/functional/otTestServer.mjs &",
|
|
23
27
|
"launchTestMJS": "npx -y wait-on http://localhost:3000/api/v1/pets && npm run sendRequests && sleep 4 && npm run checkRequestsLog",
|
|
24
28
|
"postTestMJS": "kill `ps -uax | grep \"node test/functional/otTestServer\" | grep -v \"grep\" | grep -v \"sh\" | awk '{print $2}'`",
|
|
25
29
|
"sendRequests": "npx -y newman run test/functional/request-collection.json -e test/functional/request-environment.json",
|
|
26
|
-
"checkRequestsLog": "npx -y newman run test/functional/request-collection-check.json -e test/functional/request-environment.json"
|
|
30
|
+
"checkRequestsLog": "npx -y newman run test/functional/request-collection-check.json -e test/functional/request-environment.json",
|
|
31
|
+
"launchKSApi": "npm run build; (cd test/performance/ks-api ; node indexTelemetry.js)",
|
|
32
|
+
"launchDevel": "export OTDEBUG=true && npm run launchKSApi"
|
|
27
33
|
},
|
|
28
34
|
"files": [
|
|
29
35
|
"dist",
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { ExportResultCode } from '@opentelemetry/core';
|
|
2
2
|
|
|
3
|
+
let dbglog = ()=>{};
|
|
4
|
+
|
|
5
|
+
if(process.env.OTDEBUG == "true")
|
|
6
|
+
dbglog = console.log;
|
|
7
|
+
|
|
3
8
|
//import in memory database
|
|
4
|
-
import dataStore from 'nedb'
|
|
9
|
+
import dataStore from 'nedb';
|
|
5
10
|
|
|
6
11
|
export class InMemoryExporter {
|
|
7
12
|
constructor() {
|
|
8
13
|
this._spans = new dataStore();
|
|
9
14
|
this._stopped = true;
|
|
10
|
-
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
static plugins = [];
|
|
18
|
+
|
|
11
19
|
export(readableSpans, resultCallback) {
|
|
12
20
|
try {
|
|
13
21
|
if (!this._stopped) {
|
|
@@ -19,6 +27,13 @@ export class InMemoryExporter {
|
|
|
19
27
|
|
|
20
28
|
// Insert spans into the in-memory database
|
|
21
29
|
this._spans.insert(cleanSpans, (err, newDoc) => {
|
|
30
|
+
InMemoryExporter.plugins.forEach((p,i)=>{
|
|
31
|
+
cleanSpans.forEach((t)=>{
|
|
32
|
+
dbglog(`Sending trace <${t._id}> to plugin (Plugin #${i}) <${p.name}>`);
|
|
33
|
+
dbglog(`Trace: \n<${JSON.stringify(t,null,2)}`);
|
|
34
|
+
p.newTrace(t);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
22
37
|
if (err) {
|
|
23
38
|
console.error(err);
|
|
24
39
|
return;
|
|
@@ -34,29 +49,34 @@ export class InMemoryExporter {
|
|
|
34
49
|
error: new Error('Error exporting spans\n' + error.message + '\n' + error.stack),
|
|
35
50
|
})
|
|
36
51
|
}
|
|
37
|
-
}
|
|
52
|
+
};
|
|
38
53
|
start() {
|
|
39
54
|
this._stopped = false;
|
|
40
|
-
}
|
|
55
|
+
};
|
|
41
56
|
stop() {
|
|
42
57
|
this._stopped = true;
|
|
43
|
-
}
|
|
58
|
+
};
|
|
44
59
|
shutdown() {
|
|
45
60
|
this._stopped = true;
|
|
46
61
|
this._spans = new dataStore();
|
|
47
62
|
return this.forceFlush();
|
|
48
|
-
}
|
|
63
|
+
};
|
|
49
64
|
/**
|
|
50
65
|
* Exports any pending spans in the exporter
|
|
51
66
|
*/
|
|
52
67
|
forceFlush() {
|
|
53
68
|
return Promise.resolve();
|
|
54
|
-
}
|
|
69
|
+
};
|
|
55
70
|
reset() {
|
|
56
71
|
this._spans = new dataStore();
|
|
57
|
-
}
|
|
72
|
+
};
|
|
58
73
|
getFinishedSpans() {
|
|
59
74
|
return this._spans;
|
|
75
|
+
};
|
|
76
|
+
activatePlugin(plugin){
|
|
77
|
+
dbglog(`Activating plugin <${plugin.getName()}>...`);
|
|
78
|
+
InMemoryExporter.plugins.push(plugin);
|
|
79
|
+
dbglog(`Plugin <${plugin.getName()}> active (Total active plugins: ${InMemoryExporter.plugins.length})`);
|
|
60
80
|
}
|
|
61
81
|
}
|
|
62
82
|
|
package/src/index.js
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
// telemetryMiddleware.js
|
|
2
2
|
import { inMemoryExporter } from './telemetry.js';
|
|
3
|
-
import { Router } from 'express';
|
|
3
|
+
import { Router,json } from 'express';
|
|
4
4
|
import v8 from 'v8';
|
|
5
5
|
import { readFileSync, existsSync } from 'fs';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import yaml from 'js-yaml';
|
|
8
8
|
import ui from './ui.js'
|
|
9
|
+
import axios from 'axios';
|
|
10
|
+
|
|
11
|
+
let dbglog = ()=>{};
|
|
12
|
+
|
|
13
|
+
if(process.env.OTDEBUG == "true")
|
|
14
|
+
dbglog = console.log;
|
|
15
|
+
|
|
16
|
+
let plugins = [];
|
|
17
|
+
|
|
18
|
+
let telemetryStatus = {
|
|
19
|
+
active : true
|
|
20
|
+
};
|
|
9
21
|
|
|
10
22
|
let baseURL = '/telemetry';
|
|
11
23
|
|
|
@@ -16,40 +28,42 @@ let telemetryConfig = {
|
|
|
16
28
|
|
|
17
29
|
export default function oasTelemetry(tlConfig) {
|
|
18
30
|
if (tlConfig) {
|
|
19
|
-
|
|
31
|
+
dbglog('Telemetry config provided');
|
|
20
32
|
telemetryConfig = tlConfig;
|
|
21
33
|
if (telemetryConfig.exporter == undefined)
|
|
22
34
|
telemetryConfig.exporter = inMemoryExporter;
|
|
23
35
|
}
|
|
24
36
|
|
|
25
37
|
if (telemetryConfig.spec)
|
|
26
|
-
|
|
38
|
+
dbglog(`Spec content provided`);
|
|
27
39
|
else {
|
|
28
40
|
if (telemetryConfig.specFileName != "")
|
|
29
|
-
|
|
41
|
+
dbglog(`Spec file used for telemetry: ${telemetryConfig.specFileName}`);
|
|
30
42
|
else {
|
|
31
|
-
console.
|
|
43
|
+
console.error("No spec available !");
|
|
32
44
|
}
|
|
33
45
|
}
|
|
34
46
|
|
|
35
|
-
|
|
36
|
-
|
|
37
47
|
const router = Router();
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
if (telemetryConfig.baseURL)
|
|
50
|
+
baseURL = telemetryConfig.baseURL;
|
|
40
51
|
|
|
41
|
-
router.
|
|
42
|
-
router.get(baseURL + "/detail/*", detailPage);
|
|
43
|
-
router.get(baseURL + "/spec", specLoader);
|
|
44
|
-
router.get(baseURL + "/api", apiPage);
|
|
45
|
-
router.get(baseURL + "/start", startTelemetry);
|
|
46
|
-
router.get(baseURL + "/stop", stopTelemetry);
|
|
47
|
-
router.get(baseURL + "/status", statusTelemetry);
|
|
48
|
-
router.get(baseURL + "/reset", resetTelemetry);
|
|
49
|
-
router.get(baseURL + "/list", listTelemetry);
|
|
50
|
-
router.post(baseURL + "/find", findTelemetry);
|
|
51
|
-
router.get(baseURL + "/heapStats", heapStats);
|
|
52
|
+
router.use(json());
|
|
52
53
|
|
|
54
|
+
router.get(baseURL, mainPage);
|
|
55
|
+
router.get(baseURL+"/detail/*", detailPage);
|
|
56
|
+
router.get(baseURL+"/spec", specLoader);
|
|
57
|
+
router.get(baseURL+"/api", apiPage);
|
|
58
|
+
router.get(baseURL+"/start", startTelemetry);
|
|
59
|
+
router.get(baseURL+"/stop", stopTelemetry);
|
|
60
|
+
router.get(baseURL+"/status", statusTelemetry);
|
|
61
|
+
router.get(baseURL+"/reset", resetTelemetry);
|
|
62
|
+
router.get(baseURL+"/list", listTelemetry);
|
|
63
|
+
router.post(baseURL+"/find", findTelemetry);
|
|
64
|
+
router.get(baseURL+"/heapStats", heapStats);
|
|
65
|
+
router.get(baseURL+"/plugins", listPlugins);
|
|
66
|
+
router.post(baseURL+"/plugins", registerPlugin);
|
|
53
67
|
return router;
|
|
54
68
|
}
|
|
55
69
|
|
|
@@ -154,6 +168,19 @@ const listTelemetry = (req, res) => {
|
|
|
154
168
|
});
|
|
155
169
|
}
|
|
156
170
|
|
|
171
|
+
const heapStats = (req, res) => {
|
|
172
|
+
var heapStats = v8.getHeapStatistics();
|
|
173
|
+
|
|
174
|
+
// Round stats to MB
|
|
175
|
+
var roundedHeapStats = Object.getOwnPropertyNames(heapStats).reduce(function (map, stat) {
|
|
176
|
+
map[stat] = Math.round((heapStats[stat] / 1024 / 1024) * 1000) / 1000;
|
|
177
|
+
return map;
|
|
178
|
+
}, {});
|
|
179
|
+
roundedHeapStats['units'] = 'MB';
|
|
180
|
+
|
|
181
|
+
res.send(roundedHeapStats);
|
|
182
|
+
}
|
|
183
|
+
|
|
157
184
|
const findTelemetry = (req, res) => {
|
|
158
185
|
const spansDB = telemetryConfig.exporter.getFinishedSpans();
|
|
159
186
|
const body = req.body;
|
|
@@ -181,17 +208,48 @@ const findTelemetry = (req, res) => {
|
|
|
181
208
|
}
|
|
182
209
|
}
|
|
183
210
|
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
|
|
211
|
+
const listPlugins = (req, res) => {
|
|
212
|
+
res.send(plugins.map((p)=>{
|
|
213
|
+
return {
|
|
214
|
+
id:p.id,
|
|
215
|
+
url:p.url,
|
|
216
|
+
active:p.active
|
|
217
|
+
};
|
|
218
|
+
}));
|
|
219
|
+
}
|
|
193
220
|
|
|
194
|
-
|
|
221
|
+
const registerPlugin = (req, res) => {
|
|
222
|
+
let pluginResource = req.body;
|
|
223
|
+
dbglog(`Plugin Registration Request: = ${JSON.stringify(req.body,null,2)}...`);
|
|
224
|
+
dbglog(`Getting plugin at ${pluginResource.url}...`);
|
|
225
|
+
|
|
226
|
+
axios
|
|
227
|
+
.get(pluginResource.url)
|
|
228
|
+
.then((response) => {
|
|
229
|
+
dbglog(`Plugin fetched.`);
|
|
230
|
+
const pluginCode = response.data;
|
|
231
|
+
dbglog("Plugin size: "+pluginCode.length);
|
|
232
|
+
var plugin;
|
|
233
|
+
eval(pluginCode);
|
|
234
|
+
plugin.load(pluginResource.config);
|
|
235
|
+
if(plugin.isConfigured()){
|
|
236
|
+
dbglog(`Loaded plugin <${plugin.getName()}>`);
|
|
237
|
+
pluginResource.plugin = plugin;
|
|
238
|
+
pluginResource.name = plugin.getName();
|
|
239
|
+
|
|
240
|
+
pluginResource.active = true;
|
|
241
|
+
plugins.push(pluginResource);
|
|
242
|
+
inMemoryExporter.activatePlugin(pluginResource.plugin);
|
|
243
|
+
res.status(201).send(`Plugin registered`);
|
|
244
|
+
}else{
|
|
245
|
+
console.error(`Plugin <${plugin.getName()}> can not be configured`);
|
|
246
|
+
res.status(400).send(`Plugin configuration problem`);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
}).catch((err) => console.error("registerPlugin:"+err));
|
|
250
|
+
|
|
251
|
+
|
|
195
252
|
}
|
|
196
253
|
|
|
197
254
|
|
|
255
|
+
|